Merge branch 'master' into httptests

httptests
UbitUmarov 2016-07-31 23:19:51 +01:00
commit a9befe1c62
7 changed files with 507 additions and 454 deletions

View File

@ -368,47 +368,49 @@ namespace OpenSim.Framework
return Utils.UIntsToLong(X, Y); return Utils.UIntsToLong(X, Y);
} }
// Regions are identified with a 'handle' made up of its region coordinates packed into a ulong. // Regions are identified with a 'handle' made up of its world coordinates packed into a ulong.
// Several places rely on the ability to extract a region's location from its handle. // Region handles are based on the coordinate of the region corner with lower X and Y
// Note the location is in 'world coordinates' (see below). // var regions need more work than this to get that right corner from a generic world position
// Region handles are based on the lowest coordinate of the region so trim the passed x,y to be the regions 0,0. // this corner must be on a grid point
public static ulong RegionWorldLocToHandle(uint X, uint Y) public static ulong RegionWorldLocToHandle(uint X, uint Y)
{ {
return Utils.UIntsToLong(X, Y); ulong handle = X & 0xffffff00; // make sure it matchs grid coord points.
handle <<= 32; // to higher half
handle |= (Y & 0xffffff00);
return handle;
} }
public static ulong RegionLocToHandle(uint X, uint Y) public static ulong RegionGridLocToHandle(uint X, uint Y)
{ {
return Utils.UIntsToLong(Util.RegionToWorldLoc(X), Util.RegionToWorldLoc(Y)); ulong handle = X << 40; // shift to higher half and mult by 256)
handle |= (Y << 8); // mult by 256)
return handle;
} }
public static void RegionHandleToWorldLoc(ulong handle, out uint X, out uint Y) public static void RegionHandleToWorldLoc(ulong handle, out uint X, out uint Y)
{ {
X = (uint)(handle >> 32); X = (uint)(handle >> 32);
Y = (uint)(handle & (ulong)uint.MaxValue); Y = (uint)(handle & 0xfffffffful);
} }
public static void RegionHandleToRegionLoc(ulong handle, out uint X, out uint Y) public static void RegionHandleToRegionLoc(ulong handle, out uint X, out uint Y)
{ {
uint worldX, worldY; X = (uint)(handle >> 40) & 0x00ffffffu; // bring from higher half, divide by 256 and clean
RegionHandleToWorldLoc(handle, out worldX, out worldY); Y = (uint)(handle >> 8) & 0x00ffffffu; // divide by 256 and clean
X = WorldToRegionLoc(worldX); // if you trust the uint cast then the clean can be removed.
Y = WorldToRegionLoc(worldY);
} }
// A region location can be 'world coordinates' (meters from zero) or 'region coordinates' // A region location can be 'world coordinates' (meters) or 'region grid coordinates'
// (number of regions from zero). This measurement of regions relies on the legacy 256 region size. // grid coordinates have a fixed step of 256m as defined by viewers
// These routines exist to make what is being converted explicit so the next person knows what was meant.
// Convert a region's 'world coordinate' to its 'region coordinate'.
public static uint WorldToRegionLoc(uint worldCoord) public static uint WorldToRegionLoc(uint worldCoord)
{ {
return worldCoord / Constants.RegionSize; return worldCoord >> 8;
} }
// Convert a region's 'region coordinate' to its 'world coordinate'. // Convert a region's 'region grid coordinate' to its 'world coordinate'.
public static uint RegionToWorldLoc(uint regionCoord) public static uint RegionToWorldLoc(uint regionCoord)
{ {
return regionCoord * Constants.RegionSize; return regionCoord << 8;
} }
public static T Clamp<T>(T x, T min, T max) public static T Clamp<T>(T x, T min, T max)
@ -1303,7 +1305,7 @@ namespace OpenSim.Framework
} }
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat("[UTILS]: Exception copying configuration file {0} to {1}: {2}", exampleConfigFile, configFile, e.Message); m_log.WarnFormat("[UTILS]: Exception copying configuration file {0} to {1}: {2}", configFile, exampleConfigFile, e.Message);
return false; return false;
} }
} }

View File

