llviewerregion.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:39k
- /**
- * @file llviewerregion.cpp
- * @brief Implementation of the LLViewerRegion class.
- *
- * $LicenseInfo:firstyear=2000&license=viewergpl$
- *
- * Copyright (c) 2000-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llviewerregion.h"
- #include "indra_constants.h"
- #include "llfloaterreg.h"
- #include "llmath.h"
- #include "llhttpclient.h"
- #include "llregionflags.h"
- #include "llregionhandle.h"
- #include "llsurface.h"
- #include "message.h"
- //#include "vmath.h"
- #include "v3math.h"
- #include "v4math.h"
- #include "llagent.h"
- #include "llcallingcard.h"
- #include "llcaphttpsender.h"
- #include "lldir.h"
- #include "lleventpoll.h"
- #include "llfloatergodtools.h"
- #include "llfloaterreporter.h"
- #include "llfloaterregioninfo.h"
- #include "llhttpnode.h"
- #include "llsdutil.h"
- #include "llstartup.h"
- #include "lltrans.h"
- #include "llviewerobjectlist.h"
- #include "llviewerparceloverlay.h"
- #include "llvlmanager.h"
- #include "llvlcomposition.h"
- #include "llvocache.h"
- #include "llvoclouds.h"
- #include "llworld.h"
- #include "llspatialpartition.h"
- #include "stringize.h"
- #ifdef LL_WINDOWS
- #pragma warning(disable:4355)
- #endif
- // Viewer object cache version, change if object update
- // format changes. JC
- const U32 INDRA_OBJECT_CACHE_VERSION = 14;
- extern BOOL gNoRender;
- const F32 WATER_TEXTURE_SCALE = 8.f; // Number of times to repeat the water texture across a region
- const S16 MAX_MAP_DIST = 10;
- class BaseCapabilitiesComplete : public LLHTTPClient::Responder
- {
- LOG_CLASS(BaseCapabilitiesComplete);
- public:
- BaseCapabilitiesComplete(LLViewerRegion* region)
- : mRegion(region)
- { }
- virtual ~BaseCapabilitiesComplete()
- {
- if(mRegion)
- {
- mRegion->setHttpResponderPtrNULL() ;
- }
- }
- void setRegion(LLViewerRegion* region)
- {
- mRegion = region ;
- }
- void error(U32 statusNum, const std::string& reason)
- {
- LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
-
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
- }
- }
- void result(const LLSD& content)
- {
- if(!mRegion || LLHTTPClient::ResponderPtr(this) != mRegion->getHttpResponderPtr()) //region is removed or responder is not created.
- {
- return ;
- }
- LLSD::map_const_iterator iter;
- for(iter = content.beginMap(); iter != content.endMap(); ++iter)
- {
- mRegion->setCapability(iter->first, iter->second);
- LL_DEBUGS2("AppInit", "Capabilities") << "got capability for "
- << iter->first << LL_ENDL;
- /* HACK we're waiting for the ServerReleaseNotes */
- if (iter->first == "ServerReleaseNotes" && mRegion->getReleaseNotesRequested())
- {
- mRegion->showReleaseNotes();
- }
- }
-
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
- }
- }
- static boost::intrusive_ptr<BaseCapabilitiesComplete> build(
- LLViewerRegion* region)
- {
- return boost::intrusive_ptr<BaseCapabilitiesComplete>(
- new BaseCapabilitiesComplete(region));
- }
- private:
- LLViewerRegion* mRegion;
- };
- LLViewerRegion::LLViewerRegion(const U64 &handle,
- const LLHost &host,
- const U32 grids_per_region_edge,
- const U32 grids_per_patch_edge,
- const F32 region_width_meters)
- : mCenterGlobal(),
- mHandle(handle),
- mHost( host ),
- mTimeDilation(1.0f),
- mName(""),
- mZoning(""),
- mOwnerID(),
- mIsEstateManager(FALSE),
- mCompositionp(NULL),
- mRegionFlags( REGION_FLAGS_DEFAULT ),
- mSimAccess( SIM_ACCESS_MIN ),
- mBillableFactor(1.0),
- mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
- mClassID(0),
- mCPURatio(0),
- mColoName("unknown"),
- mProductSKU("unknown"),
- mProductName("unknown"),
- mCacheLoaded(FALSE),
- mCacheEntriesCount(0),
- mCacheID(),
- mEventPoll(NULL),
- mReleaseNotesRequested(FALSE),
- // I'd prefer to set the LLCapabilityListener name to match the region
- // name -- it's disappointing that's not available at construction time.
- // We could instead store an LLCapabilityListener*, making
- // setRegionNameAndZone() replace the instance. Would that pose
- // consistency problems? Can we even request a capability before calling
- // setRegionNameAndZone()?
- // For testability -- the new Michael Feathers paradigm --
- // LLCapabilityListener binds all the globals it expects to need at
- // construction time.
- mCapabilityListener(host.getString(), gMessageSystem, *this,
- gAgent.getID(), gAgent.getSessionID())
- {
- mWidth = region_width_meters;
- mOriginGlobal = from_region_handle(handle);
- updateRenderMatrix();
- mLandp = new LLSurface('l', NULL);
- if (!gNoRender)
- {
- // Create the composition layer for the surface
- mCompositionp = new LLVLComposition(mLandp, grids_per_region_edge, region_width_meters/grids_per_region_edge);
- mCompositionp->setSurface(mLandp);
- // Create the surfaces
- mLandp->setRegion(this);
- mLandp->create(grids_per_region_edge,
- grids_per_patch_edge,
- mOriginGlobal,
- mWidth);
- }
- if (!gNoRender)
- {
- mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
- }
- else
- {
- mParcelOverlay = NULL;
- }
- setOriginGlobal(from_region_handle(handle));
- calculateCenterGlobal();
- // Create the object lists
- initStats();
- mCacheStart.append(mCacheEnd);
-
- //create object partitions
- //MUST MATCH declaration of eObjectPartitions
- mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD
- mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN
- mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER
- mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE
- mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE
- mObjectPartition.push_back(new LLCloudPartition()); //PARTITION_CLOUD
- mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS
- mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME
- mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE
- mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
- mObjectPartition.push_back(NULL); //PARTITION_NONE
- }
- void LLViewerRegion::initStats()
- {
- mLastNetUpdate.reset();
- mPacketsIn = 0;
- mBitsIn = 0;
- mLastBitsIn = 0;
- mLastPacketsIn = 0;
- mPacketsOut = 0;
- mLastPacketsOut = 0;
- mPacketsLost = 0;
- mLastPacketsLost = 0;
- mPingDelay = 0;
- mAlive = false; // can become false if circuit disconnects
- }
- LLViewerRegion::~LLViewerRegion()
- {
- if(mHttpResponderPtr)
- {
- (static_cast<BaseCapabilitiesComplete*>(mHttpResponderPtr.get()))->setRegion(NULL) ;
- }
- gVLManager.cleanupData(this);
- // Can't do this on destruction, because the neighbor pointers might be invalid.
- // This should be reference counted...
- disconnectAllNeighbors();
- mCloudLayer.destroy();
- LLViewerPartSim::getInstance()->cleanupRegion(this);
- gObjectList.killObjects(this);
- delete mCompositionp;
- delete mParcelOverlay;
- delete mLandp;
- delete mEventPoll;
- LLHTTPSender::clearSender(mHost);
-
- saveCache();
- std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer());
- }
- void LLViewerRegion::loadCache()
- {
- if (mCacheLoaded)
- {
- return;
- }
- // Presume success. If it fails, we don't want to try again.
- mCacheLoaded = TRUE;
- LLVOCacheEntry *entry;
- std::string filename;
- filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"") + gDirUtilp->getDirDelimiter() +
- llformat("objects_%d_%d.slc",U32(mHandle>>32)/REGION_WIDTH_UNITS, U32(mHandle)/REGION_WIDTH_UNITS );
- LLFILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
- if (!fp)
- {
- // might not have a file, which is normal
- return;
- }
- U32 zero;
- size_t nread;
- nread = fread(&zero, sizeof(U32), 1, fp);
- if (nread != 1 || zero)
- {
- // a non-zero value here means bad things!
- // skip reading the cached values
- llinfos << "Cache file invalid" << llendl;
- fclose(fp);
- return;
- }
- U32 version;
- nread = fread(&version, sizeof(U32), 1, fp);
- if (nread != 1 || version != INDRA_OBJECT_CACHE_VERSION)
- {
- // a version mismatch here means we've changed the binary format!
- // skip reading the cached values
- llinfos << "Cache version changed, discarding" << llendl;
- fclose(fp);
- return;
- }
- LLUUID cache_id;
- nread = fread(&cache_id.mData, 1, UUID_BYTES, fp);
- if (nread != (size_t)UUID_BYTES || mCacheID != cache_id)
- {
- llinfos << "Cache ID doesn't match for this region, discarding"
- << llendl;
- fclose(fp);
- return;
- }
- S32 num_entries;
- nread = fread(&num_entries, sizeof(S32), 1, fp);
- if (nread != 1)
- {
- llinfos << "Short read, discarding" << llendl;
- fclose(fp);
- return;
- }
-
- S32 i;
- for (i = 0; i < num_entries; i++)
- {
- entry = new LLVOCacheEntry(fp);
- if (!entry->getLocalID())
- {
- llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
- delete entry;
- entry = NULL;
- break;
- }
- mCacheEnd.insert(*entry);
- mCacheMap[entry->getLocalID()] = entry;
- mCacheEntriesCount++;
- }
- fclose(fp);
- }
- void LLViewerRegion::saveCache()
- {
- if (!mCacheLoaded)
- {
- return;
- }
- S32 num_entries = mCacheEntriesCount;
- if (0 == num_entries)
- {
- return;
- }
- std::string filename;
- filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"") + gDirUtilp->getDirDelimiter() +
- llformat("sobjects_%d_%d.slc", U32(mHandle>>32)/REGION_WIDTH_UNITS, U32(mHandle)/REGION_WIDTH_UNITS );
- LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
- if (!fp)
- {
- llwarns << "Unable to write cache file " << filename << llendl;
- return;
- }
- // write out zero to indicate a version cache file
- U32 zero = 0;
- if (fwrite(&zero, sizeof(U32), 1, fp) != 1)
- {
- llwarns << "Short write" << llendl;
- }
- // write out version number
- U32 version = INDRA_OBJECT_CACHE_VERSION;
- if (fwrite(&version, sizeof(U32), 1, fp) != 1)
- {
- llwarns << "Short write" << llendl;
- }
- // write the cache id for this sim
- if (fwrite(&mCacheID.mData, 1, UUID_BYTES, fp) != (size_t)UUID_BYTES)
- {
- llwarns << "Short write" << llendl;
- }
- if (fwrite(&num_entries, sizeof(S32), 1, fp) != 1)
- {
- llwarns << "Short write" << llendl;
- }
- LLVOCacheEntry *entry;
- for (entry = mCacheStart.getNext(); entry && (entry != &mCacheEnd); entry = entry->getNext())
- {
- entry->writeToFile(fp);
- }
- mCacheMap.clear();
- mCacheEnd.unlink();
- mCacheEnd.init();
- mCacheStart.deleteAll();
- mCacheStart.init();
- fclose(fp);
- }
- void LLViewerRegion::sendMessage()
- {
- gMessageSystem->sendMessage(mHost);
- }
- void LLViewerRegion::sendReliableMessage()
- {
- gMessageSystem->sendReliable(mHost);
- }
- void LLViewerRegion::setFlags(BOOL b, U32 flags)
- {
- if (b)
- {
- mRegionFlags |= flags;
- }
- else
- {
- mRegionFlags &= ~flags;
- }
- }
- void LLViewerRegion::setWaterHeight(F32 water_level)
- {
- mLandp->setWaterHeight(water_level);
- }
- F32 LLViewerRegion::getWaterHeight() const
- {
- return mLandp->getWaterHeight();
- }
- BOOL LLViewerRegion::isVoiceEnabled() const
- {
- return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
- }
- void LLViewerRegion::setRegionFlags(U32 flags)
- {
- mRegionFlags = flags;
- }
- void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global)
- {
- mOriginGlobal = origin_global;
- updateRenderMatrix();
- mLandp->setOriginGlobal(origin_global);
- mWind.setOriginGlobal(origin_global);
- mCloudLayer.setOriginGlobal(origin_global);
- calculateCenterGlobal();
- }
- void LLViewerRegion::updateRenderMatrix()
- {
- mRenderMatrix.setTranslation(getOriginAgent());
- }
- void LLViewerRegion::setTimeDilation(F32 time_dilation)
- {
- mTimeDilation = time_dilation;
- }
- LLVector3 LLViewerRegion::getOriginAgent() const
- {
- return gAgent.getPosAgentFromGlobal(mOriginGlobal);
- }
- LLVector3 LLViewerRegion::getCenterAgent() const
- {
- return gAgent.getPosAgentFromGlobal(mCenterGlobal);
- }
- void LLViewerRegion::setRegionNameAndZone (const std::string& name_zone)
- {
- std::string::size_type pipe_pos = name_zone.find('|');
- S32 length = name_zone.size();
- if (pipe_pos != std::string::npos)
- {
- mName = name_zone.substr(0, pipe_pos);
- mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1));
- }
- else
- {
- mName = name_zone;
- mZoning = "";
- }
- LLStringUtil::stripNonprintable(mName);
- LLStringUtil::stripNonprintable(mZoning);
- }
- BOOL LLViewerRegion::canManageEstate() const
- {
- return gAgent.isGodlike()
- || isEstateManager()
- || gAgent.getID() == getOwner();
- }
- const std::string LLViewerRegion::getSimAccessString() const
- {
- return accessToString(mSimAccess);
- }
- // static
- std::string LLViewerRegion::regionFlagsToString(U32 flags)
- {
- std::string result;
- if (flags & REGION_FLAGS_SANDBOX)
- {
- result += "Sandbox";
- }
- if (flags & REGION_FLAGS_ALLOW_DAMAGE)
- {
- result += " Not Safe";
- }
- return result;
- }
- // static
- std::string LLViewerRegion::accessToString(U8 sim_access)
- {
- switch(sim_access)
- {
- case SIM_ACCESS_PG:
- return LLTrans::getString("SIM_ACCESS_PG");
- case SIM_ACCESS_MATURE:
- return LLTrans::getString("SIM_ACCESS_MATURE");
- case SIM_ACCESS_ADULT:
- return LLTrans::getString("SIM_ACCESS_ADULT");
- case SIM_ACCESS_DOWN:
- return LLTrans::getString("SIM_ACCESS_DOWN");
- case SIM_ACCESS_MIN:
- default:
- return LLTrans::getString("SIM_ACCESS_MIN");
- }
- }
- // static
- std::string LLViewerRegion::accessToShortString(U8 sim_access)
- {
- switch(sim_access) /* Flawfinder: ignore */
- {
- case SIM_ACCESS_PG:
- return "PG";
- case SIM_ACCESS_MATURE:
- return "M";
- case SIM_ACCESS_ADULT:
- return "A";
- case SIM_ACCESS_MIN:
- default:
- return "U";
- }
- }
- // static
- void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)
- {
- // send it to 'observers'
- LLFloaterGodTools::processRegionInfo(msg);
- LLFloaterRegionInfo::processRegionInfo(msg);
- LLFloaterReporter::processRegionInfo(msg);
- }
- S32 LLViewerRegion::renderPropertyLines()
- {
- if (mParcelOverlay)
- {
- return mParcelOverlay->renderPropertyLines();
- }
- else
- {
- return 0;
- }
- }
- // This gets called when the height field changes.
- void LLViewerRegion::dirtyHeights()
- {
- // Property lines need to be reconstructed when the land changes.
- if (mParcelOverlay)
- {
- mParcelOverlay->setDirty();
- }
- }
- BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
- {
- LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION);
- // did_update returns TRUE if we did at least one significant update
- BOOL did_update = mLandp->idleUpdate(max_update_time);
-
- if (mParcelOverlay)
- {
- // Hopefully not a significant time sink...
- mParcelOverlay->idleUpdate();
- }
- return did_update;
- }
- // As above, but forcibly do the update.
- void LLViewerRegion::forceUpdate()
- {
- mLandp->idleUpdate(0.f);
- if (mParcelOverlay)
- {
- mParcelOverlay->idleUpdate(true);
- }
- }
- void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
- {
- mLandp->connectNeighbor(neighborp->mLandp, direction);
- mCloudLayer.connectNeighbor(&(neighborp->mCloudLayer), direction);
- }
- void LLViewerRegion::disconnectAllNeighbors()
- {
- mLandp->disconnectAllNeighbors();
- mCloudLayer.disconnectAllNeighbors();
- }
- F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
- {
- if (x >= 256)
- {
- if (y >= 256)
- {
- LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
- if (regionp)
- {
- // OK, we need to do some hackery here - different simulators no longer use
- // the same composition values, necessarily.
- // If we're attempting to blend, then we want to make the fractional part of
- // this region match the fractional of the adjacent. For now, just minimize
- // the delta.
- F32 our_comp = getComposition()->getValueScaled(255, 255);
- F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
- while (llabs(our_comp - adj_comp) >= 1.f)
- {
- if (our_comp > adj_comp)
- {
- adj_comp += 1.f;
- }
- else
- {
- adj_comp -= 1.f;
- }
- }
- return adj_comp;
- }
- }
- else
- {
- LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
- if (regionp)
- {
- // OK, we need to do some hackery here - different simulators no longer use
- // the same composition values, necessarily.
- // If we're attempting to blend, then we want to make the fractional part of
- // this region match the fractional of the adjacent. For now, just minimize
- // the delta.
- F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
- F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
- while (llabs(our_comp - adj_comp) >= 1.f)
- {
- if (our_comp > adj_comp)
- {
- adj_comp += 1.f;
- }
- else
- {
- adj_comp -= 1.f;
- }
- }
- return adj_comp;
- }
- }
- }
- else if (y >= 256)
- {
- LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
- if (regionp)
- {
- // OK, we need to do some hackery here - different simulators no longer use
- // the same composition values, necessarily.
- // If we're attempting to blend, then we want to make the fractional part of
- // this region match the fractional of the adjacent. For now, just minimize
- // the delta.
- F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
- F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
- while (llabs(our_comp - adj_comp) >= 1.f)
- {
- if (our_comp > adj_comp)
- {
- adj_comp += 1.f;
- }
- else
- {
- adj_comp -= 1.f;
- }
- }
- return adj_comp;
- }
- }
- return getComposition()->getValueScaled((F32)x, (F32)y);
- }
- void LLViewerRegion::calculateCenterGlobal()
- {
- mCenterGlobal = mOriginGlobal;
- mCenterGlobal.mdV[VX] += 0.5 * mWidth;
- mCenterGlobal.mdV[VY] += 0.5 * mWidth;
- mCenterGlobal.mdV[VZ] = 0.5*mLandp->getMinZ() + mLandp->getMaxZ();
- }
- void LLViewerRegion::calculateCameraDistance()
- {
- mCameraDistanceSquared = (F32)(gAgent.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
- }
- std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion)
- {
- s << "{ ";
- s << region.mHost;
- s << " mOriginGlobal = " << region.getOriginGlobal()<< "n";
- std::string name(region.getName()), zone(region.getZoning());
- if (! name.empty())
- {
- s << " mName = " << name << 'n';
- }
- if (! zone.empty())
- {
- s << " mZoning = " << zone << 'n';
- }
- s << "}";
- return s;
- }
- // ---------------- Protected Member Functions ----------------
- void LLViewerRegion::updateNetStats()
- {
- F32 dt = mLastNetUpdate.getElapsedTimeAndResetF32();
- LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mHost);
- if (!cdp)
- {
- mAlive = false;
- return;
- }
- mAlive = true;
- mDeltaTime = dt;
- mLastPacketsIn = mPacketsIn;
- mLastBitsIn = mBitsIn;
- mLastPacketsOut = mPacketsOut;
- mLastPacketsLost = mPacketsLost;
- mPacketsIn = cdp->getPacketsIn();
- mBitsIn = 8 * cdp->getBytesIn();
- mPacketsOut = cdp->getPacketsOut();
- mPacketsLost = cdp->getPacketsLost();
- mPingDelay = cdp->getPingDelay();
- mBitStat.addValue(mBitsIn - mLastBitsIn);
- mPacketsStat.addValue(mPacketsIn - mLastPacketsIn);
- mPacketsLostStat.addValue(mPacketsLost);
- }
- U32 LLViewerRegion::getPacketsLost() const
- {
- LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mHost);
- if (!cdp)
- {
- llinfos << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mHost << llendl;
- return 0;
- }
- else
- {
- return cdp->getPacketsLost();
- }
- }
- BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const
- {
- LLVector3 pos_region = getPosRegionFromGlobal(point_global);
- if (pos_region.mV[VX] < 0)
- {
- return FALSE;
- }
- if (pos_region.mV[VX] >= mWidth)
- {
- return FALSE;
- }
- if (pos_region.mV[VY] < 0)
- {
- return FALSE;
- }
- if (pos_region.mV[VY] >= mWidth)
- {
- return FALSE;
- }
- return TRUE;
- }
- LLVector3 LLViewerRegion::getPosRegionFromGlobal(const LLVector3d &point_global) const
- {
- LLVector3 pos_region;
- pos_region.setVec(point_global - mOriginGlobal);
- return pos_region;
- }
- LLVector3d LLViewerRegion::getPosGlobalFromRegion(const LLVector3 &pos_region) const
- {
- LLVector3d pos_region_d;
- pos_region_d.setVec(pos_region);
- return pos_region_d + mOriginGlobal;
- }
- LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3 &pos_region) const
- {
- LLVector3d pos_global = getPosGlobalFromRegion(pos_region);
- return gAgent.getPosAgentFromGlobal(pos_global);
- }
- LLVector3 LLViewerRegion::getPosRegionFromAgent(const LLVector3 &pos_agent) const
- {
- return pos_agent - getOriginAgent();
- }
- F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
- {
- return mLandp->resolveHeightRegion( region_pos );
- }
- bool LLViewerRegion::isAlive()
- {
- return mAlive;
- }
- BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos)
- {
- if (mParcelOverlay)
- {
- return mParcelOverlay->isOwnedSelf(pos);
- } else {
- return FALSE;
- }
- }
- // Owned by a group you belong to? (officer or member)
- BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos)
- {
- if (mParcelOverlay)
- {
- return mParcelOverlay->isOwnedGroup(pos);
- } else {
- return FALSE;
- }
- }
- // the new TCP coarse location handler node
- class CoarseLocationUpdate : public LLHTTPNode
- {
- public:
- virtual void post(
- ResponsePtr responder,
- const LLSD& context,
- const LLSD& input) const
- {
- LLHost host(input["sender"].asString());
- LLViewerRegion* region = LLWorld::getInstance()->getRegion(host);
- if( !region )
- {
- return;
- }
- S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
- S32 you_index = input["body"]["Index"][0]["You" ].asInteger();
- LLDynamicArray<U32>* avatar_locs = ®ion->mMapAvatars;
- LLDynamicArray<LLUUID>* avatar_ids = ®ion->mMapAvatarIDs;
- avatar_locs->reset();
- avatar_ids->reset();
- //llinfos << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << llendl;
- //llinfos << "my agent id = " << gAgent.getID() << llendl;
- //llinfos << ll_pretty_print_sd(input) << llendl;
- LLSD
- locs = input["body"]["Location"],
- agents = input["body"]["AgentData"];
- LLSD::array_iterator
- locs_it = locs.beginArray(),
- agents_it = agents.beginArray();
- BOOL has_agent_data = input["body"].has("AgentData");
- for(int i=0;
- locs_it != locs.endArray();
- i++, locs_it++)
- {
- U8
- x = locs_it->get("X").asInteger(),
- y = locs_it->get("Y").asInteger(),
- z = locs_it->get("Z").asInteger();
- // treat the target specially for the map, and don't add you or the target
- if(i == target_index)
- {
- LLVector3d global_pos(region->getOriginGlobal());
- global_pos.mdV[VX] += (F64)x;
- global_pos.mdV[VY] += (F64)y;
- global_pos.mdV[VZ] += (F64)z * 4.0;
- LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
- }
- else if( i != you_index)
- {
- U32 loc = x << 16 | y << 8 | z; loc = loc;
- U32 pos = 0x0;
- pos |= x;
- pos <<= 8;
- pos |= y;
- pos <<= 8;
- pos |= z;
- avatar_locs->put(pos);
- //llinfos << "next pos: " << x << "," << y << "," << z << ": " << pos << llendl;
- if(has_agent_data) // for backwards compatibility with old message format
- {
- LLUUID agent_id(agents_it->get("AgentID").asUUID());
- //llinfos << "next agent: " << agent_id.asString() << llendl;
- avatar_ids->put(agent_id);
- }
- }
- if (has_agent_data)
- {
- agents_it++;
- }
- }
- }
- };
- // build the coarse location HTTP node under the "/message" URL
- LLHTTPRegistration<CoarseLocationUpdate>
- gHTTPRegistrationCoarseLocationUpdate(
- "/message/CoarseLocationUpdate");
- // the deprecated coarse location handler
- void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
- {
- //llinfos << "CoarseLocationUpdate" << llendl;
- mMapAvatars.reset();
- mMapAvatarIDs.reset(); // only matters in a rare case but it's good to be safe.
- U8 x_pos = 0;
- U8 y_pos = 0;
- U8 z_pos = 0;
- U32 pos = 0x0;
- S16 agent_index;
- S16 target_index;
- msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
- msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
- BOOL has_agent_data = msg->has(_PREHASH_AgentData);
- S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
- for(S32 i = 0; i < count; i++)
- {
- msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
- msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
- msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
- LLUUID agent_id = LLUUID::null;
- if(has_agent_data)
- {
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i);
- }
- //llinfos << " object X: " << (S32)x_pos << " Y: " << (S32)y_pos
- // << " Z: " << (S32)(z_pos * 4)
- // << llendl;
- // treat the target specially for the map
- if(i == target_index)
- {
- LLVector3d global_pos(mOriginGlobal);
- global_pos.mdV[VX] += (F64)(x_pos);
- global_pos.mdV[VY] += (F64)(y_pos);
- global_pos.mdV[VZ] += (F64)(z_pos) * 4.0;
- LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
- }
-
- //don't add you
- if( i != agent_index)
- {
- pos = 0x0;
- pos |= x_pos;
- pos <<= 8;
- pos |= y_pos;
- pos <<= 8;
- pos |= z_pos;
- mMapAvatars.put(pos);
- if(has_agent_data)
- {
- mMapAvatarIDs.put(agent_id);
- }
- }
- }
- }
- void LLViewerRegion::getInfo(LLSD& info)
- {
- info["Region"]["Host"] = getHost().getIPandPort();
- info["Region"]["Name"] = getName();
- U32 x, y;
- from_region_handle(getHandle(), &x, &y);
- info["Region"]["Handle"]["x"] = (LLSD::Integer)x;
- info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
- }
- void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)
- {
- U32 local_id = objectp->getLocalID();
- U32 crc = objectp->getCRC();
- LLVOCacheEntry* entry = get_if_there(mCacheMap, local_id, (LLVOCacheEntry*)NULL);
- if (entry)
- {
- // we've seen this object before
- if (entry->getCRC() == crc)
- {
- // Record a hit
- entry->recordDupe();
- }
- else
- {
- // Update the cache entry
- mCacheMap.erase(local_id);
- delete entry;
- entry = new LLVOCacheEntry(local_id, crc, dp);
- mCacheEnd.insert(*entry);
- mCacheMap[local_id] = entry;
- }
- }
- else
- {
- // we haven't seen this object before
- // Create new entry and add to map
- if (mCacheEntriesCount > MAX_OBJECT_CACHE_ENTRIES)
- {
- entry = mCacheStart.getNext();
- mCacheMap.erase(entry->getLocalID());
- delete entry;
- mCacheEntriesCount--;
- }
- entry = new LLVOCacheEntry(local_id, crc, dp);
- mCacheEnd.insert(*entry);
- mCacheMap[local_id] = entry;
- mCacheEntriesCount++;
- }
- return ;
- }
- // Get data packer for this object, if we have cached data
- // AND the CRC matches. JC
- LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc)
- {
- llassert(mCacheLoaded);
- LLVOCacheEntry* entry = get_if_there(mCacheMap, local_id, (LLVOCacheEntry*)NULL);
- if (entry)
- {
- // we've seen this object before
- if (entry->getCRC() == crc)
- {
- // Record a hit
- entry->recordHit();
- return entry->getDP(crc);
- }
- else
- {
- // llinfos << "CRC miss for " << local_id << llendl;
- mCacheMissCRC.put(local_id);
- }
- }
- else
- {
- // llinfos << "Cache miss for " << local_id << llendl;
- mCacheMissFull.put(local_id);
- }
- return NULL;
- }
- void LLViewerRegion::addCacheMissFull(const U32 local_id)
- {
- mCacheMissFull.put(local_id);
- }
- void LLViewerRegion::requestCacheMisses()
- {
- S32 full_count = mCacheMissFull.count();
- S32 crc_count = mCacheMissCRC.count();
- if (full_count == 0 && crc_count == 0) return;
- LLMessageSystem* msg = gMessageSystem;
- BOOL start_new_message = TRUE;
- S32 blocks = 0;
- S32 i;
- const U8 CACHE_MISS_TYPE_FULL = 0;
- const U8 CACHE_MISS_TYPE_CRC = 1;
- // Send full cache miss updates. For these, we KNOW we don't
- // have a viewer object.
- for (i = 0; i < full_count; i++)
- {
- if (start_new_message)
- {
- msg->newMessageFast(_PREHASH_RequestMultipleObjects);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- start_new_message = FALSE;
- }
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL);
- msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]);
- blocks++;
- if (blocks >= 255)
- {
- sendReliableMessage();
- start_new_message = TRUE;
- blocks = 0;
- }
- }
- // Send CRC miss updates. For these, we _might_ have a viewer object,
- // but probably not.
- for (i = 0; i < crc_count; i++)
- {
- if (start_new_message)
- {
- msg->newMessageFast(_PREHASH_RequestMultipleObjects);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- start_new_message = FALSE;
- }
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC);
- msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]);
- blocks++;
- if (blocks >= 255)
- {
- sendReliableMessage();
- start_new_message = TRUE;
- blocks = 0;
- }
- }
- // finish any pending message
- if (!start_new_message)
- {
- sendReliableMessage();
- }
- mCacheMissFull.reset();
- mCacheMissCRC.reset();
- // llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
- }
- void LLViewerRegion::dumpCache()
- {
- const S32 BINS = 4;
- S32 hit_bin[BINS];
- S32 change_bin[BINS];
- S32 i;
- for (i = 0; i < BINS; ++i)
- {
- hit_bin[i] = 0;
- change_bin[i] = 0;
- }
- LLVOCacheEntry *entry;
- for (entry = mCacheStart.getNext(); entry && (entry != &mCacheEnd); entry = entry->getNext())
- {
- S32 hits = entry->getHitCount();
- S32 changes = entry->getCRCChangeCount();
- hits = llclamp(hits, 0, BINS-1);
- changes = llclamp(changes, 0, BINS-1);
- hit_bin[hits]++;
- change_bin[changes]++;
- }
- llinfos << "Count " << mCacheEntriesCount << llendl;
- for (i = 0; i < BINS; i++)
- {
- llinfos << "Hits " << i << " " << hit_bin[i] << llendl;
- }
- for (i = 0; i < BINS; i++)
- {
- llinfos << "Changes " << i << " " << change_bin[i] << llendl;
- }
- }
- void LLViewerRegion::unpackRegionHandshake()
- {
- LLMessageSystem *msg = gMessageSystem;
- U32 region_flags;
- U8 sim_access;
- std::string sim_name;
- LLUUID sim_owner;
- BOOL is_estate_manager;
- F32 water_height;
- F32 billable_factor;
- LLUUID cache_id;
- msg->getU32 ("RegionInfo", "RegionFlags", region_flags);
- msg->getU8 ("RegionInfo", "SimAccess", sim_access);
- msg->getString ("RegionInfo", "SimName", sim_name);
- msg->getUUID ("RegionInfo", "SimOwner", sim_owner);
- msg->getBOOL ("RegionInfo", "IsEstateManager", is_estate_manager);
- msg->getF32 ("RegionInfo", "WaterHeight", water_height);
- msg->getF32 ("RegionInfo", "BillableFactor", billable_factor);
- msg->getUUID ("RegionInfo", "CacheID", cache_id );
- setRegionFlags(region_flags);
- setSimAccess(sim_access);
- setRegionNameAndZone(sim_name);
- setOwner(sim_owner);
- setIsEstateManager(is_estate_manager);
- setWaterHeight(water_height);
- setBillableFactor(billable_factor);
- setCacheID(cache_id);
- LLUUID region_id;
- msg->getUUID("RegionInfo2", "RegionID", region_id);
- setRegionID(region_id);
-
- // Retrieve the CR-53 (Homestead/Land SKU) information
- S32 classID = 0;
- S32 cpuRatio = 0;
- std::string coloName;
- std::string productSKU;
- std::string productName;
- // the only reasonable way to decide if we actually have any data is to
- // check to see if any of these fields have positive sizes
- if (msg->getSize("RegionInfo3", "ColoName") > 0 ||
- msg->getSize("RegionInfo3", "ProductSKU") > 0 ||
- msg->getSize("RegionInfo3", "ProductName") > 0)
- {
- msg->getS32 ("RegionInfo3", "CPUClassID", classID);
- msg->getS32 ("RegionInfo3", "CPURatio", cpuRatio);
- msg->getString ("RegionInfo3", "ColoName", coloName);
- msg->getString ("RegionInfo3", "ProductSKU", productSKU);
- msg->getString ("RegionInfo3", "ProductName", productName);
-
- mClassID = classID;
- mCPURatio = cpuRatio;
- mColoName = coloName;
- mProductSKU = productSKU;
- mProductName = productName;
- }
- LLVLComposition *compp = getComposition();
- if (compp)
- {
- LLUUID tmp_id;
- msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id);
- compp->setDetailTextureID(0, tmp_id);
- msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id);
- compp->setDetailTextureID(1, tmp_id);
- msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id);
- compp->setDetailTextureID(2, tmp_id);
- msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id);
- compp->setDetailTextureID(3, tmp_id);
- F32 tmp_f32;
- msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32);
- compp->setStartHeight(0, tmp_f32);
- msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32);
- compp->setStartHeight(1, tmp_f32);
- msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32);
- compp->setStartHeight(2, tmp_f32);
- msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32);
- compp->setStartHeight(3, tmp_f32);
- msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32);
- compp->setHeightRange(0, tmp_f32);
- msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32);
- compp->setHeightRange(1, tmp_f32);
- msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32);
- compp->setHeightRange(2, tmp_f32);
- msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32);
- compp->setHeightRange(3, tmp_f32);
- // If this is an UPDATE (params already ready, we need to regenerate
- // all of our terrain stuff, by
- if (compp->getParamsReady())
- {
- getLand().dirtyAllPatches();
- }
- else
- {
- compp->setParamsReady();
- }
- }
- // Now that we have the name, we can load the cache file
- // off disk.
- loadCache();
- // After loading cache, signal that simulator can start
- // sending data.
- // TODO: Send all upstream viewer->sim handshake info here.
- LLHost host = msg->getSender();
- msg->newMessage("RegionHandshakeReply");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgent.getID());
- msg->addUUID("SessionID", gAgent.getSessionID());
- msg->nextBlock("RegionInfo");
- msg->addU32("Flags", 0x0 );
- msg->sendReliable(host);
- }
- void LLViewerRegion::setSeedCapability(const std::string& url)
- {
- if (getCapability("Seed") == url)
- {
- // llwarns << "Ignoring duplicate seed capability" << llendl;
- return;
- }
-
- delete mEventPoll;
- mEventPoll = NULL;
-
- mCapabilities.clear();
- setCapability("Seed", url);
- LLSD capabilityNames = LLSD::emptyArray();
-
- capabilityNames.append("AttachmentResources");
- capabilityNames.append("ChatSessionRequest");
- capabilityNames.append("CopyInventoryFromNotecard");
- capabilityNames.append("DispatchRegionInfo");
- capabilityNames.append("EstateChangeInfo");
- capabilityNames.append("EventQueueGet");
- capabilityNames.append("FetchInventory");
- capabilityNames.append("ObjectMedia");
- capabilityNames.append("ObjectMediaNavigate");
- capabilityNames.append("FetchLib");
- capabilityNames.append("FetchLibDescendents");
- capabilityNames.append("GetTexture");
- capabilityNames.append("GroupProposalBallot");
- capabilityNames.append("HomeLocation");
- capabilityNames.append("LandResources");
- capabilityNames.append("MapLayer");
- capabilityNames.append("MapLayerGod");
- capabilityNames.append("NewFileAgentInventory");
- capabilityNames.append("ParcelPropertiesUpdate");
- capabilityNames.append("ParcelMediaURLFilterList");
- capabilityNames.append("ParcelNavigateMedia");
- capabilityNames.append("ParcelVoiceInfoRequest");
- capabilityNames.append("ProductInfoRequest");
- capabilityNames.append("ProvisionVoiceAccountRequest");
- capabilityNames.append("RemoteParcelRequest");
- capabilityNames.append("RequestTextureDownload");
- capabilityNames.append("SearchStatRequest");
- capabilityNames.append("SearchStatTracking");
- capabilityNames.append("SendPostcard");
- capabilityNames.append("SendUserReport");
- capabilityNames.append("SendUserReportWithScreenshot");
- capabilityNames.append("ServerReleaseNotes");
- capabilityNames.append("StartGroupProposal");
- capabilityNames.append("TextureStats");
- capabilityNames.append("UntrustedSimulatorMessage");
- capabilityNames.append("UpdateAgentInformation");
- capabilityNames.append("UpdateAgentLanguage");
- capabilityNames.append("UpdateGestureAgentInventory");
- capabilityNames.append("UpdateNotecardAgentInventory");
- capabilityNames.append("UpdateScriptAgent");
- capabilityNames.append("UpdateGestureTaskInventory");
- capabilityNames.append("UpdateNotecardTaskInventory");
- capabilityNames.append("UpdateScriptTask");
- capabilityNames.append("UploadBakedTexture");
- capabilityNames.append("ViewerStartAuction");
- capabilityNames.append("ViewerStats");
- capabilityNames.append("WebFetchInventoryDescendents");
- // Please add new capabilities alphabetically to reduce
- // merge conflicts.
- llinfos << "posting to seed " << url << llendl;
- mHttpResponderPtr = BaseCapabilitiesComplete::build(this) ;
- LLHTTPClient::post(url, capabilityNames, mHttpResponderPtr);
- }
- void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
- {
- if(name == "EventQueueGet")
- {
- delete mEventPoll;
- mEventPoll = NULL;
- mEventPoll = new LLEventPoll(url, getHost());
- }
- else if(name == "UntrustedSimulatorMessage")
- {
- LLHTTPSender::setSender(mHost, new LLCapHTTPSender(url));
- }
- else
- {
- mCapabilities[name] = url;
- }
- }
- bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
- {
- return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
- }
- std::string LLViewerRegion::getCapability(const std::string& name) const
- {
- CapabilityMap::const_iterator iter = mCapabilities.find(name);
- if(iter == mCapabilities.end())
- {
- return "";
- }
- return iter->second;
- }
- void LLViewerRegion::logActiveCapabilities() const
- {
- int count = 0;
- CapabilityMap::const_iterator iter;
- for (iter = mCapabilities.begin(); iter != mCapabilities.end(); iter++, count++)
- {
- if (!iter->second.empty())
- {
- llinfos << iter->first << " URL is " << iter->second << llendl;
- }
- }
- llinfos << "Dumped " << count << " entries." << llendl;
- }
- LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
- {
- if (type < mObjectPartition.size())
- {
- return mObjectPartition[type];
- }
- return NULL;
- }
- void LLViewerRegion::showReleaseNotes()
- {
- std::string url = this->getCapability("ServerReleaseNotes");
- if (url.empty()) {
- // HACK haven't received the capability yet, we'll wait until
- // it arives.
- mReleaseNotesRequested = TRUE;
- return;
- }
- LLWeb::loadURL(url);
- mReleaseNotesRequested = FALSE;
- }
- std::string LLViewerRegion::getDescription() const
- {
- return stringize(*this);
- }