From 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb Mon Sep 17 00:00:00 2001
From: onefang
Date: Sun, 19 May 2019 21:24:15 +1000
Subject: Dump OpenSim 0.9.0.1 into it's own branch.
---
.../Framework/Caps/CapabilitiesModule.cs | 150 +-
.../Framework/DynamicAttributes/DAExampleModule.cs | 30 +-
.../Framework/DynamicAttributes/DOExampleModule.cs | 24 +-
.../EntityTransfer/EntityTransferModule.cs | 1709 ++++++++++----------
.../EntityTransfer/EntityTransferStateMachine.cs | 44 +-
.../EntityTransfer/HGEntityTransferModule.cs | 84 +-
.../Framework/InterfaceCommander/Commander.cs | 20 +-
.../Framework/InventoryAccess/HGAssetMapper.cs | 8 +-
.../InventoryAccess/HGInventoryAccessModule.cs | 86 +-
.../InventoryAccess/InventoryAccessModule.cs | 557 ++++---
.../InventoryAccess/Tests/HGAssetMapperTests.cs | 9 +-
.../Tests/InventoryAccessModuleTests.cs | 64 +-
.../CoreModules/Framework/Library/LibraryModule.cs | 6 +-
.../Framework/Library/LocalInventoryService.cs | 15 +-
.../Framework/Monitoring/MonitorModule.cs | 12 +-
.../Framework/Search/BasicSearchModule.cs | 2 +-
.../ServiceThrottle/ServiceThrottleModule.cs | 148 +-
.../Statistics/Logging/BinaryLoggingModule.cs | 24 +-
.../UserManagement/HGUserManagementModule.cs | 14 +-
.../Tests/HGUserManagementModuleTests.cs | 2 +-
.../UserManagement/UserManagementModule.cs | 345 +++-
21 files changed, 1879 insertions(+), 1474 deletions(-)
(limited to 'OpenSim/Region/CoreModules/Framework')
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 817ef85..c0afe7c 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -47,23 +47,23 @@ namespace OpenSim.Region.CoreModules.Framework
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CapabilitiesModule")]
public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule
- {
+ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_showCapsCommandFormat = " {0,-38} {1,-60}\n";
-
+
protected Scene m_scene;
-
+
///
/// Each agent has its own capabilities handler.
///
- protected Dictionary m_capsObjects = new Dictionary();
-
+ protected Dictionary m_capsObjects = new Dictionary();
+
protected Dictionary m_capsPaths = new Dictionary();
- protected Dictionary> m_childrenSeeds
+ protected Dictionary> m_childrenSeeds
= new Dictionary>();
-
+
public void Initialise(IConfigSource source)
{
}
@@ -101,16 +101,16 @@ namespace OpenSim.Region.CoreModules.Framework
{
m_scene.UnregisterModuleInterface(this);
}
-
- public void PostInitialise()
+
+ public void PostInitialise()
{
}
public void Close() {}
- public string Name
- {
- get { return "Capabilities Module"; }
+ public string Name
+ {
+ get { return "Capabilities Module"; }
}
public Type ReplaceableInterface
@@ -118,23 +118,46 @@ namespace OpenSim.Region.CoreModules.Framework
get { return null; }
}
- public void CreateCaps(UUID agentId)
+ public void CreateCaps(UUID agentId, uint circuitCode)
{
- if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId))
- return;
+ int ts = Util.EnvironmentTickCount();
+/* this as no business here...
+ * must be done elsewhere ( and is )
+ int flags = m_scene.GetUserFlags(agentId);
+
+ m_log.ErrorFormat("[CreateCaps]: banCheck {0} ", Util.EnvironmentTickCountSubtract(ts));
+ if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
+ return;
+*/
Caps caps;
String capsObjectPath = GetCapsPath(agentId);
lock (m_capsObjects)
{
- if (m_capsObjects.ContainsKey(agentId))
+ if (m_capsObjects.ContainsKey(circuitCode))
{
- Caps oldCaps = m_capsObjects[agentId];
-
- //m_log.WarnFormat(
- // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
- // agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
+ Caps oldCaps = m_capsObjects[circuitCode];
+
+
+ if (capsObjectPath == oldCaps.CapsObjectPath)
+ {
+// m_log.WarnFormat(
+// "[CAPS]: Reusing caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
+// agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
+ return;
+ }
+ else
+ {
+ // not reusing add extra melanie cleanup
+ // Remove tge handlers. They may conflict with the
+ // new object created below
+ oldCaps.DeregisterHandlers();
+
+ // Better safe ... should not be needed but also
+ // no big deal
+ m_capsObjects.Remove(circuitCode);
+ }
}
// m_log.DebugFormat(
@@ -145,13 +168,17 @@ namespace OpenSim.Region.CoreModules.Framework
(MainServer.Instance == null) ? 0: MainServer.Instance.Port,
capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
- m_capsObjects[agentId] = caps;
- }
+ m_log.DebugFormat("[CreateCaps]: new caps agent {0}, circuit {1}, path {2}, time {3} ",agentId,
+ circuitCode,caps.CapsObjectPath, Util.EnvironmentTickCountSubtract(ts));
+ m_capsObjects[circuitCode] = caps;
+ }
m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
+// m_log.ErrorFormat("[CreateCaps]: end {0} ", Util.EnvironmentTickCountSubtract(ts));
+
}
- public void RemoveCaps(UUID agentId)
+ public void RemoveCaps(UUID agentId, uint circuitCode)
{
m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName);
lock (m_childrenSeeds)
@@ -164,44 +191,65 @@ namespace OpenSim.Region.CoreModules.Framework
lock (m_capsObjects)
{
- if (m_capsObjects.ContainsKey(agentId))
+ if (m_capsObjects.ContainsKey(circuitCode))
{
- m_capsObjects[agentId].DeregisterHandlers();
- m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]);
- m_capsObjects.Remove(agentId);
+ m_capsObjects[circuitCode].DeregisterHandlers();
+ m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
+ m_capsObjects.Remove(circuitCode);
}
else
{
+ foreach (KeyValuePair kvp in m_capsObjects)
+ {
+ if (kvp.Value.AgentID == agentId)
+ {
+ kvp.Value.DeregisterHandlers();
+ m_scene.EventManager.TriggerOnDeregisterCaps(agentId, kvp.Value);
+ m_capsObjects.Remove(kvp.Key);
+ return;
+ }
+ }
m_log.WarnFormat(
"[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!",
agentId, m_scene.RegionInfo.RegionName);
}
}
}
-
- public Caps GetCapsForUser(UUID agentId)
+
+ public Caps GetCapsForUser(uint circuitCode)
{
lock (m_capsObjects)
{
- if (m_capsObjects.ContainsKey(agentId))
+ if (m_capsObjects.ContainsKey(circuitCode))
{
- return m_capsObjects[agentId];
+ return m_capsObjects[circuitCode];
}
}
-
+
return null;
}
-
+
+ public void ActivateCaps(uint circuitCode)
+ {
+ lock (m_capsObjects)
+ {
+ if (m_capsObjects.ContainsKey(circuitCode))
+ {
+ m_capsObjects[circuitCode].Activate();
+ }
+ }
+ }
+
public void SetAgentCapsSeeds(AgentCircuitData agent)
{
lock (m_capsPaths)
m_capsPaths[agent.AgentID] = agent.CapsPath;
lock (m_childrenSeeds)
- m_childrenSeeds[agent.AgentID]
+ m_childrenSeeds[agent.AgentID]
= ((agent.ChildrenCapSeeds == null) ? new Dictionary() : agent.ChildrenCapSeeds);
}
-
+
public string GetCapsPath(UUID agentId)
{
lock (m_capsPaths)
@@ -214,7 +262,7 @@ namespace OpenSim.Region.CoreModules.Framework
return null;
}
-
+
public Dictionary GetChildrenSeeds(UUID agentID)
{
Dictionary seeds = null;
@@ -289,9 +337,9 @@ namespace OpenSim.Region.CoreModules.Framework
lock (m_capsObjects)
{
- foreach (KeyValuePair kvp in m_capsObjects)
+ foreach (KeyValuePair kvp in m_capsObjects)
{
- capsReport.AppendFormat("** User {0}:\n", kvp.Key);
+ capsReport.AppendFormat("** Circuit {0}:\n", kvp.Key);
Caps caps = kvp.Value;
for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
@@ -339,6 +387,7 @@ namespace OpenSim.Region.CoreModules.Framework
private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName)
{
+ /*
sb.AppendFormat("Capability name {0}\n", capName);
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -365,8 +414,8 @@ namespace OpenSim.Region.CoreModules.Framework
{
receivedStats[sp.Name] = reqHandler.RequestsReceived;
handledStats[sp.Name] = reqHandler.RequestsHandled;
- }
- else
+ }
+ else
{
PollServiceEventArgs pollHandler = null;
if (caps.TryGetPollHandler(capName, out pollHandler))
@@ -384,10 +433,12 @@ namespace OpenSim.Region.CoreModules.Framework
}
sb.Append(cdt.ToString());
+ */
}
private void BuildSummaryStatsByCapReport(StringBuilder sb)
{
+ /*
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Name", 34);
cdt.AddColumn("Req Received", 12);
@@ -403,7 +454,7 @@ namespace OpenSim.Region.CoreModules.Framework
Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
if (caps == null)
- return;
+ return;
foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
{
@@ -439,15 +490,17 @@ namespace OpenSim.Region.CoreModules.Framework
}
}
);
-
+
foreach (KeyValuePair kvp in receivedStats.OrderByDescending(kp => kp.Value))
cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
sb.Append(cdt.ToString());
+ */
}
private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams)
{
+ /*
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
return;
@@ -478,10 +531,12 @@ namespace OpenSim.Region.CoreModules.Framework
}
MainConsole.Instance.Output(sb.ToString());
+ */
}
private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp)
{
+ /*
sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root");
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -504,13 +559,15 @@ namespace OpenSim.Region.CoreModules.Framework
capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled));
foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived))
- cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled);
+ cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled);
sb.Append(cdt.ToString());
+ */
}
private void BuildSummaryStatsByUserReport(StringBuilder sb)
{
+ /*
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("Name", 32);
cdt.AddColumn("Type", 5);
@@ -544,12 +601,13 @@ namespace OpenSim.Region.CoreModules.Framework
totalRequestsReceived += handler.RequestsReceived;
totalRequestsHandled += handler.RequestsHandled;
}
-
+
cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
}
);
sb.Append(cdt.ToString());
+ */
}
private class CapTableRow
@@ -566,4 +624,4 @@ namespace OpenSim.Region.CoreModules.Framework
}
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
index 0c632b1..d652f43 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
@@ -53,12 +53,12 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
protected Scene m_scene;
protected IDialogModule m_dialogMod;
-
- public string Name { get { return "DAExample Module"; } }
- public Type ReplaceableInterface { get { return null; } }
+
+ public string Name { get { return "DAExample Module"; } }
+ public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source) {}
-
+
public void AddRegion(Scene scene)
{
if (ENABLED)
@@ -70,22 +70,22 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
m_log.DebugFormat("[DA EXAMPLE MODULE]: Added region {0}", m_scene.Name);
}
}
-
- public void RemoveRegion(Scene scene)
+
+ public void RemoveRegion(Scene scene)
{
if (ENABLED)
{
m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
}
}
-
+
public void RegionLoaded(Scene scene) {}
-
- public void Close()
+
+ public void Close()
{
RemoveRegion(m_scene);
}
-
+
protected bool OnSceneGroupMove(UUID groupId, Vector3 delta)
{
OSDMap attrs = null;
@@ -96,28 +96,28 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
if (!sop.DynAttrs.TryGetStore(Namespace, StoreName, out attrs))
attrs = new OSDMap();
-
+
OSDInteger newValue;
// We have to lock on the entire dynamic attributes map to avoid race conditions with serialization code.
- lock (sop.DynAttrs)
+ lock (sop.DynAttrs)
{
if (!attrs.ContainsKey("moves"))
newValue = new OSDInteger(1);
else
newValue = new OSDInteger(attrs["moves"].AsInteger() + 1);
-
+
attrs["moves"] = newValue;
sop.DynAttrs.SetStore(Namespace, StoreName, attrs);
}
sop.ParentGroup.HasGroupChanged = true;
-
+
string msg = string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue);
m_log.DebugFormat("[DA EXAMPLE MODULE]: {0}", msg);
m_dialogMod.SendGeneralAlert(msg);
-
+
return true;
}
}
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
index 166a994..3364cbc 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
@@ -65,11 +65,11 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
private Scene m_scene;
private IDialogModule m_dialogMod;
- public string Name { get { return "DO"; } }
- public Type ReplaceableInterface { get { return null; } }
+ public string Name { get { return "DO"; } }
+ public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source) {}
-
+
public void AddRegion(Scene scene)
{
if (ENABLED)
@@ -80,18 +80,18 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
m_dialogMod = m_scene.RequestModuleInterface();
}
}
-
- public void RemoveRegion(Scene scene)
+
+ public void RemoveRegion(Scene scene)
{
if (ENABLED)
{
m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
}
}
-
+
public void RegionLoaded(Scene scene) {}
-
- public void Close()
+
+ public void Close()
{
RemoveRegion(m_scene);
}
@@ -116,7 +116,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
rootPart.DynObjs.Add(DAExampleModule.Namespace, Name, new MyObject(movesSoFar));
}
-
+
private bool OnSceneGroupMove(UUID groupId, Vector3 delta)
{
SceneObjectGroup so = m_scene.GetSceneObjectGroup(groupId);
@@ -129,11 +129,11 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
if (rawObj != null)
{
MyObject myObj = (MyObject)rawObj;
-
+
m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", so.Name, so.UUID, ++myObj.Moves));
}
-
+
return true;
- }
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 1b4b5e6..2334e0b 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -54,9 +54,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
+ public const int DefaultMaxTransferDistance = 4095;
public const bool WaitForAgentArrivedAtDestinationDefault = true;
///
+ /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer.
+ ///
+ public int MaxTransferDistance { get; set; }
+
+ ///
/// If true then on a teleport, the source region waits for a callback from the destination region. If
/// a callback fails to arrive within a set time then the user is pulled back into the source region.
///
@@ -66,9 +72,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests.
///
///
- /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a
+ /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a
/// situation where avatars can be come 'stuck' due to a failed teleport cancellation. Unfortunately, the
- /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport
+ /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport
/// cancellation consistently suceed.
///
public bool DisableInterRegionTeleportCancellation { get; set; }
@@ -130,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
if (m_idCache.TryGetValue(pRegionHandle, out m_banUntil))
{
- if (DateTime.Now < m_banUntil)
+ if (DateTime.UtcNow < m_banUntil)
{
ret = true;
}
@@ -141,13 +147,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Add this agent in this region as a banned person
public void Add(ulong pRegionHandle, UUID pAgentID)
{
+ this.Add(pRegionHandle, pAgentID, 45, 15);
+ }
+
+ public void Add(ulong pRegionHandle, UUID pAgentID, double newTime, double extendTime)
+ {
if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache))
{
m_idCache = new ExpiringCache();
- m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(45));
+ m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(newTime));
}
- m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
+ m_idCache.Add(pRegionHandle, DateTime.UtcNow + TimeSpan.FromSeconds(extendTime), extendTime);
}
+
// Remove the agent from the region's banned list
public void Remove(ulong pRegionHandle, UUID pAgentID)
{
@@ -157,10 +169,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
}
+
private BannedRegionCache m_bannedRegionCache = new BannedRegionCache();
private IEventQueue m_eqModule;
- private IRegionCombinerModule m_regionCombinerModule;
#region ISharedRegionModule
@@ -209,11 +221,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
IConfig transferConfig = source.Configs["EntityTransfer"];
if (transferConfig != null)
{
- DisableInterRegionTeleportCancellation
+ DisableInterRegionTeleportCancellation
= transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
WaitForAgentArrivedAtDestination
= transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault);
+
+ MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance);
+ }
+ else
+ {
+ MaxTransferDistance = DefaultMaxTransferDistance;
}
m_entityTransferStateMachine = new EntityTransferStateMachine(this);
@@ -232,7 +250,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Scene = scene;
- m_interRegionTeleportAttempts =
+ m_interRegionTeleportAttempts =
new Stat(
"InterRegionTeleportAttempts",
"Number of inter-region teleports attempted.",
@@ -245,7 +263,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
null,
StatVerbosity.Debug);
- m_interRegionTeleportAborts =
+ m_interRegionTeleportAborts =
new Stat(
"InterRegionTeleportAborts",
"Number of inter-region teleports aborted due to client actions.",
@@ -257,7 +275,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
null,
StatVerbosity.Debug);
- m_interRegionTeleportCancels =
+ m_interRegionTeleportCancels =
new Stat(
"InterRegionTeleportCancels",
"Number of inter-region teleports cancelled by the client.",
@@ -269,7 +287,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
null,
StatVerbosity.Debug);
- m_interRegionTeleportFailures =
+ m_interRegionTeleportFailures =
new Stat(
"InterRegionTeleportFailures",
"Number of inter-region teleports that failed due to server/client/network issues.",
@@ -303,7 +321,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public virtual void Close() {}
- public virtual void RemoveRegion(Scene scene)
+ public virtual void RemoveRegion(Scene scene)
{
if (m_Enabled)
{
@@ -320,7 +338,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
m_eqModule = Scene.RequestModuleInterface();
- m_regionCombinerModule = Scene.RequestModuleInterface();
}
#endregion
@@ -332,7 +349,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (client.IsLoggingOut && m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting))
{
m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
+ "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
client.Name, Scene.Name);
}
}
@@ -354,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
teleportFlags |= (uint)TeleportFlags.Godlike;
}
- if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
+ else if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
return;
string destinationRegionName = "(not found)";
@@ -374,17 +391,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
try
{
- // Reset animations; the viewer does that in teleports.
- sp.Animator.ResetAnimations();
if (regionHandle == sp.Scene.RegionInfo.RegionHandle)
{
+ if(!sp.AllowMovement)
+ {
+ sp.ControllingClient.SendTeleportFailed("You are frozen");
+ m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
+ return;
+ }
+
+ // Reset animations; the viewer does that in teleports.
+ sp.Animator.ResetAnimations();
destinationRegionName = sp.Scene.RegionInfo.RegionName;
TeleportAgentWithinRegion(sp, position, lookAt, teleportFlags);
}
else // Another region possibly in another simulator
{
+ // Reset animations; the viewer does that in teleports.
+ sp.Animator.ResetAnimations();
+
GridRegion finalDestination = null;
try
{
@@ -400,12 +427,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
catch (Exception e)
{
+
m_log.ErrorFormat(
"[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}",
sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName,
e.Message, e.StackTrace);
-
- sp.ControllingClient.SendTeleportFailed("Internal error");
+ if(sp != null && sp.ControllingClient != null && !sp.IsDeleted)
+ sp.ControllingClient.SendTeleportFailed("Internal error");
}
finally
{
@@ -438,17 +466,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
position = emergencyPos;
}
+ // Check Default Location (Also See ScenePresence.CompleteMovement)
+ if (position.X == 128f && position.Y == 128f && position.Z == 22.5f)
+ position = sp.Scene.RegionInfo.DefaultLandingPoint;
+
// TODO: Get proper AVG Height
- float localAVHeight = 1.56f;
+ float localHalfAVHeight = 0.8f;
+ if (sp.Appearance != null)
+ localHalfAVHeight = sp.Appearance.AvatarHeight / 2;
+
float posZLimit = 22;
// TODO: Check other Scene HeightField
posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
- float newPosZ = posZLimit + localAVHeight;
- if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
+ posZLimit += localHalfAVHeight + 0.1f;
+
+ if ((position.Z < posZLimit) && !(Single.IsInfinity(posZLimit) || Single.IsNaN(posZLimit)))
{
- position.Z = newPosZ;
+ position.Z = posZLimit;
}
if (sp.Flying)
@@ -457,9 +493,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
sp.ControllingClient.SendTeleportStart(teleportFlags);
+ lookAt.Z = 0f;
+
+ if(Math.Abs(lookAt.X) < 0.01f && Math.Abs(lookAt.Y) < 0.01f)
+ {
+ lookAt.X = 1.0f;
+ lookAt.Y = 0;
+ }
sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
+ sp.RotateToLookAt(lookAt);
sp.Velocity = Vector3.Zero;
sp.Teleport(position);
@@ -494,15 +538,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
string homeURI = Scene.GetAgentHomeURI(sp.ControllingClient.AgentId);
- string message;
- finalDestination = GetFinalDestination(reg, sp.ControllingClient.AgentId, homeURI, out message);
+ string reason = String.Empty;
+ finalDestination = GetFinalDestination(reg, sp.ControllingClient.AgentId, homeURI, out reason);
if (finalDestination == null)
{
m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}: {3}",
- LogHeader, sp.Name, sp.UUID, message);
+ LogHeader, sp.Name, sp.UUID, reason);
- sp.ControllingClient.SendTeleportFailed(message);
+ sp.ControllingClient.SendTeleportFailed(reason);
return;
}
@@ -515,17 +559,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
}
- // Validate assorted conditions
- string reason = string.Empty;
if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason))
{
sp.ControllingClient.SendTeleportFailed(reason);
return;
}
- if (message != null)
- sp.ControllingClient.SendAgentAlertMessage(message, true);
-
//
// This is it
//
@@ -547,9 +586,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY);
MapBlockData block = new MapBlockData();
- block.X = (ushort)regX;
- block.Y = (ushort)regY;
- block.Access = (byte)SimAccess.Down;
+ block.X = (ushort)(regX);
+ block.Y = (ushort)(regY);
+ block.Access = (byte)SimAccess.Down; // == not there
List blocks = new List();
blocks.Add(block);
@@ -565,12 +604,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
uint x = 0, y = 0;
Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
+ GridRegion reg;
+
+ // handle legacy HG. linked regions are mapped into y = 0 and have no size information
+ // so we can only search by base handle
+ if( y == 0)
+ {
+ reg = gridService.GetRegionByPosition(scope, (int)x, (int)y);
+ return reg;
+ }
+
// Compute the world location we're teleporting to
double worldX = (double)x + position.X;
double worldY = (double)y + position.Y;
// Find the region that contains the position
- GridRegion reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY);
+ reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY);
if (reg != null)
{
@@ -589,6 +638,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return true;
}
+ ///
+ /// Determines whether this instance is within the max transfer distance.
+ ///
+ ///
+ ///
+ ///
+ /// true if this instance is within max transfer distance; otherwise, false.
+ ///
+ private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion)
+ {
+ if(MaxTransferDistance == 0)
+ return true;
+
+// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY);
+//
+// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}",
+// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI);
+
+ // Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position.
+ return Math.Abs(sourceRegion.RegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance
+ && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
+ }
///
/// Wraps DoTeleportInternal() and manages the transfer state.
@@ -607,7 +678,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.ControllingClient.SendTeleportFailed("Agent is already in transit.");
return;
}
-
+
try
{
DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
@@ -650,10 +721,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
RegionInfo sourceRegion = sp.Scene.RegionInfo;
+ if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination))
+ {
+ sp.ControllingClient.SendTeleportFailed(
+ string.Format(
+ "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way",
+ finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY,
+ sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
+ MaxTransferDistance));
- uint newRegionX, newRegionY, oldRegionX, oldRegionY;
- Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY);
- Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY);
+ return;
+ }
ulong destinationHandle = finalDestination.RegionHandle;
@@ -663,8 +741,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
IPEndPoint endPoint = finalDestination.ExternalEndPoint;
if (endPoint == null || endPoint.Address == null)
{
- sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
-
+ sp.ControllingClient.SendTeleportFailed("Could not resolve destination Address");
return;
}
@@ -694,7 +771,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_interRegionTeleportAttempts.Value++;
m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: {0} transfer protocol version to {1} is {2} / {3}",
+ "[ENTITY TRANSFER MODULE]: {0} transfer protocol version to {1} is {2} / {3}",
sp.Scene.Name, finalDestination.RegionName, ctx.OutboundVersion, ctx.InboundVersion);
// Fixing a bug where teleporting while sitting results in the avatar ending up removed from
@@ -704,27 +781,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
else if (sp.Flying)
teleportFlags |= (uint)TeleportFlags.IsFlying;
+ sp.IsInLocalTransit = finalDestination.RegionLocY != 0; // HG
+ sp.IsInTransit = true;
+
+
if (DisableInterRegionTeleportCancellation)
teleportFlags |= (uint)TeleportFlags.DisableCancel;
// At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
// the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
sp.ControllingClient.SendTeleportStart(teleportFlags);
-
- // the avatar.Close below will clear the child region list. We need this below for (possibly)
- // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
- //List childRegions = avatar.KnownRegionHandles;
- // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
- // failure at this point (unlike a border crossing failure). So perhaps this can never fail
- // once we reach here...
- //avatar.Scene.RemoveCapsHandler(avatar.UUID);
-
+
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
agentCircuit.startpos = position;
agentCircuit.child = true;
+
agentCircuit.Appearance = new AvatarAppearance();
- agentCircuit.Appearance.PackLegacyWearables = true;
+ agentCircuit.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
+
if (currentAgentCircuit != null)
{
agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
@@ -735,36 +810,64 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agentCircuit.Id0 = currentAgentCircuit.Id0;
}
- // if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
- float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
- (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
- if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
+ uint newRegionX, newRegionY, oldRegionX, oldRegionY;
+ Util.RegionHandleToRegionLoc(destinationHandle, out newRegionX, out newRegionY);
+ Util.RegionHandleToRegionLoc(sourceRegion.RegionHandle, out oldRegionX, out oldRegionY);
+ int oldSizeX = (int)sourceRegion.RegionSizeX;
+ int oldSizeY = (int)sourceRegion.RegionSizeY;
+ int newSizeX = finalDestination.RegionSizeX;
+ int newSizeY = finalDestination.RegionSizeY;
+
+ bool OutSideViewRange = NeedsNewAgent(sp.RegionViewDistance, oldRegionX, newRegionX, oldRegionY, newRegionY,
+ oldSizeX, oldSizeY, newSizeX, newSizeY);
+
+ if (OutSideViewRange)
{
- // brand new agent, let's create a new caps seed
+ m_log.DebugFormat(
+ "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} size {3},{4} needs new child agent for agent {5} from {6}",
+ finalDestination.RegionName, newRegionX, newRegionY,newSizeX, newSizeY, sp.Name, Scene.Name);
+
+ //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
}
+ else
+ {
+ agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
+ if (agentCircuit.CapsPath == null)
+ agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
+ }
// We're going to fallback to V1 if the destination gives us anything smaller than 0.2
if (ctx.OutboundVersion >= 0.2f)
- TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason);
+ TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, OutSideViewRange , ctx, out reason);
else
- TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason);
+ TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, OutSideViewRange, ctx, out reason);
}
private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
- IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason)
+ IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason)
{
ulong destinationHandle = finalDestination.RegionHandle;
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}",
+ "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}",
sp.Name, Scene.Name, finalDestination.RegionName);
- // Let's create an agent there if one doesn't exist yet.
+ string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
+ List childRegionsToClose = sp.GetChildAgentsToClose(destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
+ if(agentCircuit.ChildrenCapSeeds != null)
+ {
+ foreach(ulong handler in childRegionsToClose)
+ {
+ agentCircuit.ChildrenCapSeeds.Remove(handler);
+ }
+ }
+
+ // Let's create an agent there if one doesn't exist yet.
// NOTE: logout will always be false for a non-HG teleport.
bool logout = false;
- if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
+ if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout))
{
m_interRegionTeleportFailures.Value++;
@@ -773,7 +876,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
sp.ControllingClient.SendTeleportFailed(reason);
-
+ sp.IsInTransit = false;
return;
}
@@ -784,7 +887,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
-
+ sp.IsInTransit = false;
return;
}
else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
@@ -794,7 +897,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
-
+ sp.IsInTransit = false;
return;
}
@@ -802,28 +905,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
// OK, it got this agent. Let's close some child agents
- sp.CloseChildAgents(newRegionX, newRegionY);
- IClientIPEndpoint ipepClient;
- string capsPath = String.Empty;
- float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
- (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
- if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
+ if (OutSideViewRange)
{
- m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
- finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
-
- //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
- #region IP Translation for NAT
- // Uses ipepClient above
- if (sp.ClientView.TryGet(out ipepClient))
- {
- endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
- }
- #endregion
- capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
-
if (m_eqModule != null)
{
// The EnableSimulator message makes the client establish a connection with the destination
@@ -853,22 +937,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
}
}
- else
- {
- agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
- capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
- }
// Let's send a full update of the agent. This is a synchronous call.
AgentData agent = new AgentData();
- sp.CopyTo(agent);
- if (ctx.OutboundVersion < 0.5f)
- agent.Appearance.PackLegacyWearables = true;
+ sp.CopyTo(agent,false);
+
+ if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0)
+ agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
+
agent.Position = agentCircuit.startpos;
SetCallbackURL(agent, sp.Scene.RegionInfo);
-
- // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
+ // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
// establish th econnection to the destination which makes it return true.
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
{
@@ -877,15 +957,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
-
+ sp.IsInTransit = false;
return;
}
- // A common teleport failure occurs when we can send CreateAgent to the
+ // A common teleport failure occurs when we can send CreateAgent to the
// destination region but the viewer cannot establish the connection (e.g. due to network issues between
// the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
// there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
- if (!UpdateAgent(reg, finalDestination, agent, sp))
+ if (!UpdateAgent(reg, finalDestination, agent, sp, ctx))
{
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
{
@@ -894,7 +974,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
-
+ sp.IsInTransit = false;
return;
}
@@ -903,6 +983,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.Name);
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
+ sp.IsInTransit = false;
return;
}
@@ -915,7 +996,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.Name);
CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination);
-
+ sp.IsInTransit = false;
return;
}
@@ -924,7 +1005,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
// We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
- // where that neighbour simulator could otherwise request a child agent create on the source which then
+ // where that neighbour simulator could otherwise request a child agent create on the source which then
// closes our existing agent which is still signalled as root.
sp.IsChildAgent = true;
@@ -952,7 +1033,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
-
+ sp.IsInTransit = false;
return;
}
@@ -961,12 +1042,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion.");
-
+ sp.IsInTransit = false;
return;
}
- m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
-
/*
// TODO: This may be 0.6. Check if still needed
// For backwards compatibility
@@ -978,18 +1057,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
*/
- // May need to logout or other cleanup
+ m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
+
+ if(logout)
+ sp.closeAllChildAgents();
+ else
+ sp.CloseChildAgents(childRegionsToClose);
+
+ // call HG hook
AgentHasMovedAway(sp, logout);
- // Well, this is it. The agent is over there.
- KillEntity(sp.Scene, sp.LocalId);
+ sp.HasMovedAway(!(OutSideViewRange || logout));
- // Now let's make it officially a child agent
- sp.MakeChildAgent();
+// ulong sourceRegionHandle = sp.RegionHandle;
+
+ // Now let's make it officially a child agent
+ sp.MakeChildAgent(destinationHandle);
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
- if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
+ if (NeedsClosing(reg, OutSideViewRange))
{
if (!sp.Scene.IncomingPreCloseClient(sp))
return;
@@ -1001,26 +1088,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// This sleep can be increased if necessary. However, whilst it's active,
// an agent cannot teleport back to this region if it has teleported away.
Thread.Sleep(2000);
-
sp.Scene.CloseAgent(sp.UUID, false);
}
- else
- {
- // now we have a child agent in this region.
- sp.Reset();
- }
+ sp.IsInTransit = false;
}
private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
- IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason)
+ IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason)
{
ulong destinationHandle = finalDestination.RegionHandle;
- AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
- // Let's create an agent there if one doesn't exist yet.
+ List childRegionsToClose = sp.GetChildAgentsToClose(destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
+
+ if(agentCircuit.ChildrenCapSeeds != null)
+ {
+ foreach(ulong handler in childRegionsToClose)
+ {
+ agentCircuit.ChildrenCapSeeds.Remove(handler);
+ }
+ }
+
+ string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);;
+
+ // Let's create an agent there if one doesn't exist yet.
// NOTE: logout will always be false for a non-HG teleport.
bool logout = false;
- if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
+ if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout))
{
m_interRegionTeleportFailures.Value++;
@@ -1029,7 +1122,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
sp.ControllingClient.SendTeleportFailed(reason);
-
+ sp.IsInTransit = false;
return;
}
@@ -1041,6 +1134,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
+ sp.IsInTransit = false;
return;
}
else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
@@ -1051,40 +1145,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
+ sp.IsInTransit = false;
return;
}
// Past this point we have to attempt clean up if the teleport fails, so update transfer state.
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
- IClientIPEndpoint ipepClient;
- string capsPath = String.Empty;
- float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
- (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
- if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
- {
- m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
- finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
-
- //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
- #region IP Translation for NAT
- // Uses ipepClient above
- if (sp.ClientView.TryGet(out ipepClient))
- {
- endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
- }
- #endregion
- capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
- }
- else
- {
- agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
- capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
- }
-
// We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
- // where that neighbour simulator could otherwise request a child agent create on the source which then
+ // where that neighbour simulator could otherwise request a child agent create on the source which then
// closes our existing agent which is still signalled as root.
//sp.IsChildAgent = true;
@@ -1100,13 +1169,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
- // Let's send a full update of the agent.
+ // Let's send a full update of the agent.
AgentData agent = new AgentData();
- sp.CopyTo(agent);
- if (ctx.OutboundVersion < 0.5f)
- agent.Appearance.PackLegacyWearables = true;
+ sp.CopyTo(agent,false);
agent.Position = agentCircuit.startpos;
+
+ if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0)
+ agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
+
agent.SenderWantsToWaitForRoot = true;
+
//SetCallbackURL(agent, sp.Scene.RegionInfo);
// Reset the do not close flag. This must be done before the destination opens child connections (here
@@ -1118,7 +1190,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Send the Update. If this returns true, we know the client has contacted the destination
// via CompleteMovementIntoRegion, so we can let go.
// If it returns false, something went wrong, and we need to abort.
- if (!UpdateAgent(reg, finalDestination, agent, sp))
+ if (!UpdateAgent(reg, finalDestination, agent, sp, ctx))
{
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
{
@@ -1127,7 +1199,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
-
+ sp.IsInTransit = false;
return;
}
@@ -1135,31 +1207,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
- Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
+ Fail(sp, finalDestination, logout, agentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
+ sp.IsInTransit = false;
return;
}
-
+
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
- // Need to signal neighbours whether child agents may need closing irrespective of whether this
- // one needed closing. We also need to close child agents as quickly as possible to avoid complicated
- // race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back
- // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex
- // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are
- // abandoned without proper close by viewer but then re-used by an incoming connection.
- sp.CloseChildAgents(newRegionX, newRegionY);
+ if(logout)
+ sp.closeAllChildAgents();
+ else
+ sp.CloseChildAgents(childRegionsToClose);
+
+ sp.HasMovedAway(!(OutSideViewRange || logout));
- // May need to logout or other cleanup
+ //HG hook
AgentHasMovedAway(sp, logout);
- // Well, this is it. The agent is over there.
- KillEntity(sp.Scene, sp.LocalId);
+// ulong sourceRegionHandle = sp.RegionHandle;
// Now let's make it officially a child agent
- sp.MakeChildAgent();
+ sp.MakeChildAgent(destinationHandle);
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
- if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
+ // go by HG hook
+ if (NeedsClosing(reg, OutSideViewRange))
{
if (!sp.Scene.IncomingPreCloseClient(sp))
return;
@@ -1170,21 +1242,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// BEFORE THEY SETTLE IN THE NEW REGION.
// DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
// IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
+
Thread.Sleep(15000);
-
+
// OK, it got this agent. Let's close everything
- // If we shouldn't close the agent due to some other region renewing the connection
+ // If we shouldn't close the agent due to some other region renewing the connection
// then this will be handled in IncomingCloseAgent under lock conditions
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
sp.Scene.CloseAgent(sp.UUID, false);
}
- else
- {
- // now we have a child agent in this region.
- sp.Reset();
- }
+ sp.IsInTransit = false;
}
///
@@ -1232,13 +1301,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
}
- protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
+ protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout)
{
GridRegion source = new GridRegion(Scene.RegionInfo);
source.RawServerURI = m_GatekeeperURI;
logout = false;
- bool success = Scene.SimulationService.CreateAgent(source, finalDestination, agentCircuit, teleportFlags, out reason);
+ bool success = Scene.SimulationService.CreateAgent(source, finalDestination, agentCircuit, teleportFlags, ctx, out reason);
if (success)
sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
@@ -1246,9 +1315,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return success;
}
- protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp)
+ protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp, EntityTransferContext ctx)
{
- return Scene.SimulationService.UpdateAgent(finalDestination, agent);
+ return Scene.SimulationService.UpdateAgent(finalDestination, agent, ctx);
}
protected virtual void SetCallbackURL(AgentData agent, RegionInfo region)
@@ -1265,10 +1334,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
///
///
///
+ ///
+ /// now just a HG hook
protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
{
- if (sp.Scene.AttachmentsModule != null)
- sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true);
+// if (sp.Scene.AttachmentsModule != null)
+// sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, logout);
}
protected void KillEntity(Scene scene, uint localID)
@@ -1276,6 +1347,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
scene.SendKillObject(new List { localID });
}
+ // HG hook
protected virtual GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message)
{
message = null;
@@ -1285,28 +1357,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// This returns 'true' if the new region already has a child agent for our
// incoming agent. The implication is that, if 'false', we have to create the
// child and then teleport into the region.
- protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY)
+ protected virtual bool NeedsNewAgent(float viewdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY,
+ int oldsizeX, int oldsizeY, int newsizeX, int newsizeY)
{
- if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
- {
- Vector2 swCorner, neCorner;
- GetMegaregionViewRange(out swCorner, out neCorner);
-
- m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Megaregion view of {0} is from {1} to {2} with new agent check for {3},{4}",
- Scene.Name, swCorner, neCorner, newRegionX, newRegionY);
-
- return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y);
- }
- else
- {
- return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
- }
+ return Util.IsOutsideView(viewdist, oldRegionX, newRegionX, oldRegionY, newRegionY,
+ oldsizeX, oldsizeY, newsizeX, newsizeY);
}
- protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg)
+ // HG Hook
+ protected virtual bool NeedsClosing(GridRegion reg, bool OutViewRange)
+
{
- return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
+ return OutViewRange;
}
#endregion
@@ -1328,11 +1390,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
return;
}
- ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
+ ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
}
- #endregion
+ #endregion
#region Teleport Home
@@ -1366,7 +1428,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
client.SendTeleportFailed("Your home region could not be found.");
return false;
}
-
+
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})",
client.Name, regionInfo.RegionName, regionInfo.RegionCoordX, regionInfo.RegionCoordY);
@@ -1389,105 +1451,146 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Agent Crossings
- // Given a position relative to the current region (which has previously been tested to
- // see that it is actually outside the current region), find the new region that the
- // point is actually in.
- // Returns the coordinates and information of the new region or 'null' of it doesn't exist.
+ public bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position,
+ EntityTransferContext ctx, out string reason)
+ {
+ reason = String.Empty;
+
+ UUID agentID = agent.UUID;
+ ulong destinyHandle = destiny.RegionHandle;
+
+ if (m_bannedRegionCache.IfBanned(destinyHandle, agentID))
+ {
+ return false;
+ }
+
+ Scene ascene = agent.Scene;
+ string homeURI = ascene.GetAgentHomeURI(agentID);
+
+
+ if (!ascene.SimulationService.QueryAccess(destiny, agentID, homeURI, false, position,
+ agent.Scene.GetFormatsOffered(), ctx, out reason))
+ {
+ m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0);
+ return false;
+ }
+ return true;
+ }
+
+
+ // Given a position relative to the current region and outside of it
+ // find the new region that the point is actually in.
+ // returns 'null' if new region not found or if information
+ // and new position relative to it
+ // now only works for crossings
+
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos,
EntityTransferContext ctx, out Vector3 newpos, out string failureReason)
{
newpos = pos;
failureReason = string.Empty;
- string homeURI = scene.GetAgentHomeURI(agentID);
// m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
- // Compute world location of the object's position
+ // Compute world location of the agent's position
double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X;
double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y;
// Call the grid service to lookup the region containing the new position.
- GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
- presenceWorldX, presenceWorldY,
- Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY));
+ GridRegion neighbourRegion = GetRegionContainingWorldLocation(
+ scene.GridService, scene.RegionInfo.ScopeID,
+ presenceWorldX, presenceWorldY,
+ Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY));
+
+ if (neighbourRegion == null)
+ return null;
- if (neighbourRegion != null)
+ if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID))
{
- // Compute the entity's position relative to the new region
- newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
+ failureReason = "Access Denied or Temporary not possible";
+ return null;
+ }
+
+ m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID);
+
+ // Compute the entity's position relative to the new region
+ newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
(float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
pos.Z);
- if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID))
- {
- failureReason = "Cannot region cross into banned parcel";
- neighbourRegion = null;
- }
- else
- {
- // If not banned, make sure this agent is not in the list.
- m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID);
- }
-
- // Check to see if we have access to the target region.
- if (neighbourRegion != null
- && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, scene.GetFormatsOffered(), ctx, out failureReason))
- {
- // remember banned
- m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
- neighbourRegion = null;
- }
+ string homeURI = scene.GetAgentHomeURI(agentID);
+
+ if (!scene.SimulationService.QueryAccess(
+ neighbourRegion, agentID, homeURI, false, newpos,
+ scene.GetFormatsOffered(), ctx, out failureReason))
+ {
+ // remember the fail
+ m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
+ if(String.IsNullOrWhiteSpace(failureReason))
+ failureReason = "Access Denied";
+ return null;
}
- else
+
+ return neighbourRegion;
+ }
+
+ public bool Cross(ScenePresence agent, bool isFlying)
+ {
+ agent.IsInLocalTransit = true;
+ agent.IsInTransit = true;
+ CrossAsyncDelegate d = CrossAsync;
+ d.BeginInvoke(agent, isFlying, CrossCompleted, d);
+ return true;
+ }
+
+ private void CrossCompleted(IAsyncResult iar)
+ {
+ CrossAsyncDelegate icon = (CrossAsyncDelegate)iar.AsyncState;
+ ScenePresence agent = icon.EndInvoke(iar);
+
+ if(agent == null || agent.IsDeleted)
+ return;
+
+ if(!agent.IsChildAgent)
{
- // The destination region just doesn't exist
- failureReason = "Cannot cross into non-existent region";
+ // crossing failed
+ agent.CrossToNewRegionFail();
}
-
- if (neighbourRegion == null)
- m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}",
- LogHeader, scene.RegionInfo.RegionName,
- scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY,
- scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY,
- pos);
else
- m_log.DebugFormat("{0} GetDestination: new region={1} at <{2},{3}> of size <{4},{5}>, newpos=<{6},{7}>",
- LogHeader, neighbourRegion.RegionName,
- neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY,
- newpos.X, newpos.Y);
+ m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
- return neighbourRegion;
+ agent.IsInTransit = false;
}
- public bool Cross(ScenePresence agent, bool isFlying)
+ public ScenePresence CrossAsync(ScenePresence agent, bool isFlying)
{
Vector3 newpos;
EntityTransferContext ctx = new EntityTransferContext();
string failureReason;
- GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition,
+ // We need this because of decimal number parsing of the protocols.
+ Culture.SetCurrentCulture();
+
+ Vector3 pos = agent.AbsolutePosition + agent.Velocity * 0.2f;
+
+ GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos,
ctx, out newpos, out failureReason);
if (neighbourRegion == null)
{
- agent.ControllingClient.SendAlertMessage(failureReason);
- return false;
+ if (!agent.IsDeleted && failureReason != String.Empty && agent.ControllingClient != null)
+ agent.ControllingClient.SendAlertMessage(failureReason);
+ return agent;
}
- agent.IsInTransit = true;
-
- CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
- d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, ctx, CrossAgentToNewRegionCompleted, d);
+// agent.IsInTransit = true;
- Scene.EventManager.TriggerCrossAgentToNewRegion(agent, isFlying, neighbourRegion);
-
- return true;
+ CrossAgentToNewRegionAsync(agent, newpos, neighbourRegion, isFlying, ctx);
+ agent.IsInTransit = false;
+ return agent;
}
-
- public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY,
- Vector3 position,
- Scene initiatingScene);
+ public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene);
private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene)
{
@@ -1506,14 +1609,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Thread.Sleep(10000);
m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}",
+ "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}",
agent.Name, regionX, regionY, position, initiatingScene.Name);
agent.Scene.RequestTeleportLocation(
- agent.ControllingClient,
- Util.RegionLocToHandle(regionX, regionY),
- position,
- agent.Lookat,
+ agent.ControllingClient,
+ Util.RegionGridLocToHandle(regionX, regionY),
+ position,
+ agent.Lookat,
(uint)Constants.TeleportFlags.ViaLocation);
/*
@@ -1557,15 +1660,71 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
icon.EndInvoke(iar);
}
- public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
+ public bool CrossAgentCreateFarChild(ScenePresence agent, GridRegion neighbourRegion, Vector3 pos, EntityTransferContext ctx)
{
- if (neighbourRegion == null)
+ ulong regionhandler = neighbourRegion.RegionHandle;
+
+ if(agent.knowsNeighbourRegion(regionhandler))
+ return true;
+
+ string reason;
+ ulong currentRegionHandler = agent.Scene.RegionInfo.RegionHandle;
+ GridRegion source = new GridRegion(agent.Scene.RegionInfo);
+
+ AgentCircuitData currentAgentCircuit =
+ agent.Scene.AuthenticateHandler.GetAgentCircuitData(agent.ControllingClient.CircuitCode);
+ AgentCircuitData agentCircuit = agent.ControllingClient.RequestClientInfo();
+ agentCircuit.startpos = pos;
+ agentCircuit.child = true;
+
+ agentCircuit.Appearance = new AvatarAppearance();
+ agentCircuit.Appearance.AvatarHeight = agent.Appearance.AvatarHeight;
+
+ if (currentAgentCircuit != null)
+ {
+ agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
+ agentCircuit.IPAddress = currentAgentCircuit.IPAddress;
+ agentCircuit.Viewer = currentAgentCircuit.Viewer;
+ agentCircuit.Channel = currentAgentCircuit.Channel;
+ agentCircuit.Mac = currentAgentCircuit.Mac;
+ agentCircuit.Id0 = currentAgentCircuit.Id0;
+ }
+
+ agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
+ agent.AddNeighbourRegion(neighbourRegion, agentCircuit.CapsPath);
+
+ IPEndPoint endPoint = neighbourRegion.ExternalEndPoint;
+ if(endPoint == null)
+ {
+ m_log.DebugFormat("CrossAgentCreateFarChild failed to resolve neighbour address {0}", neighbourRegion.ExternalHostName);
return false;
-
- m_entityTransferStateMachine.SetInTransit(agent.UUID);
+ }
+ if (!Scene.SimulationService.CreateAgent(source, neighbourRegion, agentCircuit, (int)TeleportFlags.Default, ctx, out reason))
+ {
+ agent.RemoveNeighbourRegion(regionhandler);
+ return false;
+ }
- agent.RemoveFromPhysicalScene();
+ string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
+ int newSizeX = neighbourRegion.RegionSizeX;
+ int newSizeY = neighbourRegion.RegionSizeY;
+ if (m_eqModule != null)
+ {
+ m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
+ "and EstablishAgentCommunication with seed cap {8}", LogHeader,
+ source.RegionName, agent.Name,
+ neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, newSizeX, newSizeY , capsPath);
+
+ m_eqModule.EnableSimulator(regionhandler,
+ endPoint, agent.UUID, newSizeX, newSizeY);
+ m_eqModule.EstablishAgentCommunication(agent.UUID, endPoint, capsPath,
+ regionhandler, newSizeX, newSizeY);
+ }
+ else
+ {
+ agent.ControllingClient.InformClientOfNeighbour(regionhandler, endPoint);
+ }
return true;
}
@@ -1582,37 +1741,56 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: new region={1} at <{2},{3}>. newpos={4}",
LogHeader, neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, pos);
- if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
+ if (neighbourRegion == null)
{
- m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: prep failed. Resetting transfer state", LogHeader);
- m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
+ m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: invalid destiny", LogHeader);
+ return agent;
}
- if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying, ctx))
+ IPEndPoint endpoint = neighbourRegion.ExternalEndPoint;
+ if(endpoint == null)
+ {
+ m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: failed to resolve neighbour address {0} ",neighbourRegion.ExternalHostName);
+ return agent;
+ }
+
+ m_entityTransferStateMachine.SetInTransit(agent.UUID);
+ agent.RemoveFromPhysicalScene();
+
+ if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, endpoint, isFlying, ctx))
{
m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader);
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
}
-
- CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, ctx);
}
catch (Exception e)
{
m_log.Error(string.Format("{0}: CrossAgentToNewRegionAsync: failed with exception ", LogHeader), e);
}
-
return agent;
}
- public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx)
+ public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
+ IPEndPoint endpoint, bool isFlying, EntityTransferContext ctx)
{
+ int ts = Util.EnvironmentTickCount();
+ bool sucess = true;
+ string reason = String.Empty;
+ List childRegionsToClose = null;
try
{
- AgentData cAgent = new AgentData();
- agent.CopyTo(cAgent);
- if (ctx.OutboundVersion < 0.5f)
- cAgent.Appearance.PackLegacyWearables = true;
+ AgentData cAgent = new AgentData();
+ agent.CopyTo(cAgent,true);
+
cAgent.Position = pos;
+ cAgent.ChildrenCapSeeds = agent.KnownRegions;
+
+ childRegionsToClose = agent.GetChildAgentsToClose(neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
+ if(cAgent.ChildrenCapSeeds != null)
+ {
+ foreach(ulong regh in childRegionsToClose)
+ cAgent.ChildrenCapSeeds.Remove(regh);
+ }
if (isFlying)
cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
@@ -1623,21 +1801,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Beyond this point, extra cleanup is needed beyond removing transit state
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
- if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
+ if (sucess && !agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx))
+ {
+ sucess = false;
+ reason = "agent update failed";
+ }
+
+ if(!sucess)
{
// region doesn't take it
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
m_log.WarnFormat(
- "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.",
- neighbourRegion.RegionName, agent.Name);
+ "[ENTITY TRANSFER MODULE]: agent {0} crossing to {1} failed: {2}",
+ agent.Name, neighbourRegion.RegionName, reason);
ReInstantiateScripts(agent);
- agent.AddToPhysicalScene(isFlying);
+ if(agent.ParentID == 0 && agent.ParentUUID == UUID.Zero)
+ {
+ agent.AddToPhysicalScene(isFlying);
+ }
return false;
}
+ m_log.DebugFormat("[CrossAgentIntoNewRegionMain] ok, time {0}ms",Util.EnvironmentTickCountSubtract(ts));
}
catch (Exception e)
{
@@ -1649,44 +1837,38 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return false;
}
- return true;
- }
-
- public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
- bool isFlying, EntityTransferContext ctx)
- {
- agent.ControllingClient.RequestClientInfo();
-
string agentcaps;
if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
{
m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
neighbourRegion.RegionHandle);
- return;
+ return false;
}
// No turning back
+
agent.IsChildAgent = true;
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
- Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
+ Vector3 vel2 = Vector3.Zero;
+ if((agent.crossingFlags & 2) != 0)
+ vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
if (m_eqModule != null)
{
m_eqModule.CrossRegion(
- neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */,
- neighbourRegion.ExternalEndPoint,
- capsPath, agent.UUID, agent.ControllingClient.SessionId,
+ neighbourRegion.RegionHandle, pos, vel2 /* agent.Velocity */,
+ endpoint, capsPath, agent.UUID, agent.ControllingClient.SessionId,
neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
}
else
{
m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader);
- agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
- capsPath);
+ agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos, agent.Velocity,
+ endpoint,capsPath);
}
// SUCCESS!
@@ -1695,51 +1877,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
- agent.MakeChildAgent();
-
- // FIXME: Possibly this should occur lower down after other commands to close other agents,
- // but not sure yet what the side effects would be.
- m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
-
- // now we have a child agent in this region. Request all interesting data about other (root) agents
- agent.SendOtherAgentsAvatarDataToClient();
- agent.SendOtherAgentsAppearanceToClient();
+ if(childRegionsToClose != null)
+ agent.CloseChildAgents(childRegionsToClose);
- // TODO: Check since what version this wasn't needed anymore. May be as old as 0.6
-/*
- // Backwards compatibility. Best effort
- if (version == 0f)
- {
- m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
- Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
- CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
- }
-*/
- // Next, let's close the child agent connections that are too far away.
- uint neighbourx;
- uint neighboury;
- Util.RegionHandleToRegionLoc(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
-
- agent.CloseChildAgents(neighbourx, neighboury);
+ if((agent.crossingFlags & 8) == 0)
+ agent.ClearControls(); // don't let attachments delete (called in HasMovedAway) disturb taken controls on viewers
- AgentHasMovedAway(agent, false);
+ agent.HasMovedAway((agent.crossingFlags & 8) == 0);
- // the user may change their profile information in other region,
- // so the userinfo in UserProfileCache is not reliable any more, delete it
- // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
-// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
-// {
-// m_log.DebugFormat(
-// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
-// }
+ agent.MakeChildAgent(neighbourRegion.RegionHandle);
- //m_log.Debug("AFTER CROSS");
- //Scene.DumpChildrenSeeds(UUID);
- //DumpKnownRegions();
+ // FIXME: Possibly this should occur lower down after other commands to close other agents,
+ // but not sure yet what the side effects would be.
+ m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
- return;
+ return true;
}
-
+
private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
{
CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
@@ -1754,7 +1908,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// In any case
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
@@ -1762,7 +1916,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Enable Child Agent
///
- /// This informs a single neighbouring region about agent "avatar".
+ /// This informs a single neighbouring region about agent "avatar", and avatar about it
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
///
///
@@ -1771,42 +1925,46 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
+ ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle;
+ ulong regionhandler = region.RegionHandle;
+
+ Dictionary seeds = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
+
+ if (seeds.ContainsKey(regionhandler))
+ seeds.Remove(regionhandler);
+/*
+ List oldregions = new List(seeds.Keys);
+
+ if (oldregions.Contains(currentRegionHandler))
+ oldregions.Remove(currentRegionHandler);
+*/
+ if (!seeds.ContainsKey(currentRegionHandler))
+ seeds.Add(currentRegionHandler, sp.ControllingClient.RequestClientInfo().CapsPath);
+
AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();
agent.BaseFolder = UUID.Zero;
agent.InventoryFolder = UUID.Zero;
- agent.startpos = new Vector3(128, 128, 70);
+ agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, region);
agent.child = true;
agent.Appearance = new AvatarAppearance();
- agent.Appearance.PackLegacyWearables = true;
- agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
-
- agent.ChildrenCapSeeds = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
- //m_log.DebugFormat("[XXX] Seeds 1 {0}", agent.ChildrenCapSeeds.Count);
+ agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
- if (!agent.ChildrenCapSeeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle))
- agent.ChildrenCapSeeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath);
- //m_log.DebugFormat("[XXX] Seeds 2 {0}", agent.ChildrenCapSeeds.Count);
+ agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
- sp.AddNeighbourRegion(region.RegionHandle, agent.CapsPath);
- //foreach (ulong h in agent.ChildrenCapSeeds.Keys)
- // m_log.DebugFormat("[XXX] --> {0}", h);
- //m_log.DebugFormat("[XXX] Adding {0}", region.RegionHandle);
- if (agent.ChildrenCapSeeds.ContainsKey(region.RegionHandle))
- {
- m_log.WarnFormat(
- "[ENTITY TRANSFER]: Overwriting caps seed {0} with {1} for region {2} (handle {3}) for {4} in {5}",
- agent.ChildrenCapSeeds[region.RegionHandle], agent.CapsPath,
- region.RegionName, region.RegionHandle, sp.Name, Scene.Name);
- }
+ seeds.Add(regionhandler, agent.CapsPath);
- agent.ChildrenCapSeeds[region.RegionHandle] = agent.CapsPath;
+// agent.ChildrenCapSeeds = new Dictionary(seeds);
+ agent.ChildrenCapSeeds = null;
if (sp.Scene.CapsModule != null)
{
- sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, agent.ChildrenCapSeeds);
+ sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
}
+ sp.KnownRegions = seeds;
+ sp.AddNeighbourRegionSizeInfo(region);
+
if (currentAgentCircuit != null)
{
agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
@@ -1816,7 +1974,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.Mac = currentAgentCircuit.Mac;
agent.Id0 = currentAgentCircuit.Id0;
}
-
+/*
+ AgentPosition agentpos = null;
+
+ if (oldregions.Count > 0)
+ {
+ agentpos = new AgentPosition();
+ agentpos.AgentID = new UUID(sp.UUID.Guid);
+ agentpos.SessionID = sp.ControllingClient.SessionId;
+ agentpos.Size = sp.Appearance.AvatarSize;
+ agentpos.Center = sp.CameraPosition;
+ agentpos.Far = sp.DrawDistance;
+ agentpos.Position = sp.AbsolutePosition;
+ agentpos.Velocity = sp.Velocity;
+ agentpos.RegionHandle = currentRegionHandler;
+ agentpos.Throttles = sp.ControllingClient.GetThrottlesPacked(1);
+ agentpos.ChildrenCapSeeds = seeds;
+ }
+*/
IPEndPoint external = region.ExternalEndPoint;
if (external != null)
{
@@ -1825,7 +2000,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
InformClientOfNeighbourCompleted,
d);
}
+/*
+ if(oldregions.Count >0)
+ {
+ uint neighbourx;
+ uint neighboury;
+ UUID scope = sp.Scene.RegionInfo.ScopeID;
+ foreach (ulong handler in oldregions)
+ {
+ Utils.LongToUInts(handler, out neighbourx, out neighboury);
+ GridRegion neighbour = sp.Scene.GridService.GetRegionByPosition(scope, (int)neighbourx, (int)neighboury);
+ sp.Scene.SimulationService.UpdateAgent(neighbour, agentpos);
+ }
+ }
+ */
}
+
#endregion
#region Enable Child Agents
@@ -1835,167 +2025,175 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
///
/// This informs all neighbouring regions about agent "avatar".
+ /// and as important informs the avatar about then
///
///
public void EnableChildAgents(ScenePresence sp)
{
+ // assumes that out of view range regions are disconnected by the previus region
+
List neighbours = new List();
- RegionInfo m_regionInfo = sp.Scene.RegionInfo;
+ Scene spScene = sp.Scene;
+ RegionInfo m_regionInfo = spScene.RegionInfo;
if (m_regionInfo != null)
{
- neighbours = GetNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY);
+ neighbours = GetNeighbors(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY);
}
else
{
m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?");
}
- /// We need to find the difference between the new regions where there are no child agents
- /// and the regions where there are already child agents. We only send notification to the former.
- List neighbourHandles = NeighbourHandles(neighbours); // on this region
- neighbourHandles.Add(sp.Scene.RegionInfo.RegionHandle); // add this region too
- List previousRegionNeighbourHandles;
+ ulong currentRegionHandler = m_regionInfo.RegionHandle;
- if (sp.Scene.CapsModule != null)
+ LinkedList previousRegionNeighbourHandles;
+ Dictionary seeds;
+ ICapabilitiesModule capsModule = spScene.CapsModule;
+
+ if (capsModule != null)
{
- previousRegionNeighbourHandles =
- new List(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID).Keys);
+ seeds = new Dictionary(capsModule.GetChildrenSeeds(sp.UUID));
+ previousRegionNeighbourHandles = new LinkedList(seeds.Keys);
}
else
{
- previousRegionNeighbourHandles = new List();
+ seeds = new Dictionary();
+ previousRegionNeighbourHandles = new LinkedList();
}
- List newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles);
- List oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
-
-// Dump("Current Neighbors", neighbourHandles);
-// Dump("Previous Neighbours", previousRegionNeighbourHandles);
-// Dump("New Neighbours", newRegions);
-// Dump("Old Neighbours", oldRegions);
-
- /// Update the scene presence's known regions here on this region
- sp.DropOldNeighbours(oldRegions);
+ IClientAPI spClient = sp.ControllingClient;
- /// Collect as many seeds as possible
- Dictionary seeds;
- if (sp.Scene.CapsModule != null)
- seeds = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
- else
- seeds = new Dictionary();
+ // This will fail if the user aborts login
+ try
+ {
+ if (!seeds.ContainsKey(currentRegionHandler))
+ seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath);
+ }
+ catch
+ {
+ return;
+ }
- //m_log.Debug(" !!! No. of seeds: " + seeds.Count);
- if (!seeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle))
- seeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath);
+ AgentCircuitData currentAgentCircuit =
+ spScene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
- /// Create the necessary child agents
List cagents = new List();
+ List newneighbours = new List();
+
foreach (GridRegion neighbour in neighbours)
{
- if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
+ ulong handler = neighbour.RegionHandle;
+
+ if (previousRegionNeighbourHandles.Contains(handler))
{
- AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
- AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();
- agent.BaseFolder = UUID.Zero;
- agent.InventoryFolder = UUID.Zero;
- agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour);
- agent.child = true;
- agent.Appearance = new AvatarAppearance();
- agent.Appearance.PackLegacyWearables = true;
- if (currentAgentCircuit != null)
- {
- agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
- agent.IPAddress = currentAgentCircuit.IPAddress;
- agent.Viewer = currentAgentCircuit.Viewer;
- agent.Channel = currentAgentCircuit.Channel;
- agent.Mac = currentAgentCircuit.Mac;
- agent.Id0 = currentAgentCircuit.Id0;
- }
+ // agent already knows this region
+ previousRegionNeighbourHandles.Remove(handler);
+ continue;
+ }
- if (newRegions.Contains(neighbour.RegionHandle))
- {
- agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
- sp.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath);
- seeds.Add(neighbour.RegionHandle, agent.CapsPath);
- }
- else
- {
- agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle);
- }
+ if (handler == currentRegionHandler)
+ continue;
- cagents.Add(agent);
+ // a new region to add
+ AgentCircuitData agent = spClient.RequestClientInfo();
+ agent.BaseFolder = UUID.Zero;
+ agent.InventoryFolder = UUID.Zero;
+ agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour);
+ agent.child = true;
+ agent.Appearance = new AvatarAppearance();
+ agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
+
+ if (currentAgentCircuit != null)
+ {
+ agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
+ agent.IPAddress = currentAgentCircuit.IPAddress;
+ agent.Viewer = currentAgentCircuit.Viewer;
+ agent.Channel = currentAgentCircuit.Channel;
+ agent.Mac = currentAgentCircuit.Mac;
+ agent.Id0 = currentAgentCircuit.Id0;
}
- }
- /// Update all child agent with everyone's seeds
- foreach (AgentCircuitData a in cagents)
- {
- a.ChildrenCapSeeds = new Dictionary(seeds);
- }
+ newneighbours.Add(handler);
+ agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
+ seeds.Add(handler, agent.CapsPath);
- if (sp.Scene.CapsModule != null)
- {
- sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
+ agent.ChildrenCapSeeds = null;
+ cagents.Add(agent);
}
- sp.KnownRegions = seeds;
- //avatar.Scene.DumpChildrenSeeds(avatar.UUID);
- //avatar.DumpKnownRegions();
- bool newAgent = false;
- int count = 0;
- foreach (GridRegion neighbour in neighbours)
- {
- //m_log.WarnFormat("--> Going to send child agent to {0}", neighbour.RegionName);
- // Don't do it if there's already an agent in that region
- if (newRegions.Contains(neighbour.RegionHandle))
- newAgent = true;
- else
- newAgent = false;
-// continue;
+ if (previousRegionNeighbourHandles.Contains(currentRegionHandler))
+ previousRegionNeighbourHandles.Remove(currentRegionHandler);
- if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
- {
- try
- {
- // Let's put this back at sync, so that it doesn't clog
- // the network, especially for regions in the same physical server.
- // We're really not in a hurry here.
- InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent);
- //InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
- //d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent,
- // InformClientOfNeighbourCompleted,
- // d);
- }
+ // previousRegionNeighbourHandles now contains regions to forget
+ foreach (ulong handler in previousRegionNeighbourHandles)
+ seeds.Remove(handler);
- catch (ArgumentOutOfRangeException)
- {
- m_log.ErrorFormat(
- "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).",
- neighbour.ExternalHostName,
- neighbour.RegionHandle,
- neighbour.RegionLocX,
- neighbour.RegionLocY);
- }
- catch (Exception e)
- {
- m_log.ErrorFormat(
- "[ENTITY TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}",
- neighbour.ExternalHostName,
- neighbour.RegionHandle,
- neighbour.RegionLocX,
- neighbour.RegionLocY,
- e);
+ /// Update all child agent with everyone's seeds
+ // foreach (AgentCircuitData a in cagents)
+ // a.ChildrenCapSeeds = new Dictionary(seeds);
- // FIXME: Okay, even though we've failed, we're still going to throw the exception on,
- // since I don't know what will happen if we just let the client continue
+ if (capsModule != null)
+ capsModule.SetChildrenSeed(sp.UUID, seeds);
- // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes.
- // throw e;
+ sp.KnownRegions = seeds;
+ sp.SetNeighbourRegionSizeInfo(neighbours);
+
+ if(newneighbours.Count > 0 || previousRegionNeighbourHandles.Count > 0)
+ {
+ AgentPosition agentpos = new AgentPosition();
+ agentpos.AgentID = new UUID(sp.UUID.Guid);
+ agentpos.SessionID = spClient.SessionId;
+ agentpos.Size = sp.Appearance.AvatarSize;
+ agentpos.Center = sp.CameraPosition;
+ agentpos.Far = sp.DrawDistance;
+ agentpos.Position = sp.AbsolutePosition;
+ agentpos.Velocity = sp.Velocity;
+ agentpos.RegionHandle = currentRegionHandler;
+ //agentpos.GodLevel = sp.GodLevel;
+ agentpos.GodData = sp.GodController.State();
+ agentpos.Throttles = spClient.GetThrottlesPacked(1);
+ // agentpos.ChildrenCapSeeds = seeds;
+
+ Util.FireAndForget(delegate
+ {
+ Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start
+ int count = 0;
+ IPEndPoint ipe;
+ foreach (GridRegion neighbour in neighbours)
+ {
+ ulong handler = neighbour.RegionHandle;
+ try
+ {
+ if (newneighbours.Contains(handler))
+ {
+ ipe = neighbour.ExternalEndPoint;
+ if (ipe != null)
+ InformClientOfNeighbourAsync(sp, cagents[count], neighbour, ipe, true);
+ else
+ {
+ m_log.DebugFormat("[ENTITY TRANSFER MODULE]: lost DNS resolution for neighbour {0}", neighbour.ExternalHostName);
+ }
+ count++;
+ }
+ else if (!previousRegionNeighbourHandles.Contains(handler))
+ {
+ spScene.SimulationService.UpdateAgent(neighbour, agentpos);
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat(
+ "[ENTITY TRANSFER MODULE]: Error creating child agent at {0} ({1} ({2}, {3}). {4}",
+ neighbour.ExternalHostName,
+ neighbour.RegionHandle,
+ neighbour.RegionLocX,
+ neighbour.RegionLocY,
+ e);
+ }
}
- }
- count++;
+ });
}
}
@@ -2004,26 +2202,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// The first region is the home region of the passed scene presence.
Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
{
- /*
- int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
- int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
- int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
- int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize;
- int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
- int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
- return new Vector3(shiftx, shifty, 0f);
- */
- return new Vector3( sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX,
+ return new Vector3(sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX,
sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY,
0f);
}
-
- public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
- {
- // Since we don't know how big the regions could be, we have to search a very large area
- // to find possible regions.
- return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize);
- }
+ #endregion
#region NotFoundLocationCache class
// A collection of not found locations to make future lookups 'not found' lookups quick.
@@ -2032,162 +2215,131 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// contains that point. A conservitive estimate.
private class NotFoundLocationCache
{
- private struct NotFoundLocation
- {
- public double minX, maxX, minY, maxY;
- public DateTime expireTime;
- }
- private List m_notFoundLocations = new List();
+ private Dictionary m_notFoundLocations = new Dictionary();
public NotFoundLocationCache()
{
}
- // Add an area to the list of 'not found' places. The area is the snapped region
- // area around the added point.
+ // just use normal regions handlers and sizes
public void Add(double pX, double pY)
{
+ ulong psh = (ulong)pX & 0xffffff00ul;
+ psh <<= 32;
+ psh |= (ulong)pY & 0xffffff00ul;
+
lock (m_notFoundLocations)
- {
- if (!LockedContains(pX, pY))
- {
- 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);
- }
- }
-
+ m_notFoundLocations[psh] = DateTime.UtcNow + TimeSpan.FromSeconds(30);
}
// 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.
public bool Contains(double pX, double pY)
{
- bool ret = false;
+ ulong psh = (ulong)pX & 0xffffff00ul;
+ psh <<= 32;
+ psh |= (ulong)pY & 0xffffff00ul;
+
lock (m_notFoundLocations)
- ret = LockedContains(pX, pY);
- return ret;
- }
- private bool LockedContains(double pX, double pY)
- {
- bool ret = false;
- this.DoExpiration();
- foreach (NotFoundLocation nfl in m_notFoundLocations)
{
- if (pX >= nfl.minX && pX < nfl.maxX && pY >= nfl.minY && pY < nfl.maxY)
+ if(m_notFoundLocations.ContainsKey(psh))
{
- ret = true;
- break;
+ if(m_notFoundLocations[psh] > DateTime.UtcNow)
+ return true;
+ m_notFoundLocations.Remove(psh);
}
+ return false;
}
- return ret;
}
+
private void DoExpiration()
{
- List m_toRemove = null;
- DateTime now = DateTime.Now;
- foreach (NotFoundLocation nfl in m_notFoundLocations)
+ List m_toRemove = new List();;
+ DateTime now = DateTime.UtcNow;
+ lock (m_notFoundLocations)
{
- if (nfl.expireTime < now)
+ foreach (KeyValuePair kvp in m_notFoundLocations)
{
- if (m_toRemove == null)
- m_toRemove = new List();
- m_toRemove.Add(nfl);
+ if (kvp.Value < now)
+ m_toRemove.Add(kvp.Key);
+ }
+
+ if (m_toRemove.Count > 0)
+ {
+ foreach (ulong u in m_toRemove)
+ m_notFoundLocations.Remove(u);
+ m_toRemove.Clear();
}
- }
- if (m_toRemove != null)
- {
- foreach (NotFoundLocation nfl in m_toRemove)
- m_notFoundLocations.Remove(nfl);
- m_toRemove.Clear();
}
}
}
+
#endregion // NotFoundLocationCache class
+ #region getregions
private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache();
- // Given a world position (fractional meter coordinate), get the GridRegion info for
+ protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
+ {
+ // Since we don't know how big the regions could be, we have to search a very large area
+ // to find possible regions.
+ return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize);
+ }
+
+ // Given a world position, get the GridRegion info for
// 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.
- public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID,
+ // for compatibility with old grids it does a scan to find large regions
+ // 0.9 grids to that
+
+ protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID,
double px, double py, uint pSizeHint)
{
- m_log.DebugFormat("{0} GetRegionContainingWorldLocation: query, loc=<{1},{2}>", LogHeader, px, py);
+// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py);
GridRegion ret = null;
- 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))
{
- 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);
return null;
}
// As an optimization, since most regions will be legacy sized regions (256x256), first try to get
// the region at the appropriate legacy region location.
- uint possibleX = (uint)Math.Floor(px);
- possibleX -= possibleX % Constants.RegionSize;
- uint possibleY = (uint)Math.Floor(py);
- possibleY -= possibleY % Constants.RegionSize;
+ // this is all that is needed on 0.9 grids
+ uint possibleX = (uint)px & 0xffffff00u;
+ uint possibleY = (uint)py & 0xffffff00u;
ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
if (ret != null)
{
- m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
- LogHeader, possibleX, possibleY, ret.RegionName);
+// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
+// 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
+ List possibleRegions = pGridService.GetRegionRange(pScopeID,
+ (int)(px - Constants.MaximumRegionSize), (int)(px + 1), // +1 bc left mb not part of range
+ (int)(py - Constants.MaximumRegionSize), (int)(py + 1));
+// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
+// LogHeader, possibleRegions.Count, range);
+ if (possibleRegions != null && possibleRegions.Count > 0)
{
- // 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))
+ // If we found some regions, check to see if the point is within
+ foreach (GridRegion gr in possibleRegions)
{
- // 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 possibleRegions = pGridService.GetRegionRange(pScopeID,
- (int)(px - range), (int)(px),
- (int)(py - range), (int)(py));
- m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
- LogHeader, possibleRegions.Count, range);
- if (possibleRegions != null && possibleRegions.Count > 0)
- {
- // If we found some regions, check to see if the point is within
- foreach (GridRegion gr in possibleRegions)
- {
- 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);
- if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
+// 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);
+ if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
&& py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
- {
- // Found a region that contains the point
- ret = gr;
- m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
- break;
- }
- }
+ {
+ // Found a region that contains the point
+ return gr;
+// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
}
- // 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
- m_notFoundLocationCache.Add(px, py);
- m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py);
- }
-
- return ret;
+ // remember this location was not found so we can quickly not find it next time
+ m_notFoundLocationCache.Add(px, py);
+// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py);
+ return null;
}
private void InformClientOfNeighbourCompleted(IAsyncResult iar)
@@ -2207,81 +2359,65 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
///
///
///
- private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg,
+ private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData agentCircData, GridRegion reg,
IPEndPoint endPoint, bool newAgent)
{
- // Let's wait just a little to give time to originating regions to catch up with closing child agents
- // after a cross here
- Thread.Sleep(500);
- Scene scene = sp.Scene;
-
- m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
- sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY);
+ if (newAgent)
+ {
+ // we may already had lost this sp
+ if(sp == null || sp.IsDeleted || sp.ClientView == null) // something bad already happened
+ return;
- string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath);
+ Scene scene = sp.Scene;
- string reason = String.Empty;
+ m_log.DebugFormat(
+ "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
+ sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY);
- bool regionAccepted = scene.SimulationService.CreateAgent(null, reg, a, (uint)TeleportFlags.Default, out reason);
+ string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(agentCircData.CapsPath);
- if (regionAccepted && newAgent)
- {
- if (m_eqModule != null)
+ string reason = String.Empty;
+
+ EntityTransferContext ctx = new EntityTransferContext();
+ bool regionAccepted = scene.SimulationService.CreateAgent(reg, reg, agentCircData, (uint)TeleportFlags.Default, ctx, out reason);
+
+ if (regionAccepted)
{
- #region IP Translation for NAT
- IClientIPEndpoint ipepClient;
- if (sp.ClientView.TryGet(out ipepClient))
+ // give time for createAgent to finish, since it is async and does grid services access
+ Thread.Sleep(500);
+
+ if (m_eqModule != null)
{
- endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
- }
- #endregion
+ if(sp == null || sp.IsDeleted || sp.ClientView == null) // something bad already happened
+ return;
+
+ m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
+ "and EstablishAgentCommunication with seed cap {8}", LogHeader,
+ scene.RegionInfo.RegionName, sp.Name,
+ reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY, capsPath);
- m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
- "and EstablishAgentCommunication with seed cap {8}", LogHeader,
- scene.RegionInfo.RegionName, sp.Name,
- reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY , capsPath);
+ m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY);
+ m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY);
+ }
+ else
+ {
+ sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint);
+ // TODO: make Event Queue disablable!
+ }
- m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY);
- m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY);
+ m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint);
}
+
else
{
- sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint);
- // TODO: make Event Queue disablable!
+ sp.RemoveNeighbourRegion(reg.RegionHandle);
+ m_log.WarnFormat(
+ "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}",
+ reg.RegionName, sp.Name, sp.UUID, reason);
}
-
- m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint);
}
- if (!regionAccepted)
- m_log.WarnFormat(
- "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}",
- reg.RegionName, sp.Name, sp.UUID, reason);
- }
-
- ///
- /// Gets the range considered in view of this megaregion (assuming this is a megaregion).
- ///
- /// Expressed in 256m units
- ///
- ///
- private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner)
- {
- Vector2 extent = Vector2.Zero;
-
- if (m_regionCombinerModule != null)
- {
- Vector2 megaRegionSize = m_regionCombinerModule.GetSizeOfMegaregion(Scene.RegionInfo.RegionID);
- extent.X = (float)Util.WorldToRegionLoc((uint)megaRegionSize.X);
- extent.Y = (float)Util.WorldToRegionLoc((uint)megaRegionSize.Y);
- }
-
- swCorner.X = Scene.RegionInfo.RegionLocX - 1;
- swCorner.Y = Scene.RegionInfo.RegionLocY - 1;
- neCorner.X = Scene.RegionInfo.RegionLocX + extent.X;
- neCorner.Y = Scene.RegionInfo.RegionLocY + extent.Y;
}
///
@@ -2290,98 +2426,42 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
///
///
///
- ///
- protected List GetNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY)
+ ///
+ protected List GetNeighbors(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY)
{
Scene pScene = avatar.Scene;
RegionInfo m_regionInfo = pScene.RegionInfo;
List neighbours;
- // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't
- // clear what should be done with a "far view" given that megaregions already extended the
- // view to include everything in the megaregion
- if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
- {
- // The area to check is as big as the current region.
- // We presume all adjacent regions are the same size as this region.
- uint dd = Math.Max((uint)avatar.Scene.DefaultDrawDistance,
- Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY));
+ uint dd = (uint)avatar.RegionViewDistance;
- uint startX = Util.RegionToWorldLoc(pRegionLocX) - dd + Constants.RegionSize/2;
- uint startY = Util.RegionToWorldLoc(pRegionLocY) - dd + Constants.RegionSize/2;
+ // until avatar movement updates client connections, we need to seend at least this current region imediate neighbors
+ uint ddX = Math.Max(dd, Constants.RegionSize);
+ uint ddY = Math.Max(dd, Constants.RegionSize);
- uint endX = Util.RegionToWorldLoc(pRegionLocX) + dd + Constants.RegionSize/2;
- uint endY = Util.RegionToWorldLoc(pRegionLocY) + dd + Constants.RegionSize/2;
+ ddX--;
+ ddY--;
- neighbours
- = avatar.Scene.GridService.GetRegionRange(
- m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY);
- }
- else
- {
- Vector2 swCorner, neCorner;
- GetMegaregionViewRange(out swCorner, out neCorner);
+ // reference to region edges. Should be avatar position
+ uint startX = Util.RegionToWorldLoc(pRegionLocX);
+ uint endX = startX + m_regionInfo.RegionSizeX;
+ uint startY = Util.RegionToWorldLoc(pRegionLocY);
+ uint endY = startY + m_regionInfo.RegionSizeY;
- neighbours
- = pScene.GridService.GetRegionRange(
- m_regionInfo.ScopeID,
- (int)Util.RegionToWorldLoc((uint)swCorner.X), (int)Util.RegionToWorldLoc((uint)neCorner.X),
- (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y));
- }
+ startX -= ddX;
+ startY -= ddY;
+ endX += ddX;
+ endY += ddY;
-// neighbours.ForEach(
-// n =>
-// m_log.DebugFormat(
-// "[ENTITY TRANSFER MODULE]: Region flags for {0} as seen by {1} are {2}",
-// n.RegionName, Scene.Name, n.RegionFlags != null ? n.RegionFlags.ToString() : "not present"));
+ neighbours
+ = avatar.Scene.GridService.GetRegionRange(
+ m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY);
// The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1).
- neighbours.RemoveAll(
- r =>
- r.RegionID == m_regionInfo.RegionID
- || (r.RegionFlags != null && (r.RegionFlags & OpenSim.Framework.RegionFlags.RegionOnline) == 0));
+ neighbours.RemoveAll( r => r.RegionID == m_regionInfo.RegionID );
return neighbours;
}
-
- private List NewNeighbours(List currentNeighbours, List previousNeighbours)
- {
- return currentNeighbours.FindAll(delegate(ulong handle) { return !previousNeighbours.Contains(handle); });
- }
-
- // private List CommonNeighbours(List currentNeighbours, List previousNeighbours)
- // {
- // return currentNeighbours.FindAll(delegate(ulong handle) { return previousNeighbours.Contains(handle); });
- // }
-
- private List OldNeighbours(List currentNeighbours, List previousNeighbours)
- {
- return previousNeighbours.FindAll(delegate(ulong handle) { return !currentNeighbours.Contains(handle); });
- }
-
- private List NeighbourHandles(List neighbours)
- {
- List handles = new List();
- foreach (GridRegion reg in neighbours)
- {
- handles.Add(reg.RegionHandle);
- }
- return handles;
- }
-
-// private void Dump(string msg, List handles)
-// {
-// m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg);
-// foreach (ulong handle in handles)
-// {
-// uint x, y;
-// Utils.LongToUInts(handle, out x, out y);
-// x = x / Constants.RegionSize;
-// y = y / Constants.RegionSize;
-// m_log.InfoFormat("({0}, {1})", x, y);
-// }
-// }
-
#endregion
#region Agent Arrived
@@ -2395,83 +2475,47 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Object Transfers
- ///
- /// Move the given scene object into a new region depending on which region its absolute position has moved
- /// into.
- ///
- /// Using the objects new world location, ask the grid service for a the new region and adjust the prim
- /// position to be relative to the new region.
- ///
- /// the scene object that we're crossing
- /// the attempted out of region position of the scene object. This position is
- /// relative to the region the object currently is in.
- /// if 'true', the deletion of the client from the region is not broadcast to the clients
- public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
+ public GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition,out Vector3 newpos)
{
- if (grp == null)
- return;
- if (grp.IsDeleted)
- return;
+ newpos = targetPosition;
Scene scene = grp.Scene;
if (scene == null)
- return;
-
- if (grp.RootPart.DIE_AT_EDGE)
- {
- // We remove the object here
- try
- {
- scene.DeleteSceneObject(grp, false);
- }
- catch (Exception)
- {
- m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
- }
- return;
- }
-
- // Remember the old group position in case the region lookup fails so position can be restored.
- Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
+ return null;
- // Compute the absolute position of the object.
- double objectWorldLocX = (double)scene.RegionInfo.WorldLocX + attemptedPosition.X;
- double objectWorldLocY = (double)scene.RegionInfo.WorldLocY + attemptedPosition.Y;
+ int x = (int)targetPosition.X + (int)scene.RegionInfo.WorldLocX;
+ if (targetPosition.X >= 0)
+ x++;
+ else
+ x--;
- // Ask the grid service for the region that contains the passed address
- GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID,
- objectWorldLocX, objectWorldLocY);
+ int y = (int)targetPosition.Y + (int)scene.RegionInfo.WorldLocY;
+ if (targetPosition.Y >= 0)
+ y++;
+ else
+ y--;
- Vector3 pos = Vector3.Zero;
- if (destination != null)
+ GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID,x,y);
+ if (neighbourRegion == null)
{
- // Adjust the object's relative position from the old region (attemptedPosition)
- // to be relative to the new region (pos).
- pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX),
- (float)(objectWorldLocY - (double)destination.RegionLocY),
- attemptedPosition.Z);
+ return null;
}
- if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
- {
- m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID);
-
- // We are going to move the object back to the old position so long as the old position
- // is in the region
- oldGroupPosition.X = Util.Clamp(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
- oldGroupPosition.Y = Util.Clamp(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
- oldGroupPosition.Z = Util.Clamp(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
+ float newRegionSizeX = neighbourRegion.RegionSizeX;
+ float newRegionSizeY = neighbourRegion.RegionSizeY;
+ if (newRegionSizeX == 0)
+ newRegionSizeX = Constants.RegionSize;
+ if (newRegionSizeY == 0)
+ newRegionSizeY = Constants.RegionSize;
- grp.AbsolutePosition = oldGroupPosition;
- grp.Velocity = Vector3.Zero;
- if (grp.RootPart.PhysActor != null)
- grp.RootPart.PhysActor.CrossingFailure();
+ newpos.X = targetPosition.X - (neighbourRegion.RegionLocX - (int)scene.RegionInfo.WorldLocX);
+ newpos.Y = targetPosition.Y - (neighbourRegion.RegionLocY - (int)scene.RegionInfo.WorldLocY);
- if (grp.RootPart.KeyframeMotion != null)
- grp.RootPart.KeyframeMotion.CrossingFailure();
+ const float enterDistance = 0.2f;
+ newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance);
+ newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance);
- grp.ScheduleGroupForFullUpdate();
- }
+ return neighbourRegion;
}
///
@@ -2483,10 +2527,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// true if the crossing itself was successful, false on failure
/// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
///
- protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent)
+ public bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent, bool removeScripts)
{
//m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
+ Culture.SetCurrentCulture();
+
bool successYN = false;
grp.RootPart.ClearUpdateSchedule();
//int primcrossingXMLmethod = 0;
@@ -2515,7 +2561,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// We remove the object here
try
{
- grp.Scene.DeleteSceneObject(grp, silent);
+ grp.Scene.DeleteSceneObject(grp, silent, removeScripts);
}
catch (Exception e)
{
@@ -2524,30 +2570,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
grp, e);
}
}
-/*
- * done on caller ( not in attachments crossing for now)
- else
- {
-
- if (!grp.IsDeleted)
- {
- PhysicsActor pa = grp.RootPart.PhysActor;
- if (pa != null)
- {
- pa.CrossingFailure();
- if (grp.RootPart.KeyframeMotion != null)
- {
- // moved to KeyframeMotion.CrossingFailure
-// grp.RootPart.Velocity = Vector3.Zero;
- grp.RootPart.KeyframeMotion.CrossingFailure();
-// grp.SendGroupRootTerseUpdate();
- }
- }
- }
-
- m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
- }
- */
}
else
{
@@ -2589,7 +2611,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}",
clone.UUID, destination.RegionName);
- CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent);
+ CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent,true);
}
}
@@ -2639,7 +2661,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (Scene.RegionInfo.EstateSettings.IsBanned(so.OwnerID))
{
m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Denied prim crossing of {0} {1} into {2} for banned avatar {3}",
+ "[ENTITY TRANSFER MODULE]: Denied prim crossing of {0} {1} into {2} for banned avatar {3}",
so.Name, so.UUID, Scene.Name, so.OwnerID);
return false;
@@ -2651,7 +2673,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (!Scene.AddSceneObject(so))
{
m_log.DebugFormat(
- "[ENTITY TRANSFER MODULE]: Problem adding scene object {0} {1} into {2} ",
+ "[ENTITY TRANSFER MODULE]: Problem adding scene object {0} {1} into {2} ",
so.Name, so.UUID, Scene.Name);
return false;
@@ -2661,7 +2683,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
// FIXME: It would be better to never add the scene object at all rather than add it and then delete
// it
- if (!Scene.Permissions.CanObjectEntry(so.UUID, true, so.AbsolutePosition))
+ if (!Scene.Permissions.CanObjectEntry(so, true, so.AbsolutePosition))
{
// Deny non attachments based on parcel settings
//
@@ -2679,8 +2701,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
so.ResumeScripts();
- if (so.RootPart.KeyframeMotion != null)
- so.RootPart.KeyframeMotion.UpdateSceneObject(so);
+ // AddSceneObject already does this and doing it again messes
+ //if (so.RootPart.KeyframeMotion != null)
+ // so.RootPart.KeyframeMotion.UpdateSceneObject(so);
}
return true;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index a3109e0..0a24555 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// true if the agent was not already in transit, false if it was
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)
{
if (!m_agentsInTransit.ContainsKey(id))
@@ -123,7 +123,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// Illegal transitions will throw an Exception
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;
@@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
else
{
- if (newState == AgentTransferState.Cancelling
+ if (newState == AgentTransferState.Cancelling
&& (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring))
{
transitionOkay = true;
@@ -181,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
if (!transitionOkay)
- failureMessage
+ failureMessage
= string.Format(
"Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
id, oldState, newState, m_mod.Scene.RegionInfo.RegionName);
@@ -192,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_agentsInTransit[id] = newState;
// m_log.DebugFormat(
-// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}",
+// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}",
// id, oldState, newState, m_mod.Scene.Name);
}
else if (failIfNotOkay)
@@ -204,11 +204,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// {
// if (oldState != null)
// m_log.DebugFormat(
-// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}",
+// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}",
// id, oldState, newState, m_mod.Scene.Name);
// else
// m_log.DebugFormat(
-// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit",
+// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit",
// id, newState, m_mod.Scene.Name);
// }
}
@@ -247,32 +247,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
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
// to be handled properly - ResetFromTransit() could be invoked at any step along the process
- 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}",
- id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName);
+// 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}",
+// id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName);
// throw new Exception(
// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first",
// state, AgentTransferState.CleaningUp);
- }
+// }
m_agentsInTransit.Remove(id);
- m_log.DebugFormat(
- "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}",
- id, m_mod.Scene.RegionInfo.RegionName);
+// m_log.DebugFormat(
+// "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}",
+// id, m_mod.Scene.RegionInfo.RegionName);
return true;
}
}
- m_log.WarnFormat(
- "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared",
- id, m_mod.Scene.RegionInfo.RegionName);
+// m_log.WarnFormat(
+// "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared",
+// id, m_mod.Scene.RegionInfo.RegionName);
return false;
}
@@ -281,7 +281,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
if (!m_mod.WaitForAgentArrivedAtDestination)
return true;
-
+
lock (m_agentsInTransit)
{
AgentTransferState? currentState = GetAgentTransferState(id);
@@ -299,7 +299,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
id, m_mod.Scene.RegionInfo.RegionName, currentState));
}
- int count = 200;
+ int count = 400;
// There should be no race condition here since no other code should be removing the agent transfer or
// changing the state to another other than Transferring => ReceivedAtDestination.
@@ -354,4 +354,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index fa23590..56c654f 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -95,8 +95,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
foreach (AvatarAttachment att in a.GetAttachments())
{
- InventoryItemBase item = new InventoryItemBase(att.ItemID, account.PrincipalID);
- item = Scene.InventoryService.GetItem(item);
+ InventoryItemBase item = Scene.InventoryService.GetItem(account.PrincipalID, att.ItemID);
if (item != null)
a.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID);
else
@@ -161,10 +160,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
scene.RegisterModuleInterface(this);
//scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject;
- m_incomingSceneObjectEngine
+ m_incomingSceneObjectEngine
= new JobEngine(
- string.Format("HG Incoming Scene Object Engine ({0})", scene.Name),
- "HG INCOMING SCENE OBJECT ENGINE");
+ string.Format("HG Incoming Scene Object Engine ({0})", scene.Name),
+ "HG INCOMING SCENE OBJECT ENGINE", 30000);
StatsManager.RegisterStat(
new Stat(
@@ -239,13 +238,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return region;
}
- protected override bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg)
+ protected override bool NeedsClosing(GridRegion reg, bool OutViewRange)
{
- if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
+ if (OutViewRange)
return true;
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
- if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
+ if (flags == -1 || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
return true;
return false;
@@ -263,7 +262,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
- protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
+ protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout)
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI);
reason = string.Empty;
@@ -273,7 +272,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
// this user is going to another grid
// for local users, check if HyperGrid teleport is allowed, based on user level
- if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.UserLevel < m_levelHGTeleport)
+ if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.GodController.UserLevel < m_levelHGTeleport)
{
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
reason = "Hypergrid teleport not allowed";
@@ -292,7 +291,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
GridRegion source = new GridRegion(Scene.RegionInfo);
source.RawServerURI = m_GatekeeperURI;
-
+
bool success = connector.LoginAgentToGrid(source, agentCircuit, reg, finalDestination, false, out reason);
logout = success; // flag for later logout from this grid; this is an HG TP
@@ -308,7 +307,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
- return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
+ return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout);
+ }
+
+ public override void TriggerTeleportHome(UUID id, IClientAPI client)
+ {
+ TeleportHome(id, client);
}
protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
@@ -328,7 +332,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
// Check wearables
- for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
+ for (int i = 0; i < sp.Appearance.Wearables.Length ; i++)
{
for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++)
{
@@ -337,13 +341,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
bool found = false;
foreach (AvatarAppearance a in ExportedAppearance)
- if (a.Wearables[i] != null)
+ if (i < a.Wearables.Length && a.Wearables[i] != null)
{
found = true;
break;
}
- if (!found)
+ if (!found)
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
return false;
@@ -351,7 +355,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
found = false;
foreach (AvatarAppearance a in ExportedAppearance)
- if (sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID)
+ if (i < a.Wearables.Length && sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID)
{
found = true;
break;
@@ -412,7 +416,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// // Rez needed npc attachments
// Scene.AttachmentsModule.RezAttachments(sp);
-
+
// IAvatarFactoryModule module = Scene.RequestModuleInterface();
// //module.SendAppearance(sp.UUID);
// module.RequestRebake(sp, false);
@@ -429,11 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// return base.UpdateAgent(reg, finalDestination, agentData, sp);
//}
- public override void TriggerTeleportHome(UUID id, IClientAPI client)
- {
- TeleportHome(id, client);
- }
-
+
public override bool TeleportHome(UUID id, IClientAPI client)
{
m_log.DebugFormat(
@@ -449,7 +449,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
// Foreign user wants to go home
- //
+ //
AgentCircuitData aCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("HomeURI")))
{
@@ -470,7 +470,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
m_log.Debug("[HG ENTITY TRANSFER MODULE]: GetHomeRegion call failed ", e);
}
-
+
if (finalDestination == null)
{
client.SendTeleportFailed("Your home region could not be found");
@@ -487,13 +487,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
GridRegion homeGatekeeper = MakeRegion(aCircuit);
-
+
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
- DoTeleport(
- sp, homeGatekeeper, finalDestination,
- position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
+ DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
return true;
}
@@ -505,7 +503,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
///
public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
{
- m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
+ m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
(lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
if (lm.Gatekeeper == string.Empty)
@@ -523,7 +521,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
remoteClient, info.RegionHandle, lm.Position,
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
}
- else
+ else
{
// Foreign region
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
@@ -583,7 +581,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
jobsRemoved, commonIdToRemove, jobsToReinsert.Count);
if (jobsToReinsert.Count > 0)
- {
+ {
foreach (JobEngine.Job jobToReinsert in jobsToReinsert)
m_incomingSceneObjectEngine.QueueJob(jobToReinsert);
}
@@ -613,16 +611,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
{
m_incomingSceneObjectEngine.QueueJob(
- string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name),
- () =>
+ string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name),
+ () =>
{
string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
// m_log.DebugFormat(
- // "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}",
+ // "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}",
// so.Name, so.AttachedAvatar, url);
IDictionary ids = new Dictionary();
- HGUuidGatherer uuidGatherer
+ HGUuidGatherer uuidGatherer
= new HGUuidGatherer(Scene.AssetService, url, ids);
uuidGatherer.AddForInspection(so);
@@ -648,7 +646,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());
return;
- }
+ }
}
// m_log.DebugFormat(
@@ -659,7 +657,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
int tickStart = Util.EnvironmentTickCount();
- uuidGatherer.FetchAsset(kvp.Key);
+ uuidGatherer.FetchAsset(kvp.Key);
int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
@@ -672,15 +670,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());
return;
- }
+ }
}
base.HandleIncomingSceneObject(so, newPosition);
// m_log.DebugFormat(
- // "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}",
+ // "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}",
// so.Name, so.OwnerID, url);
- },
+ },
so.OwnerID.ToString());
}
}
@@ -700,7 +698,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
string url = aCircuit.ServiceURLs["HomeURI"].ToString();
IUserAgentService security = new UserAgentServiceConnector(url);
return security.VerifyClient(aCircuit.SessionID, token);
- }
+ }
else
{
m_log.DebugFormat(
@@ -748,7 +746,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
GridRegion region = new GridRegion();
Uri uri = null;
- if (!aCircuit.ServiceURLs.ContainsKey("HomeURI") ||
+ if (!aCircuit.ServiceURLs.ContainsKey("HomeURI") ||
(aCircuit.ServiceURLs.ContainsKey("HomeURI") && !Uri.TryCreate(aCircuit.ServiceURLs["HomeURI"].ToString(), UriKind.Absolute, out uri)))
return null;
@@ -760,4 +758,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return region;
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs
index b5a4005..63dbb19 100644
--- a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs
+++ b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs
@@ -41,34 +41,34 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
public class Commander : ICommander
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
+
///
/// Used in runtime class generation
///
private string m_generatedApiClassName;
-
+
public string Name
{
get { return m_name; }
}
private string m_name;
-
+
public string Help
{
get
{
StringBuilder sb = new StringBuilder();
-
+
sb.AppendLine("=== " + m_name + " ===");
-
+
foreach (ICommand com in m_commands.Values)
{
sb.AppendLine("* " + Name + " " + com.Name + " - " + com.Help);
}
-
+
return sb.ToString();
}
- }
+ }
///
/// Constructor
@@ -78,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
{
m_name = name;
m_generatedApiClassName = m_name[0].ToString().ToUpper();
-
+
if (m_name.Length > 1)
m_generatedApiClassName += m_name.Substring(1);
}
@@ -87,7 +87,7 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
{
get { return m_commands; }
}
- private Dictionary m_commands = new Dictionary();
+ private Dictionary m_commands = new Dictionary();
#region ICommander Members
@@ -162,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
{
if (function != "help")
Console.WriteLine("ERROR: Invalid command - No such command exists");
-
+
Console.Write(Help);
}
}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index f54298c..51ae217 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
UUID uuid = UUID.Zero;
UUID.TryParse(meta.CreatorID, out uuid);
- UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
+ UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
if (creator != null)
meta.CreatorID = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
}
@@ -300,8 +300,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
m_log.Error(
string.Format(
- "[HG ASSET MAPPER]: Failed to post asset {0} (type {1}, length {2}) referenced from {3} to {4} with exception ",
- asset.ID, asset.Type, asset.Data.Length, assetID, userAssetURL),
+ "[HG ASSET MAPPER]: Failed to post asset {0} (type {1}, length {2}) referenced from {3} to {4} with exception ",
+ asset.ID, asset.Type, asset.Data.Length, assetID, userAssetURL),
e);
// For debugging purposes for now we will continue to throw the exception up the stack as was already happening. However, after
@@ -315,7 +315,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
else
{
m_log.DebugFormat(
- "[HG ASSET MAPPER]: Didn't post asset {0} referenced from {1} because it already exists in asset server {2}",
+ "[HG ASSET MAPPER]: Didn't post asset {0} referenced from {1} because it already exists in asset server {2}",
uuid, assetID, userAssetURL);
}
}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 582b267..ba3a7c9 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -91,9 +91,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (name == Name)
{
m_Enabled = true;
-
+
InitialiseCommon(source);
-
+
m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name);
IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
@@ -117,7 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
m_bypassPermissions = !Util.GetConfigVarFromSections(source, "serverside_object_permissions",
- new string[] { "Startup", "Permissions" }, true);
+ new string[] { "Startup", "Permissions" }, true);
}
}
@@ -209,7 +209,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
}
- public void PostInventoryAsset(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel)
+ private void PostInventoryAsset(InventoryItemBase item, int userlevel)
+ {
+ InventoryFolderBase f = m_Scene.InventoryService.GetFolderForType(item.Owner, FolderType.Trash);
+ if (f == null || (f != null && item.Folder != f.ID))
+ PostInventoryAsset(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
+ }
+
+ private void PostInventoryAsset(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel)
{
if (type == AssetType.Link)
return;
@@ -241,26 +248,34 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
- ///
+ ///
/// CapsUpdateInventoryItemAsset
///
public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
{
UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
- PostInventoryAsset(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0);
+ // We need to construct this here to satisfy the calling convention.
+ // Better this in two places than five formal params in all others.
+ InventoryItemBase item = new InventoryItemBase();
+ item.Owner = remoteClient.AgentId;
+ item.AssetType = (int)AssetType.Unknown;
+ item.AssetID = newAssetID;
+ item.Name = String.Empty;
+
+ PostInventoryAsset(item, 0);
return newAssetID;
}
- ///
+ ///
/// UpdateInventoryItemAsset
///
public override bool UpdateInventoryItemAsset(UUID ownerID, InventoryItemBase item, AssetBase asset)
{
if (base.UpdateInventoryItemAsset(ownerID, item, asset))
{
- PostInventoryAsset(ownerID, (AssetType)asset.Type, asset.FullID, asset.Name, 0);
+ PostInventoryAsset(item, 0);
return true;
}
@@ -273,25 +288,45 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
protected override void ExportAsset(UUID agentID, UUID assetID)
{
if (!assetID.Equals(UUID.Zero))
- PostInventoryAsset(agentID, AssetType.Unknown, assetID, "", 0);
+ {
+ InventoryItemBase item = new InventoryItemBase();
+ item.Owner = agentID;
+ item.AssetType = (int)AssetType.Unknown;
+ item.AssetID = assetID;
+ item.Name = String.Empty;
+
+ PostInventoryAsset(item, 0);
+ }
else
+ {
m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
+ }
}
///
/// RezObject
///
- public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
- UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
- bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
+ // compatibility do not use
+ public override SceneObjectGroup RezObject(
+ IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
+ UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
+ bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
+ {
+ return RezObject(remoteClient, itemID, UUID.Zero, RayEnd, RayStart,
+ RayTargetID, BypassRayCast, RayEndIsIntersection,
+ RezSelected, RemoveItem, fromTaskID, attachment);
+ }
+
+ public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID,
+ UUID groupID, Vector3 RayEnd, Vector3 RayStart,
+ UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
+ bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
{
- m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
+ //m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
//if (fromTaskID.Equals(UUID.Zero))
//{
- InventoryItemBase item = new InventoryItemBase(itemID);
- item.Owner = remoteClient.AgentId;
- item = m_Scene.InventoryService.GetItem(item);
+ InventoryItemBase item = m_Scene.InventoryService.GetItem(remoteClient.AgentId, itemID);
//if (item == null)
//{ // Fetch the item
// item = new InventoryItemBase();
@@ -308,7 +343,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
//}
// OK, we're done fetching. Pass it up to the default RezObject
- SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
+ SceneObjectGroup sog = base.RezObject(remoteClient, itemID, groupID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
RezSelected, RemoveItem, fromTaskID, attachment);
return sog;
@@ -351,7 +386,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (!m_CheckSeparateAssets)
{
if (!UserManagementModule.IsLocalGridUser(userID))
- { // foreign
+ { // foreign
ScenePresence sp = null;
if (m_Scene.TryGetScenePresence(userID, out sp))
{
@@ -489,7 +524,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
foreach (InventoryItemBase it in content.Items)
it.Name = it.Name + " (Unavailable)"; ;
- // Send the new names
+ // Send the new names
inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
}
@@ -506,16 +541,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
#region Permissions
- private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene)
+ private bool CanTakeObject(SceneObjectGroup sog, ScenePresence sp)
{
if (m_bypassPermissions) return true;
- if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer))
+ if(sp == null || sog == null)
+ return false;
+
+ if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(sp.UUID))
{
- SceneObjectGroup sog = null;
- if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer)
+ if (sog.OwnerID == sp.UUID)
return true;
-
return false;
}
@@ -535,4 +571,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 5a9efb8..788ed1c 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
return m_UserManagement;
}
}
-
+
public bool CoalesceMultipleObjectsToInventory { get; set; }
#region INonSharedRegionModule
@@ -92,14 +92,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (name == Name)
{
m_Enabled = true;
-
+
InitialiseCommon(source);
-
- m_log.InfoFormat("[INVENTORY ACCESS MODULE]: {0} enabled.", Name);
+
+ m_log.InfoFormat("[INVENTORY ACCESS MODULE]: {0} enabled.", Name);
}
}
}
-
+
///
/// Common module config for both this and descendant classes.
///
@@ -107,9 +107,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
protected virtual void InitialiseCommon(IConfigSource source)
{
IConfig inventoryConfig = source.Configs["Inventory"];
-
+
if (inventoryConfig != null)
- CoalesceMultipleObjectsToInventory
+ CoalesceMultipleObjectsToInventory
= inventoryConfig.GetBoolean("CoalesceMultipleObjectsToInventory", true);
else
CoalesceMultipleObjectsToInventory = true;
@@ -175,53 +175,73 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
///
public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
uint callbackID, string description, string name, sbyte invType,
- sbyte assetType,
- byte wearableType, uint nextOwnerMask, int creationDate)
+ sbyte assetType, byte wearableType,
+ uint nextOwnerMask, int creationDate)
{
- m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}", name, folderID);
+ m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}, transactionID {2}", name,
+ folderID, transactionID);
if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
return;
- if (transactionID == UUID.Zero)
+ InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(remoteClient.AgentId, folderID);
+
+ if (folder == null && Enum.IsDefined(typeof(FolderType), (sbyte)invType))
{
- ScenePresence presence;
- if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
- {
- byte[] data = null;
+ folder = m_Scene.InventoryService.GetFolderForType(remoteClient.AgentId, (FolderType)invType);
+ if (folder != null)
+ m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Requested folder not found but found folder for type {0}", invType);
+ }
- if (invType == (sbyte)InventoryType.Landmark && presence != null)
- {
- string suffix = string.Empty, prefix = string.Empty;
- string strdata = GenerateLandmark(presence, out prefix, out suffix);
- data = Encoding.ASCII.GetBytes(strdata);
- name = prefix + name;
- description += suffix;
- }
+ if (folder == null || folder.Owner != remoteClient.AgentId)
+ return;
- AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
- m_Scene.AssetService.Store(asset);
- m_Scene.CreateNewInventoryItem(
- remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
- name, description, 0, callbackID, asset.FullID, asset.Type, invType, nextOwnerMask, creationDate);
- }
- else
- {
- m_log.ErrorFormat(
- "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
- remoteClient.AgentId);
- }
- }
- else
+ if (transactionID != UUID.Zero)
{
IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule;
if (agentTransactions != null)
{
- agentTransactions.HandleItemCreationFromTransaction(
+ if (agentTransactions.HandleItemCreationFromTransaction(
remoteClient, transactionID, folderID, callbackID, description,
- name, invType, assetType, wearableType, nextOwnerMask);
+ name, invType, assetType, wearableType, nextOwnerMask))
+ return;
}
}
+
+ ScenePresence presence;
+ if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
+ {
+ byte[] data = null;
+ uint everyonemask = 0;
+ uint groupmask = 0;
+
+ if (invType == (sbyte)InventoryType.Landmark && presence != null)
+ {
+ string suffix = string.Empty, prefix = string.Empty;
+ string strdata = GenerateLandmark(presence, out prefix, out suffix);
+ data = Encoding.ASCII.GetBytes(strdata);
+ name = prefix + name;
+ description += suffix;
+ groupmask = (uint)PermissionMask.AllAndExport;
+ everyonemask = (uint)(PermissionMask.AllAndExport & ~PermissionMask.Modify);
+ }
+
+ AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
+ m_Scene.AssetService.Store(asset);
+ m_Scene.CreateNewInventoryItem(
+ remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
+ name, description, 0, callbackID, asset.FullID, asset.Type, invType,
+ (uint)PermissionMask.AllAndExport, // Base
+ (uint)PermissionMask.AllAndExport, // Current
+ everyonemask,
+ nextOwnerMask, groupmask, creationDate, false); // Data from viewer
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
+ remoteClient.AgentId);
+ }
}
protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
@@ -244,53 +264,65 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
///
public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
{
- InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
- item = m_Scene.InventoryService.GetItem(item);
+ InventoryItemBase item = m_Scene.InventoryService.GetItem(remoteClient.AgentId, itemID);
+
+ if (item == null)
+ {
+ m_log.ErrorFormat(
+ "[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update", itemID);
+ return UUID.Zero;
+ }
if (item.Owner != remoteClient.AgentId)
return UUID.Zero;
- if (item != null)
+ if ((InventoryType)item.InvType == InventoryType.Notecard)
{
- if ((InventoryType)item.InvType == InventoryType.Notecard)
+ if (!m_Scene.Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId))
{
- if (!m_Scene.Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId))
- {
- remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
- return UUID.Zero;
- }
-
- remoteClient.SendAlertMessage("Notecard saved");
+ remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
+ return UUID.Zero;
}
- else if ((InventoryType)item.InvType == InventoryType.LSL)
- {
- if (!m_Scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
- {
- remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
- return UUID.Zero;
- }
- remoteClient.SendAlertMessage("Script saved");
+ remoteClient.SendAlertMessage("Notecard saved");
+ }
+ else if ((InventoryType)item.InvType == InventoryType.LSL)
+ {
+ if (!m_Scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
+ {
+ remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
+ return UUID.Zero;
}
- AssetBase asset =
- CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId.ToString());
- item.AssetID = asset.FullID;
- m_Scene.AssetService.Store(asset);
-
- m_Scene.InventoryService.UpdateItem(item);
-
- // remoteClient.SendInventoryItemCreateUpdate(item);
- return (asset.FullID);
+ remoteClient.SendAlertMessage("Script saved");
}
- else
+ else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet)
{
- m_log.ErrorFormat(
- "[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update",
- itemID);
+ AnimationSet animSet = new AnimationSet(data);
+ uint res = animSet.Validate(x => {
+ const int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
+ int perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x);
+ // enforce previus perm rule
+ if ((perms & required) != required)
+ return 0;
+ return (uint) perms;
+ });
+ if(res == 0)
+ {
+ remoteClient.SendAgentAlertMessage("Not enought permissions on asset(s) referenced by animation set '{0}', update failed", false);
+ return UUID.Zero;
+ }
}
- return UUID.Zero;
+ AssetBase asset =
+ CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId.ToString());
+ item.AssetID = asset.FullID;
+ m_Scene.AssetService.Store(asset);
+
+ m_Scene.InventoryService.UpdateItem(item);
+
+ // remoteClient.SendInventoryItemCreateUpdate(item);
+ return (asset.FullID);
}
public virtual bool UpdateInventoryItemAsset(UUID ownerID, InventoryItemBase item, AssetBase asset)
@@ -298,7 +330,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (item != null && item.Owner == ownerID && asset != null)
{
// m_log.DebugFormat(
-// "[INVENTORY ACCESS MODULE]: Updating item {0} {1} with new asset {2}",
+// "[INVENTORY ACCESS MODULE]: Updating item {0} {1} with new asset {2}",
// item.Name, item.ID, asset.ID);
item.AssetID = asset.FullID;
@@ -327,7 +359,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
List copiedItems = new List();
Dictionary> bundlesToCopy = new Dictionary>();
-
+
if (CoalesceMultipleObjectsToInventory)
{
// The following code groups the SOG's by owner. No objects
@@ -337,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
if (!bundlesToCopy.ContainsKey(g.OwnerID))
bundlesToCopy[g.OwnerID] = new List();
-
+
bundlesToCopy[g.OwnerID].Add(g);
}
}
@@ -348,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
List bundle = new List();
bundle.Add(g);
- bundlesToCopy[g.UUID] = bundle;
+ bundlesToCopy[g.UUID] = bundle;
}
}
@@ -360,10 +392,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// with distinct destinations as well.
foreach (List bundle in bundlesToCopy.Values)
copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment));
-
+
return copiedItems;
}
-
+
///
/// Copy a bundle of objects to inventory. If there is only one object, then this will create an object
/// item. If there are multiple objects then these will be saved as a single coalesced item.
@@ -379,33 +411,42 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
DeRezAction action, UUID folderID, List objlist, IClientAPI remoteClient,
bool asAttachment)
{
- CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
-// Dictionary originalPositions = new Dictionary();
-
- Dictionary group2Keyframe = new Dictionary();
+ CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
+ Dictionary originalPositions = new Dictionary();
+ Dictionary originalRotations = new Dictionary();
+ // this possible is not needed if keyframes are saved
+// Dictionary originalKeyframes = new Dictionary();
foreach (SceneObjectGroup objectGroup in objlist)
{
if (objectGroup.RootPart.KeyframeMotion != null)
{
- objectGroup.RootPart.KeyframeMotion.Pause();
- group2Keyframe.Add(objectGroup, objectGroup.RootPart.KeyframeMotion);
- objectGroup.RootPart.KeyframeMotion = null;
+ objectGroup.RootPart.KeyframeMotion.Suspend();
}
+ objectGroup.RootPart.SetForce(Vector3.Zero);
+ objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false);
-// Vector3 inventoryStoredPosition = new Vector3
-// (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
-// ? 250
-// : objectGroup.AbsolutePosition.X)
-// ,
-// (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
-// ? 250
-// : objectGroup.AbsolutePosition.Y,
-// objectGroup.AbsolutePosition.Z);
-//
-// originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
-//
-// objectGroup.AbsolutePosition = inventoryStoredPosition;
+// originalKeyframes[objectGroup.UUID] = objectGroup.RootPart.KeyframeMotion;
+// objectGroup.RootPart.KeyframeMotion = null;
+
+ Vector3 inventoryStoredPosition = objectGroup.AbsolutePosition;
+ originalPositions[objectGroup.UUID] = inventoryStoredPosition;
+ Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
+ originalRotations[objectGroup.UUID] = inventoryStoredRotation;
+
+ // Restore attachment data after trip through the sim
+ if (objectGroup.AttachmentPoint > 0)
+ {
+ inventoryStoredPosition = objectGroup.RootPart.AttachedPos;
+ inventoryStoredRotation = objectGroup.RootPart.AttachRotation;
+ if (objectGroup.RootPart.Shape.PCode != (byte) PCode.Tree &&
+ objectGroup.RootPart.Shape.PCode != (byte) PCode.NewTree)
+ objectGroup.RootPart.Shape.LastAttachPoint = (byte)objectGroup.AttachmentPoint;
+
+ }
+
+ objectGroup.AbsolutePosition = inventoryStoredPosition;
+ objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
// Make sure all bits but the ones we want are clear
// on take.
@@ -418,7 +459,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
(uint)PermissionMask.Export);
objectGroup.RootPart.NextOwnerMask |=
(uint)PermissionMask.Move;
-
+
coa.Add(objectGroup);
}
@@ -432,10 +473,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment);
else
itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
-
-// // Restore the position of each group now that it has been stored to inventory.
-// foreach (SceneObjectGroup objectGroup in objlist)
-// objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
+
+ // Restore the position of each group now that it has been stored to inventory.
+ foreach (SceneObjectGroup objectGroup in objlist)
+ {
+ objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
+ objectGroup.RootPart.RotationOffset = originalRotations[objectGroup.UUID];
+// objectGroup.RootPart.KeyframeMotion = originalKeyframes[objectGroup.UUID];
+ if (objectGroup.RootPart.KeyframeMotion != null)
+ objectGroup.RootPart.KeyframeMotion.Resume();
+ }
InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
@@ -448,11 +495,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
item.CreatorData = objlist[0].RootPart.CreatorData;
-
+
if (objlist.Count > 1)
{
item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
-
+
// If the objects have different creators then don't specify a creator at all
foreach (SceneObjectGroup objectGroup in objlist)
{
@@ -468,8 +515,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
else
{
item.SaleType = objlist[0].RootPart.ObjectSaleType;
- item.SalePrice = objlist[0].RootPart.SalePrice;
- }
+ item.SalePrice = objlist[0].RootPart.SalePrice;
+ }
AssetBase asset = CreateAsset(
objlist[0].GetPartName(objlist[0].RootPart.LocalId),
@@ -478,7 +525,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
Utils.StringToBytes(itemXml),
objlist[0].OwnerID.ToString());
m_Scene.AssetService.Store(asset);
-
+
item.AssetID = asset.FullID;
if (DeRezAction.SaveToExistingUserInventoryItem == action)
@@ -487,13 +534,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
else
{
+ AddPermissions(item, objlist[0], objlist, remoteClient);
+
item.CreationDate = Util.UnixTimeSinceEpoch();
item.Description = asset.Description;
item.Name = asset.Name;
item.AssetType = asset.Type;
- AddPermissions(item, objlist[0], objlist, remoteClient);
-
m_Scene.AddInventoryItem(item);
if (remoteClient != null && item.Owner == remoteClient.AgentId)
@@ -510,17 +557,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
}
- // Restore KeyframeMotion
- foreach (SceneObjectGroup objectGroup in group2Keyframe.Keys)
- {
- objectGroup.RootPart.KeyframeMotion = group2Keyframe[objectGroup];
- objectGroup.RootPart.KeyframeMotion.Start();
- }
-
// This is a hook to do some per-asset post-processing for subclasses that need that
- if (remoteClient != null)
+ if (remoteClient != null && action != DeRezAction.Delete)
ExportAsset(remoteClient.AgentId, asset.FullID);
-
+
return item;
}
@@ -538,56 +578,41 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
///
///
protected InventoryItemBase AddPermissions(
- InventoryItemBase item, SceneObjectGroup so, List objsForEffectivePermissions,
+ InventoryItemBase item, SceneObjectGroup so, List objsForEffectivePermissions,
IClientAPI remoteClient)
{
- uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7;
- uint allObjectsNextOwnerPerms = 0x7fffffff;
- uint allObjectsEveryOnePerms = 0x7fffffff;
- uint allObjectsGroupPerms = 0x7fffffff;
-
+ uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export | PermissionMask.FoldedMask);
+
foreach (SceneObjectGroup grp in objsForEffectivePermissions)
{
- effectivePerms &= grp.GetEffectivePermissions();
- allObjectsNextOwnerPerms &= grp.RootPart.NextOwnerMask;
- allObjectsEveryOnePerms &= grp.RootPart.EveryoneMask;
- allObjectsGroupPerms &= grp.RootPart.GroupMask;
+ effectivePerms &= grp.CurrentAndFoldedNextPermissions();
}
- effectivePerms |= (uint)PermissionMask.Move;
-
- //PermissionsUtil.LogPermissions(item.Name, "Before AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
-
+
if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
{
- // Changing ownership, so apply the "Next Owner" permissions to all of the
- // inventory item's permissions.
-
- uint perms = effectivePerms;
- PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref perms);
-
- item.BasePermissions = perms & allObjectsNextOwnerPerms;
- item.CurrentPermissions = item.BasePermissions;
- item.NextPermissions = perms & allObjectsNextOwnerPerms;
- item.EveryOnePermissions = allObjectsEveryOnePerms & allObjectsNextOwnerPerms;
- item.GroupPermissions = allObjectsGroupPerms & allObjectsNextOwnerPerms;
-
+ // apply parts inventory items next owner
+ PermissionsUtil.ApplyNoModFoldedPermissions(effectivePerms, ref effectivePerms);
+ // change to next owner
+ uint basePerms = effectivePerms & so.RootPart.NextOwnerMask;
+ // fix and update folded
+ basePerms = PermissionsUtil.FixAndFoldPermissions(basePerms);
+
+ item.BasePermissions = basePerms;
+ item.CurrentPermissions = basePerms;
+ item.NextPermissions = basePerms & so.RootPart.NextOwnerMask;
+ item.EveryOnePermissions = basePerms & so.RootPart.EveryoneMask;
+ item.GroupPermissions = basePerms & so.RootPart.GroupMask;
+
// apply next owner perms on rez
- item.CurrentPermissions |= SceneObjectGroup.SLAM;
+ item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
}
else
{
- // Not changing ownership.
- // In this case we apply the permissions in the object's items ONLY to the inventory
- // item's "Next Owner" permissions, but NOT to its "Current", "Base", etc. permissions.
- // E.g., if the object contains a No-Transfer item then the item's "Next Owner"
- // permissions are also No-Transfer.
- PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref allObjectsNextOwnerPerms);
-
item.BasePermissions = effectivePerms;
item.CurrentPermissions = effectivePerms;
- item.NextPermissions = allObjectsNextOwnerPerms & effectivePerms;
- item.EveryOnePermissions = allObjectsEveryOnePerms & effectivePerms;
- item.GroupPermissions = allObjectsGroupPerms & effectivePerms;
+ item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms;
+ item.EveryOnePermissions = so.RootPart.EveryoneMask & effectivePerms;
+ item.GroupPermissions = so.RootPart.GroupMask & effectivePerms;
item.CurrentPermissions &=
((uint)PermissionMask.Copy |
@@ -595,14 +620,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
(uint)PermissionMask.Modify |
(uint)PermissionMask.Move |
(uint)PermissionMask.Export |
- 7); // Preserve folded permissions
- }
-
- //PermissionsUtil.LogPermissions(item.Name, "After AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
-
+ (uint)PermissionMask.FoldedMask); // Preserve folded permissions ??
+ }
+
return item;
}
-
+
///
/// Create an item using details for the given scene object.
///
@@ -615,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID)
{
// m_log.DebugFormat(
-// "[BASIC INVENTORY ACCESS MODULE]: Creating item for object {0} {1} for folder {2}, action {3}",
+// "[BASIC INVENTORY ACCESS MODULE]: Creating item for object {0} {1} for folder {2}, action {3}",
// so.Name, so.UUID, folderID, action);
//
// Get the user info of the item destination
@@ -663,14 +686,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// Delete is treated like return in this case
// Deleting your own items makes them go to trash
//
-
+
InventoryFolderBase folder = null;
InventoryItemBase item = null;
if (DeRezAction.SaveToExistingUserInventoryItem == action)
{
- item = new InventoryItemBase(so.RootPart.FromUserInventoryItemID, userID);
- item = m_Scene.InventoryService.GetItem(item);
+ item = m_Scene.InventoryService.GetItem(userID, so.RootPart.FromUserInventoryItemID);
//item = userInfo.RootFolder.FindItem(
// objectGroup.RootPart.FromUserInventoryItemID);
@@ -680,7 +702,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
m_log.DebugFormat(
"[INVENTORY ACCESS MODULE]: Object {0} {1} scheduled for save to inventory has already been deleted.",
so.Name, so.UUID);
-
+
return null;
}
}
@@ -742,8 +764,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId)
{
- InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
- folder = m_Scene.InventoryService.GetFolder(f);
+ folder = m_Scene.InventoryService.GetFolder(userID, so.FromFolderID);
if(folder.Type == 14 || folder.Type == 16)
{
@@ -763,49 +784,65 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
}
- item = new InventoryItemBase();
+ item = new InventoryItemBase();
item.ID = UUID.Random();
item.InvType = (int)InventoryType.Object;
item.Folder = folder.ID;
item.Owner = userID;
- }
-
+ }
+
return item;
}
-
+ // compatibility do not use
public virtual SceneObjectGroup RezObject(
IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
{
-// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
+ return RezObject(remoteClient, itemID, UUID.Zero, RayEnd, RayStart,
+ RayTargetID, BypassRayCast, RayEndIsIntersection,
+ RezSelected, RemoveItem, fromTaskID, attachment);
+ }
- InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
- item = m_Scene.InventoryService.GetItem(item);
+ public virtual SceneObjectGroup RezObject(
+ IClientAPI remoteClient, UUID itemID, UUID rezGroupID, Vector3 RayEnd, Vector3 RayStart,
+ UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
+ bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
+ {
+// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
+ InventoryItemBase item = m_Scene.InventoryService.GetItem(remoteClient.AgentId, itemID);
if (item == null)
{
- m_log.WarnFormat(
- "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()",
- itemID, remoteClient.Name);
-
return null;
}
item.Owner = remoteClient.AgentId;
return RezObject(
- remoteClient, item, item.AssetID,
+ remoteClient, item, rezGroupID, item.AssetID,
RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
RezSelected, RemoveItem, fromTaskID, attachment);
}
-
+ // compatility
public virtual SceneObjectGroup RezObject(
IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart,
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
{
- AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
+ return RezObject(remoteClient, item, UUID.Zero, assetID,
+ RayEnd, RayStart, RayTargetID,
+ BypassRayCast, RayEndIsIntersection,
+ RezSelected, RemoveItem, fromTaskID, attachment);
+ }
+
+ public virtual SceneObjectGroup RezObject(
+ IClientAPI remoteClient, InventoryItemBase item, UUID groupID, UUID assetID,
+ Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID,
+ byte BypassRayCast, bool RayEndIsIntersection,
+ bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
+ {
+ AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
if (rezAsset == null)
{
@@ -827,6 +864,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
return null;
}
+ if(rezAsset.Data == null || rezAsset.Data.Length == 0)
+ {
+ m_log.WarnFormat(
+ "[INVENTORY ACCESS MODULE]: missing data in asset {0} to RezObject()",
+ assetID, remoteClient.Name);
+ remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: missing data in asset {0} ", assetID), false);
+ return null;
+ }
+
SceneObjectGroup group = null;
List objlist;
@@ -836,7 +882,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
Vector3 pos;
- bool single
+ bool single
= m_Scene.GetObjectsToRez(
rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight);
@@ -856,12 +902,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
pos -= bbox / 2;
}
+ int primcount = 0;
+ foreach (SceneObjectGroup g in objlist)
+ primcount += g.PrimCount;
+
+ if (!m_Scene.Permissions.CanRezObject(
+ primcount, remoteClient.AgentId, pos)
+ && !attachment)
+ {
+ // The client operates in no fail mode. It will
+ // have already removed the item from the folder
+ // if it's no copy.
+ // Put it back if it's not an attachment
+ //
+ if (item != null)
+ {
+ if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
+ remoteClient.SendBulkUpdateInventory(item);
+ }
+
+ return null;
+ }
+
if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment))
return null;
for (int i = 0; i < objlist.Count; i++)
{
group = objlist[i];
+ SceneObjectPart rootPart = group.RootPart;
// m_log.DebugFormat(
// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -891,9 +960,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
part.LastOwnerID = part.OwnerID;
part.OwnerID = remoteClient.AgentId;
+ part.RezzerID = remoteClient.AgentId;
}
}
+ group.ResetIDs();
+
if (!attachment)
{
// If it's rezzed in world, select it. Much easier to
@@ -903,48 +975,38 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
part.CreateSelected = true;
}
- }
- group.ResetIDs();
-
- if (attachment)
+ if (rootPart.Shape.PCode == (byte)PCode.Prim)
+ group.ClearPartAttachmentData();
+ }
+ else
{
- group.RootPart.Flags |= PrimFlags.Phantom;
group.IsAttachment = true;
}
+ group.SetGroup(groupID, remoteClient);
+
// If we're rezzing an attachment then don't ask
// AddNewSceneObject() to update the client since
// we'll be doing that later on. Scheduling more than
// one full update during the attachment
// process causes some clients to fail to display the
// attachment properly.
- m_Scene.AddNewSceneObject(group, !attachment, false);
- // if attachment we set it's asset id so object updates
- // can reflect that, if not, we set it's position in world.
if (!attachment)
{
- group.ScheduleGroupForFullUpdate();
-
group.AbsolutePosition = pos + veclist[i];
- }
-
- group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
-
- if (!attachment)
- {
- SceneObjectPart rootPart = group.RootPart;
-
- if (rootPart.Shape.PCode == (byte)PCode.Prim)
- group.ClearPartAttachmentData();
+ m_Scene.AddNewSceneObject(group, true, false);
// Fire on_rez
group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
rootPart.ParentGroup.ResumeScripts();
- rootPart.ScheduleFullUpdate();
+ group.ScheduleGroupForFullUpdate();
}
+ else
+ m_Scene.AddNewSceneObject(group, true, false);
+
// m_log.DebugFormat(
// "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -953,6 +1015,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// remoteClient.Name);
}
+// group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
+
if (item != null)
DoPostRezWhenFromItem(item, attachment);
@@ -973,7 +1037,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
///
/// true if we can processed with rezzing, false if we need to abort
private bool DoPreRezWhenFromItem(
- IClientAPI remoteClient, InventoryItemBase item, List objlist,
+ IClientAPI remoteClient, InventoryItemBase item, List objlist,
Vector3 pos, List veclist, bool isAttachment)
{
UUID fromUserInventoryItemId = UUID.Zero;
@@ -1033,10 +1097,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// object itself before we rez.
//
// Only do these for the first object if we are rezzing a coalescence.
- if (i == 0)
+ // nahh dont mess with coalescence objects,
+ // the name in inventory can be change for inventory purpuses only
+ if (objlist.Count == 1)
{
rootPart.Name = item.Name;
rootPart.Description = item.Description;
+ }
+
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
+ {
rootPart.ObjectSaleType = item.SaleType;
rootPart.SalePrice = item.SalePrice;
}
@@ -1047,20 +1117,78 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
- if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & SceneObjectGroup.SLAM) != 0)
+ if ((rootPart.OwnerID != item.Owner) ||
+ (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 ||
+ (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
{
//Need to kill the for sale here
rootPart.ObjectSaleType = 0;
rootPart.SalePrice = 10;
- }
- foreach (SceneObjectPart part in so.Parts)
+ if (m_Scene.Permissions.PropagatePermissions())
+ {
+ foreach (SceneObjectPart part in so.Parts)
+ {
+ part.GroupMask = 0; // DO NOT propagate here
+ if( part.OwnerID != part.GroupID)
+ part.LastOwnerID = part.OwnerID;
+ part.OwnerID = item.Owner;
+ part.RezzerID = item.Owner;
+ part.Inventory.ChangeInventoryOwner(item.Owner);
+
+ // Reconstruct the original item's base permissions. They
+ // can be found in the lower (folded) bits.
+ if ((item.BasePermissions & (uint)PermissionMask.FoldedMask) != 0)
+ {
+ // We have permissions stored there so use them
+ part.NextOwnerMask = ((item.BasePermissions & (uint)PermissionMask.FoldedMask) << (int)PermissionMask.FoldingShift);
+ part.NextOwnerMask |= (uint)PermissionMask.Move;
+ }
+ else
+ {
+ // This is a legacy object and we can't avoid the issues that
+ // caused perms loss or escalation before, treat it the legacy
+ // way.
+ part.NextOwnerMask = item.NextPermissions;
+ }
+ }
+
+ so.ApplyNextOwnerPermissions();
+
+ // In case the user has changed flags on a received item
+ // we have to apply those changes after the slam. Else we
+ // get a net loss of permissions.
+ // On legacy objects, this opts for a loss of permissions rather
+ // than the previous handling that allowed escalation.
+ foreach (SceneObjectPart part in so.Parts)
+ {
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
+ {
+ part.GroupMask = item.GroupPermissions & part.BaseMask;
+ part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
+ part.NextOwnerMask = item.NextPermissions & part.BaseMask;
+ }
+ }
+
+ }
+ }
+ else
{
- part.FromUserInventoryItemID = fromUserInventoryItemId;
- part.ApplyPermissionsOnRez(item, true, m_Scene);
+ foreach (SceneObjectPart part in so.Parts)
+ {
+ part.FromUserInventoryItemID = fromUserInventoryItemId;
+
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
+ part.EveryoneMask = item.EveryOnePermissions;
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
+ part.NextOwnerMask = item.NextPermissions;
+ if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
+ part.GroupMask = item.GroupPermissions;
+ }
}
rootPart.TrimPermissions();
+ so.InvalidateDeepEffectivePerms();
if (isAttachment)
so.FromItemID = item.ID;
@@ -1184,9 +1312,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID)
{
IInventoryService invService = m_Scene.RequestModuleInterface();
- InventoryItemBase item = new InventoryItemBase(itemID, agentID);
- item = invService.GetItem(item);
-
+ InventoryItemBase item = invService.GetItem(agentID, itemID);
+
if (item != null && item.CreatorData != null && item.CreatorData != string.Empty)
UserManagementModule.AddUser(item.CreatorIdAsUuid, item.CreatorData);
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs
index 007ff63..01c5d3b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs
@@ -77,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
scene.StartScripts();
HGAssetMapper hgam = new HGAssetMapper(scene, homeUrl);
- UserAccount ua
+ UserAccount ua
= UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "password");
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, soPartsCount, ua.PrincipalID, "part", soIdTail);
@@ -93,6 +93,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
Assert.AreEqual(foreignUrl, ncAssetGet.CreatorID);
string xmlData = Utils.BytesToString(ncAssetGet.Data);
XmlDocument ncAssetGetXmlDoc = new XmlDocument();
+ ncAssetGetXmlDoc.XmlResolver=null;
ncAssetGetXmlDoc.LoadXml(xmlData);
// Console.WriteLine(ncAssetGetXmlDoc.OuterXml);
@@ -116,7 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
XmlNode uuidAttribute = savedScriptStateNodes[0].Attributes.GetNamedItem("UUID");
Assert.NotNull(uuidAttribute);
// XXX: To check the actual UUID attribute we would have to do some work to retreive the UUID of the task
- // item created earlier.
+ // item created earlier.
}
private void RezScript(Scene scene, UUID soId, string script, string itemName, UUID userId)
@@ -131,9 +132,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
// immediately for tests rather than chunter through it's threaded mechanisms.
AutoResetEvent chatEvent = new AutoResetEvent(false);
- scene.EventManager.OnChatFromWorld += (s, c) =>
+ scene.EventManager.OnChatFromWorld += (s, c) =>
{
-// Console.WriteLine("Got chat [{0}]", c.Message);
+// Console.WriteLine("Got chat [{0}]", c.Message);
chatEvent.Set();
};
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index 1d91165..de29ae9 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -48,12 +48,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
{
[TestFixture]
public class InventoryAccessModuleTests : OpenSimTestCase
- {
+ {
protected TestScene m_scene;
protected BasicInventoryAccessModule m_iam;
protected UUID m_userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
protected TestClient m_tc;
-
+
[SetUp]
public override void SetUp()
{
@@ -68,31 +68,32 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
SceneHelpers sceneHelpers = new SceneHelpers();
m_scene = sceneHelpers.SetupScene();
SceneHelpers.SetupSceneModules(m_scene, config, m_iam);
-
+
// Create user
string userFirstName = "Jock";
string userLastName = "Stirrup";
string userPassword = "troll";
- UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, m_userId, userPassword);
-
+ UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, m_userId, userPassword);
+
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = m_userId;
m_tc = new TestClient(acd, m_scene);
}
-
+
[Test]
public void TestRezCoalescedObject()
{
+/*
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
-
+
// Create asset
SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20);
object1.AbsolutePosition = new Vector3(15, 30, 45);
-
+
SceneObjectGroup object2 = SceneHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40);
- object2.AbsolutePosition = new Vector3(25, 50, 75);
-
+ object2.AbsolutePosition = new Vector3(25, 50, 75);
+
CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2);
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
@@ -106,45 +107,46 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
item1.Name = item1Name;
item1.AssetID = asset1.FullID;
item1.ID = item1Id;
- InventoryFolderBase objsFolder
+ InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
item1.Folder = objsFolder.ID;
item1.Flags |= (uint)InventoryItemFlags.ObjectHasMultipleItems;
m_scene.AddInventoryItem(item1);
-
- SceneObjectGroup so
+
+ SceneObjectGroup so
= m_iam.RezObject(
- m_tc, item1Id, new Vector3(100, 100, 100), Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false);
-
+ m_tc, item1Id, new Vector3(100, 100, 100), Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false);
+
Assert.That(so, Is.Not.Null);
-
+
Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(2));
-
+
SceneObjectPart retrievedObj1Part = m_scene.GetSceneObjectPart(object1.Name);
Assert.That(retrievedObj1Part, Is.Null);
-
+
retrievedObj1Part = m_scene.GetSceneObjectPart(item1.Name);
Assert.That(retrievedObj1Part, Is.Not.Null);
Assert.That(retrievedObj1Part.Name, Is.EqualTo(item1.Name));
-
+
// Bottom of coalescence is placed on ground, hence we end up with 100.5 rather than 85 since the bottom
// object is unit square.
Assert.That(retrievedObj1Part.AbsolutePosition, Is.EqualTo(new Vector3(95, 90, 100.5f)));
-
+
SceneObjectPart retrievedObj2Part = m_scene.GetSceneObjectPart(object2.Name);
- Assert.That(retrievedObj2Part, Is.Not.Null);
+ Assert.That(retrievedObj2Part, Is.Not.Null);
Assert.That(retrievedObj2Part.Name, Is.EqualTo(object2.Name));
Assert.That(retrievedObj2Part.AbsolutePosition, Is.EqualTo(new Vector3(105, 110, 130.5f)));
- }
-
+*/
+ }
+
[Test]
public void TestRezObject()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
-
+
// Create asset
- SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40);
+ SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40);
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -157,17 +159,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
item1.Name = item1Name;
item1.AssetID = asset1.FullID;
item1.ID = item1Id;
- InventoryFolderBase objsFolder
+ InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
item1.Folder = objsFolder.ID;
m_scene.AddInventoryItem(item1);
-
- SceneObjectGroup so
+
+ SceneObjectGroup so
= m_iam.RezObject(
- m_tc, item1Id, Vector3.Zero, Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false);
-
+ m_tc, item1Id, UUID.Zero, Vector3.Zero, Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false);
+
Assert.That(so, Is.Not.Null);
-
+
SceneObjectPart retrievedPart = m_scene.GetSceneObjectPart(so.UUID);
Assert.That(retrievedPart, Is.Not.Null);
}
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index 862f0b7..5d77201 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -126,7 +126,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
return;
// This will never run more than once, even if the region is restarted
- if (!m_HasRunOnce)
+ if (!m_HasRunOnce)
{
LoadLibrariesFromArchives();
//DumpLibrary();
@@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false);
try
{
- HashSet nodes = archread.Execute();
+ Dictionary nodes = archread.Execute();
if (nodes != null && nodes.Count == 0)
{
// didn't find the subfolder with the given name; place it on the top
@@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
archread.Execute();
}
- foreach (InventoryNodeBase node in nodes)
+ foreach (InventoryNodeBase node in nodes.Values)
FixPerms(node);
}
catch (Exception e)
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
index e1e1838..c1a9457 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
@@ -103,13 +103,8 @@ namespace OpenSim.Region.CoreModules.Framework.Library
{
InventoryItemBase[] itemColl = new InventoryItemBase[itemIDs.Length];
int i = 0;
- InventoryItemBase item = new InventoryItemBase();
- item.Owner = principalID;
foreach (UUID fid in itemIDs)
- {
- item.ID = fid;
- itemColl[i++] = GetItem(item);
- }
+ itemColl[i++] = GetItem(principalID, fid);
return itemColl;
}
@@ -239,14 +234,14 @@ namespace OpenSim.Region.CoreModules.Framework.Library
///
///
///
- public InventoryItemBase GetItem(InventoryItemBase item) { return null; }
+ public InventoryItemBase GetItem(UUID principalID, UUID itemID) { return null; }
///
/// Get a folder, given by its UUID
///
///
///
- public InventoryFolderBase GetFolder(InventoryFolderBase folder) { return null; }
+ public InventoryFolderBase GetFolder(UUID principalID, UUID folderID) { return null; }
///
/// Does the given user have an inventory structure?
@@ -264,11 +259,11 @@ namespace OpenSim.Region.CoreModules.Framework.Library
///
/// Get the union of permissions of all inventory items
- /// that hold the given assetID.
+ /// that hold the given assetID.
///
///
///
- /// The permissions or 0 if no such asset is found in
+ /// The permissions or 0 if no such asset is found in
/// the user's inventory
public int GetAssetPermissions(UUID userID, UUID assetID) { return 0; }
}
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index 64feec1..fb3d31c 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -44,7 +44,7 @@ using Mono.Addins;
namespace OpenSim.Region.CoreModules.Framework.Monitoring
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MonitorModule")]
- public class MonitorModule : INonSharedRegionModule
+ public class MonitorModule : INonSharedRegionModule
{
///
/// Is this module enabled?
@@ -78,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
if (cnfg != null)
Enabled = cnfg.GetBoolean("Enabled", true);
-
+
if (!Enabled)
return;
@@ -205,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
m_scene,
"ScriptEventsPerSecondMonitor",
"Script Events",
- m => m.Scene.StatsReporter.LastReportedSimStats[20],
+ m => m.Scene.StatsReporter.LastReportedSimStats[23],
m => string.Format("{0} per second", m.GetValue())));
m_staticMonitors.Add(
@@ -301,7 +301,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
m_scene,
"SpareFrameTimeMonitor",
"Spare Frame Time",
- m => m.Scene.StatsReporter.LastReportedSimStats[21],
+ m => m.Scene.StatsReporter.LastReportedSimStats[38],
m => string.Format("{0} ms", m.GetValue())));
m_alerts.Add(new DeadlockAlert(m_staticMonitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor));
@@ -433,7 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
MakeStat("ScriptLines", "lines/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[20]; });
MakeStat("SimSpareMS", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[21]; });
}
-
+
private void UnRegisterStatsManagerRegionStatistics()
{
foreach (Stat stat in registeredStats)
@@ -443,6 +443,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
}
registeredStats.Clear();
}
-
+
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
index 3849996..c04d856 100644
--- a/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
@@ -135,7 +135,7 @@ namespace OpenSim.Region.CoreModules.Framework.Search
#endregion ISharedRegionModule
-
+
#region Event Handlers
void EventManager_OnMakeRootAgent(ScenePresence sp)
diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
index 3abacbd..2c74c0e 100644
--- a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
@@ -48,31 +48,16 @@ namespace OpenSim.Region.CoreModules.Framework
MethodBase.GetCurrentMethod().DeclaringType);
private readonly List m_scenes = new List();
- private System.Timers.Timer m_timer = new System.Timers.Timer();
-
- private Queue m_RequestQueue = new Queue();
- private Dictionary> m_Pending = new Dictionary>();
- private int m_Interval;
+ private JobEngine m_processorJobEngine;
#region ISharedRegionModule
public void Initialise(IConfigSource config)
{
- m_Interval = Util.GetConfigVarFromSections(config, "Interval", new string[] { "ServiceThrottle" }, 5000);
-
- m_timer = new System.Timers.Timer();
- m_timer.AutoReset = false;
- m_timer.Enabled = true;
- m_timer.Interval = 15000; // 15 secs at first
- m_timer.Elapsed += ProcessQueue;
- m_timer.Start();
-
- //WorkManager.StartThread(
- // ProcessQueue,
- // "GridServiceRequestThread",
- // ThreadPriority.BelowNormal,
- // true,
- // false);
+ m_processorJobEngine = new JobEngine(
+ "ServiceThrottle","ServiceThrottle");
+ m_processorJobEngine.RequestProcessTimeoutOnStop = 31000; // many webrequests have 30s expire
+ m_processorJobEngine.Start();
}
public void AddRegion(Scene scene)
@@ -82,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework
m_scenes.Add(scene);
scene.RegisterModuleInterface(this);
scene.EventManager.OnNewClient += OnNewClient;
- scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
}
}
@@ -105,6 +89,7 @@ namespace OpenSim.Region.CoreModules.Framework
public void Close()
{
+ m_processorJobEngine.Stop();
}
public string Name
@@ -126,38 +111,32 @@ namespace OpenSim.Region.CoreModules.Framework
client.OnRegionHandleRequest += OnRegionHandleRequest;
}
- void OnMakeRootAgent(ScenePresence obj)
- {
- lock (m_timer)
- {
- if (!m_timer.Enabled)
- {
- m_timer.Interval = m_Interval;
- m_timer.Enabled = true;
- m_timer.Start();
- }
- }
- }
-
public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
{
//m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
- ulong handle = 0;
- if (IsLocalRegionHandle(regionID, out handle))
- {
- client.SendRegionHandle(regionID, handle);
- return;
- }
-
Action action = delegate
{
- GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID);
+ if(!client.IsActive)
+ return;
+
+ if(m_scenes.Count == 0)
+ return;
+
+ Scene baseScene = m_scenes[0];
+
+ if(baseScene == null || baseScene.ShuttingDown)
+ return;
+
+ GridRegion r = baseScene.GridService.GetRegionByUUID(UUID.Zero, regionID);
+
+ if(!client.IsActive)
+ return;
if (r != null && r.RegionHandle != 0)
client.SendRegionHandle(regionID, r.RegionHandle);
};
- Enqueue("region", regionID.ToString(), action);
+ m_processorJobEngine.QueueJob("regionHandle", action, regionID.ToString());
}
#endregion Events
@@ -166,91 +145,10 @@ namespace OpenSim.Region.CoreModules.Framework
public void Enqueue(string category, string itemid, Action continuation)
{
- lock (m_RequestQueue)
- {
- if (m_Pending.ContainsKey(category))
- {
- if (m_Pending[category].Contains(itemid))
- // Don't enqueue, it's already pending
- return;
- }
- else
- m_Pending.Add(category, new List());
-
- m_Pending[category].Add(itemid);
-
- m_RequestQueue.Enqueue(delegate
- {
- lock (m_RequestQueue)
- m_Pending[category].Remove(itemid);
-
- continuation();
- });
- }
+ m_processorJobEngine.QueueJob(category, continuation, itemid);
}
#endregion IServiceThrottleModule
-
- #region Process Continuation Queue
-
- private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e)
- {
- //m_log.DebugFormat("[YYY]: Process queue with {0} continuations", m_RequestQueue.Count);
-
- while (m_RequestQueue.Count > 0)
- {
- Action continuation = null;
- lock (m_RequestQueue)
- continuation = m_RequestQueue.Dequeue();
-
- if (continuation != null)
- continuation();
- }
-
- if (AreThereRootAgents())
- {
- lock (m_timer)
- {
- m_timer.Interval = 1000; // 1 sec
- m_timer.Enabled = true;
- m_timer.Start();
- }
- }
- else
- lock (m_timer)
- m_timer.Enabled = false;
-
- }
-
- #endregion Process Continuation Queue
-
- #region Misc
-
- private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
- {
- regionHandle = 0;
- foreach (Scene s in m_scenes)
- if (s.RegionInfo.RegionID == regionID)
- {
- regionHandle = s.RegionInfo.RegionHandle;
- return true;
- }
- return false;
- }
-
- private bool AreThereRootAgents()
- {
- foreach (Scene s in m_scenes)
- {
- foreach (ScenePresence sp in s.GetScenePresences())
- if (!sp.IsChildAgent)
- return true;
- }
-
- return false;
- }
-
- #endregion Misc
}
}
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
index f3436d1..3e6c8b5 100644
--- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
@@ -45,14 +45,14 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
public class BinaryLoggingModule : INonSharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
+
protected bool m_collectStats;
protected Scene m_scene = null;
-
+
public string Name { get { return "Binary Statistics Logging Module"; } }
public Type ReplaceableInterface { get { return null; } }
- public void Initialise(IConfigSource source)
+ public void Initialise(IConfigSource source)
{
try
{
@@ -81,23 +81,23 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
// if it doesn't work, we don't collect anything
}
}
-
+
public void AddRegion(Scene scene)
{
m_scene = scene;
}
-
- public void RemoveRegion(Scene scene)
+
+ public void RemoveRegion(Scene scene)
{
}
-
- public void RegionLoaded(Scene scene)
+
+ public void RegionLoaded(Scene scene)
{
if (m_collectStats)
m_scene.StatsReporter.OnSendStatsResult += LogSimStats;
}
-
- public void Close()
+
+ public void Close()
{
}
@@ -107,12 +107,12 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
public string Path;
public System.IO.BinaryWriter Log;
}
-
+
static StatLogger m_statLog = null;
static TimeSpan m_statLogPeriod = TimeSpan.FromSeconds(300);
static string m_statsDir = String.Empty;
static Object m_statLockObject = new Object();
-
+
private void LogSimStats(SimStats stats)
{
SimStatsPacket pack = new SimStatsPacket();
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
index 7b89c2c..3e0a610 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#region ISharedRegionModule
- public new void Initialise(IConfigSource config)
+ public override void Initialise(IConfigSource config)
{
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", null);
if (umanmod == Name)
@@ -111,7 +111,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
// This is it! Let's ask the other world
- if (words[0].Contains("."))
+ if (words[0].Contains("."))
{
string[] names = words[0].Split(new char[] { '.' });
if (names.Length >= 2)
@@ -130,7 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
-
+
UUID userID = UUID.Zero;
try
{
@@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
{
m_log.Debug("[USER MANAGEMENT MODULE]: GetUUID call failed ", e);
}
-
+
if (!userID.Equals(UUID.Zero))
{
UserData ud = new UserData();
@@ -163,8 +163,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
//{
// foreach (UserData d in m_UserCache.Values)
// {
- // if (d.LastName.StartsWith("@") &&
- // (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
+ // if (d.LastName.StartsWith("@") &&
+ // (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
// d.LastName.ToLower().StartsWith(query.ToLower())))
// users.Add(d);
// }
@@ -172,4 +172,4 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
index 4e3b7e5..9d91aa3 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
@@ -37,7 +37,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement.Tests
{
[TestFixture]
public class HGUserManagementModuleTests : OpenSimTestCase
- {
+ {
///
/// Test that a new HG agent (i.e. one without a user account) has their name cached in the UMM upon creation.
///
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 7ecbd26..2695464 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#region ISharedRegionModule
- public void Initialise(IConfigSource config)
+ public virtual void Initialise(IConfigSource config)
{
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name);
if (umanmod == Name)
@@ -88,7 +88,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
m_DisplayChangingHomeURI = userManagementConfig.GetBoolean("DisplayChangingHomeURI", false);
}
- public bool IsSharedModule
+ public virtual bool IsSharedModule
{
get { return true; }
}
@@ -98,12 +98,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
get { return "BasicUserManagementModule"; }
}
- public Type ReplaceableInterface
+ public virtual Type ReplaceableInterface
{
get { return null; }
}
- public void AddRegion(Scene scene)
+ public virtual void AddRegion(Scene scene)
{
if (m_Enabled)
{
@@ -119,7 +119,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
}
- public void RemoveRegion(Scene scene)
+ public virtual void RemoveRegion(Scene scene)
{
if (m_Enabled)
{
@@ -131,17 +131,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
}
- public void RegionLoaded(Scene s)
+ public virtual void RegionLoaded(Scene s)
{
if (m_Enabled && m_ServiceThrottle == null)
m_ServiceThrottle = s.RequestModuleInterface();
}
- public void PostInitialise()
+ public virtual void PostInitialise()
{
}
- public void Close()
+ public virtual void Close()
{
lock (m_Scenes)
{
@@ -157,31 +157,34 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#region Event Handlers
- void EventManager_OnPrimsLoaded(Scene s)
+ protected virtual void EventManager_OnPrimsLoaded(Scene s)
{
// let's sniff all the user names referenced by objects in the scene
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
}
- void EventManager_OnNewClient(IClientAPI client)
+ protected virtual void EventManager_OnNewClient(IClientAPI client)
{
client.OnConnectionClosed += new Action(HandleConnectionClosed);
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest);
}
- void HandleConnectionClosed(IClientAPI client)
+ protected virtual void HandleConnectionClosed(IClientAPI client)
{
client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest);
client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
+ client.OnConnectionClosed -= new Action(HandleConnectionClosed);
}
- void HandleUUIDNameRequest(UUID uuid, IClientAPI client)
+ protected virtual void HandleUUIDNameRequest(UUID uuid, IClientAPI client)
{
// m_log.DebugFormat(
// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
// uuid, remote_client.Name);
+ if(m_Scenes.Count <= 0)
+ return;
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
{
@@ -204,7 +207,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
// Not found in cache, queue continuation
- m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate
+ m_ServiceThrottle.Enqueue("uuidname", uuid.ToString(), delegate
{
//m_log.DebugFormat("[YYY]: Name request {0}", uuid);
@@ -214,9 +217,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
// So to avoid clients
// (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will
// instead drop the request entirely.
+ if(!client.IsActive)
+ return;
if (GetUser(uuid, out user))
{
- client.SendNameReply(uuid, user.FirstName, user.LastName);
+ if(client.IsActive)
+ client.SendNameReply(uuid, user.FirstName, user.LastName);
}
// else
// m_log.DebugFormat(
@@ -226,7 +232,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
}
- public void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
+ public virtual void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
{
//EventManager.TriggerAvatarPickerRequest();
@@ -286,8 +292,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#region IPeople
- public List GetUserData(string query, int page_size, int page_number)
+ public virtual List GetUserData(string query, int page_size, int page_number)
{
+ if(m_Scenes.Count <= 0)
+ return new List();;
+
// search the user accounts service
List accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
@@ -323,7 +332,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#endregion IPeople
- private void CacheCreators(SceneObjectGroup sog)
+ protected virtual void CacheCreators(SceneObjectGroup sog)
{
//m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification);
AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData);
@@ -336,9 +345,108 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
}
+ ///
+ ///
+ ///
+ ///
+ /// Caller please provide a properly instantiated array for names, string[2]
+ ///
+ protected virtual bool TryGetUserNames(UUID uuid, string[] names)
+ {
+ if (names == null)
+ names = new string[2];
+
+ if (TryGetUserNamesFromCache(uuid, names))
+ return true;
+
+ if (TryGetUserNamesFromServices(uuid, names))
+ return true;
+
+ return false;
+ }
+
+ protected virtual bool TryGetUserNamesFromCache(UUID uuid, string[] names)
+ {
+ lock (m_UserCache)
+ {
+ if (m_UserCache.ContainsKey(uuid))
+ {
+ names[0] = m_UserCache[uuid].FirstName;
+ names[1] = m_UserCache[uuid].LastName;
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// Try to get the names bound to the given uuid, from the services.
+ ///
+ /// True if the name was found, false if not.
+ ///
+ /// The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"
+ protected virtual bool TryGetUserNamesFromServices(UUID uuid, string[] names)
+ {
+ if(m_Scenes.Count <= 0)
+ return false;
+
+ UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
+
+ if (account != null)
+ {
+ names[0] = account.FirstName;
+ names[1] = account.LastName;
+
+ UserData user = new UserData();
+ user.FirstName = account.FirstName;
+ user.LastName = account.LastName;
+
+ lock (m_UserCache)
+ m_UserCache[uuid] = user;
+
+ return true;
+ }
+ else
+ {
+ // Let's try the GridUser service
+ GridUserInfo uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString());
+ if (uInfo != null)
+ {
+ string url, first, last, tmp;
+ UUID u;
+ if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp))
+ {
+ AddUser(uuid, first, last, url);
+
+ if (m_UserCache.ContainsKey(uuid))
+ {
+ names[0] = m_UserCache[uuid].FirstName;
+ names[1] = m_UserCache[uuid].LastName;
+
+ return true;
+ }
+ }
+ else
+ m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID);
+ }
+// else
+// {
+// m_log.DebugFormat("[USER MANAGEMENT MODULE]: No grid user found for {0}", uuid);
+// }
+
+ names[0] = "Unknown";
+ names[1] = "UserUMMTGUN9";
+
+ return false;
+ }
+ }
+
+
#region IUserManagement
- public UUID GetUserIdByName(string name)
+ public virtual UUID GetUserIdByName(string name)
{
string[] parts = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
@@ -347,8 +455,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return GetUserIdByName(parts[0], parts[1]);
}
- public UUID GetUserIdByName(string firstName, string lastName)
+ public virtual UUID GetUserIdByName(string firstName, string lastName)
{
+ if(m_Scenes.Count <= 0)
+ return UUID.Zero;
+
// TODO: Optimize for reverse lookup if this gets used by non-console commands.
lock (m_UserCache)
{
@@ -367,14 +478,159 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return UUID.Zero;
}
- public string GetUserName(UUID uuid)
+ public virtual string GetUserName(UUID uuid)
{
UserData user;
GetUser(uuid, out user);
return user.FirstName + " " + user.LastName;
}
- public string GetUserHomeURL(UUID userID)
+ public virtual Dictionary GetUsersNames(string[] ids)
+ {
+ Dictionary ret = new Dictionary();
+ if(m_Scenes.Count <= 0)
+ return ret;
+
+ List missing = new List();
+ Dictionary untried = new Dictionary();
+
+ // look in cache
+ UserData userdata = new UserData();
+
+ UUID uuid = UUID.Zero;
+ foreach(string id in ids)
+ {
+ if(UUID.TryParse(id, out uuid))
+ {
+ lock (m_UserCache)
+ {
+ if (m_UserCache.TryGetValue(uuid, out userdata) &&
+ userdata.FirstName != "Unknown" && userdata.FirstName != string.Empty)
+ {
+ string name = userdata.FirstName + " " + userdata.LastName;
+
+ if(userdata.HasGridUserTried)
+ ret[uuid] = name;
+ else
+ {
+ untried[uuid] = name;
+ missing.Add(id);
+ }
+ }
+ else
+ missing.Add(id);
+ }
+ }
+ }
+
+ if(missing.Count == 0)
+ return ret;
+
+ // try user account service
+ List accounts = m_Scenes[0].UserAccountService.GetUserAccounts(
+ m_Scenes[0].RegionInfo.ScopeID, missing);
+
+ if(accounts.Count != 0)
+ {
+ foreach(UserAccount uac in accounts)
+ {
+ if(uac != null)
+ {
+ string name = uac.FirstName + " " + uac.LastName;
+ ret[uac.PrincipalID] = name;
+ missing.Remove(uac.PrincipalID.ToString()); // slowww
+ untried.Remove(uac.PrincipalID);
+
+ userdata = new UserData();
+ userdata.Id = uac.PrincipalID;
+ userdata.FirstName = uac.FirstName;
+ userdata.LastName = uac.LastName;
+ userdata.HomeURL = string.Empty;
+ userdata.IsUnknownUser = false;
+ userdata.HasGridUserTried = true;
+ lock (m_UserCache)
+ m_UserCache[uac.PrincipalID] = userdata;
+ }
+ }
+ }
+
+ if (missing.Count == 0 || m_Scenes[0].GridUserService == null)
+ return ret;
+
+ // try grid user service
+
+ GridUserInfo[] pinfos = m_Scenes[0].GridUserService.GetGridUserInfo(missing.ToArray());
+ if(pinfos.Length > 0)
+ {
+ foreach(GridUserInfo uInfo in pinfos)
+ {
+ if (uInfo != null)
+ {
+ string url, first, last, tmp;
+
+ if(uInfo.UserID.Length <= 36)
+ continue;
+
+ if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out uuid, out url, out first, out last, out tmp))
+ {
+ if (url != string.Empty)
+ {
+ try
+ {
+ userdata = new UserData();
+ userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", ".");
+ userdata.LastName = "@" + new Uri(url).Authority;
+ userdata.Id = uuid;
+ userdata.HomeURL = url;
+ userdata.IsUnknownUser = false;
+ userdata.HasGridUserTried = true;
+ lock (m_UserCache)
+ m_UserCache[uuid] = userdata;
+
+ string name = userdata.FirstName + " " + userdata.LastName;
+ ret[uuid] = name;
+ missing.Remove(uuid.ToString());
+ untried.Remove(uuid);
+ }
+ catch
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // add the untried in cache that still failed
+ if(untried.Count > 0)
+ {
+ foreach(KeyValuePair kvp in untried)
+ {
+ ret[kvp.Key] = kvp.Value;
+ missing.Remove((kvp.Key).ToString());
+ }
+ }
+
+ // add the UMMthings ( not sure we should)
+ if(missing.Count > 0)
+ {
+ foreach(string id in missing)
+ {
+ if(UUID.TryParse(id, out uuid) && uuid != UUID.Zero)
+ {
+ if (m_Scenes[0].LibraryService != null &&
+ (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
+ ret[uuid] = "Mr OpenSim";
+ else
+ ret[uuid] = "Unknown UserUMMAU43";
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ public virtual string GetUserHomeURL(UUID userID)
{
UserData user;
if(GetUser(userID, out user))
@@ -384,7 +640,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return string.Empty;
}
- public string GetUserServerURL(UUID userID, string serverType)
+ public virtual string GetUserServerURL(UUID userID, string serverType)
{
UserData userdata;
if(!GetUser(userID, out userdata))
@@ -424,14 +680,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return string.Empty;
}
- public string GetUserUUI(UUID userID)
+ public virtual string GetUserUUI(UUID userID)
{
string uui;
GetUserUUI(userID, out uui);
return uui;
}
- public bool GetUserUUI(UUID userID, out string uui)
+ public virtual bool GetUserUUI(UUID userID, out string uui)
{
UserData ud;
bool result = GetUser(userID, out ud);
@@ -449,6 +705,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
last = parts[1];
}
uui = userID + ";" + homeURL + ";" + first + " " + last;
+ return result;
}
}
@@ -457,8 +714,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
#region Cache Management
- public bool GetUser(UUID uuid, out UserData userdata)
+ public virtual bool GetUser(UUID uuid, out UserData userdata)
{
+ if(m_Scenes.Count <= 0)
+ {
+ userdata = new UserData();
+ return false;
+ }
+
lock (m_UserCache)
{
if (m_UserCache.TryGetValue(uuid, out userdata))
@@ -471,7 +734,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
else
{
userdata = new UserData();
- userdata.HasGridUserTried = false;
userdata.Id = uuid;
userdata.FirstName = "Unknown";
userdata.LastName = "UserUMMAU42";
@@ -544,7 +806,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return !userdata.IsUnknownUser;
}
- public void AddUser(UUID uuid, string first, string last)
+ public virtual void AddUser(UUID uuid, string first, string last, bool isNPC = false)
{
lock(m_UserCache)
{
@@ -555,13 +817,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
user.FirstName = first;
user.LastName = last;
user.IsUnknownUser = false;
- user.HasGridUserTried = false;
+ user.HasGridUserTried = isNPC;
m_UserCache.Add(uuid, user);
}
}
}
- public void AddUser(UUID uuid, string first, string last, string homeURL)
+ public virtual void AddUser(UUID uuid, string first, string last, string homeURL)
{
//m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
@@ -611,7 +873,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
}
- public void AddUser(UUID id, string creatorData)
+ public virtual void AddUser(UUID id, string creatorData)
{
// m_log.InfoFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
@@ -694,24 +956,29 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
#endregion
- public bool IsLocalGridUser(UUID uuid)
+ public virtual bool IsLocalGridUser(UUID uuid)
{
- UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid);
- if (account == null || (account != null && !account.LocalToGrid))
- return false;
+ lock (m_Scenes)
+ {
+ if (m_Scenes.Count == 0)
+ return true;
+ UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid);
+ if (account == null || (account != null && !account.LocalToGrid))
+ return false;
+ }
return true;
}
#endregion IUserManagement
- protected void Init()
+ protected virtual void Init()
{
AddUser(UUID.Zero, "Unknown", "User");
RegisterConsoleCmds();
}
- protected void RegisterConsoleCmds()
+ protected virtual void RegisterConsoleCmds()
{
MainConsole.Instance.Commands.AddCommand("Users", true,
"show name",
@@ -735,7 +1002,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
HandleResetUserCache);
}
- private void HandleResetUserCache(string module, string[] cmd)
+ protected virtual void HandleResetUserCache(string module, string[] cmd)
{
lock(m_UserCache)
{
@@ -743,7 +1010,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
}
}
- private void HandleShowUser(string module, string[] cmd)
+ protected virtual void HandleShowUser(string module, string[] cmd)
{
if (cmd.Length < 3)
{
@@ -772,7 +1039,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
MainConsole.Instance.Output(cdt.ToString());
}
- private void HandleShowUsers(string module, string[] cmd)
+ protected virtual void HandleShowUsers(string module, string[] cmd)
{
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
cdt.AddColumn("UUID", 36);
--
cgit v1.1