@ -1537,8 +1537,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public ScenePresence CrossAsync(ScenePresence agent, bool isFlying) public ScenePresence CrossAsync(ScenePresence agent, bool isFlying)
{ {
uint x;
uint y;
Vector3 newpos; Vector3 newpos;
EntityTransferContext ctx = new EntityTransferContext(); EntityTransferContext ctx = new EntityTransferContext();
string failureReason; string failureReason;
@ -1588,7 +1586,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.Scene.RequestTeleportLocation( agent.Scene.RequestTeleportLocation(
agent.ControllingClient, agent.ControllingClient,
Util.RegionLocToHandle(regionX, regionY), Util.RegionGridLocToHandle(regionX, regionY),
position, position,
agent.Lookat, agent.Lookat,
(uint)Constants.TeleportFlags.ViaLocation); (uint)Constants.TeleportFlags.ViaLocation);
@ -1814,7 +1812,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// In any case // In any case
agent.IsInTransit = false; agent.IsInTransit = false;
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
} }
#endregion #endregion
@ -2115,79 +2113,62 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// contains that point. A conservitive estimate. // contains that point. A conservitive estimate.
private class NotFoundLocationCache private class NotFoundLocationCache
{ {
private struct NotFoundLocation private Dictionary<ulong, DateTime> m_notFoundLocations = new Dictionary<ulong, DateTime>();
{
public double minX, maxX, minY, maxY;
public DateTime expireTime;
}
private List<NotFoundLocation> m_notFoundLocations = new List<NotFoundLocation>();
public NotFoundLocationCache() public NotFoundLocationCache()
{ {
} }
// Add an area to the list of 'not found' places. The area is the snapped region // just use normal regions handlers and sizes
// area around the added point.
public void Add(double pX, double pY) public void Add(double pX, double pY)
{ {
lock (m_notFoundLocations) ulong psh = (ulong)pX & 0xffffff00ul;
{ psh <<= 32;
if (!LockedContains(pX, pY)) psh |= (ulong)pY & 0xffffff00ul;
{
NotFoundLocation nfl = new NotFoundLocation();
// A not found location is not found for at least a whole region sized area
nfl.minX = pX - (pX % (double)Constants.RegionSize);
nfl.minY = pY - (pY % (double)Constants.RegionSize);
nfl.maxX = nfl.minX + (double)Constants.RegionSize;
nfl.maxY = nfl.minY + (double)Constants.RegionSize;
nfl.expireTime = DateTime.Now + TimeSpan.FromSeconds(30);
m_notFoundLocations.Add(nfl);
}
}
lock (m_notFoundLocations)
m_notFoundLocations[psh] = DateTime.Now + TimeSpan.FromSeconds(30);;
} }
// Test to see of this point is in any of the 'not found' areas. // Test to see of this point is in any of the 'not found' areas.
// Return 'true' if the point is found inside the 'not found' areas. // Return 'true' if the point is found inside the 'not found' areas.
public bool Contains(double pX, double pY) public bool Contains(double pX, double pY)
{ {
bool ret = false; ulong psh = (ulong)pX & 0xffffff00ul;
psh <<= 32;
psh |= (ulong)pY & 0xffffff00ul;
lock (m_notFoundLocations) lock (m_notFoundLocations)
ret = LockedContains(pX, pY);
return ret;
}
private bool LockedContains(double pX, double pY)
{ {
bool ret = false; if(m_notFoundLocations.ContainsKey(psh))
this.DoExpiration();
foreach (NotFoundLocation nfl in m_notFoundLocations)
{ {
if (pX >= nfl.minX && pX < nfl.maxX && pY >= nfl.minY && pY < nfl.maxY) if(m_notFoundLocations[psh] > DateTime.UtcNow)
{ return true;
ret = true; m_notFoundLocations.Remove(psh);
break; }
return false;
} }
} }
return ret;
}
private void DoExpiration() private void DoExpiration()
{ {
List<NotFoundLocation> m_toRemove = null; List<ulong> m_toRemove = new List<ulong>();;
DateTime now = DateTime.Now; DateTime now = DateTime.UtcNow;
foreach (NotFoundLocation nfl in m_notFoundLocations) lock (m_notFoundLocations)
{ {
if (nfl.expireTime < now) foreach (KeyValuePair<ulong, DateTime> kvp in m_notFoundLocations)
{ {
if (m_toRemove == null) if (kvp.Value < now)
m_toRemove = new List<NotFoundLocation>(); m_toRemove.Add(kvp.Key);
m_toRemove.Add(nfl);
} }
}
if (m_toRemove != null) if (m_toRemove.Count > 0)
{ {
foreach (NotFoundLocation nfl in m_toRemove) foreach (ulong u in m_toRemove)
m_notFoundLocations.Remove(nfl); m_notFoundLocations.Remove(u);
m_toRemove.Clear(); m_toRemove.Clear();
} }
} }
} }
}
#endregion // NotFoundLocationCache class #endregion // NotFoundLocationCache class
private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache();
@ -2202,10 +2183,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Given a world position, get the GridRegion info for // Given a world position, get the GridRegion info for
// the region containing that point. // the region containing that point.
// Someday this should be a method on GridService.
// 'pSizeHint' is the size of the source region but since the destination point can be anywhere
// the size of the target region is unknown thus the search area might have to be very large.
// Return 'null' if no such region exists.
protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID,
double px, double py, uint pSizeHint) double px, double py, uint pSizeHint)
{ {
@ -2213,11 +2190,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
GridRegion ret = null; GridRegion ret = null;
const double fudge = 2.0; const double fudge = 2.0;
// One problem with this routine is negative results. That is, this can be called lots of times
// for regions that don't exist. m_notFoundLocationCache remembers 'not found' results so they
// will be quick 'not found's next time.
// NotFoundLocationCache is an expiring cache so it will eventually forget about 'not found' and
// thus re-ask the GridService about the location.
if (m_notFoundLocationCache.Contains(px, py)) if (m_notFoundLocationCache.Contains(px, py))
{ {
// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py); // m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py);
@ -2226,60 +2198,45 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// As an optimization, since most regions will be legacy sized regions (256x256), first try to get // As an optimization, since most regions will be legacy sized regions (256x256), first try to get
// the region at the appropriate legacy region location. // the region at the appropriate legacy region location.
uint possibleX = (uint)Math.Floor(px); // this is all that is needed on 0.9 grids
possibleX -= possibleX % Constants.RegionSize; uint possibleX = (uint)px & 0xffffff00u;
uint possibleY = (uint)Math.Floor(py); uint possibleY = (uint)py & 0xffffff00u;
possibleY -= possibleY % Constants.RegionSize;
ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY); ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
if (ret != null) if (ret != null)
{ {
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}", // m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
LogHeader, possibleX, possibleY, ret.RegionName); // LogHeader, possibleX, possibleY, ret.RegionName);
return ret;
} }
if (ret == null) // for 0.8 regions just make a BIG area request. old code whould do it plus 4 more smaller on region open edges
{ // this is what 0.9 grids now do internally
// If the simple lookup failed, search the larger area for a region that contains this point
double range = (double)pSizeHint + fudge;
while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
{
// Get from the grid service a list of regions that might contain this point.
// The region origin will be in the zero direction so only subtract the range.
List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID, List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
(int)(px - range), (int)(px), (int)(px - Constants.MaximumRegionSize), (int)(px + 1), // +1 bc left mb not part of range
(int)(py - range), (int)(py)); (int)(py - Constants.MaximumRegionSize), (int)(py + 1));
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}", // m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
LogHeader, possibleRegions.Count, range); // LogHeader, possibleRegions.Count, range);
if (possibleRegions != null && possibleRegions.Count > 0) if (possibleRegions != null && possibleRegions.Count > 0)
{ {
// If we found some regions, check to see if the point is within // If we found some regions, check to see if the point is within
foreach (GridRegion gr in possibleRegions) foreach (GridRegion gr in possibleRegions)
{ {
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>", // m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY); // LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX) if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
&& py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY)) && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
{ {
// Found a region that contains the point // Found a region that contains the point
ret = gr; return gr;
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName); // m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
break;
} }
} }
} }
// Larger search area for next time around if not found
range *= 2;
}
}
if (ret == null)
{
// remember this location was not found so we can quickly not find it next time // remember this location was not found so we can quickly not find it next time
m_notFoundLocationCache.Add(px, py); m_notFoundLocationCache.Add(px, py);
m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py); // m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py);
} return null;
return ret;
} }
private void InformClientOfNeighbourCompleted(IAsyncResult iar) private void InformClientOfNeighbourCompleted(IAsyncResult iar)

