The "About Landmark" code with the fake parcelIDs had a serious bug.

- Fix that bug. It will work with OSSearch now, too
- Add some caching to reduce inter-region requests.
0.6.0-stable
Homer Horwitz 2008-10-11 22:42:59 +00:00
parent 82b2b2dccb
commit b48885ece4
1 changed files with 52 additions and 13 deletions

View File

@ -42,6 +42,13 @@ using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
namespace OpenSim.Region.Environment.Modules.World.Land
{
// used for caching
internal class ExtendedLandData {
public LandData landData;
public ulong regionHandle;
public uint x, y;
}
public class LandManagementModule : IRegionModule
{
private static readonly ILog m_log =
@ -60,6 +67,9 @@ namespace OpenSim.Region.Environment.Modules.World.Land
private bool m_allowedForcefulBans = true;
// caches ExtendedLandData
private Cache parcelInfoCache;
#region IRegionModule Members
public void Initialise(Scene scene, IConfigSource source)
@ -68,6 +78,10 @@ namespace OpenSim.Region.Environment.Modules.World.Land
landIDList.Initialize();
landChannel = new LandChannel(scene, this);
parcelInfoCache = new Cache();
parcelInfoCache.Size = 30; // the number of different parcel requests in this region to cache
parcelInfoCache.DefaultTTL = new TimeSpan(0, 5, 0);
m_scene.EventManager.OnParcelPrimCountAdd += AddPrimToLandPrimCounts;
m_scene.EventManager.OnParcelPrimCountUpdate += UpdateLandPrimCounts;
m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(handleAvatarChangingParcel);
@ -1173,23 +1187,48 @@ namespace OpenSim.Region.Environment.Modules.World.Land
if (parcelID == UUID.Zero)
return;
ExtendedLandData data = (ExtendedLandData)parcelInfoCache.Get(parcelID, delegate(UUID parcel) {
// assume we've got the parcelID we just computed in RemoteParcelRequest
ulong regionHandle;
uint x, y;
Util.ParseFakeParcelID(parcelID, out regionHandle, out x, out y);
m_log.DebugFormat("[LAND] got parcelinfo request for regionHandle {0}, x/y {1}/{2}", regionHandle, x, y);
ExtendedLandData extLandData = new ExtendedLandData();
Util.ParseFakeParcelID(parcel, out extLandData.regionHandle, out extLandData.x, out extLandData.y);
m_log.DebugFormat("[LAND] got parcelinfo request for regionHandle {0}, x/y {1}/{2}",
extLandData.regionHandle, extLandData.x, extLandData.y);
LandData landData;
if (regionHandle == m_scene.RegionInfo.RegionHandle)
landData = this.GetLandObject(x, y).landData;
else
landData = m_scene.CommsManager.GridService.RequestLandData(regionHandle, x, y);
if (landData != null)
// for this region or for somewhere else?
if (extLandData.regionHandle == m_scene.RegionInfo.RegionHandle)
{
extLandData.landData = this.GetLandObject(extLandData.x, extLandData.y).landData;
}
else
{
extLandData.landData = m_scene.CommsManager.GridService.RequestLandData(extLandData.regionHandle,
extLandData.x,
extLandData.y);
if (extLandData.landData == null)
{
// we didn't find the region/land => don't cache
return null;
}
}
return extLandData;
});
if (data != null) // if we found some data, send it
{
RegionInfo info;
if (data.regionHandle == m_scene.RegionInfo.RegionHandle)
{
info = m_scene.RegionInfo;
}
else
{
// most likely still cached from building the extLandData entry
info = m_scene.CommsManager.GridService.RequestNeighbourInfo(data.regionHandle);
}
// we need to transfer the fake parcelID, not the one in landData, so the viewer can match it to the landmark.
m_log.Debug("[LAND] got parcelinfo; sending");
remoteClient.SendParcelInfo(m_scene.RegionInfo, landData, parcelID, x, y);
m_log.DebugFormat("[LAND] got parcelinfo for parcel {0} in region {1}; sending...",
data.landData.Name, data.regionHandle);
remoteClient.SendParcelInfo(info, data.landData, parcelID, data.x, data.y);
}
else
m_log.Debug("[LAND] got no parcelinfo; not sending");