diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 83beff4692..f7e3a59de5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
}
- public void SaveChangedAttachments(IScenePresence sp)
+ public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted)
{
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
@@ -158,13 +158,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
foreach (SceneObjectGroup grp in sp.GetAttachments())
{
-// if (grp.HasGroupChanged) // Resizer scripts?
-// {
- grp.IsAttachment = false;
- grp.AbsolutePosition = grp.RootPart.AttachedPos;
- UpdateKnownItem(sp, grp);
- grp.IsAttachment = true;
-// }
+ grp.IsAttachment = false;
+ grp.AbsolutePosition = grp.RootPart.AttachedPos;
+ UpdateKnownItem(sp, grp, saveAllScripted);
+ grp.IsAttachment = true;
}
}
@@ -466,7 +463,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
///
///
///
- private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp)
+ private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted)
{
// Saving attachments for NPCs messes them up for the real owner!
INPCModule module = m_scene.RequestModuleInterface();
@@ -476,7 +473,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return;
}
- if (grp.HasGroupChanged || grp.ContainsScripts())
+ if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts()))
{
m_log.DebugFormat(
"[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
@@ -509,6 +506,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (sp.ControllingClient != null)
sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
}
+ grp.HasGroupChanged = false; // Prevent it being saved over and over
}
else
{
@@ -702,7 +700,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
group.IsAttachment = false;
group.AbsolutePosition = group.RootPart.AttachedPos;
- UpdateKnownItem(sp, group);
+ UpdateKnownItem(sp, group, true);
m_scene.DeleteSceneObject(group, false);
return;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index b16d0d3448..5c7ca22207 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -353,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
region.ExternalHostName = uri.Host;
region.HttpPort = (uint)uri.Port;
- region.ServerURI = uri.ToString();
+ region.ServerURI = aCircuit.ServiceURLs["HomeURI"].ToString();
region.RegionName = string.Empty;
region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0);
return region;
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index 57c109e581..e3d04cd669 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
+ private ICommandConsole m_console;
public string Name { get { return "Object Commands Module"; } }
@@ -75,6 +76,51 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
m_scene = scene;
+ m_console = MainConsole.Instance;
+
+ m_console.Commands.AddCommand("region", false, "delete object owner",
+ "delete object owner ",
+ "Delete a scene object by owner", HandleDeleteObject);
+ m_console.Commands.AddCommand("region", false, "delete object creator",
+ "delete object creator ",
+ "Delete a scene object by creator", HandleDeleteObject);
+ m_console.Commands.AddCommand("region", false, "delete object uuid",
+ "delete object uuid ",
+ "Delete a scene object by uuid", HandleDeleteObject);
+ m_console.Commands.AddCommand("region", false, "delete object name",
+ "delete object name ",
+ "Delete a scene object by name", HandleDeleteObject);
+ m_console.Commands.AddCommand("region", false, "delete object outside",
+ "delete object outside",
+ "Delete all scene objects outside region boundaries", HandleDeleteObject);
+
+ m_console.Commands.AddCommand(
+ "region",
+ false,
+ "show object uuid",
+ "show object uuid ",
+ "Show details of a scene object with the given UUID", HandleShowObjectByUuid);
+
+ m_console.Commands.AddCommand(
+ "region",
+ false,
+ "show object name",
+ "show object name ",
+ "Show details of scene objects with the given name", HandleShowObjectByName);
+
+ m_console.Commands.AddCommand(
+ "region",
+ false,
+ "show part uuid",
+ "show part uuid ",
+ "Show details of a scene object parts with the given UUID", HandleShowPartByUuid);
+
+ m_console.Commands.AddCommand(
+ "region",
+ false,
+ "show part name",
+ "show part name ",
+ "Show details of scene object parts with the given name", HandleShowPartByName);
}
public void RemoveRegion(Scene scene)
@@ -85,26 +131,167 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
public void RegionLoaded(Scene scene)
{
// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
+ }
- MainConsole.Instance.Commands.AddCommand("region", false, "delete object owner",
- "delete object owner ",
- "Delete object by owner", HandleDeleteObject);
- MainConsole.Instance.Commands.AddCommand("region", false, "delete object creator",
- "delete object creator ",
- "Delete object by creator", HandleDeleteObject);
- MainConsole.Instance.Commands.AddCommand("region", false, "delete object uuid",
- "delete object uuid ",
- "Delete object by uuid", HandleDeleteObject);
- MainConsole.Instance.Commands.AddCommand("region", false, "delete object name",
- "delete object name ",
- "Delete object by name", HandleDeleteObject);
- MainConsole.Instance.Commands.AddCommand("region", false, "delete object outside",
- "delete object outside",
- "Delete all objects outside boundaries", HandleDeleteObject);
+ private void HandleShowObjectByUuid(string module, string[] cmd)
+ {
+ if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
+ return;
+
+ if (cmd.Length < 4)
+ {
+ m_console.OutputFormat("Usage: show object uuid ");
+ return;
+ }
+
+ UUID objectUuid;
+ if (!UUID.TryParse(cmd[3], out objectUuid))
+ {
+ m_console.OutputFormat("{0} is not a valid uuid", cmd[3]);
+ return;
+ }
+
+ SceneObjectGroup so = m_scene.GetSceneObjectGroup(objectUuid);
+
+ if (so == null)
+ {
+// m_console.OutputFormat("No part found with uuid {0}", objectUuid);
+ return;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ AddSceneObjectReport(sb, so);
+
+ m_console.OutputFormat(sb.ToString());
+ }
+
+ private void HandleShowObjectByName(string module, string[] cmd)
+ {
+ if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
+ return;
+
+ if (cmd.Length < 4)
+ {
+ m_console.OutputFormat("Usage: show object name ");
+ return;
+ }
+
+ string name = cmd[3];
+
+ List sceneObjects = new List();
+
+ m_scene.ForEachSOG(so => { if (so.Name == name) { sceneObjects.Add(so); }});
+
+ if (sceneObjects.Count == 0)
+ {
+ m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
+ return;
+ }
+
+ StringBuilder sb = new StringBuilder();
+
+ foreach (SceneObjectGroup so in sceneObjects)
+ {
+ AddSceneObjectReport(sb, so);
+ sb.Append("\n");
+ }
+
+ m_console.OutputFormat(sb.ToString());
+ }
+
+ private void HandleShowPartByUuid(string module, string[] cmd)
+ {
+ if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
+ return;
+
+ if (cmd.Length < 4)
+ {
+ m_console.OutputFormat("Usage: show part uuid ");
+ return;
+ }
+
+ UUID objectUuid;
+ if (!UUID.TryParse(cmd[3], out objectUuid))
+ {
+ m_console.OutputFormat("{0} is not a valid uuid", cmd[3]);
+ return;
+ }
+
+ SceneObjectPart sop = m_scene.GetSceneObjectPart(objectUuid);
+
+ if (sop == null)
+ {
+// m_console.OutputFormat("No part found with uuid {0}", objectUuid);
+ return;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ AddScenePartReport(sb, sop);
+
+ m_console.OutputFormat(sb.ToString());
+ }
+
+ private void HandleShowPartByName(string module, string[] cmd)
+ {
+ if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
+ return;
+
+ if (cmd.Length < 4)
+ {
+ m_console.OutputFormat("Usage: show part name ");
+ return;
+ }
+
+ string name = cmd[3];
+
+ List parts = new List();
+
+ m_scene.ForEachSOG(so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }));
+
+ if (parts.Count == 0)
+ {
+ m_console.OutputFormat("No parts with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
+ return;
+ }
+
+ StringBuilder sb = new StringBuilder();
+
+ foreach (SceneObjectPart part in parts)
+ {
+ AddScenePartReport(sb, part);
+ sb.Append("\n");
+ }
+
+ m_console.OutputFormat(sb.ToString());
+ }
+
+ private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so)
+ {
+ sb.AppendFormat("Name: {0}\n", so.Name);
+ sb.AppendFormat("Description: {0}\n", so.Description);
+ sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName);
+ sb.AppendFormat("Parts: {0}\n", so.PrimCount);
+
+ return sb;
+ }
+
+ private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop)
+ {
+ sb.AppendFormat("Name: {0}\n", sop.Name);
+ sb.AppendFormat("Description: {0}\n", sop.Description);
+ sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName);
+ sb.AppendFormat("Parent: {0}",
+ sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID));
+ sb.AppendFormat("Parts: {0}\n", !sop.IsRoot ? "1" : sop.ParentGroup.PrimCount.ToString());;
+
+ return sb;
}
private void HandleDeleteObject(string module, string[] cmd)
{
+ if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
+ return;
+
if (cmd.Length < 3)
return;
@@ -135,6 +322,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
deletes.Add(g);
});
+// if (deletes.Count == 0)
+// m_console.OutputFormat("No objects were found with owner {0}", match);
+
break;
case "creator":
@@ -147,6 +337,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
deletes.Add(g);
});
+// if (deletes.Count == 0)
+// m_console.OutputFormat("No objects were found with creator {0}", match);
+
break;
case "uuid":
@@ -159,6 +352,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
deletes.Add(g);
});
+// if (deletes.Count == 0)
+// m_console.OutputFormat("No objects were found with uuid {0}", match);
+
break;
case "name":
@@ -168,6 +364,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
deletes.Add(g);
});
+// if (deletes.Count == 0)
+// m_console.OutputFormat("No objects were found with name {0}", o);
+
break;
case "outside":
@@ -193,12 +392,17 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
deletes.Add(g);
});
+// if (deletes.Count == 0)
+// m_console.OutputFormat("No objects were found outside region bounds");
+
break;
}
+ m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName);
+
foreach (SceneObjectGroup g in deletes)
{
- MainConsole.Instance.OutputFormat("Deleting object {0}", g.UUID);
+ m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name);
m_scene.DeleteSceneObject(g, false);
}
}
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index a7770add85..69ce967f52 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// Save the attachments that have change on this presence.
///
///
- void SaveChangedAttachments(IScenePresence sp);
+ void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted);
///
/// Delete all the presence's attachments from the scene
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 273d8bdc50..b37df820ff 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3191,11 +3191,11 @@ namespace OpenSim.Region.Framework.Scenes
public override void RemoveClient(UUID agentID, bool closeChildAgents)
{
CheckHeartbeat();
- bool childagentYN = false;
+ bool isChildAgent = false;
ScenePresence avatar = GetScenePresence(agentID);
if (avatar != null)
{
- childagentYN = avatar.IsChildAgent;
+ isChildAgent = avatar.IsChildAgent;
if (avatar.ParentID != 0)
{
@@ -3206,9 +3206,9 @@ namespace OpenSim.Region.Framework.Scenes
{
m_log.DebugFormat(
"[SCENE]: Removing {0} agent {1} from region {2}",
- (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
+ (isChildAgent ? "child" : "root"), agentID, RegionInfo.RegionName);
- m_sceneGraph.removeUserCount(!childagentYN);
+ m_sceneGraph.removeUserCount(!isChildAgent);
// TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
// unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
@@ -3239,8 +3239,18 @@ namespace OpenSim.Region.Framework.Scenes
{
m_eventManager.TriggerOnRemovePresence(agentID);
- if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
- AttachmentsModule.SaveChangedAttachments(avatar);
+ if (AttachmentsModule != null && !isChildAgent && avatar.PresenceType != PresenceType.Npc)
+ {
+ IUserManagement uMan = RequestModuleInterface();
+ // Don't save attachments for HG visitors, it
+ // messes up their inventory. When a HG visitor logs
+ // out on a foreign grid, their attachments will be
+ // reloaded in the state they were in when they left
+ // the home grid. This is best anyway as the visited
+ // grid may use an incompatible script engine.
+ if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
+ AttachmentsModule.SaveChangedAttachments(avatar, false);
+ }
ForEachClient(
delegate(IClientAPI client)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index cf7bf16404..c31cbab85d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -327,6 +327,12 @@ namespace OpenSim.Region.Framework.Scenes
set { RootPart.Name = value; }
}
+ public string Description
+ {
+ get { return RootPart.Description; }
+ set { RootPart.Description = value; }
+ }
+
///
/// Added because the Parcel code seems to use it
/// but not sure a object should have this
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 23531a9cfd..084ef48aef 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -26,15 +26,16 @@
*/
using System;
-using System.IO;
-using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics; //for [DebuggerNonUserCode]
+using System.Globalization;
+using System.IO;
+using System.Reflection;
using System.Security;
using System.Security.Policy;
-using System.Reflection;
-using System.Globalization;
+using System.Text;
+using System.Threading;
using System.Xml;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
@@ -340,6 +341,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved;
}
+ MainConsole.Instance.Commands.AddCommand(
+ "scripts", false, "xengine status", "xengine status", "Show status information",
+ "Show status information on the script engine.",
+ HandleShowStatus);
+
MainConsole.Instance.Commands.AddCommand(
"scripts", false, "scripts show", "scripts show []", "Show script information",
"Show information on all scripts known to the script engine."
@@ -386,6 +392,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
/// true if we're okay to proceed, false if not.
private void HandleScriptsAction(string[] cmdparams, Action action)
{
+ if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
+ return;
+
lock (m_Scripts)
{
string rawItemId;
@@ -427,8 +436,32 @@ namespace OpenSim.Region.ScriptEngine.XEngine
}
}
+ private void HandleShowStatus(string module, string[] cmdparams)
+ {
+ if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
+ return;
+
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName);
+
+ lock (m_Scripts)
+ sb.AppendFormat("Scripts loaded : {0}\n", m_Scripts.Count);
+
+ sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count);
+ sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count);
+ sb.AppendFormat("Allocated threads : {0}\n", m_ThreadPool.ActiveThreads);
+ sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads);
+ sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks);
+// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count);
+
+ MainConsole.Instance.OutputFormat(sb.ToString());
+ }
+
public void HandleShowScripts(string module, string[] cmdparams)
{
+ if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
+ return;
+
if (cmdparams.Length == 2)
{
lock (m_Scripts)
@@ -463,10 +496,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine
status = "running";
}
- MainConsole.Instance.OutputFormat(
- "{0}.{1}, item UUID {2}, prim UUID {3} @ {4} ({5})",
- instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID,
- sop.AbsolutePosition, status);
+ StringBuilder sb = new StringBuilder();
+ Queue eq = instance.EventQueue;
+
+ sb.AppendFormat("Script name : {0}\n", instance.ScriptName);
+ sb.AppendFormat("Status : {0}\n", status);
+
+ lock (eq)
+ sb.AppendFormat("Queued events : {0}\n", eq.Count);
+
+ sb.AppendFormat("Item UUID : {0}\n", instance.ItemID);
+ sb.AppendFormat("Containing part name: {0}\n", instance.PrimName);
+ sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID);
+ sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition);
+
+ MainConsole.Instance.OutputFormat(sb.ToString());
}
private void HandleSuspendScript(IScriptInstance instance)