View File

@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <returns>true if the agent was not already in transit, false if it was</returns> /// <returns>true if the agent was not already in transit, false if it was</returns>
internal bool SetInTransit(UUID id) internal bool SetInTransit(UUID id)
{ {
m_log.DebugFormat("{0} SetInTransit. agent={1}, newState=Preparing", LogHeader, id); // m_log.DebugFormat("{0} SetInTransit. agent={1}, newState=Preparing", LogHeader, id);
lock (m_agentsInTransit) lock (m_agentsInTransit)
{ {
if (!m_agentsInTransit.ContainsKey(id)) if (!m_agentsInTransit.ContainsKey(id))
@ -123,7 +123,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
internal bool UpdateInTransit(UUID id, AgentTransferState newState) internal bool UpdateInTransit(UUID id, AgentTransferState newState)
{ {
m_log.DebugFormat("{0} UpdateInTransit. agent={1}, newState={2}", LogHeader, id, newState); // m_log.DebugFormat("{0} UpdateInTransit. agent={1}, newState={2}", LogHeader, id, newState);
bool transitionOkay = false; bool transitionOkay = false;
@ -247,32 +247,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{ {
AgentTransferState state = m_agentsInTransit[id]; AgentTransferState state = m_agentsInTransit[id];
if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination) // if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination)
{ // {
// FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed
// to be handled properly - ResetFromTransit() could be invoked at any step along the process // to be handled properly - ResetFromTransit() could be invoked at any step along the process
m_log.WarnFormat( // m_log.WarnFormat(
"[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}", // "[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}",
id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName); // id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName);
// throw new Exception( // throw new Exception(
// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", // "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first",
// state, AgentTransferState.CleaningUp); // state, AgentTransferState.CleaningUp);
} // }
m_agentsInTransit.Remove(id); m_agentsInTransit.Remove(id);
m_log.DebugFormat( // m_log.DebugFormat(
"[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}", // "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}",
id, m_mod.Scene.RegionInfo.RegionName); // id, m_mod.Scene.RegionInfo.RegionName);
return true; return true;
} }
} }
m_log.WarnFormat( // m_log.WarnFormat(
"[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared", // "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared",
id, m_mod.Scene.RegionInfo.RegionName); // id, m_mod.Scene.RegionInfo.RegionName);
return false; return false;
} }

View File

@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (!m_Enabled) if (!m_Enabled)
return; return;
m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionID); m_RegionInfoCache.Remove(scene.RegionInfo.ScopeID, scene.RegionInfo.RegionHandle);
scene.EventManager.OnRegionUp -= OnRegionUp; scene.EventManager.OnRegionUp -= OnRegionUp;
} }
@ -220,16 +220,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
// be the base coordinate of the region. // be the base coordinate of the region.
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
{ {
// try in cache by handler first // try in cache by handler first
ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y); // ulong regionHandle = Util.RegionWorldLocToHandle((uint)x, (uint)y);
bool inCache = false; bool inCache = false;
GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache); // GridRegion rinfo = m_RegionInfoCache.Get(scopeID, regionHandle, out inCache);
if (inCache) // if (inCache)
return rinfo; // return rinfo;
// try in cache by slower position next GridRegion rinfo = m_RegionInfoCache.Get(scopeID, (uint)x, (uint)y, out inCache);
rinfo = m_RegionInfoCache.Get(scopeID, x, y, out inCache);
if (inCache) if (inCache)
return rinfo; return rinfo;

View File

@ -44,11 +44,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
// LogManager.GetLogger( // LogManager.GetLogger(
// MethodBase.GetCurrentMethod().DeclaringType); // MethodBase.GetCurrentMethod().DeclaringType);
private RegionsExpiringCache m_Cache; private static RegionsExpiringCache m_Cache;
private int numberInstances;
public RegionInfoCache() public RegionInfoCache()
{ {
if(m_Cache == null)
m_Cache = new RegionsExpiringCache(); m_Cache = new RegionsExpiringCache();
numberInstances++;
} }
public void Cache(GridRegion rinfo) public void Cache(GridRegion rinfo)
@ -78,8 +81,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (rinfo == null) if (rinfo == null)
return; return;
// m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); m_Cache.AddOrUpdate(scopeID, rinfo, CACHE_EXPIRATION_SECONDS);
m_Cache.Add(scopeID, rinfo, CACHE_EXPIRATION_SECONDS); // don't override local regions
} }
public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds) public void Cache(UUID scopeID, GridRegion rinfo, float expireSeconds)
@ -90,9 +92,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds); m_Cache.AddOrUpdate(scopeID, rinfo, expireSeconds);
} }
public void Remove(UUID scopeID, UUID regionID) public void Remove(UUID scopeID, GridRegion rinfo)
{ {
m_Cache.Remove(scopeID, regionID); m_Cache.Remove(scopeID, rinfo);
}
public void Remove(UUID scopeID, ulong regionHandle)
{
m_Cache.Remove(scopeID, regionHandle);
} }
public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache) public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache)
@ -137,7 +144,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
return null; return null;
} }
public GridRegion Get(UUID scopeID, int x, int y, out bool inCache) public GridRegion Get(UUID scopeID, uint x, uint y, out bool inCache)
{ {
inCache = false; inCache = false;
@ -152,109 +159,285 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
} }
} }
public class RegionInfoForScope
// following code partialy adapted from lib OpenMetaverse
public class RegionKey
{ {
public UUID ScopeID; public const ulong HANDLEMASH = 0xffffff00ffffff00ul;
public UUID RegionID; public const ulong HANDLECOORDMASH = 0xffffff00ul;
public RegionKey(UUID scopeID, UUID id) private Dictionary<ulong, GridRegion> storage;
private Dictionary<ulong, DateTime> expires;
private Dictionary<string, ulong> byname;
private Dictionary<UUID, ulong> byuuid;
public RegionInfoForScope()
{ {
ScopeID = scopeID; storage = new Dictionary<ulong, GridRegion>();
RegionID = id; expires = new Dictionary<ulong, DateTime>();
byname = new Dictionary<string, ulong>();
byuuid = new Dictionary<UUID, ulong>();
} }
public override int GetHashCode() public RegionInfoForScope(GridRegion region, DateTime expire)
{ {
int hash = ScopeID.GetHashCode(); storage = new Dictionary<ulong, GridRegion>();
hash += hash * 23 + RegionID.GetHashCode(); expires = new Dictionary<ulong, DateTime>();
return hash; byname = new Dictionary<string, ulong>();
byuuid = new Dictionary<UUID, ulong>();
ulong handle = region.RegionHandle & HANDLEMASH;
storage[handle] = region;
expires[handle] = expire;
byname[region.RegionName] = handle;
byuuid[region.RegionID] = handle;
} }
public override bool Equals(Object b) public void Add(GridRegion region, DateTime expire)
{ {
if(b == null) ulong handle = region.RegionHandle & HANDLEMASH;
return false;
RegionKey kb = b as RegionKey;
return (ScopeID == kb.ScopeID && RegionID == kb.RegionID);
}
}
class RegionKeyEqual : EqualityComparer<RegionKey> if(storage != null && storage.ContainsKey(handle))
{ return;
public override int GetHashCode(RegionKey rk)
{
return rk.GetHashCode();
}
public override bool Equals(RegionKey a, RegionKey b) if(storage == null)
{ storage = new Dictionary<ulong, GridRegion>();
return (a.ScopeID == b.ScopeID && a.RegionID == b.RegionID); if(expires == null)
} expires = new Dictionary<ulong, DateTime>();
}
public class RegionInfoByScope
{
private Dictionary<string, RegionKey> byname;
private Dictionary<ulong, RegionKey> byhandle;
public RegionInfoByScope()
{
byname = new Dictionary<string, RegionKey>();
byhandle = new Dictionary<ulong, RegionKey>();
}
public RegionInfoByScope(GridRegion region, RegionKey key)
{
byname = new Dictionary<string, RegionKey>();
byhandle = new Dictionary<ulong, RegionKey>();
byname[region.RegionName] = key;
byhandle[region.RegionHandle] = key;
}
public void AddRegion(GridRegion region, RegionKey key)
{
if(byname == null) if(byname == null)
byname = new Dictionary<string, RegionKey>(); byname = new Dictionary<string, ulong>();
if(byhandle == null) if(byuuid == null)
byhandle = new Dictionary<ulong, RegionKey>(); byuuid = new Dictionary<UUID, ulong>();
byname[region.RegionName] = key; storage[handle] = region;
byhandle[region.RegionHandle] = key; expires[handle] = expire;
byname[region.RegionName] = handle;
byuuid[region.RegionID] = handle;
} }
public void RemoveRegion(GridRegion region) public void AddUpdate(GridRegion region, DateTime expire)
{ {
if(storage == null)
storage = new Dictionary<ulong, GridRegion>();
if(expires == null)
expires = new Dictionary<ulong, DateTime>();
if(byname == null)
byname = new Dictionary<string, ulong>();
if(byuuid == null)
byuuid = new Dictionary<UUID, ulong>();
ulong handle = region.RegionHandle & HANDLEMASH;
storage[handle] = region;
if(expires.ContainsKey(handle))
{
if(expires[handle] < expire)
expires[handle] = expire;
}
else
expires[handle] = expire;
byname[region.RegionName] = handle;
byuuid[region.RegionID] = handle;
}
public void Remove(GridRegion region)
{
if(region == null)
return;
if(byname != null) if(byname != null)
byname.Remove(region.RegionName); byname.Remove(region.RegionName);
if(byhandle != null) if(byuuid != null)
byhandle.Remove(region.RegionHandle); byuuid.Remove(region.RegionID);
ulong handle = region.RegionHandle & HANDLEMASH;
if(storage != null)
storage.Remove(handle);
if(expires != null)
{
expires.Remove(handle);
if(expires.Count == 0)
Clear();
}
}
public void Remove(ulong handle)
{
handle &= HANDLEMASH;
if(storage != null)
{
if(storage.ContainsKey(handle))
{
GridRegion r = storage[handle];
if(byname != null)
byname.Remove(r.RegionName);
if(byuuid != null)
byuuid.Remove(r.RegionID);
}
storage.Remove(handle);
}
if(expires != null)
{
expires.Remove(handle);
if(expires.Count == 0)
Clear();
}
} }
public void Clear() public void Clear()
{ {
if(expires != null)
expires.Clear();
if(storage != null)
storage.Clear();
if(byname != null) if(byname != null)
byname.Clear(); byname.Clear();
if(byhandle != null) if(byuuid != null)
byhandle.Clear(); byuuid.Clear();
byname = null; byname = null;
byhandle = null; byuuid = null;
storage = null;
expires = null;
} }
public RegionKey get(string name) public bool Contains(GridRegion region)
{
if(storage == null)
return false;
if(region == null)
return false;
ulong handle = region.RegionHandle & HANDLEMASH;
return storage.ContainsKey(handle);
}
public bool Contains(ulong handle)
{
if(storage == null)
return false;
handle &= HANDLEMASH;
return storage.ContainsKey(handle);
}
public GridRegion get(ulong handle)
{
if(storage == null)
return null;
handle &= HANDLEMASH;
if(storage.ContainsKey(handle))
return storage[handle];
return null;
}
public GridRegion get(string name)
{ {
if(byname == null || !byname.ContainsKey(name)) if(byname == null || !byname.ContainsKey(name))
return null; return null;
return byname[name];
ulong handle = byname[name];
if(storage.ContainsKey(handle))
return storage[handle];
return null;
} }
public RegionKey get(ulong handle) public GridRegion get(UUID id)
{ {
if(byhandle == null || !byhandle.ContainsKey(handle)) if(byuuid == null || !byuuid.ContainsKey(id))
return null; return null;
return byhandle[handle];
ulong handle = byuuid[id];
if(storage.ContainsKey(handle))
return storage[handle];
return null;
}
public GridRegion get(uint x, uint y)
{
if(storage == null)
return null;
// look for a handle first this should find normal size regions
ulong handle = (ulong)x & HANDLECOORDMASH;
handle <<= 32;
handle |= ((ulong)y & HANDLECOORDMASH);
if(storage.ContainsKey(handle))
return storage[handle];
// next do the harder work
foreach(KeyValuePair<ulong, GridRegion> kvp in storage)
{
GridRegion r = kvp.Value;
if(r == null) // ??
continue;
int test = r.RegionLocX;
if(x < test)
continue;
test += r.RegionSizeX;
if(x >= test)
continue;
test = r.RegionLocY;
if (y < test)
continue;
test += r.RegionSizeY;
if (y < test)
return r;
}
return null;
}
public int expire(DateTime now )
{
if(expires == null || expires.Count == 0)
return 0;
List<ulong> toexpire = new List<ulong>();
foreach(KeyValuePair<ulong, DateTime> kvp in expires)
{
if(kvp.Value < now)
toexpire.Add(kvp.Key);
}
if(toexpire.Count == 0)
return expires.Count;
if(toexpire.Count == expires.Count)
{
Clear();
return 0;
}
foreach(ulong h in toexpire)
{
if(storage != null)
{
if(storage.ContainsKey(h))
{
GridRegion r = storage[h];
if(byname != null)
byname.Remove(r.RegionName);
if(byuuid != null)
byuuid.Remove(r.RegionID);
}
storage.Remove(h);
}
if(expires != null)
expires.Remove(h);
}
if(expires.Count == 0)
{
byname = null;
byuuid = null;
storage = null;
expires = null;
return 0;
}
return expires.Count;
} }
public int Count() public int Count()
@ -276,10 +459,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
/// <summary>For thread safety</summary> /// <summary>For thread safety</summary>
object isPurging = new object(); object isPurging = new object();
static RegionKeyEqual keyequal = new RegionKeyEqual(); Dictionary<UUID, RegionInfoForScope> InfobyScope = new Dictionary<UUID, RegionInfoForScope>();
Dictionary<RegionKey, GridRegion> timedStorage = new Dictionary<RegionKey, GridRegion>(keyequal);
Dictionary<RegionKey, DateTime> timedExpires = new Dictionary<RegionKey, DateTime>();
Dictionary<UUID, RegionInfoByScope> InfobyScope = new Dictionary<UUID, RegionInfoByScope>();
private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds); private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds);
public RegionsExpiringCache() public RegionsExpiringCache()
@ -288,74 +468,29 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
timer.Start(); timer.Start();
} }
public bool Add(UUID scope, GridRegion region, float expirationSeconds)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
RegionKey key = new RegionKey(scope , region.RegionID);
try
{
if (timedStorage.ContainsKey(key))
return false;
DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
timedStorage[key] = region;
timedExpires[key] = expire;
RegionInfoByScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
{
ris = new RegionInfoByScope(region, key);
InfobyScope[scope] = ris;
}
else
ris.AddRegion(region, key);
return true;
}
finally { Monitor.Exit(syncRoot);}
}
public bool AddOrUpdate(UUID scope, GridRegion region, float expirationSeconds) public bool AddOrUpdate(UUID scope, GridRegion region, float expirationSeconds)
{ {
if(region == null)
return false;
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try try
{ {
RegionKey key = new RegionKey(scope, region.RegionID);
DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
if (timedStorage.ContainsKey(key)) RegionInfoForScope ris = null;
{
timedStorage[key] = region;
if(expire > timedExpires[key])
timedExpires[key] = expire;
if(!InfobyScope.ContainsKey(scope))
{
RegionInfoByScope ris = new RegionInfoByScope(region, key);
InfobyScope[scope] = ris;
}
return false;
}
else
{
timedStorage[key] = region;
timedExpires[key] = expire;
RegionInfoByScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
{ {
ris = new RegionInfoByScope(region,key); ris = new RegionInfoForScope(region, expire);
InfobyScope[scope] = ris; InfobyScope[scope] = ris;
} }
else else
ris.AddRegion(region,key); ris.AddUpdate(region, expire);
return true; return true;
} }
}
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }
} }
@ -365,8 +500,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try try
{ {
timedStorage.Clear(); foreach(RegionInfoForScope ris in InfobyScope.Values)
timedExpires.Clear(); ris.Clear();
InfobyScope.Clear(); InfobyScope.Clear();
} }
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }
@ -374,211 +509,184 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public bool Contains(UUID scope, GridRegion region) public bool Contains(UUID scope, GridRegion region)
{ {
RegionKey key = new RegionKey(scope, region.RegionID); if(region == null)
return Contains(key);
}
public bool Contains(RegionKey key)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try
{
return timedStorage.ContainsKey(key);
}
finally { Monitor.Exit(syncRoot); }
}
public int Count
{
get
{
return timedStorage.Count;
}
}
public bool Remove(UUID scope, GridRegion region)
{
return Remove(scope, region.RegionID);
}
public bool Remove(UUID scope, UUID regionID)
{
RegionKey key = new RegionKey(scope, regionID);
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try
{
if (timedStorage.ContainsKey(key))
{
RegionInfoByScope ris = null;
if(InfobyScope.TryGetValue(scope, out ris) && ris != null)
{
GridRegion r = timedStorage[key];
if(r != null)
ris.RemoveRegion(r);
if(ris.Count() == 0)
InfobyScope.Remove(scope);
}
timedStorage.Remove(key);
timedExpires.Remove(key);
return true;
}
else
return false; return false;
}
finally { Monitor.Exit(syncRoot); }
}
public bool TryGetValue(RegionKey key, out GridRegion value)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try try
{ {
if (timedStorage.ContainsKey(key)) RegionInfoForScope ris = null;
{
value = timedStorage[key];
return true;
}
}
finally { Monitor.Exit(syncRoot); }
value = null;
return false;
}
public bool TryGetValue(UUID scope, UUID id, out GridRegion value)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try
{
RegionKey rk = new RegionKey(scope, id);
if(timedStorage.ContainsKey(rk))
{
value = timedStorage[rk];
return true;
}
}
finally { Monitor.Exit(syncRoot); }
value = null;
return false;
}
public bool TryGetValue(UUID scope, string name, out GridRegion value)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try
{
value = null;
RegionInfoByScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
return false; return false;
RegionKey key = ris.get(name); return ris.Contains(region);
if(key == null)
return false;
if(timedStorage.ContainsKey(key))
{
value = timedStorage[key];
return true;
}
} }
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }
}
public bool Contains(UUID scope, ulong handle)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try
{
RegionInfoForScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
return false; return false;
return ris.Contains(handle);
}
finally { Monitor.Exit(syncRoot); }
}
public int Count()
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try
{
int count = 0;
foreach(RegionInfoForScope ris in InfobyScope.Values)
count += ris.Count();
return count;
}
finally { Monitor.Exit(syncRoot); }
}
public bool Remove(UUID scope, ulong handle)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try
{
RegionInfoForScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
return false;
ris.Remove(handle);
if(ris.Count() == 0)
InfobyScope.Remove(scope);
return true;
}
finally { Monitor.Exit(syncRoot); }
}
public bool Remove(UUID scope, GridRegion region)
{
if(region == null)
return false;
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
try
{
RegionInfoForScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
return false;
ris.Remove(region);
if(ris.Count() == 0)
InfobyScope.Remove(scope);
return true;
}
finally { Monitor.Exit(syncRoot); }
} }
public bool TryGetValue(UUID scope, ulong handle, out GridRegion value) public bool TryGetValue(UUID scope, ulong handle, out GridRegion value)
{ {
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
value = null;
try try
{ {
value = null; RegionInfoForScope ris = null;
RegionInfoByScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null) if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
return false; return false;
value = ris.get(handle);
RegionKey key = ris.get(handle);
if(key == null)
return false;
if(timedStorage.ContainsKey(key))
{
value = timedStorage[key];
return true;
}
} }
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }
return value != null;
}
public bool TryGetValue(UUID scope, string name, out GridRegion value)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
value = null; value = null;
try
{
RegionInfoForScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
return false; return false;
value = ris.get(name);
}
finally { Monitor.Exit(syncRoot); }
return value != null;
}
public bool TryGetValue(UUID scope, UUID id, out GridRegion value)
{
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
value = null;
try
{
RegionInfoForScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
return false;
value = ris.get(id);
}
finally { Monitor.Exit(syncRoot); }
return value != null;
} }
// gets a region that contains world position (x,y) // gets a region that contains world position (x,y)
// hopefull will not take ages // hopefull will not take ages
public bool TryGetValue(UUID scope, int x, int y, out GridRegion value) public bool TryGetValue(UUID scope, uint x, uint y, out GridRegion value)
{ {
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
value = null;
try try
{ {
value = null; RegionInfoForScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
if(timedStorage.Count == 0)
return false; return false;
foreach(KeyValuePair<RegionKey, GridRegion> kvp in timedStorage) value = ris.get(x, y);
{
if(kvp.Key.ScopeID != scope)
continue;
GridRegion r = kvp.Value;
if(r == null) // ??
continue;
int test = r.RegionLocX;
if(x < test)
continue;
test += r.RegionSizeX;
if(x >= test)
continue;
test = r.RegionLocY;
if(y < test)
continue;
test += r.RegionSizeY;
if (y < test)
{
value = r;
return true;
}
}
} }
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }
value = null; return value != null;
return false;
} }
public bool Update(UUID scope, GridRegion region, double expirationSeconds) public bool Update(UUID scope, GridRegion region, double expirationSeconds)
{ {
if(region == null)
return false;
if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT))
throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms");
RegionKey key = new RegionKey(scope, region.RegionID);
try try
{ {
if (!timedStorage.ContainsKey(key)) RegionInfoForScope ris = null;
if(!InfobyScope.TryGetValue(scope, out ris) || ris == null)
return false; return false;
DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds); DateTime expire = DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds);
timedStorage[key] = region; ris.AddUpdate(region,expire);
if(expire > timedExpires[key])
timedExpires[key] = expire;
return true; return true;
} }
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }
@ -595,7 +703,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (!Monitor.TryEnter(isPurging)) if (!Monitor.TryEnter(isPurging))
return; return;
DateTime signalTime = DateTime.UtcNow; DateTime now = DateTime.UtcNow;
try try
{ {
@ -604,32 +712,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
return; return;
try try
{ {
List<RegionKey> expiredkeys = new List<RegionKey>(); List<UUID> expiredscopes = new List<UUID>();
foreach (KeyValuePair<RegionKey, DateTime> kvp in timedExpires) foreach (KeyValuePair<UUID, RegionInfoForScope> kvp in InfobyScope)
{ {
if (kvp.Value < signalTime) if (kvp.Value.expire(now) == 0)
expiredkeys.Add(kvp.Key); expiredscopes.Add(kvp.Key);
} }
if (expiredkeys.Count > 0) if (expiredscopes.Count > 0)
{ {
RegionInfoByScope ris; foreach (UUID sid in expiredscopes)
foreach (RegionKey key in expiredkeys) InfobyScope.Remove(sid);
{
ris = null;
if(InfobyScope.TryGetValue(key.ScopeID, out ris) && ris != null)
{
GridRegion r = timedStorage[key];
if(r != null)
ris.RemoveRegion(r);
if(ris.Count() == 0)
InfobyScope.Remove(key.ScopeID);
}
timedStorage.Remove(key);
timedExpires.Remove(key);
}
} }
} }
finally { Monitor.Exit(syncRoot); } finally { Monitor.Exit(syncRoot); }

View File

@ -204,8 +204,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y); GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
if (rinfo != null) if (rinfo != null)
{ {
m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache from local. Pos=<{1},{2}>, RegionHandle={3}", // m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Found region {0} on local. Pos=<{1},{2}>, RegionHandle={3}",
rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); // rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
return rinfo; return rinfo;
} }
@ -213,16 +213,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
if (rinfo == null) if (rinfo == null)
{ {
uint regionX = Util.WorldToRegionLoc((uint)x); // uint regionX = Util.WorldToRegionLoc((uint)x);
uint regionY = Util.WorldToRegionLoc((uint)y); // uint regionY = Util.WorldToRegionLoc((uint)y);
m_log.WarnFormat("[REMOTE GRID CONNECTOR]: Requested region {0}-{1} not found", regionX, regionY); // m_log.WarnFormat("[REMOTE GRID CONNECTOR]: Requested region {0}-{1} not found", regionX, regionY);
} }
else else
{ {
m_RegionInfoCache.Cache(scopeID, rinfo); m_RegionInfoCache.Cache(scopeID, rinfo);
m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}", // m_log.DebugFormat("[REMOTE GRID CONNECTOR]: GetRegionByPosition. Added region {0} to the cache. Pos=<{1},{2}>, RegionHandle={3}",
rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle); // rinfo.RegionName, rinfo.RegionCoordX, rinfo.RegionCoordY, rinfo.RegionHandle);
} }
return rinfo; return rinfo;
} }

View File

@ -852,19 +852,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
} }
public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) public void osTeleportAgent(string agent, int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{ {
// High because there is no security check. High griefer potential // High because there is no security check. High griefer potential
// //
CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent"); CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
TeleportAgent(agent, regionX, regionY, position, lookat, false); TeleportAgent(agent, regionGridX, regionGridY, position, lookat, false);
} }
private void TeleportAgent(string agent, int regionX, int regionY, private void TeleportAgent(string agent, int regionGridX, int regionGridY,
LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions)
{ {
ulong regionHandle = Util.RegionLocToHandle((uint)regionX, (uint)regionY); ulong regionHandle = Util.RegionGridLocToHandle((uint)regionGridX, (uint)regionGridY);
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
UUID agentId = new UUID(); UUID agentId = new UUID();
@ -917,11 +917,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
osTeleportOwner(World.RegionInfo.RegionName, position, lookat); osTeleportOwner(World.RegionInfo.RegionName, position, lookat);
} }
public void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) public void osTeleportOwner(int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{ {
CheckThreatLevel(ThreatLevel.None, "osTeleportOwner"); CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
TeleportAgent(m_host.OwnerID.ToString(), regionX, regionY, position, lookat, true); TeleportAgent(m_host.OwnerID.ToString(), regionGridX, regionGridY, position, lookat, true);
} }
///<summary> ///<summary>