aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs49
-rw-r--r--OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs78
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Permissions.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs830
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs61
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs28
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs253
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs200
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs367
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs569
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs45
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs72
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs300
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs33
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs34
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs154
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs130
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs34
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs478
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs2
40 files changed, 2632 insertions, 1280 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index e577958..9ddac19 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -294,6 +294,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
294 return "FALLDOWN"; 294 return "FALLDOWN";
295 } 295 }
296 296
297 // Check if the user has stopped walking just now
298 if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero))
299 return "STAND";
300
297 return CurrentMovementAnimation; 301 return CurrentMovementAnimation;
298 } 302 }
299 303
@@ -418,13 +422,16 @@ namespace OpenSim.Region.Framework.Scenes.Animation
418 /// </summary> 422 /// </summary>
419 public void UpdateMovementAnimations() 423 public void UpdateMovementAnimations()
420 { 424 {
421 CurrentMovementAnimation = DetermineMovementAnimation(); 425 lock (m_animations)
426 {
427 CurrentMovementAnimation = DetermineMovementAnimation();
422 428
423// m_log.DebugFormat( 429// m_log.DebugFormat(
424// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", 430// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
425// CurrentMovementAnimation, m_scenePresence.Name); 431// CurrentMovementAnimation, m_scenePresence.Name);
426 432
427 TrySetMovementAnimation(CurrentMovementAnimation); 433 TrySetMovementAnimation(CurrentMovementAnimation);
434 }
428 } 435 }
429 436
430 public UUID[] GetAnimationArray() 437 public UUID[] GetAnimationArray()
diff --git a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
index 9cb5674..d9d2e64 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncInventorySender.cs
@@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes
137 } 137 }
138 } 138 }
139 139
140 if (fh.Client.IsLoggingOut) 140 if (!fh.Client.IsActive)
141 continue; 141 continue;
142 142
143// m_log.DebugFormat( 143// m_log.DebugFormat(
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index f678d07..f555b49 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -117,7 +117,7 @@ namespace OpenSim.Region.Framework.Scenes
117 117
118 private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) 118 private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
119 { 119 {
120 m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop"); 120// m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop");
121 121
122 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved 122 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
123 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as 123 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
@@ -147,15 +147,15 @@ namespace OpenSim.Region.Framework.Scenes
147 { 147 {
148 x = m_inventoryDeletes.Dequeue(); 148 x = m_inventoryDeletes.Dequeue();
149 149
150 m_log.DebugFormat( 150// m_log.DebugFormat(
151 "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", 151// "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.",
152 left, x.action, x.objectGroups.Count); 152// left, x.action, x.objectGroups.Count);
153 153
154 try 154 try
155 { 155 {
156 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 156 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
157 if (invAccess != null) 157 if (invAccess != null)
158 invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient); 158 invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient, false);
159 159
160 if (x.permissionToDelete) 160 if (x.permissionToDelete)
161 { 161 {
@@ -185,7 +185,7 @@ namespace OpenSim.Region.Framework.Scenes
185 e.StackTrace); 185 e.StackTrace);
186 } 186 }
187 187
188 m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue."); 188// m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue.");
189 189
190 return false; 190 return false;
191 } 191 }
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 2365cfe..76a952b 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -53,6 +53,10 @@ namespace OpenSim.Region.Framework.Scenes
53 53
54 public event ClientMovement OnClientMovement; 54 public event ClientMovement OnClientMovement;
55 55
56 public delegate void OnTerrainTaintedDelegate();
57
58 public event OnTerrainTaintedDelegate OnTerrainTainted;
59
56 public delegate void OnTerrainTickDelegate(); 60 public delegate void OnTerrainTickDelegate();
57 61
58 public delegate void OnTerrainUpdateDelegate(); 62 public delegate void OnTerrainUpdateDelegate();
@@ -484,6 +488,9 @@ namespace OpenSim.Region.Framework.Scenes
484 public delegate void SceneObjectPartUpdated(SceneObjectPart sop); 488 public delegate void SceneObjectPartUpdated(SceneObjectPart sop);
485 public event SceneObjectPartUpdated OnSceneObjectPartUpdated; 489 public event SceneObjectPartUpdated OnSceneObjectPartUpdated;
486 490
491 public delegate void ScenePresenceUpdated(ScenePresence sp);
492 public event ScenePresenceUpdated OnScenePresenceUpdated;
493
487 public delegate void RegionUp(GridRegion region); 494 public delegate void RegionUp(GridRegion region);
488 public event RegionUp OnRegionUp; 495 public event RegionUp OnRegionUp;
489 496
@@ -935,6 +942,27 @@ namespace OpenSim.Region.Framework.Scenes
935 } 942 }
936 } 943 }
937 944
945 public void TriggerTerrainTainted()
946 {
947 OnTerrainTaintedDelegate handlerTerrainTainted = OnTerrainTainted;
948 if (handlerTerrainTainted != null)
949 {
950 foreach (OnTerrainTaintedDelegate d in handlerTerrainTainted.GetInvocationList())
951 {
952 try
953 {
954 d();
955 }
956 catch (Exception e)
957 {
958 m_log.ErrorFormat(
959 "[EVENT MANAGER]: Delegate for TriggerTerrainTainted failed - continuing. {0} {1}",
960 e.Message, e.StackTrace);
961 }
962 }
963 }
964 }
965
938 public void TriggerParcelPrimCountAdd(SceneObjectGroup obj) 966 public void TriggerParcelPrimCountAdd(SceneObjectGroup obj)
939 { 967 {
940 OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = OnParcelPrimCountAdd; 968 OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = OnParcelPrimCountAdd;
@@ -2367,6 +2395,27 @@ namespace OpenSim.Region.Framework.Scenes
2367 } 2395 }
2368 } 2396 }
2369 2397
2398 public void TriggerScenePresenceUpdated(ScenePresence sp)
2399 {
2400 ScenePresenceUpdated handler = OnScenePresenceUpdated;
2401 if (handler != null)
2402 {
2403 foreach (ScenePresenceUpdated d in handler.GetInvocationList())
2404 {
2405 try
2406 {
2407 d(sp);
2408 }
2409 catch (Exception e)
2410 {
2411 m_log.ErrorFormat(
2412 "[EVENT MANAGER]: Delegate for TriggerScenePresenceUpdated failed - continuing. {0} {1}",
2413 e.Message, e.StackTrace);
2414 }
2415 }
2416 }
2417 }
2418
2370 public void TriggerOnParcelPropertiesUpdateRequest(LandUpdateArgs args, 2419 public void TriggerOnParcelPropertiesUpdateRequest(LandUpdateArgs args,
2371 int local_id, IClientAPI remote_client) 2420 int local_id, IClientAPI remote_client)
2372 { 2421 {
diff --git a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
index 6c5685c..1365831 100644
--- a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
+++ b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
@@ -48,16 +48,19 @@ namespace OpenSim.Region.Framework.Scenes
48{ 48{
49 public class RegionStatsHandler : IStreamedRequestHandler 49 public class RegionStatsHandler : IStreamedRequestHandler
50 { 50 {
51 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
51 private string osRXStatsURI = String.Empty; 53 private string osRXStatsURI = String.Empty;
52 private string osXStatsURI = String.Empty; 54 private string osXStatsURI = String.Empty;
53 //private string osSecret = String.Empty; 55 //private string osSecret = String.Empty;
54 private OpenSim.Framework.RegionInfo regionInfo; 56 private OpenSim.Framework.RegionInfo regionInfo;
55 public string localZone = TimeZone.CurrentTimeZone.StandardName; 57 public string localZone = TimeZone.CurrentTimeZone.StandardName;
56 public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); 58 public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
57
58 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 59
60 public RegionStatsHandler(OpenSim.Framework.RegionInfo region_info) 60 public string Name { get { return "RegionStats"; } }
61 public string Description { get { return "Region Statistics"; } }
62
63 public RegionStatsHandler(RegionInfo region_info)
61 { 64 {
62 regionInfo = region_info; 65 regionInfo = region_info;
63 osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret); 66 osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 29465c0..9776a82 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -60,19 +60,32 @@ namespace OpenSim.Region.Framework.Scenes
60 /// <summary> 60 /// <summary>
61 /// Creates all the scripts in the scene which should be started. 61 /// Creates all the scripts in the scene which should be started.
62 /// </summary> 62 /// </summary>
63 public void CreateScriptInstances() 63 /// <returns>
64 /// Number of scripts that were valid for starting. This does not guarantee that all these scripts
65 /// were actually started, but just that the start could be attempt (e.g. the asset data for the script could be found)
66 /// </returns>
67 public int CreateScriptInstances()
64 { 68 {
65 m_log.Info("[PRIM INVENTORY]: Creating scripts in scene"); 69 m_log.InfoFormat("[SCENE]: Initializing script instances in {0}", RegionInfo.RegionName);
70
71 int scriptsValidForStarting = 0;
66 72
67 EntityBase[] entities = Entities.GetEntities(); 73 EntityBase[] entities = Entities.GetEntities();
68 foreach (EntityBase group in entities) 74 foreach (EntityBase group in entities)
69 { 75 {
70 if (group is SceneObjectGroup) 76 if (group is SceneObjectGroup)
71 { 77 {
72 ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0); 78 scriptsValidForStarting
79 += ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
73 ((SceneObjectGroup) group).ResumeScripts(); 80 ((SceneObjectGroup) group).ResumeScripts();
74 } 81 }
75 } 82 }
83
84 m_log.InfoFormat(
85 "[SCENE]: Initialized {0} script instances in {1}",
86 scriptsValidForStarting, RegionInfo.RegionName);
87
88 return scriptsValidForStarting;
76 } 89 }
77 90
78 /// <summary> 91 /// <summary>
@@ -80,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
80 /// </summary> 93 /// </summary>
81 public void StartScripts() 94 public void StartScripts()
82 { 95 {
83 m_log.Info("[PRIM INVENTORY]: Starting scripts in scene"); 96 m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
84 97
85 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>(); 98 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
86 99
@@ -300,6 +313,10 @@ namespace OpenSim.Region.Framework.Scenes
300 AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId); 313 AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId);
301 AssetService.Store(asset); 314 AssetService.Store(asset);
302 315
316// m_log.DebugFormat(
317// "[PRIM INVENTORY]: Stored asset {0} when updating item {1} in prim {2} for {3}",
318// asset.ID, item.Name, part.Name, remoteClient.Name);
319
303 if (isScriptRunning) 320 if (isScriptRunning)
304 { 321 {
305 part.Inventory.RemoveScriptInstance(item.ItemID, false); 322 part.Inventory.RemoveScriptInstance(item.ItemID, false);
@@ -431,10 +448,9 @@ namespace OpenSim.Region.Framework.Scenes
431 } 448 }
432 else 449 else
433 { 450 {
434 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); 451 if (AgentTransactionsModule != null)
435 if (agentTransactions != null)
436 { 452 {
437 agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); 453 AgentTransactionsModule.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
438 } 454 }
439 } 455 }
440 } 456 }
@@ -950,8 +966,8 @@ namespace OpenSim.Region.Framework.Scenes
950 sbyte invType, sbyte type, UUID olditemID) 966 sbyte invType, sbyte type, UUID olditemID)
951 { 967 {
952// m_log.DebugFormat( 968// m_log.DebugFormat(
953// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}", 969// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}, assetType {4}, inventoryType {5}",
954// remoteClient.Name, name, folderID, olditemID); 970// remoteClient.Name, name, folderID, olditemID, (AssetType)type, (InventoryType)invType);
955 971
956 if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) 972 if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
957 return; 973 return;
@@ -984,10 +1000,10 @@ namespace OpenSim.Region.Framework.Scenes
984 asset.Type = type; 1000 asset.Type = type;
985 asset.Name = name; 1001 asset.Name = name;
986 asset.Description = description; 1002 asset.Description = description;
987 1003
988 CreateNewInventoryItem( 1004 CreateNewInventoryItem(
989 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType, 1005 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType,
990 (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, 1006 (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All,
991 (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); 1007 (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch());
992 } 1008 }
993 else 1009 else
@@ -1562,21 +1578,17 @@ namespace OpenSim.Region.Framework.Scenes
1562 // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the 1578 // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the
1563 // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update) 1579 // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update)
1564 // will not pass in a transaction ID in the update message. 1580 // will not pass in a transaction ID in the update message.
1565 if (transactionID != UUID.Zero) 1581 if (transactionID != UUID.Zero && AgentTransactionsModule != null)
1566 { 1582 {
1567 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); 1583 AgentTransactionsModule.HandleTaskItemUpdateFromTransaction(
1568 if (agentTransactions != null) 1584 remoteClient, part, transactionID, currentItem);
1569 { 1585
1570 agentTransactions.HandleTaskItemUpdateFromTransaction( 1586// if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
1571 remoteClient, part, transactionID, currentItem); 1587// remoteClient.SendAgentAlertMessage("Notecard saved", false);
1572 1588// else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
1573// if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) 1589// remoteClient.SendAgentAlertMessage("Script saved", false);
1574// remoteClient.SendAgentAlertMessage("Notecard saved", false); 1590// else
1575// else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) 1591// remoteClient.SendAgentAlertMessage("Item saved", false);
1576// remoteClient.SendAgentAlertMessage("Script saved", false);
1577// else
1578// remoteClient.SendAgentAlertMessage("Item saved", false);
1579 }
1580 } 1592 }
1581 1593
1582 // Base ALWAYS has move 1594 // Base ALWAYS has move
@@ -2286,10 +2298,24 @@ namespace OpenSim.Region.Framework.Scenes
2286 if (part == null) 2298 if (part == null)
2287 return; 2299 return;
2288 2300
2301 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
2302
2289 if (running) 2303 if (running)
2304 {
2305 foreach (IScriptModule engine in engines)
2306 {
2307 engine.SetRunEnable(itemID, true);
2308 }
2290 EventManager.TriggerStartScript(part.LocalId, itemID); 2309 EventManager.TriggerStartScript(part.LocalId, itemID);
2310 }
2291 else 2311 else
2312 {
2313 foreach (IScriptModule engine in engines)
2314 {
2315 engine.SetRunEnable(itemID, false);
2316 }
2292 EventManager.TriggerStopScript(part.LocalId, itemID); 2317 EventManager.TriggerStopScript(part.LocalId, itemID);
2318 }
2293 } 2319 }
2294 2320
2295 public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) 2321 public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index e1fedf4..535d87a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -67,6 +67,7 @@ namespace OpenSim.Region.Framework.Scenes
67 public delegate bool RunConsoleCommandHandler(UUID user, Scene requestFromScene); 67 public delegate bool RunConsoleCommandHandler(UUID user, Scene requestFromScene);
68 public delegate bool IssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand); 68 public delegate bool IssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand);
69 public delegate bool IsGodHandler(UUID user, Scene requestFromScene); 69 public delegate bool IsGodHandler(UUID user, Scene requestFromScene);
70 public delegate bool IsGridGodHandler(UUID user, Scene requestFromScene);
70 public delegate bool IsAdministratorHandler(UUID user); 71 public delegate bool IsAdministratorHandler(UUID user);
71 public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene); 72 public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene);
72 public delegate bool EditParcelPropertiesHandler(UUID user, ILandObject parcel, GroupPowers p, Scene scene); 73 public delegate bool EditParcelPropertiesHandler(UUID user, ILandObject parcel, GroupPowers p, Scene scene);
@@ -134,6 +135,7 @@ namespace OpenSim.Region.Framework.Scenes
134 public event RunConsoleCommandHandler OnRunConsoleCommand; 135 public event RunConsoleCommandHandler OnRunConsoleCommand;
135 public event IssueEstateCommandHandler OnIssueEstateCommand; 136 public event IssueEstateCommandHandler OnIssueEstateCommand;
136 public event IsGodHandler OnIsGod; 137 public event IsGodHandler OnIsGod;
138 public event IsGridGodHandler OnIsGridGod;
137 public event IsAdministratorHandler OnIsAdministrator; 139 public event IsAdministratorHandler OnIsAdministrator;
138// public event EditParcelHandler OnEditParcel; 140// public event EditParcelHandler OnEditParcel;
139 public event EditParcelPropertiesHandler OnEditParcelProperties; 141 public event EditParcelPropertiesHandler OnEditParcelProperties;
@@ -728,6 +730,21 @@ namespace OpenSim.Region.Framework.Scenes
728 return true; 730 return true;
729 } 731 }
730 732
733 public bool IsGridGod(UUID user)
734 {
735 IsGridGodHandler handler = OnIsGridGod;
736 if (handler != null)
737 {
738 Delegate[] list = handler.GetInvocationList();
739 foreach (IsGridGodHandler h in list)
740 {
741 if (h(user, m_scene) == false)
742 return false;
743 }
744 }
745 return true;
746 }
747
731 public bool IsAdministrator(UUID user) 748 public bool IsAdministrator(UUID user)
732 { 749 {
733 IsAdministratorHandler handler = OnIsAdministrator; 750 IsAdministratorHandler handler = OnIsAdministrator;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 48aca98..f437bc8 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -77,7 +77,12 @@ namespace OpenSim.Region.Framework.Scenes
77 public bool DebugUpdates { get; private set; } 77 public bool DebugUpdates { get; private set; }
78 78
79 public SynchronizeSceneHandler SynchronizeScene; 79 public SynchronizeSceneHandler SynchronizeScene;
80 public SimStatsReporter StatsReporter; 80
81 /// <summary>
82 /// Statistical information for this scene.
83 /// </summary>
84 public SimStatsReporter StatsReporter { get; private set; }
85
81 public List<Border> NorthBorders = new List<Border>(); 86 public List<Border> NorthBorders = new List<Border>();
82 public List<Border> EastBorders = new List<Border>(); 87 public List<Border> EastBorders = new List<Border>();
83 public List<Border> SouthBorders = new List<Border>(); 88 public List<Border> SouthBorders = new List<Border>();
@@ -103,6 +108,7 @@ namespace OpenSim.Region.Framework.Scenes
103 public bool m_trustBinaries; 108 public bool m_trustBinaries;
104 public bool m_allowScriptCrossings; 109 public bool m_allowScriptCrossings;
105 public bool m_useFlySlow; 110 public bool m_useFlySlow;
111 public bool m_useTrashOnDelete = true;
106 112
107 /// <summary> 113 /// <summary>
108 /// Temporarily setting to trigger appearance resends at 60 second intervals. 114 /// Temporarily setting to trigger appearance resends at 60 second intervals.
@@ -114,6 +120,9 @@ namespace OpenSim.Region.Framework.Scenes
114 { 120 {
115 get { return m_defaultDrawDistance; } 121 get { return m_defaultDrawDistance; }
116 } 122 }
123
124 private List<string> m_AllowedViewers = new List<string>();
125 private List<string> m_BannedViewers = new List<string>();
117 126
118 // TODO: need to figure out how allow client agents but deny 127 // TODO: need to figure out how allow client agents but deny
119 // root agents when ACL denies access to root agent 128 // root agents when ACL denies access to root agent
@@ -163,7 +172,6 @@ namespace OpenSim.Region.Framework.Scenes
163 protected IConfigSource m_config; 172 protected IConfigSource m_config;
164 protected IRegionSerialiserModule m_serialiser; 173 protected IRegionSerialiserModule m_serialiser;
165 protected IDialogModule m_dialogModule; 174 protected IDialogModule m_dialogModule;
166 protected IEntityTransferModule m_teleportModule;
167 protected ICapabilitiesModule m_capsModule; 175 protected ICapabilitiesModule m_capsModule;
168 protected IGroupsModule m_groupsModule; 176 protected IGroupsModule m_groupsModule;
169 177
@@ -217,6 +225,7 @@ namespace OpenSim.Region.Framework.Scenes
217 private int backupMS; 225 private int backupMS;
218 private int terrainMS; 226 private int terrainMS;
219 private int landMS; 227 private int landMS;
228 private int spareMS;
220 229
221 /// <summary> 230 /// <summary>
222 /// Tick at which the last frame was processed. 231 /// Tick at which the last frame was processed.
@@ -458,6 +467,7 @@ namespace OpenSim.Region.Framework.Scenes
458 { 467 {
459 if (m_simulationService == null) 468 if (m_simulationService == null)
460 m_simulationService = RequestModuleInterface<ISimulationService>(); 469 m_simulationService = RequestModuleInterface<ISimulationService>();
470
461 return m_simulationService; 471 return m_simulationService;
462 } 472 }
463 } 473 }
@@ -513,6 +523,9 @@ namespace OpenSim.Region.Framework.Scenes
513 } 523 }
514 524
515 public IAttachmentsModule AttachmentsModule { get; set; } 525 public IAttachmentsModule AttachmentsModule { get; set; }
526 public IEntityTransferModule EntityTransferModule { get; private set; }
527 public IAgentAssetTransactions AgentTransactionsModule { get; private set; }
528 public IUserManagement UserManagementModule { get; private set; }
516 529
517 public IAvatarFactoryModule AvatarFactory 530 public IAvatarFactoryModule AvatarFactory
518 { 531 {
@@ -589,6 +602,20 @@ namespace OpenSim.Region.Framework.Scenes
589 get { return m_sceneGraph.Entities; } 602 get { return m_sceneGraph.Entities; }
590 } 603 }
591 604
605
606 // used in sequence see: SpawnPoint()
607 private int m_SpawnPoint;
608 // can be closest/random/sequence
609 public string SpawnPointRouting
610 {
611 get; private set;
612 }
613 // allow landmarks to pass
614 public bool TelehubAllowLandmarks
615 {
616 get; private set;
617 }
618
592 #endregion Properties 619 #endregion Properties
593 620
594 #region Constructors 621 #region Constructors
@@ -606,14 +633,13 @@ namespace OpenSim.Region.Framework.Scenes
606 633
607 Random random = new Random(); 634 Random random = new Random();
608 635
609 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4); 636 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4);
610 m_moduleLoader = moduleLoader; 637 m_moduleLoader = moduleLoader;
611 m_authenticateHandler = authen; 638 m_authenticateHandler = authen;
612 m_sceneGridService = sceneGridService; 639 m_sceneGridService = sceneGridService;
613 m_SimulationDataService = simDataService; 640 m_SimulationDataService = simDataService;
614 m_EstateDataService = estateDataService; 641 m_EstateDataService = estateDataService;
615 m_regionHandle = m_regInfo.RegionHandle; 642 m_regionHandle = m_regInfo.RegionHandle;
616 m_regionName = m_regInfo.RegionName;
617 m_lastIncoming = 0; 643 m_lastIncoming = 0;
618 m_lastOutgoing = 0; 644 m_lastOutgoing = 0;
619 645
@@ -630,7 +656,7 @@ namespace OpenSim.Region.Framework.Scenes
630 // resave. 656 // resave.
631 // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new 657 // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
632 // region is set up and avoid these gyrations. 658 // region is set up and avoid these gyrations.
633 RegionSettings rs = simDataService.LoadRegionSettings(m_regInfo.RegionID); 659 RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
634 bool updatedTerrainTextures = false; 660 bool updatedTerrainTextures = false;
635 if (rs.TerrainTexture1 == UUID.Zero) 661 if (rs.TerrainTexture1 == UUID.Zero)
636 { 662 {
@@ -659,10 +685,10 @@ namespace OpenSim.Region.Framework.Scenes
659 if (updatedTerrainTextures) 685 if (updatedTerrainTextures)
660 rs.Save(); 686 rs.Save();
661 687
662 m_regInfo.RegionSettings = rs; 688 RegionInfo.RegionSettings = rs;
663 689
664 if (estateDataService != null) 690 if (estateDataService != null)
665 m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); 691 RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
666 692
667 #endregion Region Settings 693 #endregion Region Settings
668 694
@@ -726,6 +752,9 @@ namespace OpenSim.Region.Framework.Scenes
726 m_maxPhys = RegionInfo.PhysPrimMax; 752 m_maxPhys = RegionInfo.PhysPrimMax;
727 } 753 }
728 754
755 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
756 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
757
729 // Here, if clamping is requested in either global or 758 // Here, if clamping is requested in either global or
730 // local config, it will be used 759 // local config, it will be used
731 // 760 //
@@ -735,6 +764,7 @@ namespace OpenSim.Region.Framework.Scenes
735 m_clampPrimSize = true; 764 m_clampPrimSize = true;
736 } 765 }
737 766
767 m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete);
738 m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); 768 m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
739 m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); 769 m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
740 m_dontPersistBefore = 770 m_dontPersistBefore =
@@ -781,6 +811,24 @@ namespace OpenSim.Region.Framework.Scenes
781 } 811 }
782 } 812 }
783 813
814 string grant = startupConfig.GetString("AllowedClients", String.Empty);
815 if (grant.Length > 0)
816 {
817 foreach (string viewer in grant.Split(','))
818 {
819 m_AllowedViewers.Add(viewer.Trim().ToLower());
820 }
821 }
822
823 grant = startupConfig.GetString("BannedClients", String.Empty);
824 if (grant.Length > 0)
825 {
826 foreach (string viewer in grant.Split(','))
827 {
828 m_BannedViewers.Add(viewer.Trim().ToLower());
829 }
830 }
831
784 MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime); 832 MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime);
785 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); 833 m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup);
786 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); 834 m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
@@ -835,13 +883,11 @@ namespace OpenSim.Region.Framework.Scenes
835 MainConsole.Instance.Commands.AddCommand("scene", false, "gc collect", "gc collect", "gc collect", "Cause the garbage collector to make a single pass", HandleGcCollect); 883 MainConsole.Instance.Commands.AddCommand("scene", false, "gc collect", "gc collect", "gc collect", "Cause the garbage collector to make a single pass", HandleGcCollect);
836 } 884 }
837 885
838 /// <summary> 886 public Scene(RegionInfo regInfo) : base(regInfo)
839 /// Mock constructor for scene group persistency unit tests.
840 /// SceneObjectGroup RegionId property is delegated to Scene.
841 /// </summary>
842 /// <param name="regInfo"></param>
843 public Scene(RegionInfo regInfo)
844 { 887 {
888 PhysicalPrims = true;
889 CollidablePrims = true;
890
845 BordersLocked = true; 891 BordersLocked = true;
846 Border northBorder = new Border(); 892 Border northBorder = new Border();
847 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<--- 893 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
@@ -864,12 +910,9 @@ namespace OpenSim.Region.Framework.Scenes
864 WestBorders.Add(westBorder); 910 WestBorders.Add(westBorder);
865 BordersLocked = false; 911 BordersLocked = false;
866 912
867 m_regInfo = regInfo;
868 m_eventManager = new EventManager(); 913 m_eventManager = new EventManager();
869 914
870 m_permissions = new ScenePermissions(this); 915 m_permissions = new ScenePermissions(this);
871
872// m_lastUpdate = Util.EnvironmentTickCount();
873 } 916 }
874 917
875 #endregion 918 #endregion
@@ -938,8 +981,8 @@ namespace OpenSim.Region.Framework.Scenes
938 List<ulong> old = new List<ulong>(); 981 List<ulong> old = new List<ulong>();
939 old.Add(otherRegion.RegionHandle); 982 old.Add(otherRegion.RegionHandle);
940 agent.DropOldNeighbours(old); 983 agent.DropOldNeighbours(old);
941 if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) 984 if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
942 m_teleportModule.EnableChildAgent(agent, otherRegion); 985 EntityTransferModule.EnableChildAgent(agent, otherRegion);
943 }); 986 });
944 } 987 }
945 catch (NullReferenceException) 988 catch (NullReferenceException)
@@ -952,7 +995,7 @@ namespace OpenSim.Region.Framework.Scenes
952 else 995 else
953 { 996 {
954 m_log.InfoFormat( 997 m_log.InfoFormat(
955 "[INTERGRID]: Got notice about far away Region: {0} at ({1}, {2})", 998 "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})",
956 otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY); 999 otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY);
957 } 1000 }
958 } 1001 }
@@ -1046,13 +1089,13 @@ namespace OpenSim.Region.Framework.Scenes
1046 } 1089 }
1047 } 1090 }
1048 1091
1092 m_log.Error("[REGION]: Closing");
1093 Close();
1094
1049 if (PhysicsScene != null) 1095 if (PhysicsScene != null)
1050 { 1096 {
1051 PhysicsScene.Dispose(); 1097 PhysicsScene.Dispose();
1052 } 1098 }
1053
1054 m_log.Error("[REGION]: Closing");
1055 Close();
1056 1099
1057 m_log.Error("[REGION]: Firing Region Restart Message"); 1100 m_log.Error("[REGION]: Firing Region Restart Message");
1058 1101
@@ -1076,8 +1119,8 @@ namespace OpenSim.Region.Framework.Scenes
1076 { 1119 {
1077 ForEachRootScenePresence(delegate(ScenePresence agent) 1120 ForEachRootScenePresence(delegate(ScenePresence agent)
1078 { 1121 {
1079 if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) 1122 if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
1080 m_teleportModule.EnableChildAgent(agent, r); 1123 EntityTransferModule.EnableChildAgent(agent, r);
1081 }); 1124 });
1082 } 1125 }
1083 catch (NullReferenceException) 1126 catch (NullReferenceException)
@@ -1210,8 +1253,8 @@ namespace OpenSim.Region.Framework.Scenes
1210 1253
1211 m_sceneGraph.Close(); 1254 m_sceneGraph.Close();
1212 1255
1213 if (!GridService.DeregisterRegion(m_regInfo.RegionID)) 1256 if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1214 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName); 1257 m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1215 1258
1216 // call the base class Close method. 1259 // call the base class Close method.
1217 base.Close(); 1260 base.Close();
@@ -1267,8 +1310,10 @@ namespace OpenSim.Region.Framework.Scenes
1267 m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); 1310 m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
1268 m_dialogModule = RequestModuleInterface<IDialogModule>(); 1311 m_dialogModule = RequestModuleInterface<IDialogModule>();
1269 m_capsModule = RequestModuleInterface<ICapabilitiesModule>(); 1312 m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
1270 m_teleportModule = RequestModuleInterface<IEntityTransferModule>(); 1313 EntityTransferModule = RequestModuleInterface<IEntityTransferModule>();
1271 m_groupsModule = RequestModuleInterface<IGroupsModule>(); 1314 m_groupsModule = RequestModuleInterface<IGroupsModule>();
1315 AgentTransactionsModule = RequestModuleInterface<IAgentAssetTransactions>();
1316 UserManagementModule = RequestModuleInterface<IUserManagement>();
1272 } 1317 }
1273 1318
1274 #endregion 1319 #endregion
@@ -1389,37 +1434,41 @@ namespace OpenSim.Region.Framework.Scenes
1389 endFrame = Frame + frames; 1434 endFrame = Frame + frames;
1390 1435
1391 float physicsFPS = 0f; 1436 float physicsFPS = 0f;
1392 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; 1437 int previousFrameTick, tmpMS;
1393 int previousFrameTick; 1438 int maintc = Util.EnvironmentTickCount();
1394 int maintc;
1395 int sleepMS;
1396 int framestart;
1397 1439
1398 while (!m_shuttingDown && (endFrame == null || Frame < endFrame)) 1440 while (!m_shuttingDown && (endFrame == null || Frame < endFrame))
1399 { 1441 {
1400 framestart = Util.EnvironmentTickCount();
1401 ++Frame; 1442 ++Frame;
1402 1443
1403// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); 1444// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1404 1445
1405 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; 1446 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = spareMS = 0;
1406 1447
1407 try 1448 try
1408 { 1449 {
1409 tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1450 // Apply taints in terrain module to terrain in physics scene
1451 if (Frame % m_update_terrain == 0)
1452 {
1453 tmpMS = Util.EnvironmentTickCount();
1454 UpdateTerrain();
1455 terrainMS = Util.EnvironmentTickCountSubtract(tmpMS);
1456 }
1457
1458 tmpMS = Util.EnvironmentTickCount();
1410 if ((Frame % m_update_physics == 0) && m_physics_enabled) 1459 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1411 m_sceneGraph.UpdatePreparePhysics(); 1460 m_sceneGraph.UpdatePreparePhysics();
1412 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); 1461 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpMS);
1413 1462
1414 // Apply any pending avatar force input to the avatar's velocity 1463 // Apply any pending avatar force input to the avatar's velocity
1415 tmpAgentMS = Util.EnvironmentTickCount(); 1464 tmpMS = Util.EnvironmentTickCount();
1416 if (Frame % m_update_entitymovement == 0) 1465 if (Frame % m_update_entitymovement == 0)
1417 m_sceneGraph.UpdateScenePresenceMovement(); 1466 m_sceneGraph.UpdateScenePresenceMovement();
1418 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS); 1467 agentMS = Util.EnvironmentTickCountSubtract(tmpMS);
1419 1468
1420 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their 1469 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1421 // velocity 1470 // velocity
1422 tmpPhysicsMS = Util.EnvironmentTickCount(); 1471 tmpMS = Util.EnvironmentTickCount();
1423 if (Frame % m_update_physics == 0) 1472 if (Frame % m_update_physics == 0)
1424 { 1473 {
1425 if (m_physics_enabled) 1474 if (m_physics_enabled)
@@ -1428,9 +1477,9 @@ namespace OpenSim.Region.Framework.Scenes
1428 if (SynchronizeScene != null) 1477 if (SynchronizeScene != null)
1429 SynchronizeScene(this); 1478 SynchronizeScene(this);
1430 } 1479 }
1431 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS); 1480 physicsMS = Util.EnvironmentTickCountSubtract(tmpMS);
1432 1481
1433 tmpAgentMS = Util.EnvironmentTickCount(); 1482 tmpMS = Util.EnvironmentTickCount();
1434 1483
1435 // Check if any objects have reached their targets 1484 // Check if any objects have reached their targets
1436 CheckAtTargets(); 1485 CheckAtTargets();
@@ -1445,36 +1494,29 @@ namespace OpenSim.Region.Framework.Scenes
1445 if (Frame % m_update_presences == 0) 1494 if (Frame % m_update_presences == 0)
1446 m_sceneGraph.UpdatePresences(); 1495 m_sceneGraph.UpdatePresences();
1447 1496
1448 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); 1497 agentMS += Util.EnvironmentTickCountSubtract(tmpMS);
1449 1498
1450 // Delete temp-on-rez stuff 1499 // Delete temp-on-rez stuff
1451 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) 1500 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1452 { 1501 {
1453 tmpTempOnRezMS = Util.EnvironmentTickCount(); 1502 tmpMS = Util.EnvironmentTickCount();
1454 m_cleaningTemps = true; 1503 m_cleaningTemps = true;
1455 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); 1504 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1456 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS); 1505 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS);
1457 } 1506 }
1458 1507
1459 if (Frame % m_update_events == 0) 1508 if (Frame % m_update_events == 0)
1460 { 1509 {
1461 evMS = Util.EnvironmentTickCount(); 1510 tmpMS = Util.EnvironmentTickCount();
1462 UpdateEvents(); 1511 UpdateEvents();
1463 eventMS = Util.EnvironmentTickCountSubtract(evMS); 1512 eventMS = Util.EnvironmentTickCountSubtract(tmpMS);
1464 } 1513 }
1465 1514
1466 if (Frame % m_update_backup == 0) 1515 if (Frame % m_update_backup == 0)
1467 { 1516 {
1468 backMS = Util.EnvironmentTickCount(); 1517 tmpMS = Util.EnvironmentTickCount();
1469 UpdateStorageBackup(); 1518 UpdateStorageBackup();
1470 backupMS = Util.EnvironmentTickCountSubtract(backMS); 1519 backupMS = Util.EnvironmentTickCountSubtract(tmpMS);
1471 }
1472
1473 if (Frame % m_update_terrain == 0)
1474 {
1475 terMS = Util.EnvironmentTickCount();
1476 UpdateTerrain();
1477 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1478 } 1520 }
1479 1521
1480 //if (Frame % m_update_land == 0) 1522 //if (Frame % m_update_land == 0)
@@ -1483,29 +1525,6 @@ namespace OpenSim.Region.Framework.Scenes
1483 // UpdateLand(); 1525 // UpdateLand();
1484 // landMS = Util.EnvironmentTickCountSubtract(ldMS); 1526 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1485 //} 1527 //}
1486
1487 // frameMS = Util.EnvironmentTickCountSubtract(maintc);
1488 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1489
1490 // if (Frame%m_update_avatars == 0)
1491 // UpdateInWorldTime();
1492 StatsReporter.AddPhysicsFPS(physicsFPS);
1493 StatsReporter.AddTimeDilation(TimeDilation);
1494 StatsReporter.AddFPS(1);
1495 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1496 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1497 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1498 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1499
1500 // frameMS currently records work frame times, not total frame times (work + any required sleep to
1501 // reach min frame time.
1502 // StatsReporter.addFrameMS(frameMS);
1503
1504 StatsReporter.addAgentMS(agentMS);
1505 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1506 StatsReporter.addOtherMS(otherMS);
1507 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1508 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1509 1528
1510 if (LoginsDisabled && Frame == 20) 1529 if (LoginsDisabled && Frame == 20)
1511 { 1530 {
@@ -1526,11 +1545,11 @@ namespace OpenSim.Region.Framework.Scenes
1526 LoginLock = false; 1545 LoginLock = false;
1527 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); 1546 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
1528 } 1547 }
1529 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1530 1548
1531 // For RegionReady lockouts 1549 // For RegionReady lockouts
1532 if(LoginLock == false) 1550 if (!LoginLock)
1533 { 1551 {
1552 m_log.InfoFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1534 LoginsDisabled = false; 1553 LoginsDisabled = false;
1535 } 1554 }
1536 1555
@@ -1556,23 +1575,36 @@ namespace OpenSim.Region.Framework.Scenes
1556 1575
1557 previousFrameTick = m_lastFrameTick; 1576 previousFrameTick = m_lastFrameTick;
1558 m_lastFrameTick = Util.EnvironmentTickCount(); 1577 m_lastFrameTick = Util.EnvironmentTickCount();
1559 maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, framestart); 1578 tmpMS = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
1560 maintc = (int)(MinFrameTime * 1000) - maintc; 1579 tmpMS = (int)(MinFrameTime * 1000) - tmpMS;
1561 1580
1562 m_firstHeartbeat = false; 1581 m_firstHeartbeat = false;
1563 1582
1583 if (tmpMS > 0)
1584 {
1585 Thread.Sleep(tmpMS);
1586 spareMS += tmpMS;
1587 }
1588
1589 frameMS = Util.EnvironmentTickCountSubtract(maintc);
1590 maintc = Util.EnvironmentTickCount();
1564 1591
1565 sleepMS = Util.EnvironmentTickCount(); 1592 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1566 1593
1567 if (maintc > 0) 1594 // if (Frame%m_update_avatars == 0)
1568 Thread.Sleep(maintc); 1595 // UpdateInWorldTime();
1596 StatsReporter.AddPhysicsFPS(physicsFPS);
1597 StatsReporter.AddTimeDilation(TimeDilation);
1598 StatsReporter.AddFPS(1);
1569 1599
1570 sleepMS = Util.EnvironmentTickCountSubtract(sleepMS);
1571 frameMS = Util.EnvironmentTickCountSubtract(framestart);
1572 StatsReporter.addSleepMS(sleepMS);
1573 StatsReporter.addFrameMS(frameMS); 1600 StatsReporter.addFrameMS(frameMS);
1574 1601 StatsReporter.addAgentMS(agentMS);
1575 // Optionally warn if a frame takes double the amount of time that it should. 1602 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1603 StatsReporter.addOtherMS(otherMS);
1604 StatsReporter.AddSpareMS(spareMS);
1605 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1606
1607 // Optionally warn if a frame takes double the amount of time that it should.
1576 if (DebugUpdates 1608 if (DebugUpdates
1577 && Util.EnvironmentTickCountSubtract( 1609 && Util.EnvironmentTickCountSubtract(
1578 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) 1610 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
@@ -1759,14 +1791,14 @@ namespace OpenSim.Region.Framework.Scenes
1759 1791
1760 public void StoreWindlightProfile(RegionLightShareData wl) 1792 public void StoreWindlightProfile(RegionLightShareData wl)
1761 { 1793 {
1762 m_regInfo.WindlightSettings = wl; 1794 RegionInfo.WindlightSettings = wl;
1763 SimulationDataService.StoreRegionWindlightSettings(wl); 1795 SimulationDataService.StoreRegionWindlightSettings(wl);
1764 m_eventManager.TriggerOnSaveNewWindlightProfile(); 1796 m_eventManager.TriggerOnSaveNewWindlightProfile();
1765 } 1797 }
1766 1798
1767 public void LoadWindlightProfile() 1799 public void LoadWindlightProfile()
1768 { 1800 {
1769 m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID); 1801 RegionInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID);
1770 m_eventManager.TriggerOnSaveNewWindlightProfile(); 1802 m_eventManager.TriggerOnSaveNewWindlightProfile();
1771 } 1803 }
1772 1804
@@ -2085,9 +2117,8 @@ namespace OpenSim.Region.Framework.Scenes
2085 sceneObject.SetGroup(groupID, null); 2117 sceneObject.SetGroup(groupID, null);
2086 } 2118 }
2087 2119
2088 IUserManagement uman = RequestModuleInterface<IUserManagement>(); 2120 if (UserManagementModule != null)
2089 if (uman != null) 2121 sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID);
2090 sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
2091 2122
2092 sceneObject.ScheduleGroupForFullUpdate(); 2123 sceneObject.ScheduleGroupForFullUpdate();
2093 2124
@@ -2252,13 +2283,30 @@ namespace OpenSim.Region.Framework.Scenes
2252 /// <summary> 2283 /// <summary>
2253 /// Synchronously delete the given object from the scene. 2284 /// Synchronously delete the given object from the scene.
2254 /// </summary> 2285 /// </summary>
2286 /// <remarks>
2287 /// Scripts are also removed.
2288 /// </remarks>
2255 /// <param name="group">Object Id</param> 2289 /// <param name="group">Object Id</param>
2256 /// <param name="silent">Suppress broadcasting changes to other clients.</param> 2290 /// <param name="silent">Suppress broadcasting changes to other clients.</param>
2257 public void DeleteSceneObject(SceneObjectGroup group, bool silent) 2291 public void DeleteSceneObject(SceneObjectGroup group, bool silent)
2292 {
2293 DeleteSceneObject(group, silent, true);
2294 }
2295
2296 /// <summary>
2297 /// Synchronously delete the given object from the scene.
2298 /// </summary>
2299 /// <param name="group">Object Id</param>
2300 /// <param name="silent">Suppress broadcasting changes to other clients.</param>
2301 /// <param name="removeScripts">If true, then scripts are removed. If false, then they are only stopped.</para>
2302 public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
2258 { 2303 {
2259// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); 2304// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
2260 2305
2261 group.RemoveScriptInstances(true); 2306 if (removeScripts)
2307 group.RemoveScriptInstances(true);
2308 else
2309 group.StopScriptInstances();
2262 2310
2263 SceneObjectPart[] partList = group.Parts; 2311 SceneObjectPart[] partList = group.Parts;
2264 2312
@@ -2308,7 +2356,7 @@ namespace OpenSim.Region.Framework.Scenes
2308 ForceSceneObjectBackup(so); 2356 ForceSceneObjectBackup(so);
2309 2357
2310 so.DetachFromBackup(); 2358 so.DetachFromBackup();
2311 SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID); 2359 SimulationDataService.RemoveObject(so.UUID, RegionInfo.RegionID);
2312 } 2360 }
2313 2361
2314 // We need to keep track of this state in case this group is still queued for further backup. 2362 // We need to keep track of this state in case this group is still queued for further backup.
@@ -2365,8 +2413,8 @@ namespace OpenSim.Region.Framework.Scenes
2365 return; 2413 return;
2366 } 2414 }
2367 2415
2368 if (m_teleportModule != null) 2416 if (EntityTransferModule != null)
2369 m_teleportModule.Cross(grp, attemptedPosition, silent); 2417 EntityTransferModule.Cross(grp, attemptedPosition, silent);
2370 } 2418 }
2371 2419
2372 public Border GetCrossedBorder(Vector3 position, Cardinals gridline) 2420 public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
@@ -2566,7 +2614,16 @@ namespace OpenSim.Region.Framework.Scenes
2566 } 2614 }
2567 catch (Exception e) 2615 catch (Exception e)
2568 { 2616 {
2569 m_log.WarnFormat("[SCENE]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace); 2617 m_log.WarnFormat("[INTERREGION]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace);
2618 return false;
2619 }
2620
2621 // If the user is banned, we won't let any of their objects
2622 // enter. Period.
2623 //
2624 if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID, 36))
2625 {
2626 m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID);
2570 return false; 2627 return false;
2571 } 2628 }
2572 2629
@@ -2577,32 +2634,30 @@ namespace OpenSim.Region.Framework.Scenes
2577 2634
2578 if (!AddSceneObject(newObject)) 2635 if (!AddSceneObject(newObject))
2579 { 2636 {
2580 m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName); 2637 m_log.DebugFormat(
2638 "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName);
2581 return false; 2639 return false;
2582 } 2640 }
2583 2641
2584 // For attachments, we need to wait until the agent is root
2585 // before we restart the scripts, or else some functions won't work.
2586 if (!newObject.IsAttachment) 2642 if (!newObject.IsAttachment)
2587 { 2643 {
2588 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); 2644 // FIXME: It would be better to never add the scene object at all rather than add it and then delete
2589 newObject.ResumeScripts(); 2645 // it
2590 } 2646 if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition))
2591 else
2592 {
2593 ScenePresence sp;
2594 if (TryGetScenePresence(newObject.OwnerID, out sp))
2595 { 2647 {
2596 // If the scene presence is here and already a root 2648 // Deny non attachments based on parcel settings
2597 // agent, we came from a ;egacy region. Start the scripts 2649 //
2598 // here as they used to start. 2650 m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
2599 // TODO: Remove in 0.7.3 2651
2600 if (!sp.IsChildAgent) 2652 DeleteSceneObject(newObject, false);
2601 { 2653
2602 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); 2654 return false;
2603 newObject.ResumeScripts();
2604 }
2605 } 2655 }
2656
2657 // For attachments, we need to wait until the agent is root
2658 // before we restart the scripts, or else some functions won't work.
2659 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2660 newObject.ResumeScripts();
2606 } 2661 }
2607 2662
2608 // Do this as late as possible so that listeners have full access to the incoming object 2663 // Do this as late as possible so that listeners have full access to the incoming object
@@ -2612,28 +2667,6 @@ namespace OpenSim.Region.Framework.Scenes
2612 } 2667 }
2613 2668
2614 /// <summary> 2669 /// <summary>
2615 /// Attachment rezzing
2616 /// </summary>
2617 /// <param name="userID">Agent Unique ID</param>
2618 /// <param name="itemID">Object ID</param>
2619 /// <returns>False</returns>
2620 public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
2621 {
2622 m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
2623
2624 // Commented out since this is as yet unused and is arguably not the appropriate place to do this, as
2625 // attachments are being rezzed elsewhere in AddNewClient()
2626// ScenePresence sp = GetScenePresence(userID);
2627// if (sp != null && AttachmentsModule != null)
2628// {
2629// uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
2630// AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
2631// }
2632
2633 return false;
2634 }
2635
2636 /// <summary>
2637 /// Adds a Scene Object group to the Scene. 2670 /// Adds a Scene Object group to the Scene.
2638 /// Verifies that the creator of the object is not banned from the simulator. 2671 /// Verifies that the creator of the object is not banned from the simulator.
2639 /// Checks if the item is an Attachment 2672 /// Checks if the item is an Attachment
@@ -2652,15 +2685,13 @@ namespace OpenSim.Region.Framework.Scenes
2652 // enter. Period. 2685 // enter. Period.
2653 // 2686 //
2654 int flags = GetUserFlags(sceneObject.OwnerID); 2687 int flags = GetUserFlags(sceneObject.OwnerID);
2655 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags)) 2688 if (RegionInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2656 { 2689 {
2657 m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID); 2690 m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID);
2658 2691
2659 return false; 2692 return false;
2660 } 2693 }
2661 2694
2662 sceneObject.SetScene(this);
2663
2664 // Force allocation of new LocalId 2695 // Force allocation of new LocalId
2665 // 2696 //
2666 SceneObjectPart[] parts = sceneObject.Parts; 2697 SceneObjectPart[] parts = sceneObject.Parts;
@@ -2686,10 +2717,10 @@ namespace OpenSim.Region.Framework.Scenes
2686 { 2717 {
2687 SceneObjectGroup grp = sceneObject; 2718 SceneObjectGroup grp = sceneObject;
2688 2719
2689 m_log.DebugFormat( 2720// m_log.DebugFormat(
2690 "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); 2721// "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID);
2691 m_log.DebugFormat( 2722// m_log.DebugFormat(
2692 "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); 2723// "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
2693 2724
2694 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2725 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2695 2726
@@ -2716,18 +2747,6 @@ namespace OpenSim.Region.Framework.Scenes
2716 return false; 2747 return false;
2717 } 2748 }
2718 AddRestoredSceneObject(sceneObject, true, false); 2749 AddRestoredSceneObject(sceneObject, true, false);
2719
2720 if (!Permissions.CanObjectEntry(sceneObject.UUID,
2721 true, sceneObject.AbsolutePosition))
2722 {
2723 // Deny non attachments based on parcel settings
2724 //
2725 m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
2726
2727 DeleteSceneObject(sceneObject, false);
2728
2729 return false;
2730 }
2731 } 2750 }
2732 2751
2733 return true; 2752 return true;
@@ -2785,7 +2804,8 @@ namespace OpenSim.Region.Framework.Scenes
2785 if (sp == null) 2804 if (sp == null)
2786 { 2805 {
2787 m_log.DebugFormat( 2806 m_log.DebugFormat(
2788 "[SCENE]: Adding new child scene presence {0} to scene {1} at pos {2}", client.Name, RegionInfo.RegionName, client.StartPos); 2807 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2808 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2789 2809
2790 m_clientManager.Add(client); 2810 m_clientManager.Add(client);
2791 SubscribeToClientEvents(client); 2811 SubscribeToClientEvents(client);
@@ -2845,14 +2865,13 @@ namespace OpenSim.Region.Framework.Scenes
2845 /// <param name="aCircuit"></param> 2865 /// <param name="aCircuit"></param>
2846 private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit) 2866 private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit)
2847 { 2867 {
2848 IUserManagement uMan = RequestModuleInterface<IUserManagement>(); 2868 if (UserManagementModule != null)
2849 if (uMan != null)
2850 { 2869 {
2851 string first = aCircuit.firstname, last = aCircuit.lastname; 2870 string first = aCircuit.firstname, last = aCircuit.lastname;
2852 2871
2853 if (sp.PresenceType == PresenceType.Npc) 2872 if (sp.PresenceType == PresenceType.Npc)
2854 { 2873 {
2855 uMan.AddUser(aCircuit.AgentID, first, last); 2874 UserManagementModule.AddUser(aCircuit.AgentID, first, last);
2856 } 2875 }
2857 else 2876 else
2858 { 2877 {
@@ -2871,7 +2890,7 @@ namespace OpenSim.Region.Framework.Scenes
2871 } 2890 }
2872 } 2891 }
2873 2892
2874 uMan.AddUser(aCircuit.AgentID, first, last, homeURL); 2893 UserManagementModule.AddUser(aCircuit.AgentID, first, last, homeURL);
2875 } 2894 }
2876 } 2895 }
2877 } 2896 }
@@ -3209,8 +3228,10 @@ namespace OpenSim.Region.Framework.Scenes
3209 /// <param name="client">The IClientAPI for the client</param> 3228 /// <param name="client">The IClientAPI for the client</param>
3210 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client) 3229 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
3211 { 3230 {
3212 if (m_teleportModule != null) 3231 if (EntityTransferModule != null)
3213 return m_teleportModule.TeleportHome(agentId, client); 3232 {
3233 EntityTransferModule.TeleportHome(agentId, client);
3234 }
3214 else 3235 else
3215 { 3236 {
3216 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3237 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
@@ -3372,65 +3393,82 @@ namespace OpenSim.Region.Framework.Scenes
3372// CheckHeartbeat(); 3393// CheckHeartbeat();
3373 bool isChildAgent = false; 3394 bool isChildAgent = false;
3374 ScenePresence avatar = GetScenePresence(agentID); 3395 ScenePresence avatar = GetScenePresence(agentID);
3375 if (avatar != null) 3396
3397 if (avatar == null)
3398 {
3399 m_log.WarnFormat(
3400 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3401
3402 return;
3403 }
3404
3405 try
3376 { 3406 {
3377 isChildAgent = avatar.IsChildAgent; 3407 isChildAgent = avatar.IsChildAgent;
3378 3408
3379 if (avatar.ParentID != 0) 3409 m_log.DebugFormat(
3410 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3411 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3412
3413 // Don't do this to root agents, it's not nice for the viewer
3414 if (closeChildAgents && isChildAgent)
3380 { 3415 {
3381 avatar.StandUp(); 3416 // Tell a single agent to disconnect from the region.
3417 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3418 if (eq != null)
3419 {
3420 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3421 }
3422 else
3423 {
3424 avatar.ControllingClient.SendShutdownConnectionNotice();
3425 }
3382 } 3426 }
3383 3427
3384 try 3428 // Only applies to root agents.
3429 if (avatar.ParentID != 0)
3385 { 3430 {
3386 m_log.DebugFormat( 3431 avatar.StandUp();
3387 "[SCENE]: Removing {0} agent {1} from region {2}", 3432 }
3388 (isChildAgent ? "child" : "root"), agentID, RegionInfo.RegionName);
3389 3433
3390 m_sceneGraph.removeUserCount(!isChildAgent); 3434 m_sceneGraph.removeUserCount(!isChildAgent);
3391 3435
3392 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3436 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3393 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3437 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3394 if (closeChildAgents && CapsModule != null) 3438 if (closeChildAgents && CapsModule != null)
3395 CapsModule.RemoveCaps(agentID); 3439 CapsModule.RemoveCaps(agentID);
3396 3440
3397 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever 3441 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3398 // this method is doing is HORRIBLE!!! 3442 // this method is doing is HORRIBLE!!!
3399 avatar.Scene.NeedSceneCacheClear(avatar.UUID); 3443 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3400 3444
3401 if (closeChildAgents && !avatar.IsChildAgent) 3445 if (closeChildAgents && !isChildAgent)
3402 {
3403 List<ulong> regions = avatar.KnownRegionHandles;
3404 regions.Remove(RegionInfo.RegionHandle);
3405 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3406 }
3407 m_log.Debug("[Scene] Beginning ClientClosed");
3408 m_eventManager.TriggerClientClosed(agentID, this);
3409 m_log.Debug("[Scene] Finished ClientClosed");
3410 }
3411 catch (NullReferenceException)
3412 { 3446 {
3413 // We don't know which count to remove it from 3447 List<ulong> regions = avatar.KnownRegionHandles;
3414 // Avatar is already disposed :/ 3448 regions.Remove(RegionInfo.RegionHandle);
3449 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3415 } 3450 }
3416 3451
3417 try 3452 m_eventManager.TriggerClientClosed(agentID, this);
3453 m_eventManager.TriggerOnRemovePresence(agentID);
3454
3455 if (!isChildAgent)
3418 { 3456 {
3419 m_eventManager.TriggerOnRemovePresence(agentID); 3457 if (AttachmentsModule != null)
3420
3421 if (AttachmentsModule != null && !isChildAgent && avatar.PresenceType != PresenceType.Npc)
3422 { 3458 {
3423 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
3424 // Don't save attachments for HG visitors, it 3459 // Don't save attachments for HG visitors, it
3425 // messes up their inventory. When a HG visitor logs 3460 // messes up their inventory. When a HG visitor logs
3426 // out on a foreign grid, their attachments will be 3461 // out on a foreign grid, their attachments will be
3427 // reloaded in the state they were in when they left 3462 // reloaded in the state they were in when they left
3428 // the home grid. This is best anyway as the visited 3463 // the home grid. This is best anyway as the visited
3429 // grid may use an incompatible script engine. 3464 // grid may use an incompatible script engine.
3430 if (uMan == null || uMan.IsLocalGridUser(avatar.UUID)) 3465 bool saveChanged
3431 AttachmentsModule.SaveChangedAttachments(avatar, false); 3466 = avatar.PresenceType != PresenceType.Npc
3467 && (UserManagementModule == null || UserManagementModule.IsLocalGridUser(avatar.UUID));
3468
3469 AttachmentsModule.DeRezAttachments(avatar, saveChanged, false);
3432 } 3470 }
3433 3471
3434 ForEachClient( 3472 ForEachClient(
3435 delegate(IClientAPI client) 3473 delegate(IClientAPI client)
3436 { 3474 {
@@ -3438,43 +3476,35 @@ namespace OpenSim.Region.Framework.Scenes
3438 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3476 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
3439 catch (NullReferenceException) { } 3477 catch (NullReferenceException) { }
3440 }); 3478 });
3441
3442 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
3443 if (agentTransactions != null)
3444 {
3445 agentTransactions.RemoveAgentAssetTransactions(agentID);
3446 }
3447 }
3448 finally
3449 {
3450 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3451 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3452 // the same cleanup exception continually.
3453 // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE
3454 // since this would hide the underlying failure and other associated problems.
3455 m_sceneGraph.RemoveScenePresence(agentID);
3456 m_clientManager.Remove(agentID);
3457 } 3479 }
3458 3480
3459 try 3481 // It's possible for child agents to have transactions if changes are being made cross-border.
3460 { 3482 if (AgentTransactionsModule != null)
3461 avatar.Close(); 3483 AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3462 } 3484
3463 catch (NullReferenceException) 3485 avatar.Close();
3464 { 3486
3465 //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
3466 }
3467 catch (Exception e)
3468 {
3469 m_log.ErrorFormat("[SCENE] Scene.cs:RemoveClient exception {0}{1}", e.Message, e.StackTrace);
3470 }
3471 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3472 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3487 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3473// CleanDroppedAttachments();
3474 m_log.Debug("[Scene] The avatar has left the building"); 3488 m_log.Debug("[Scene] The avatar has left the building");
3475 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3476 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3477 } 3489 }
3490 catch (Exception e)
3491 {
3492 m_log.Error(
3493 string.Format("[SCENE]: Exception removing {0} from {1}, ", avatar.Name, RegionInfo.RegionName), e);
3494 }
3495 finally
3496 {
3497 // Always clean these structures up so that any failure above doesn't cause them to remain in the
3498 // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3499 // the same cleanup exception continually.
3500 // TODO: This should probably extend to the whole method, but we don't want to also catch the NRE
3501 // since this would hide the underlying failure and other associated problems.
3502 m_sceneGraph.RemoveScenePresence(agentID);
3503 m_clientManager.Remove(agentID);
3504 }
3505
3506 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3507 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3478 } 3508 }
3479 3509
3480 /// <summary> 3510 /// <summary>
@@ -3556,7 +3586,7 @@ namespace OpenSim.Region.Framework.Scenes
3556 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) 3586 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup)
3557 { 3587 {
3558 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || 3588 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
3559 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); 3589 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
3560 bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0); 3590 bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0);
3561 bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0); 3591 bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0);
3562 3592
@@ -3572,8 +3602,17 @@ namespace OpenSim.Region.Framework.Scenes
3572 // Don't disable this log message - it's too helpful 3602 // Don't disable this log message - it's too helpful
3573 m_log.DebugFormat( 3603 m_log.DebugFormat(
3574 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", 3604 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})",
3575 RegionInfo.RegionName, (agent.child ? "child" : "root"),agent.firstname, agent.lastname, 3605 RegionInfo.RegionName,
3576 agent.AgentID, agent.circuitcode, agent.IPAddress, agent.Viewer, ((TPFlags)teleportFlags).ToString(), agent.startpos); 3606 (agent.child ? "child" : "root"),
3607 agent.firstname,
3608 agent.lastname,
3609 agent.AgentID,
3610 agent.circuitcode,
3611 agent.IPAddress,
3612 agent.Viewer,
3613 ((TPFlags)teleportFlags).ToString(),
3614 agent.startpos
3615 );
3577 3616
3578 if (LoginsDisabled) 3617 if (LoginsDisabled)
3579 { 3618 {
@@ -3581,6 +3620,50 @@ namespace OpenSim.Region.Framework.Scenes
3581 return false; 3620 return false;
3582 } 3621 }
3583 3622
3623 //Check if the viewer is banned or in the viewer access list
3624 //We check if the substring is listed for higher flexebility
3625 bool ViewerDenied = true;
3626
3627 //Check if the specific viewer is listed in the allowed viewer list
3628 if (m_AllowedViewers.Count > 0)
3629 {
3630 foreach (string viewer in m_AllowedViewers)
3631 {
3632 if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower())
3633 {
3634 ViewerDenied = false;
3635 break;
3636 }
3637 }
3638 }
3639 else
3640 {
3641 ViewerDenied = false;
3642 }
3643
3644 //Check if the viewer is in the banned list
3645 if (m_BannedViewers.Count > 0)
3646 {
3647 foreach (string viewer in m_BannedViewers)
3648 {
3649 if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower())
3650 {
3651 ViewerDenied = true;
3652 break;
3653 }
3654 }
3655 }
3656
3657 if (ViewerDenied)
3658 {
3659 m_log.DebugFormat(
3660 "[SCENE]: Access denied for {0} {1} using {2}",
3661 agent.firstname, agent.lastname, agent.Viewer);
3662 reason = "Access denied, your viewer is banned by the region owner";
3663 return false;
3664 }
3665
3666
3584 ScenePresence sp = GetScenePresence(agent.AgentID); 3667 ScenePresence sp = GetScenePresence(agent.AgentID);
3585 3668
3586 if (sp != null && !sp.IsChildAgent) 3669 if (sp != null && !sp.IsChildAgent)
@@ -3588,7 +3671,10 @@ namespace OpenSim.Region.Framework.Scenes
3588 // We have a zombie from a crashed session. 3671 // We have a zombie from a crashed session.
3589 // Or the same user is trying to be root twice here, won't work. 3672 // Or the same user is trying to be root twice here, won't work.
3590 // Kill it. 3673 // Kill it.
3591 m_log.DebugFormat("[SCENE]: Zombie scene presence detected for {0} in {1}", agent.AgentID, RegionInfo.RegionName); 3674 m_log.DebugFormat(
3675 "[SCENE]: Zombie scene presence detected for {0} {1} in {2}",
3676 sp.Name, sp.UUID, RegionInfo.RegionName);
3677
3592 sp.ControllingClient.Close(); 3678 sp.ControllingClient.Close();
3593 sp = null; 3679 sp = null;
3594 } 3680 }
@@ -3615,8 +3701,7 @@ namespace OpenSim.Region.Framework.Scenes
3615 { 3701 {
3616 if (!VerifyUserPresence(agent, out reason)) 3702 if (!VerifyUserPresence(agent, out reason))
3617 return false; 3703 return false;
3618 } 3704 } catch (Exception e)
3619 catch (Exception e)
3620 { 3705 {
3621 m_log.ErrorFormat( 3706 m_log.ErrorFormat(
3622 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3707 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
@@ -3651,8 +3736,7 @@ namespace OpenSim.Region.Framework.Scenes
3651 CapsModule.SetAgentCapsSeeds(agent); 3736 CapsModule.SetAgentCapsSeeds(agent);
3652 CapsModule.CreateCaps(agent.AgentID); 3737 CapsModule.CreateCaps(agent.AgentID);
3653 } 3738 }
3654 } 3739 } else
3655 else
3656 { 3740 {
3657 // Let the SP know how we got here. This has a lot of interesting 3741 // Let the SP know how we got here. This has a lot of interesting
3658 // uses down the line. 3742 // uses down the line.
@@ -3675,7 +3759,7 @@ namespace OpenSim.Region.Framework.Scenes
3675 agent.teleportFlags = teleportFlags; 3759 agent.teleportFlags = teleportFlags;
3676 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3760 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
3677 3761
3678 if (vialogin) 3762 if (vialogin)
3679 { 3763 {
3680// CleanDroppedAttachments(); 3764// CleanDroppedAttachments();
3681 3765
@@ -3716,8 +3800,7 @@ namespace OpenSim.Region.Framework.Scenes
3716 agent.startpos.Z = 720; 3800 agent.startpos.Z = 720;
3717 } 3801 }
3718 } 3802 }
3719 } 3803 } else
3720 else
3721 { 3804 {
3722 if (agent.startpos.X > EastBorders[0].BorderLine.Z) 3805 if (agent.startpos.X > EastBorders[0].BorderLine.Z)
3723 { 3806 {
@@ -3743,10 +3826,19 @@ namespace OpenSim.Region.Framework.Scenes
3743 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); 3826 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject);
3744 // Can have multiple SpawnPoints 3827 // Can have multiple SpawnPoints
3745 List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); 3828 List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints();
3746 if ( spawnpoints.Count > 1) 3829 if (spawnpoints.Count > 1)
3747 { 3830 {
3748 // We have multiple SpawnPoints, Route the agent to a random one 3831 // We have multiple SpawnPoints, Route the agent to a random or sequential one
3749 agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count)].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 3832 if (SpawnPointRouting == "random")
3833 agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation(
3834 telehub.AbsolutePosition,
3835 telehub.GroupRotation
3836 );
3837 else
3838 agent.startpos = spawnpoints[SpawnPoint()].GetLocation(
3839 telehub.AbsolutePosition,
3840 telehub.GroupRotation
3841 );
3750 } 3842 }
3751 else 3843 else
3752 { 3844 {
@@ -3869,9 +3961,9 @@ namespace OpenSim.Region.Framework.Scenes
3869 } 3961 }
3870 } 3962 }
3871 3963
3872 if (m_regInfo.EstateSettings != null) 3964 if (RegionInfo.EstateSettings != null)
3873 { 3965 {
3874 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0)) 3966 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, 0))
3875 { 3967 {
3876 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3968 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3877 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3969 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3903,7 +3995,7 @@ namespace OpenSim.Region.Framework.Scenes
3903 } 3995 }
3904 3996
3905 bool groupAccess = false; 3997 bool groupAccess = false;
3906 UUID[] estateGroups = m_regInfo.EstateSettings.EstateGroups; 3998 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups;
3907 3999
3908 if (estateGroups != null) 4000 if (estateGroups != null)
3909 { 4001 {
@@ -3921,8 +4013,8 @@ namespace OpenSim.Region.Framework.Scenes
3921 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); 4013 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
3922 } 4014 }
3923 4015
3924 if (!m_regInfo.EstateSettings.PublicAccess && 4016 if (!RegionInfo.EstateSettings.PublicAccess &&
3925 !m_regInfo.EstateSettings.HasAccess(agent.AgentID) && 4017 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) &&
3926 !groupAccess) 4018 !groupAccess)
3927 { 4019 {
3928 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", 4020 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
@@ -3983,41 +4075,41 @@ namespace OpenSim.Region.Framework.Scenes
3983 return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc); 4075 return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc);
3984 } 4076 }
3985 4077
3986 /// <summary> 4078// /// <summary>
3987 /// The Grid has requested that we log-off a user. Log them off. 4079// /// The Grid has requested that we log-off a user. Log them off.
3988 /// </summary> 4080// /// </summary>
3989 /// <param name="AvatarID">Unique ID of the avatar to log-off</param> 4081// /// <param name="AvatarID">Unique ID of the avatar to log-off</param>
3990 /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param> 4082// /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param>
3991 /// <param name="message">message to display to the user. Reason for being logged off</param> 4083// /// <param name="message">message to display to the user. Reason for being logged off</param>
3992 public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) 4084// public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
3993 { 4085// {
3994 ScenePresence loggingOffUser = GetScenePresence(AvatarID); 4086// ScenePresence loggingOffUser = GetScenePresence(AvatarID);
3995 if (loggingOffUser != null) 4087// if (loggingOffUser != null)
3996 { 4088// {
3997 UUID localRegionSecret = UUID.Zero; 4089// UUID localRegionSecret = UUID.Zero;
3998 bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret); 4090// bool parsedsecret = UUID.TryParse(RegionInfo.regionSecret, out localRegionSecret);
3999 4091//
4000 // Region Secret is used here in case a new sessionid overwrites an old one on the user server. 4092// // Region Secret is used here in case a new sessionid overwrites an old one on the user server.
4001 // Will update the user server in a few revisions to use it. 4093// // Will update the user server in a few revisions to use it.
4002 4094//
4003 if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) 4095// if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
4004 { 4096// {
4005 m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); 4097// m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles);
4006 loggingOffUser.ControllingClient.Kick(message); 4098// loggingOffUser.ControllingClient.Kick(message);
4007 // Give them a second to receive the message! 4099// // Give them a second to receive the message!
4008 Thread.Sleep(1000); 4100// Thread.Sleep(1000);
4009 loggingOffUser.ControllingClient.Close(); 4101// loggingOffUser.ControllingClient.Close();
4010 } 4102// }
4011 else 4103// else
4012 { 4104// {
4013 m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate"); 4105// m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate");
4014 } 4106// }
4015 } 4107// }
4016 else 4108// else
4017 { 4109// {
4018 m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString()); 4110// m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString());
4019 } 4111// }
4020 } 4112// }
4021 4113
4022 /// <summary> 4114 /// <summary>
4023 /// Triggered when an agent crosses into this sim. Also happens on initial login. 4115 /// Triggered when an agent crosses into this sim. Also happens on initial login.
@@ -4070,21 +4162,19 @@ namespace OpenSim.Region.Framework.Scenes
4070 return false; 4162 return false;
4071 } 4163 }
4072 4164
4165 // TODO: This check should probably be in QueryAccess().
4073 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 4166 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
4074 if (nearestParcel == null) 4167 if (nearestParcel == null)
4075 { 4168 {
4076 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: no allowed parcel", cAgentData.AgentID); 4169 m_log.DebugFormat(
4077 return false; 4170 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel",
4078 } 4171 cAgentData.AgentID, RegionInfo.RegionName);
4079
4080 int num = m_sceneGraph.GetNumberOfScenePresences();
4081 4172
4082 if (num >= RegionInfo.RegionSettings.AgentLimit) 4173 return false;
4083 {
4084 if (!Permissions.IsAdministrator(cAgentData.AgentID))
4085 return false;
4086 } 4174 }
4087 4175
4176 // We have to wait until the viewer contacts this region after receiving EAC.
4177 // That calls AddNewClient, which finally creates the ScenePresence
4088 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4178 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4089 4179
4090 if (childAgentUpdate != null) 4180 if (childAgentUpdate != null)
@@ -4128,14 +4218,28 @@ namespace OpenSim.Region.Framework.Scenes
4128 return false; 4218 return false;
4129 } 4219 }
4130 4220
4221 /// <summary>
4222 /// Poll until the requested ScenePresence appears or we timeout.
4223 /// </summary>
4224 /// <returns>The scene presence is found, else null.</returns>
4225 /// <param name='agentID'></param>
4131 protected virtual ScenePresence WaitGetScenePresence(UUID agentID) 4226 protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
4132 { 4227 {
4133 int ntimes = 10; 4228 int ntimes = 10;
4134 ScenePresence childAgentUpdate = null; 4229 ScenePresence sp = null;
4135 while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0)) 4230 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
4136 Thread.Sleep(1000); 4231 Thread.Sleep(1000);
4137 return childAgentUpdate;
4138 4232
4233 if (sp == null)
4234 m_log.WarnFormat(
4235 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4236 agentID, RegionInfo.RegionName);
4237// else
4238// m_log.DebugFormat(
4239// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
4240// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes);
4241
4242 return sp;
4139 } 4243 }
4140 4244
4141 public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) 4245 public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
@@ -4173,33 +4277,7 @@ namespace OpenSim.Region.Framework.Scenes
4173 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4277 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4174 if (presence != null) 4278 if (presence != null)
4175 { 4279 {
4176 // Nothing is removed here, so down count it as such 4280 presence.ControllingClient.Close();
4177 if (presence.IsChildAgent)
4178 {
4179 m_sceneGraph.removeUserCount(false);
4180 }
4181 else if (!childOnly)
4182 {
4183 m_sceneGraph.removeUserCount(true);
4184 }
4185
4186 // Don't do this to root agents on logout, it's not nice for the viewer
4187 if (presence.IsChildAgent)
4188 {
4189 // Tell a single agent to disconnect from the region.
4190 IEventQueue eq = RequestModuleInterface<IEventQueue>();
4191 if (eq != null)
4192 {
4193 eq.DisableSimulator(RegionInfo.RegionHandle, agentID);
4194 }
4195 else
4196 presence.ControllingClient.SendShutdownConnectionNotice();
4197 presence.ControllingClient.Close(false);
4198 }
4199 else if (!childOnly)
4200 {
4201 presence.ControllingClient.Close(true);
4202 }
4203 return true; 4281 return true;
4204 } 4282 }
4205 4283
@@ -4247,13 +4325,13 @@ namespace OpenSim.Region.Framework.Scenes
4247 ScenePresence sp = GetScenePresence(remoteClient.AgentId); 4325 ScenePresence sp = GetScenePresence(remoteClient.AgentId);
4248 if (sp != null) 4326 if (sp != null)
4249 { 4327 {
4250 uint regionX = m_regInfo.RegionLocX; 4328 uint regionX = RegionInfo.RegionLocX;
4251 uint regionY = m_regInfo.RegionLocY; 4329 uint regionY = RegionInfo.RegionLocY;
4252 4330
4253 Utils.LongToUInts(regionHandle, out regionX, out regionY); 4331 Utils.LongToUInts(regionHandle, out regionX, out regionY);
4254 4332
4255 int shiftx = (int) regionX - (int) m_regInfo.RegionLocX * (int)Constants.RegionSize; 4333 int shiftx = (int) regionX - (int) RegionInfo.RegionLocX * (int)Constants.RegionSize;
4256 int shifty = (int) regionY - (int) m_regInfo.RegionLocY * (int)Constants.RegionSize; 4334 int shifty = (int) regionY - (int) RegionInfo.RegionLocY * (int)Constants.RegionSize;
4257 4335
4258 position.X += shiftx; 4336 position.X += shiftx;
4259 position.Y += shifty; 4337 position.Y += shifty;
@@ -4276,7 +4354,7 @@ namespace OpenSim.Region.Framework.Scenes
4276 4354
4277 if (!result) 4355 if (!result)
4278 { 4356 {
4279 regionHandle = m_regInfo.RegionHandle; 4357 regionHandle = RegionInfo.RegionHandle;
4280 } 4358 }
4281 else 4359 else
4282 { 4360 {
@@ -4285,8 +4363,10 @@ namespace OpenSim.Region.Framework.Scenes
4285 position.Y -= shifty; 4363 position.Y -= shifty;
4286 } 4364 }
4287 4365
4288 if (m_teleportModule != null) 4366 if (EntityTransferModule != null)
4289 m_teleportModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); 4367 {
4368 EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
4369 }
4290 else 4370 else
4291 { 4371 {
4292 m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active"); 4372 m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
@@ -4297,8 +4377,10 @@ namespace OpenSim.Region.Framework.Scenes
4297 4377
4298 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) 4378 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
4299 { 4379 {
4300 if (m_teleportModule != null) 4380 if (EntityTransferModule != null)
4301 return m_teleportModule.Cross(agent, isFlying); 4381 {
4382 return EntityTransferModule.Cross(agent, isFlying);
4383 }
4302 else 4384 else
4303 { 4385 {
4304 m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule"); 4386 m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule");
@@ -4600,6 +4682,17 @@ namespace OpenSim.Region.Framework.Scenes
4600 } 4682 }
4601 4683
4602 /// <summary> 4684 /// <summary>
4685 /// Get all the scene object groups.
4686 /// </summary>
4687 /// <returns>
4688 /// The scene object groups. If the scene is empty then an empty list is returned.
4689 /// </returns>
4690 public List<SceneObjectGroup> GetSceneObjectGroups()
4691 {
4692 return m_sceneGraph.GetSceneObjectGroups();
4693 }
4694
4695 /// <summary>
4603 /// Get a group via its UUID 4696 /// Get a group via its UUID
4604 /// </summary> 4697 /// </summary>
4605 /// <param name="fullID"></param> 4698 /// <param name="fullID"></param>
@@ -4778,7 +4871,7 @@ namespace OpenSim.Region.Framework.Scenes
4778 4871
4779 public void DeleteFromStorage(UUID uuid) 4872 public void DeleteFromStorage(UUID uuid)
4780 { 4873 {
4781 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4874 SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID);
4782 } 4875 }
4783 4876
4784 public int GetHealth(out int flags, out string message) 4877 public int GetHealth(out int flags, out string message)
@@ -5259,7 +5352,7 @@ Environment.Exit(1);
5259 IEstateDataService estateDataService = EstateDataService; 5352 IEstateDataService estateDataService = EstateDataService;
5260 if (estateDataService != null) 5353 if (estateDataService != null)
5261 { 5354 {
5262 m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false); 5355 RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
5263 TriggerEstateSunUpdate(); 5356 TriggerEstateSunUpdate();
5264 } 5357 }
5265 } 5358 }
@@ -5446,29 +5539,58 @@ Environment.Exit(1);
5446 throw new Exception(error); 5539 throw new Exception(error);
5447 } 5540 }
5448 5541
5449 // This method is called across the simulation connector to 5542 /// <summary>
5450 // determine if a given agent is allowed in this region 5543 /// This method is called across the simulation connector to
5451 // AS A ROOT AGENT. Returning false here will prevent them 5544 /// determine if a given agent is allowed in this region
5452 // from logging into the region, teleporting into the region 5545 /// AS A ROOT AGENT
5453 // or corssing the broder walking, but will NOT prevent 5546 /// </summary>
5454 // child agent creation, thereby emulating the SL behavior. 5547 /// <remarks>
5548 /// Returning false here will prevent them
5549 /// from logging into the region, teleporting into the region
5550 /// or corssing the broder walking, but will NOT prevent
5551 /// child agent creation, thereby emulating the SL behavior.
5552 /// </remarks>
5553 /// <param name='agentID'></param>
5554 /// <param name='position'></param>
5555 /// <param name='reason'></param>
5556 /// <returns></returns>
5455 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5557 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5456 { 5558 {
5457 reason = "You are banned from the region"; 5559 reason = "You are banned from the region";
5458 5560
5561 if (EntityTransferModule.IsInTransit(agentID))
5562 {
5563 reason = "Agent is still in transit from this region";
5564
5565 m_log.WarnFormat(
5566 "[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit",
5567 agentID, RegionInfo.RegionName);
5568
5569 return false;
5570 }
5571
5459 if (Permissions.IsGod(agentID)) 5572 if (Permissions.IsGod(agentID))
5460 { 5573 {
5461 reason = String.Empty; 5574 reason = String.Empty;
5462 return true; 5575 return true;
5463 } 5576 }
5464 5577
5465 int num = m_sceneGraph.GetNumberOfScenePresences(); 5578 // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check.
5579 // However, the long term fix is to make sure root agent count is always accurate.
5580 m_sceneGraph.RecalculateStats();
5581
5582 int num = m_sceneGraph.GetRootAgentCount();
5466 5583
5467 if (num >= RegionInfo.RegionSettings.AgentLimit) 5584 if (num >= RegionInfo.RegionSettings.AgentLimit)
5468 { 5585 {
5469 if (!Permissions.IsAdministrator(agentID)) 5586 if (!Permissions.IsAdministrator(agentID))
5470 { 5587 {
5471 reason = "The region is full"; 5588 reason = "The region is full";
5589
5590 m_log.DebugFormat(
5591 "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}",
5592 agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit);
5593
5472 return false; 5594 return false;
5473 } 5595 }
5474 } 5596 }
@@ -5640,6 +5762,20 @@ Environment.Exit(1);
5640 } 5762 }
5641 } 5763 }
5642 5764
5765 // manage and select spawn points in sequence
5766 public int SpawnPoint()
5767 {
5768 int spawnpoints = RegionInfo.RegionSettings.SpawnPoints().Count;
5769
5770 if (spawnpoints == 0)
5771 return 0;
5772
5773 m_SpawnPoint++;
5774 if (m_SpawnPoint > spawnpoints)
5775 m_SpawnPoint = 1;
5776 return m_SpawnPoint - 1;
5777 }
5778
5643 private void HandleGcCollect(string module, string[] args) 5779 private void HandleGcCollect(string module, string[] args)
5644 { 5780 {
5645 GC.Collect(); 5781 GC.Collect();
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 9b8a3ae..e8134cd 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -51,6 +51,8 @@ namespace OpenSim.Region.Framework.Scenes
51 #endregion 51 #endregion
52 52
53 #region Fields 53 #region Fields
54
55 public string Name { get { return RegionInfo.RegionName; } }
54 56
55 public IConfigSource Config 57 public IConfigSource Config
56 { 58 {
@@ -148,6 +150,11 @@ namespace OpenSim.Region.Framework.Scenes
148 150
149 #endregion 151 #endregion
150 152
153 public SceneBase(RegionInfo regInfo)
154 {
155 RegionInfo = regInfo;
156 }
157
151 #region Update Methods 158 #region Update Methods
152 159
153 /// <summary> 160 /// <summary>
@@ -211,10 +218,7 @@ namespace OpenSim.Region.Framework.Scenes
211 /// 218 ///
212 /// </summary> 219 /// </summary>
213 /// <returns></returns> 220 /// <returns></returns>
214 public virtual RegionInfo RegionInfo 221 public virtual RegionInfo RegionInfo { get; private set; }
215 {
216 get { return m_regInfo; }
217 }
218 222
219 #region admin stuff 223 #region admin stuff
220 224
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index b806d91..5d8447b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -84,16 +84,23 @@ namespace OpenSim.Region.Framework.Scenes
84 if (neighbourService != null) 84 if (neighbourService != null)
85 neighbour = neighbourService.HelloNeighbour(regionhandle, region); 85 neighbour = neighbourService.HelloNeighbour(regionhandle, region);
86 else 86 else
87 m_log.DebugFormat("[SCS]: No neighbour service provided for informing neigbhours of this region"); 87 m_log.DebugFormat(
88 "[SCENE COMMUNICATION SERVICE]: No neighbour service provided for region {0} to inform neigbhours of status",
89 m_scene.Name);
88 90
89 if (neighbour != null) 91 if (neighbour != null)
90 { 92 {
91 // m_log.DebugFormat("[INTERGRID]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize); 93 m_log.DebugFormat(
94 "[SCENE COMMUNICATION SERVICE]: Region {0} successfully informed neighbour {1} at {2}-{3} that it is up",
95 m_scene.Name, neighbour.RegionName, x / Constants.RegionSize, y / Constants.RegionSize);
96
92 m_scene.EventManager.TriggerOnRegionUp(neighbour); 97 m_scene.EventManager.TriggerOnRegionUp(neighbour);
93 } 98 }
94 else 99 else
95 { 100 {
96 m_log.InfoFormat("[INTERGRID]: Failed to inform neighbour {0}-{1} that I'm here.", x / Constants.RegionSize, y / Constants.RegionSize); 101 m_log.WarnFormat(
102 "[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.",
103 x / Constants.RegionSize, y / Constants.RegionSize);
97 } 104 }
98 } 105 }
99 106
@@ -101,8 +108,13 @@ namespace OpenSim.Region.Framework.Scenes
101 { 108 {
102 //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName); 109 //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
103 110
104 List<GridRegion> neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); 111 List<GridRegion> neighbours
105 //m_log.DebugFormat("[INTERGRID]: Informing {0} neighbours that this region is up", neighbours.Count); 112 = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID);
113
114 m_log.DebugFormat(
115 "[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that region {1} is up",
116 neighbours.Count, m_scene.Name);
117
106 foreach (GridRegion n in neighbours) 118 foreach (GridRegion n in neighbours)
107 { 119 {
108 InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync; 120 InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync;
@@ -156,7 +168,9 @@ namespace OpenSim.Region.Framework.Scenes
156 // that the region position is cached or performance will degrade 168 // that the region position is cached or performance will degrade
157 Utils.LongToUInts(regionHandle, out x, out y); 169 Utils.LongToUInts(regionHandle, out x, out y);
158 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); 170 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
159// bool v = true; 171 if (dest == null)
172 continue;
173
160 if (!simulatorList.Contains(dest.ServerURI)) 174 if (!simulatorList.Contains(dest.ServerURI))
161 { 175 {
162 // we havent seen this simulator before, add it to the list 176 // we havent seen this simulator before, add it to the list
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 0587846..c3d66eb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -101,6 +101,13 @@ namespace OpenSim.Region.Framework.Scenes
101 /// </summary> 101 /// </summary>
102 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>(); 102 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>();
103 103
104 /// <summary>
105 /// Lock to prevent object group update, linking, delinking and duplication operations from running concurrently.
106 /// </summary>
107 /// <remarks>
108 /// These operations rely on the parts composition of the object. If allowed to run concurrently then race
109 /// conditions can occur.
110 /// </remarks>
104 private Object m_updateLock = new Object(); 111 private Object m_updateLock = new Object();
105 112
106 #endregion 113 #endregion
@@ -394,9 +401,9 @@ namespace OpenSim.Region.Framework.Scenes
394 401
395 if (Entities.ContainsKey(sceneObject.UUID)) 402 if (Entities.ContainsKey(sceneObject.UUID))
396 { 403 {
397// m_log.DebugFormat( 404 m_log.DebugFormat(
398// "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()", 405 "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
399// m_parentScene.RegionInfo.RegionName, sceneObject.UUID); 406 m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
400 407
401 return false; 408 return false;
402 } 409 }
@@ -775,12 +782,6 @@ namespace OpenSim.Region.Framework.Scenes
775 782
776 public int GetChildAgentCount() 783 public int GetChildAgentCount()
777 { 784 {
778 // some network situations come in where child agents get closed twice.
779 if (m_numChildAgents < 0)
780 {
781 m_numChildAgents = 0;
782 }
783
784 return m_numChildAgents; 785 return m_numChildAgents;
785 } 786 }
786 787
@@ -852,11 +853,6 @@ namespace OpenSim.Region.Framework.Scenes
852 return m_scenePresenceArray; 853 return m_scenePresenceArray;
853 } 854 }
854 855
855 public int GetNumberOfScenePresences()
856 {
857 return m_scenePresenceArray.Count;
858 }
859
860 /// <summary> 856 /// <summary>
861 /// Request a scene presence by UUID. Fast, indexed lookup. 857 /// Request a scene presence by UUID. Fast, indexed lookup.
862 /// </summary> 858 /// </summary>
@@ -1042,6 +1038,18 @@ namespace OpenSim.Region.Framework.Scenes
1042 } 1038 }
1043 1039
1044 /// <summary> 1040 /// <summary>
1041 /// Get all the scene object groups.
1042 /// </summary>
1043 /// <returns>
1044 /// The scene object groups. If the scene is empty then an empty list is returned.
1045 /// </returns>
1046 protected internal List<SceneObjectGroup> GetSceneObjectGroups()
1047 {
1048 lock (SceneObjectGroupsByFullID)
1049 return new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
1050 }
1051
1052 /// <summary>
1045 /// Get a group in the scene 1053 /// Get a group in the scene
1046 /// </summary> 1054 /// </summary>
1047 /// <param name="fullID">UUID of the group</param> 1055 /// <param name="fullID">UUID of the group</param>
@@ -1184,11 +1192,7 @@ namespace OpenSim.Region.Framework.Scenes
1184 /// <param name="action"></param> 1192 /// <param name="action"></param>
1185 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1193 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1186 { 1194 {
1187 List<SceneObjectGroup> objlist; 1195 foreach (SceneObjectGroup obj in GetSceneObjectGroups())
1188 lock (SceneObjectGroupsByFullID)
1189 objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
1190
1191 foreach (SceneObjectGroup obj in objlist)
1192 { 1196 {
1193 try 1197 try
1194 { 1198 {
@@ -2065,12 +2069,14 @@ namespace OpenSim.Region.Framework.Scenes
2065 /// <param name="AgentID"></param> 2069 /// <param name="AgentID"></param>
2066 /// <param name="GroupID"></param> 2070 /// <param name="GroupID"></param>
2067 /// <param name="rot"></param> 2071 /// <param name="rot"></param>
2072 /// <returns>null if duplication fails, otherwise the duplicated object</returns>
2073 /// <summary>
2068 public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot) 2074 public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot)
2069 { 2075 {
2070// m_log.DebugFormat( 2076// m_log.DebugFormat(
2071// "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}", 2077// "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}",
2072// originalPrimID, offset, AgentID); 2078// originalPrimID, offset, AgentID);
2073 2079
2074 SceneObjectGroup original = GetGroupByPrim(originalPrimID); 2080 SceneObjectGroup original = GetGroupByPrim(originalPrimID);
2075 if (original != null) 2081 if (original != null)
2076 { 2082 {
@@ -2100,25 +2106,25 @@ namespace OpenSim.Region.Framework.Scenes
2100 2106
2101 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 2107 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()
2102 Entities.Add(copy); 2108 Entities.Add(copy);
2103 2109
2104 lock (SceneObjectGroupsByFullID) 2110 lock (SceneObjectGroupsByFullID)
2105 SceneObjectGroupsByFullID[copy.UUID] = copy; 2111 SceneObjectGroupsByFullID[copy.UUID] = copy;
2106 2112
2107 SceneObjectPart[] children = copy.Parts; 2113 SceneObjectPart[] children = copy.Parts;
2108 2114
2109 lock (SceneObjectGroupsByFullPartID) 2115 lock (SceneObjectGroupsByFullPartID)
2110 { 2116 {
2111 SceneObjectGroupsByFullPartID[copy.UUID] = copy; 2117 SceneObjectGroupsByFullPartID[copy.UUID] = copy;
2112 foreach (SceneObjectPart part in children) 2118 foreach (SceneObjectPart part in children)
2113 SceneObjectGroupsByFullPartID[part.UUID] = copy; 2119 SceneObjectGroupsByFullPartID[part.UUID] = copy;
2114 } 2120 }
2115 2121
2116 lock (SceneObjectGroupsByLocalPartID) 2122 lock (SceneObjectGroupsByLocalPartID)
2117 { 2123 {
2118 SceneObjectGroupsByLocalPartID[copy.LocalId] = copy; 2124 SceneObjectGroupsByLocalPartID[copy.LocalId] = copy;
2119 foreach (SceneObjectPart part in children) 2125 foreach (SceneObjectPart part in children)
2120 SceneObjectGroupsByLocalPartID[part.LocalId] = copy; 2126 SceneObjectGroupsByLocalPartID[part.LocalId] = copy;
2121 } 2127 }
2122 // PROBABLE END OF FIXME 2128 // PROBABLE END OF FIXME
2123 2129
2124 // Since we copy from a source group that is in selected 2130 // Since we copy from a source group that is in selected
@@ -2150,11 +2156,10 @@ namespace OpenSim.Region.Framework.Scenes
2150 { 2156 {
2151 m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID); 2157 m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID);
2152 } 2158 }
2153 2159
2154 return null; 2160 return null;
2155 } 2161 }
2156 2162
2157 /// <summary>
2158 /// Calculates the distance between two Vector3s 2163 /// Calculates the distance between two Vector3s
2159 /// </summary> 2164 /// </summary>
2160 /// <param name="v1"></param> 2165 /// <param name="v1"></param>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 2effa25..26524fb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -54,20 +54,32 @@ namespace OpenSim.Region.Framework.Scenes
54 /// <summary> 54 /// <summary>
55 /// Start the scripts contained in all the prims in this group. 55 /// Start the scripts contained in all the prims in this group.
56 /// </summary> 56 /// </summary>
57 public void CreateScriptInstances(int startParam, bool postOnRez, 57 /// <param name="startParam"></param>
58 string engine, int stateSource) 58 /// <param name="postOnRez"></param>
59 /// <param name="engine"></param>
60 /// <param name="stateSource"></param>
61 /// <returns>
62 /// Number of scripts that were valid for starting. This does not guarantee that all these scripts
63 /// were actually started, but just that the start could be attempt (e.g. the asset data for the script could be found)
64 /// </returns>
65 public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
59 { 66 {
67 int scriptsStarted = 0;
68
60 // Don't start scripts if they're turned off in the region! 69 // Don't start scripts if they're turned off in the region!
61 if (!m_scene.RegionInfo.RegionSettings.DisableScripts) 70 if (!m_scene.RegionInfo.RegionSettings.DisableScripts)
62 { 71 {
63 SceneObjectPart[] parts = m_parts.GetArray(); 72 SceneObjectPart[] parts = m_parts.GetArray();
64 for (int i = 0; i < parts.Length; i++) 73 for (int i = 0; i < parts.Length; i++)
65 parts[i].Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource); 74 scriptsStarted
75 += parts[i].Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource);
66 } 76 }
77
78 return scriptsStarted;
67 } 79 }
68 80
69 /// <summary> 81 /// <summary>
70 /// Stop the scripts contained in all the prims in this group 82 /// Stop and remove the scripts contained in all the prims in this group
71 /// </summary> 83 /// </summary>
72 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 84 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
73 { 85 {
@@ -77,6 +89,14 @@ namespace OpenSim.Region.Framework.Scenes
77 } 89 }
78 90
79 /// <summary> 91 /// <summary>
92 /// Stop the scripts contained in all the prims in this group
93 /// </summary>
94 public void StopScriptInstances()
95 {
96 Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => p.Inventory.StopScriptInstances());
97 }
98
99 /// <summary>
80 /// Add an inventory item from a user's inventory to a prim in this scene object. 100 /// Add an inventory item from a user's inventory to a prim in this scene object.
81 /// </summary> 101 /// </summary>
82 /// <param name="agentID">The agent adding the item.</param> 102 /// <param name="agentID">The agent adding the item.</param>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 1734ab7..f1f94a7 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -131,6 +131,15 @@ namespace OpenSim.Region.Framework.Scenes
131 } 131 }
132 } 132 }
133 133
134 /// <summary>
135 /// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
136 /// (the database).
137 /// </summary>
138 /// <remarks>
139 /// Ultimately, this should be managed such that region modules can change it at the end of a set of operations
140 /// so that either all changes are preserved or none at all. However, currently, a large amount of internal
141 /// code will set this anyway when some object properties are changed.
142 /// </remarks>
134 public bool HasGroupChanged 143 public bool HasGroupChanged
135 { 144 {
136 set 145 set
@@ -244,6 +253,22 @@ namespace OpenSim.Region.Framework.Scenes
244 } 253 }
245 } 254 }
246 255
256 /// <summary>
257 /// If this scene object has an attachment point then indicate whether there is a point where
258 /// attachments are perceivable by avatars other than the avatar to which this object is attached.
259 /// </summary>
260 /// <remarks>
261 /// HUDs are not perceivable by other avatars.
262 /// </remarks>
263 public bool HasPrivateAttachmentPoint
264 {
265 get
266 {
267 return AttachmentPoint >= (uint)OpenMetaverse.AttachmentPoint.HUDCenter2
268 && AttachmentPoint <= (uint)OpenMetaverse.AttachmentPoint.HUDBottomRight;
269 }
270 }
271
247 public void ClearPartAttachmentData() 272 public void ClearPartAttachmentData()
248 { 273 {
249 AttachmentPoint = 0; 274 AttachmentPoint = 0;
@@ -621,6 +646,9 @@ namespace OpenSim.Region.Framework.Scenes
621 return; 646 return;
622 } 647 }
623 } 648 }
649
650 // Restuff the new GroupPosition into each SOP of the linkset.
651 // This has the affect of resetting and tainting the physics actors.
624 SceneObjectPart[] parts = m_parts.GetArray(); 652 SceneObjectPart[] parts = m_parts.GetArray();
625 bool triggerScriptEvent = m_rootPart.GroupPosition != val; 653 bool triggerScriptEvent = m_rootPart.GroupPosition != val;
626 if (m_dupeInProgress) 654 if (m_dupeInProgress)
@@ -1649,16 +1677,6 @@ namespace OpenSim.Region.Framework.Scenes
1649 { 1677 {
1650 return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); 1678 return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
1651 } 1679 }
1652
1653 /// <summary>
1654 /// Added as a way for the storage provider to reset the scene,
1655 /// most likely a better way to do this sort of thing but for now...
1656 /// </summary>
1657 /// <param name="scene"></param>
1658 public void SetScene(Scene scene)
1659 {
1660 m_scene = scene;
1661 }
1662 1680
1663 /// <summary> 1681 /// <summary>
1664 /// Set a part to act as the root part for this scene object 1682 /// Set a part to act as the root part for this scene object
@@ -1740,6 +1758,9 @@ namespace OpenSim.Region.Framework.Scenes
1740 1758
1741 public void ResetChildPrimPhysicsPositions() 1759 public void ResetChildPrimPhysicsPositions()
1742 { 1760 {
1761 // Setting this SOG's absolute position also loops through and sets the positions
1762 // of the SOP's in this SOG's linkset. This has the side affect of making sure
1763 // the physics world matches the simulated world.
1743 AbsolutePosition = AbsolutePosition; // could someone in the know please explain how this works? 1764 AbsolutePosition = AbsolutePosition; // could someone in the know please explain how this works?
1744 1765
1745 // teravus: AbsolutePosition is NOT a normal property! 1766 // teravus: AbsolutePosition is NOT a normal property!
@@ -1816,8 +1837,9 @@ namespace OpenSim.Region.Framework.Scenes
1816 part.ClearUpdateSchedule(); 1837 part.ClearUpdateSchedule();
1817 if (part == m_rootPart) 1838 if (part == m_rootPart)
1818 { 1839 {
1819 if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) || 1840 if (!IsAttachment
1820 (AttachmentPoint < 31) || (AttachmentPoint > 38)) 1841 || AttachedAvatar == avatar.ControllingClient.AgentId
1842 || !HasPrivateAttachmentPoint)
1821 avatar.ControllingClient.SendKillObject(m_regionHandle, new List<uint> { part.LocalId }); 1843 avatar.ControllingClient.SendKillObject(m_regionHandle, new List<uint> { part.LocalId });
1822 } 1844 }
1823 } 1845 }
@@ -2531,8 +2553,13 @@ namespace OpenSim.Region.Framework.Scenes
2531 } 2553 }
2532 2554
2533 /// <summary> 2555 /// <summary>
2534 /// Schedule a full update for this scene object 2556 /// Schedule a full update for this scene object to all interested viewers.
2535 /// </summary> 2557 /// </summary>
2558 /// <remarks>
2559 /// Ultimately, this should be managed such that region modules can invoke it at the end of a set of operations
2560 /// so that either all changes are sent at once. However, currently, a large amount of internal
2561 /// code will set this anyway when some object properties are changed.
2562 /// </remarks>
2536 public void ScheduleGroupForFullUpdate() 2563 public void ScheduleGroupForFullUpdate()
2537 { 2564 {
2538// if (IsAttachment) 2565// if (IsAttachment)
@@ -2551,8 +2578,13 @@ namespace OpenSim.Region.Framework.Scenes
2551 } 2578 }
2552 2579
2553 /// <summary> 2580 /// <summary>
2554 /// Schedule a terse update for this scene object 2581 /// Schedule a terse update for this scene object to all interested viewers.
2555 /// </summary> 2582 /// </summary>
2583 /// <remarks>
2584 /// Ultimately, this should be managed such that region modules can invoke it at the end of a set of operations
2585 /// so that either all changes are sent at once. However, currently, a large amount of internal
2586 /// code will set this anyway when some object properties are changed.
2587 /// </remarks>
2556 public void ScheduleGroupForTerseUpdate() 2588 public void ScheduleGroupForTerseUpdate()
2557 { 2589 {
2558// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); 2590// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID);
@@ -2682,12 +2714,18 @@ namespace OpenSim.Region.Framework.Scenes
2682 /// <summary> 2714 /// <summary>
2683 /// Link the prims in a given group to this group 2715 /// Link the prims in a given group to this group
2684 /// </summary> 2716 /// </summary>
2717 /// <remarks>
2718 /// Do not call this method directly - use Scene.LinkObjects() instead to avoid races between threads.
2719 /// FIXME: There are places where scripts call these methods directly without locking. This is a potential race condition.
2720 /// </remarks>
2685 /// <param name="objectGroup">The group of prims which should be linked to this group</param> 2721 /// <param name="objectGroup">The group of prims which should be linked to this group</param>
2686 public void LinkToGroup(SceneObjectGroup objectGroup) 2722 public void LinkToGroup(SceneObjectGroup objectGroup)
2687 { 2723 {
2688 LinkToGroup(objectGroup, false); 2724 LinkToGroup(objectGroup, false);
2689 } 2725 }
2690 2726
2727 // Link an existing group to this group.
2728 // The group being linked need not be a linkset -- it can have just one prim.
2691 public void LinkToGroup(SceneObjectGroup objectGroup, bool insert) 2729 public void LinkToGroup(SceneObjectGroup objectGroup, bool insert)
2692 { 2730 {
2693// m_log.DebugFormat( 2731// m_log.DebugFormat(
@@ -2698,6 +2736,7 @@ namespace OpenSim.Region.Framework.Scenes
2698 if (objectGroup == this) 2736 if (objectGroup == this)
2699 return; 2737 return;
2700 2738
2739 // 'linkPart' == the root of the group being linked into this group
2701 SceneObjectPart linkPart = objectGroup.m_rootPart; 2740 SceneObjectPart linkPart = objectGroup.m_rootPart;
2702 2741
2703 if (m_rootPart.PhysActor != null) 2742 if (m_rootPart.PhysActor != null)
@@ -2709,31 +2748,44 @@ namespace OpenSim.Region.Framework.Scenes
2709 bool grpusephys = UsesPhysics; 2748 bool grpusephys = UsesPhysics;
2710 bool grptemporary = IsTemporary; 2749 bool grptemporary = IsTemporary;
2711 2750
2751 // Remember where the group being linked thought it was
2712 Vector3 oldGroupPosition = linkPart.GroupPosition; 2752 Vector3 oldGroupPosition = linkPart.GroupPosition;
2713 Quaternion oldRootRotation = linkPart.RotationOffset; 2753 Quaternion oldRootRotation = linkPart.RotationOffset;
2714 2754
2715 linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; 2755 // A linked SOP remembers its location and rotation relative to the root of a group.
2756 // Convert the root of the group being linked to be relative to the
2757 // root of the group being linked to.
2758 // Note: Some of the assignments have complex side effects.
2716 2759
2760 // First move the new group's root SOP's position to be relative to ours
2761 // (radams1: Not sure if the multiple setting of OffsetPosition is required. If not,
2762 // this code can be reordered to have a more logical flow.)
2763 linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
2764 // Assign the new parent to the root of the old group
2717 linkPart.ParentID = m_rootPart.LocalId; 2765 linkPart.ParentID = m_rootPart.LocalId;
2718 2766 // Now that it's a child, it's group position is our root position
2719 linkPart.GroupPosition = AbsolutePosition; 2767 linkPart.GroupPosition = AbsolutePosition;
2720 2768
2721 Vector3 axPos = linkPart.OffsetPosition; 2769 Vector3 axPos = linkPart.OffsetPosition;
2770 // Rotate the linking root SOP's position to be relative to the new root prim
2722 Quaternion parentRot = m_rootPart.RotationOffset; 2771 Quaternion parentRot = m_rootPart.RotationOffset;
2723 axPos *= Quaternion.Conjugate(parentRot); 2772 axPos *= Quaternion.Conjugate(parentRot);
2724 linkPart.OffsetPosition = axPos; 2773 linkPart.OffsetPosition = axPos;
2725 2774
2775 // Make the linking root SOP's rotation relative to the new root prim
2726 Quaternion oldRot = linkPart.RotationOffset; 2776 Quaternion oldRot = linkPart.RotationOffset;
2727 Quaternion newRot = Quaternion.Conjugate(parentRot) * oldRot; 2777 Quaternion newRot = Quaternion.Conjugate(parentRot) * oldRot;
2728 linkPart.RotationOffset = newRot; 2778 linkPart.RotationOffset = newRot;
2729 2779
2730// linkPart.ParentID = m_rootPart.LocalId; done above 2780 // If there is only one SOP in a SOG, the LinkNum is zero. I.e., not a linkset.
2731 2781 // Now that we know this SOG has at least two SOPs in it, the new root
2782 // SOP becomes the first in the linkset.
2732 if (m_rootPart.LinkNum == 0) 2783 if (m_rootPart.LinkNum == 0)
2733 m_rootPart.LinkNum = 1; 2784 m_rootPart.LinkNum = 1;
2734 2785
2735 lock (m_parts.SyncRoot) 2786 lock (m_parts.SyncRoot)
2736 { 2787 {
2788 // Calculate the new link number for the old root SOP
2737 int linkNum; 2789 int linkNum;
2738 if (insert) 2790 if (insert)
2739 { 2791 {
@@ -2749,6 +2801,7 @@ namespace OpenSim.Region.Framework.Scenes
2749 linkNum = PrimCount + 1; 2801 linkNum = PrimCount + 1;
2750 } 2802 }
2751 2803
2804 // Add the old root SOP as a part in our group's list
2752 m_parts.Add(linkPart.UUID, linkPart); 2805 m_parts.Add(linkPart.UUID, linkPart);
2753 2806
2754 linkPart.SetParent(this); 2807 linkPart.SetParent(this);
@@ -2756,6 +2809,8 @@ namespace OpenSim.Region.Framework.Scenes
2756 2809
2757 // let physics know preserve part volume dtc messy since UpdatePrimFlags doesn't look to parent changes for now 2810 // let physics know preserve part volume dtc messy since UpdatePrimFlags doesn't look to parent changes for now
2758 linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive, true); 2811 linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive, true);
2812
2813 // If the added SOP is physical, also tell the physics engine about the link relationship.
2759 if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) 2814 if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
2760 { 2815 {
2761 linkPart.PhysActor.link(m_rootPart.PhysActor); 2816 linkPart.PhysActor.link(m_rootPart.PhysActor);
@@ -2763,21 +2818,28 @@ namespace OpenSim.Region.Framework.Scenes
2763 } 2818 }
2764 2819
2765 linkPart.LinkNum = linkNum++; 2820 linkPart.LinkNum = linkNum++;
2821 linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
2766 2822
2823 // Get a list of the SOP's in the old group in order of their linknum's.
2767 SceneObjectPart[] ogParts = objectGroup.Parts; 2824 SceneObjectPart[] ogParts = objectGroup.Parts;
2768 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) 2825 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b)
2769 { 2826 {
2770 return a.LinkNum - b.LinkNum; 2827 return a.LinkNum - b.LinkNum;
2771 }); 2828 });
2772 2829
2830 // Add each of the SOP's from the old linkset to our linkset
2773 for (int i = 0; i < ogParts.Length; i++) 2831 for (int i = 0; i < ogParts.Length; i++)
2774 { 2832 {
2775 SceneObjectPart part = ogParts[i]; 2833 SceneObjectPart part = ogParts[i];
2776 if (part.UUID != objectGroup.m_rootPart.UUID) 2834 if (part.UUID != objectGroup.m_rootPart.UUID)
2777 { 2835 {
2778 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); 2836 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2779 // let physics know 2837
2838 // Update the physics flags for the newly added SOP
2839 // (Is this necessary? LinkNonRootPart() has already called UpdatePrimFlags but with different flags!??)
2780 part.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (part.Flags & PrimFlags.Phantom) != 0), part.VolumeDetectActive, true); 2840 part.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (part.Flags & PrimFlags.Phantom) != 0), part.VolumeDetectActive, true);
2841
2842 // If the added SOP is physical, also tell the physics engine about the link relationship.
2781 if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) 2843 if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
2782 { 2844 {
2783 part.PhysActor.link(m_rootPart.PhysActor); 2845 part.PhysActor.link(m_rootPart.PhysActor);
@@ -2788,6 +2850,7 @@ namespace OpenSim.Region.Framework.Scenes
2788 } 2850 }
2789 } 2851 }
2790 2852
2853 // Now that we've aquired all of the old SOG's parts, remove the old SOG from the scene.
2791 m_scene.UnlinkSceneObject(objectGroup, true); 2854 m_scene.UnlinkSceneObject(objectGroup, true);
2792 objectGroup.IsDeleted = true; 2855 objectGroup.IsDeleted = true;
2793 2856
@@ -2814,6 +2877,11 @@ namespace OpenSim.Region.Framework.Scenes
2814 /// Delink the given prim from this group. The delinked prim is established as 2877 /// Delink the given prim from this group. The delinked prim is established as
2815 /// an independent SceneObjectGroup. 2878 /// an independent SceneObjectGroup.
2816 /// </summary> 2879 /// </summary>
2880 /// <remarks>
2881 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2882 /// condition. But currently there is no
2883 /// alternative method that does take a lonk to delink a single prim.
2884 /// </remarks>
2817 /// <param name="partID"></param> 2885 /// <param name="partID"></param>
2818 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2886 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
2819 public SceneObjectGroup DelinkFromGroup(uint partID) 2887 public SceneObjectGroup DelinkFromGroup(uint partID)
@@ -2825,6 +2893,11 @@ namespace OpenSim.Region.Framework.Scenes
2825 /// Delink the given prim from this group. The delinked prim is established as 2893 /// Delink the given prim from this group. The delinked prim is established as
2826 /// an independent SceneObjectGroup. 2894 /// an independent SceneObjectGroup.
2827 /// </summary> 2895 /// </summary>
2896 /// <remarks>
2897 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2898 /// condition. But currently there is no
2899 /// alternative method that does take a lonk to delink a single prim.
2900 /// </remarks>
2828 /// <param name="partID"></param> 2901 /// <param name="partID"></param>
2829 /// <param name="sendEvents"></param> 2902 /// <param name="sendEvents"></param>
2830 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2903 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
@@ -2850,6 +2923,11 @@ namespace OpenSim.Region.Framework.Scenes
2850 /// Delink the given prim from this group. The delinked prim is established as 2923 /// Delink the given prim from this group. The delinked prim is established as
2851 /// an independent SceneObjectGroup. 2924 /// an independent SceneObjectGroup.
2852 /// </summary> 2925 /// </summary>
2926 /// <remarks>
2927 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2928 /// condition. But currently there is no
2929 /// alternative method that does take a lock to delink a single prim.
2930 /// </remarks>
2853 /// <param name="partID"></param> 2931 /// <param name="partID"></param>
2854 /// <param name="sendEvents"></param> 2932 /// <param name="sendEvents"></param>
2855 /// <returns>The object group of the newly delinked prim.</returns> 2933 /// <returns>The object group of the newly delinked prim.</returns>
@@ -2864,6 +2942,7 @@ namespace OpenSim.Region.Framework.Scenes
2864 2942
2865 linkPart.ClearUndoState(); 2943 linkPart.ClearUndoState();
2866 2944
2945 Vector3 worldPos = linkPart.GetWorldPosition();
2867 Quaternion worldRot = linkPart.GetWorldRotation(); 2946 Quaternion worldRot = linkPart.GetWorldRotation();
2868 2947
2869 // Remove the part from this object 2948 // Remove the part from this object
@@ -2873,6 +2952,7 @@ namespace OpenSim.Region.Framework.Scenes
2873 2952
2874 SceneObjectPart[] parts = m_parts.GetArray(); 2953 SceneObjectPart[] parts = m_parts.GetArray();
2875 2954
2955 // Rejigger the linknum's of the remaining SOP's to fill any gap
2876 if (parts.Length == 1 && RootPart != null) 2956 if (parts.Length == 1 && RootPart != null)
2877 { 2957 {
2878 // Single prim left 2958 // Single prim left
@@ -2894,22 +2974,31 @@ namespace OpenSim.Region.Framework.Scenes
2894 2974
2895 PhysicsActor linkPartPa = linkPart.PhysActor; 2975 PhysicsActor linkPartPa = linkPart.PhysActor;
2896 2976
2977 // Remove the SOP from the physical scene.
2978 // If the new SOG is physical, it is re-created later.
2979 // (There is a problem here in that we have not yet told the physics
2980 // engine about the delink. Someday, linksets should be made first
2981 // class objects in the physics engine interface).
2897 if (linkPartPa != null) 2982 if (linkPartPa != null)
2898 m_scene.PhysicsScene.RemovePrim(linkPartPa); 2983 m_scene.PhysicsScene.RemovePrim(linkPartPa);
2899 2984
2900 // We need to reset the child part's position 2985 // We need to reset the child part's position
2901 // ready for life as a separate object after being a part of another object 2986 // ready for life as a separate object after being a part of another object
2902 Quaternion parentRot = m_rootPart.RotationOffset;
2903 2987
2988 /* This commented out code seems to recompute what GetWorldPosition already does.
2989 * Replace with a call to GetWorldPosition (before unlinking)
2990 Quaternion parentRot = m_rootPart.RotationOffset;
2904 Vector3 axPos = linkPart.OffsetPosition; 2991 Vector3 axPos = linkPart.OffsetPosition;
2905
2906 axPos *= parentRot; 2992 axPos *= parentRot;
2907 linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z); 2993 linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z);
2908 linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition; 2994 linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
2909 linkPart.OffsetPosition = new Vector3(0, 0, 0); 2995 linkPart.OffsetPosition = new Vector3(0, 0, 0);
2910 2996 */
2997 linkPart.GroupPosition = worldPos;
2998 linkPart.OffsetPosition = Vector3.Zero;
2911 linkPart.RotationOffset = worldRot; 2999 linkPart.RotationOffset = worldRot;
2912 3000
3001 // Create a new SOG to go around this unlinked and unattached SOP
2913 SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart); 3002 SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);
2914 3003
2915 m_scene.AddNewSceneObject(objectGroup, true); 3004 m_scene.AddNewSceneObject(objectGroup, true);
@@ -2947,42 +3036,58 @@ namespace OpenSim.Region.Framework.Scenes
2947 m_isBackedUp = false; 3036 m_isBackedUp = false;
2948 } 3037 }
2949 3038
3039 // This links an SOP from a previous linkset into my linkset.
3040 // The trick is that the SOP's position and rotation are relative to the old root SOP's
3041 // so we are passed in the position and rotation of the old linkset so this can
3042 // unjigger this SOP's position and rotation from the previous linkset and
3043 // then make them relative to my linkset root.
2950 private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum) 3044 private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum)
2951 { 3045 {
2952 Quaternion parentRot = oldGroupRotation; 3046 Quaternion parentRot = oldGroupRotation;
2953 Quaternion oldRot = part.RotationOffset; 3047 Quaternion oldRot = part.RotationOffset;
2954 Quaternion worldRot = parentRot * oldRot;
2955
2956 parentRot = oldGroupRotation;
2957 3048
3049 // Move our position to not be relative to the old parent
2958 Vector3 axPos = part.OffsetPosition; 3050 Vector3 axPos = part.OffsetPosition;
2959
2960 axPos *= parentRot; 3051 axPos *= parentRot;
2961 part.OffsetPosition = axPos; 3052 part.OffsetPosition = axPos;
2962 Vector3 newPos = oldGroupPosition + part.OffsetPosition; 3053 Vector3 newPos = oldGroupPosition + part.OffsetPosition;
2963 part.GroupPosition = newPos; 3054 part.GroupPosition = newPos;
2964 part.OffsetPosition = Vector3.Zero; 3055 part.OffsetPosition = Vector3.Zero;
3056
3057 // Compution our rotation to be not relative to the old parent
3058 Quaternion worldRot = parentRot * oldRot;
2965 part.RotationOffset = worldRot; 3059 part.RotationOffset = worldRot;
2966 3060
3061 // Add this SOP to our linkset
2967 part.SetParent(this); 3062 part.SetParent(this);
2968 part.ParentID = m_rootPart.LocalId; 3063 part.ParentID = m_rootPart.LocalId;
2969
2970 m_parts.Add(part.UUID, part); 3064 m_parts.Add(part.UUID, part);
2971 3065
2972 part.LinkNum = linkNum; 3066 part.LinkNum = linkNum;
2973 3067
2974 part.OffsetPosition = newPos - AbsolutePosition; 3068 // Compute the new position of this SOP relative to the group position
3069 part.OffsetPosition = part.GroupPosition - AbsolutePosition;
2975 3070
2976 Quaternion rootRotation = m_rootPart.RotationOffset; 3071 // (radams1 20120711: I don't know why part.OffsetPosition is set multiple times.
3072 // It would have the affect of setting the physics engine position multiple
3073 // times. In theory, that is not necessary but I don't have a good linkset
3074 // test to know that cleaning up this code wouldn't break things.)
2977 3075
3076 // Rotate the relative position by the rotation of the group
3077 Quaternion rootRotation = m_rootPart.RotationOffset;
2978 Vector3 pos = part.OffsetPosition; 3078 Vector3 pos = part.OffsetPosition;
2979 pos *= Quaternion.Conjugate(rootRotation); 3079 pos *= Quaternion.Conjugate(rootRotation);
2980 part.OffsetPosition = pos; 3080 part.OffsetPosition = pos;
2981 3081
3082 // Compute the SOP's rotation relative to the rotation of the group.
2982 parentRot = m_rootPart.RotationOffset; 3083 parentRot = m_rootPart.RotationOffset;
2983 oldRot = part.RotationOffset; 3084 oldRot = part.RotationOffset;
2984 Quaternion newRot = Quaternion.Conjugate(parentRot) * worldRot; 3085 Quaternion newRot = Quaternion.Conjugate(parentRot) * worldRot;
2985 part.RotationOffset = newRot; 3086 part.RotationOffset = newRot;
3087
3088 // Since this SOP's state has changed, push those changes into the physics engine
3089 // and the simulator.
3090 part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
2986 } 3091 }
2987 3092
2988 /// <summary> 3093 /// <summary>
@@ -3498,7 +3603,7 @@ namespace OpenSim.Region.Framework.Scenes
3498 3603
3499 //we need to do a terse update even if the move wasn't allowed 3604 //we need to do a terse update even if the move wasn't allowed
3500 // so that the position is reset in the client (the object snaps back) 3605 // so that the position is reset in the client (the object snaps back)
3501 ScheduleGroupForTerseUpdate(); 3606 RootPart.ScheduleTerseUpdate();
3502 } 3607 }
3503 3608
3504 /// <summary> 3609 /// <summary>
@@ -3613,6 +3718,11 @@ namespace OpenSim.Region.Framework.Scenes
3613 m_scene.PhysicsScene.AddPhysicsActorTaint(actor); 3718 m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
3614 } 3719 }
3615 3720
3721 if (IsAttachment)
3722 {
3723 m_rootPart.AttachedPos = pos;
3724 }
3725
3616 AbsolutePosition = pos; 3726 AbsolutePosition = pos;
3617 3727
3618 HasGroupChanged = true; 3728 HasGroupChanged = true;
@@ -4199,7 +4309,86 @@ namespace OpenSim.Region.Framework.Scenes
4199 for (int i = 0; i < parts.Length; i++) 4309 for (int i = 0; i < parts.Length; i++)
4200 parts[i].TriggerScriptChangedEvent(val); 4310 parts[i].TriggerScriptChangedEvent(val);
4201 } 4311 }
4202 4312
4313 /// <summary>
4314 /// Returns a count of the number of scripts in this groups parts.
4315 /// </summary>
4316 public int ScriptCount()
4317 {
4318 int count = 0;
4319 SceneObjectPart[] parts = m_parts.GetArray();
4320 for (int i = 0; i < parts.Length; i++)
4321 count += parts[i].Inventory.ScriptCount();
4322
4323 return count;
4324 }
4325
4326 /// <summary>
4327 /// A float the value is a representative execution time in milliseconds of all scripts in the link set.
4328 /// </summary>
4329 public float ScriptExecutionTime()
4330 {
4331 IScriptModule[] engines = Scene.RequestModuleInterfaces<IScriptModule>();
4332
4333 if (engines.Length == 0) // No engine at all
4334 return 0.0f;
4335
4336 float time = 0.0f;
4337
4338 // get all the scripts in all parts
4339 SceneObjectPart[] parts = m_parts.GetArray();
4340 List<TaskInventoryItem> scripts = new List<TaskInventoryItem>();
4341 for (int i = 0; i < parts.Length; i++)
4342 {
4343 scripts.AddRange(parts[i].Inventory.GetInventoryItems(InventoryType.LSL));
4344 }
4345 // extract the UUIDs
4346 List<UUID> ids = new List<UUID>(scripts.Count);
4347 foreach (TaskInventoryItem script in scripts)
4348 {
4349 if (!ids.Contains(script.ItemID))
4350 {
4351 ids.Add(script.ItemID);
4352 }
4353 }
4354 // Offer the list of script UUIDs to each engine found and accumulate the time
4355 foreach (IScriptModule e in engines)
4356 {
4357 if (e != null)
4358 {
4359 time += e.GetScriptExecutionTime(ids);
4360 }
4361 }
4362 return time;
4363 }
4364
4365 /// <summary>
4366 /// Returns a count of the number of running scripts in this groups parts.
4367 /// </summary>
4368 public int RunningScriptCount()
4369 {
4370 int count = 0;
4371 SceneObjectPart[] parts = m_parts.GetArray();
4372 for (int i = 0; i < parts.Length; i++)
4373 count += parts[i].Inventory.RunningScriptCount();
4374
4375 return count;
4376 }
4377
4378 /// <summary>
4379 /// Gets the number of sitting avatars.
4380 /// </summary>
4381 /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
4382 /// <returns></returns>
4383 public int GetSittingAvatarsCount()
4384 {
4385 int count = 0;
4386
4387 Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => count += p.GetSittingAvatarsCount());
4388
4389 return count;
4390 }
4391
4203 public override string ToString() 4392 public override string ToString()
4204 { 4393 {
4205 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); 4394 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 16a8588..b038876 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -147,6 +147,21 @@ namespace OpenSim.Region.Framework.Scenes
147 get { return ParentGroup.RootPart == this; } 147 get { return ParentGroup.RootPart == this; }
148 } 148 }
149 149
150 /// <summary>
151 /// Is an explicit sit target set for this part?
152 /// </summary>
153 public bool IsSitTargetSet
154 {
155 get
156 {
157 return
158 !(SitTargetPosition == Vector3.Zero
159 && (SitTargetOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
160 || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 1f && SitTargetOrientation.W == 0f // W-Z Mapping was invalid at one point
161 || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 0f && SitTargetOrientation.W == 0f)); // Invalid Quaternion
162 }
163 }
164
150 #region Fields 165 #region Fields
151 166
152 public bool AllowedDrop; 167 public bool AllowedDrop;
@@ -426,7 +441,6 @@ namespace OpenSim.Region.Framework.Scenes
426 private uint _category; 441 private uint _category;
427 private Int32 _creationDate; 442 private Int32 _creationDate;
428 private uint _parentID = 0; 443 private uint _parentID = 0;
429 private UUID m_sitTargetAvatar = UUID.Zero;
430 private uint _baseMask = (uint)PermissionMask.All; 444 private uint _baseMask = (uint)PermissionMask.All;
431 private uint _ownerMask = (uint)PermissionMask.All; 445 private uint _ownerMask = (uint)PermissionMask.All;
432 private uint _groupMask = (uint)PermissionMask.None; 446 private uint _groupMask = (uint)PermissionMask.None;
@@ -738,6 +752,7 @@ namespace OpenSim.Region.Framework.Scenes
738 return m_groupPosition; 752 return m_groupPosition;
739 } 753 }
740 754
755 // If I'm an attachment, my position is reported as the position of who I'm attached to
741 if (ParentGroup.IsAttachment) 756 if (ParentGroup.IsAttachment)
742 { 757 {
743 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar); 758 ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
@@ -765,7 +780,7 @@ namespace OpenSim.Region.Framework.Scenes
765 } 780 }
766 else 781 else
767 { 782 {
768 // To move the child prim in respect to the group position and rotation we have to calculate 783 // The physics engine always sees all objects (root or linked) in world coordinates.
769 actor.Position = GetWorldPosition(); 784 actor.Position = GetWorldPosition();
770 actor.Orientation = GetWorldRotation(); 785 actor.Orientation = GetWorldRotation();
771 } 786 }
@@ -844,6 +859,8 @@ namespace OpenSim.Region.Framework.Scenes
844 { 859 {
845 // We don't want the physics engine mucking up the rotations in a linkset 860 // We don't want the physics engine mucking up the rotations in a linkset
846 PhysicsActor actor = PhysActor; 861 PhysicsActor actor = PhysActor;
862 // If this is a root of a linkset, the real rotation is what the physics engine thinks.
863 // If not a root prim, the offset rotation is computed by SOG and is relative to the root.
847 if (ParentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null) 864 if (ParentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null)
848 { 865 {
849 if (actor.Orientation.X != 0f || actor.Orientation.Y != 0f 866 if (actor.Orientation.X != 0f || actor.Orientation.Y != 0f
@@ -1024,7 +1041,18 @@ namespace OpenSim.Region.Framework.Scenes
1024 public int LinkNum 1041 public int LinkNum
1025 { 1042 {
1026 get { return m_linkNum; } 1043 get { return m_linkNum; }
1027 set { m_linkNum = value; } 1044 set
1045 {
1046// if (ParentGroup != null)
1047// {
1048// m_log.DebugFormat(
1049// "[SCENE OBJECT PART]: Setting linknum of {0}@{1} to {2} from {3}",
1050// Name, AbsolutePosition, value, m_linkNum);
1051// Util.PrintCallStack();
1052// }
1053
1054 m_linkNum = value;
1055 }
1028 } 1056 }
1029 1057
1030 public byte ClickAction 1058 public byte ClickAction
@@ -1309,13 +1337,20 @@ namespace OpenSim.Region.Framework.Scenes
1309 } 1337 }
1310 1338
1311 /// <summary> 1339 /// <summary>
1312 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1340 /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero
1313 /// </summary> 1341 /// </summary>
1314 public UUID SitTargetAvatar 1342 public UUID SitTargetAvatar { get; set; }
1315 { 1343
1316 get { return m_sitTargetAvatar; } 1344 /// <summary>
1317 set { m_sitTargetAvatar = value; } 1345 /// IDs of all avatars start on this object part.
1318 } 1346 /// </summary>
1347 /// <remarks>
1348 /// We need to track this so that we can stop sat upon prims from being attached.
1349 /// </remarks>
1350 /// <value>
1351 /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene.
1352 /// </value>
1353 private HashSet<UUID> m_sittingAvatars;
1319 1354
1320 public virtual UUID RegionID 1355 public virtual UUID RegionID
1321 { 1356 {
@@ -2111,7 +2146,7 @@ namespace OpenSim.Region.Framework.Scenes
2111 else 2146 else
2112 m_log.WarnFormat( 2147 m_log.WarnFormat(
2113 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", 2148 "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
2114 Name, LocalId, id); 2149 Name, UUID, id);
2115 } 2150 }
2116 2151
2117 /// <summary> 2152 /// <summary>
@@ -2216,6 +2251,9 @@ namespace OpenSim.Region.Framework.Scenes
2216 /// <param name="isNew"></param> 2251 /// <param name="isNew"></param>
2217 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) 2252 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
2218 { 2253 {
2254 if (ParentGroup.Scene == null)
2255 return;
2256
2219 if (!ParentGroup.Scene.PhysicalPrims && UsePhysics) 2257 if (!ParentGroup.Scene.PhysicalPrims && UsePhysics)
2220 return; 2258 return;
2221 2259
@@ -2494,14 +2532,20 @@ namespace OpenSim.Region.Framework.Scenes
2494 /// <returns>A Linked Child Prim objects position in world</returns> 2532 /// <returns>A Linked Child Prim objects position in world</returns>
2495 public Vector3 GetWorldPosition() 2533 public Vector3 GetWorldPosition()
2496 { 2534 {
2497 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 2535 Vector3 ret;
2498 Vector3 axPos = OffsetPosition; 2536 if (_parentID == 0)
2499 axPos *= parentRot; 2537 // if a root SOP, my position is what it is
2500 Vector3 translationOffsetPosition = axPos; 2538 ret = GroupPosition;
2501 if(_parentID == 0)
2502 return GroupPosition;
2503 else 2539 else
2504 return ParentGroup.AbsolutePosition + translationOffsetPosition; 2540 {
2541 // If a child SOP, my position is relative to the root SOP so take
2542 // my info and add the root's position and rotation to
2543 // get my world position.
2544 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
2545 Vector3 translationOffsetPosition = OffsetPosition * parentRot;
2546 ret = ParentGroup.AbsolutePosition + translationOffsetPosition;
2547 }
2548 return ret;
2505 } 2549 }
2506 2550
2507 /// <summary> 2551 /// <summary>
@@ -2518,6 +2562,8 @@ namespace OpenSim.Region.Framework.Scenes
2518 } 2562 }
2519 else 2563 else
2520 { 2564 {
2565 // A child SOP's rotation is relative to the root SOP's rotation.
2566 // Combine them to get my absolute rotation.
2521 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 2567 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
2522 Quaternion oldRot = RotationOffset; 2568 Quaternion oldRot = RotationOffset;
2523 newRot = parentRot * oldRot; 2569 newRot = parentRot * oldRot;
@@ -3174,8 +3220,9 @@ namespace OpenSim.Region.Framework.Scenes
3174 if (ParentGroup.IsDeleted) 3220 if (ParentGroup.IsDeleted)
3175 return; 3221 return;
3176 3222
3177 if (ParentGroup.IsAttachment && (ParentGroup.AttachedAvatar != remoteClient.AgentId) && 3223 if (ParentGroup.IsAttachment
3178 (ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38)) 3224 && ParentGroup.AttachedAvatar != remoteClient.AgentId
3225 && ParentGroup.HasPrivateAttachmentPoint)
3179 return; 3226 return;
3180 3227
3181 if (remoteClient.AgentId == OwnerID) 3228 if (remoteClient.AgentId == OwnerID)
@@ -3694,7 +3741,6 @@ namespace OpenSim.Region.Framework.Scenes
3694 hasProfileCut = hasDimple; // is it the same thing? 3741 hasProfileCut = hasDimple; // is it the same thing?
3695 } 3742 }
3696 3743
3697
3698 public void SetGroup(UUID groupID, IClientAPI client) 3744 public void SetGroup(UUID groupID, IClientAPI client)
3699 { 3745 {
3700 // Scene.AddNewPrims() calls with client == null so can't use this. 3746 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3724,10 +3770,12 @@ namespace OpenSim.Region.Framework.Scenes
3724 3770
3725 public void SetPhysicsAxisRotation() 3771 public void SetPhysicsAxisRotation()
3726 { 3772 {
3727 if (PhysActor != null) 3773 PhysicsActor pa = PhysActor;
3774
3775 if (pa != null)
3728 { 3776 {
3729 PhysActor.LockAngularMotion(RotationAxis); 3777 pa.LockAngularMotion(RotationAxis);
3730 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 3778 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
3731 } 3779 }
3732 } 3780 }
3733 3781
@@ -4444,7 +4492,7 @@ namespace OpenSim.Region.Framework.Scenes
4444 // For now, we use the NINJA naming scheme for identifying joints. 4492 // For now, we use the NINJA naming scheme for identifying joints.
4445 // In the future, we can support other joint specification schemes such as a 4493 // In the future, we can support other joint specification schemes such as a
4446 // custom checkbox in the viewer GUI. 4494 // custom checkbox in the viewer GUI.
4447 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4495 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4448 { 4496 {
4449 string hingeString = "hingejoint"; 4497 string hingeString = "hingejoint";
4450 return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString); 4498 return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString);
@@ -4460,7 +4508,7 @@ namespace OpenSim.Region.Framework.Scenes
4460 // For now, we use the NINJA naming scheme for identifying joints. 4508 // For now, we use the NINJA naming scheme for identifying joints.
4461 // In the future, we can support other joint specification schemes such as a 4509 // In the future, we can support other joint specification schemes such as a
4462 // custom checkbox in the viewer GUI. 4510 // custom checkbox in the viewer GUI.
4463 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4511 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4464 { 4512 {
4465 string ballString = "balljoint"; 4513 string ballString = "balljoint";
4466 return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString); 4514 return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString);
@@ -4476,7 +4524,7 @@ namespace OpenSim.Region.Framework.Scenes
4476 // For now, we use the NINJA naming scheme for identifying joints. 4524 // For now, we use the NINJA naming scheme for identifying joints.
4477 // In the future, we can support other joint specification schemes such as a 4525 // In the future, we can support other joint specification schemes such as a
4478 // custom checkbox in the viewer GUI. 4526 // custom checkbox in the viewer GUI.
4479 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4527 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4480 { 4528 {
4481 return IsHingeJoint() || IsBallJoint(); 4529 return IsHingeJoint() || IsBallJoint();
4482 } 4530 }
@@ -4598,7 +4646,6 @@ namespace OpenSim.Region.Framework.Scenes
4598 } 4646 }
4599*/ 4647*/
4600 } 4648 }
4601
4602 else // it already has a physical representation 4649 else // it already has a physical representation
4603 { 4650 {
4604 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. 4651 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
@@ -5074,8 +5121,9 @@ namespace OpenSim.Region.Framework.Scenes
5074 if (ParentGroup.IsDeleted) 5121 if (ParentGroup.IsDeleted)
5075 return; 5122 return;
5076 5123
5077 if (ParentGroup.IsAttachment && ((ParentGroup.RootPart != this) || 5124 if (ParentGroup.IsAttachment
5078 ((ParentGroup.AttachedAvatar != remoteClient.AgentId) && (ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38)))) 5125 && (ParentGroup.RootPart != this
5126 || ParentGroup.AttachedAvatar != remoteClient.AgentId && ParentGroup.HasPrivateAttachmentPoint))
5079 return; 5127 return;
5080 5128
5081 // Causes this thread to dig into the Client Thread Data. 5129 // Causes this thread to dig into the Client Thread Data.
@@ -5147,5 +5195,99 @@ namespace OpenSim.Region.Framework.Scenes
5147 Inventory.UpdateInventoryItem(item, false, false); 5195 Inventory.UpdateInventoryItem(item, false, false);
5148 } 5196 }
5149 } 5197 }
5198
5199 /// <summary>
5200 /// Record an avatar sitting on this part.
5201 /// </summary>
5202 /// <remarks>This is called for all the sitting avatars whether there is a sit target set or not.</remarks>
5203 /// <returns>
5204 /// true if the avatar was not already recorded, false otherwise.
5205 /// </returns>
5206 /// <param name='avatarId'></param>
5207 protected internal bool AddSittingAvatar(UUID avatarId)
5208 {
5209 if (IsSitTargetSet && SitTargetAvatar == UUID.Zero)
5210 SitTargetAvatar = avatarId;
5211
5212 HashSet<UUID> sittingAvatars = m_sittingAvatars;
5213
5214 if (sittingAvatars == null)
5215 sittingAvatars = new HashSet<UUID>();
5216
5217 lock (sittingAvatars)
5218 {
5219 m_sittingAvatars = sittingAvatars;
5220 return m_sittingAvatars.Add(avatarId);
5221 }
5222 }
5223
5224 /// <summary>
5225 /// Remove an avatar recorded as sitting on this part.
5226 /// </summary>
5227 /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
5228 /// <returns>
5229 /// true if the avatar was present and removed, false if it was not present.
5230 /// </returns>
5231 /// <param name='avatarId'></param>
5232 protected internal bool RemoveSittingAvatar(UUID avatarId)
5233 {
5234 if (SitTargetAvatar == avatarId)
5235 SitTargetAvatar = UUID.Zero;
5236
5237 HashSet<UUID> sittingAvatars = m_sittingAvatars;
5238
5239 // This can occur under a race condition where another thread
5240 if (sittingAvatars == null)
5241 return false;
5242
5243 lock (sittingAvatars)
5244 {
5245 if (sittingAvatars.Remove(avatarId))
5246 {
5247 if (sittingAvatars.Count == 0)
5248 m_sittingAvatars = null;
5249
5250 return true;
5251 }
5252 }
5253
5254 return false;
5255 }
5256
5257 /// <summary>
5258 /// Get a copy of the list of sitting avatars.
5259 /// </summary>
5260 /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
5261 /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns>
5262 public HashSet<UUID> GetSittingAvatars()
5263 {
5264 HashSet<UUID> sittingAvatars = m_sittingAvatars;
5265
5266 if (sittingAvatars == null)
5267 {
5268 return null;
5269 }
5270 else
5271 {
5272 lock (sittingAvatars)
5273 return new HashSet<UUID>(sittingAvatars);
5274 }
5275 }
5276
5277 /// <summary>
5278 /// Gets the number of sitting avatars.
5279 /// </summary>
5280 /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
5281 /// <returns></returns>
5282 public int GetSittingAvatarsCount()
5283 {
5284 HashSet<UUID> sittingAvatars = m_sittingAvatars;
5285
5286 if (sittingAvatars == null)
5287 return 0;
5288
5289 lock (sittingAvatars)
5290 return sittingAvatars.Count;
5291 }
5150 } 5292 }
5151} 5293}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 959046a..1c9a17e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -176,16 +176,14 @@ namespace OpenSim.Region.Framework.Scenes
176 /// <param name="ownerId"></param> 176 /// <param name="ownerId"></param>
177 public void ChangeInventoryOwner(UUID ownerId) 177 public void ChangeInventoryOwner(UUID ownerId)
178 { 178 {
179 m_items.LockItemsForWrite(true); 179 List<TaskInventoryItem> items = GetInventoryItems();
180 if (0 == Items.Count) 180
181 { 181 if (items.Count == 0)
182 m_items.LockItemsForWrite(false);
183 return; 182 return;
184 }
185 183
184 m_items.LockItemsForWrite(true);
186 HasInventoryChanged = true; 185 HasInventoryChanged = true;
187 m_part.ParentGroup.HasGroupChanged = true; 186 m_part.ParentGroup.HasGroupChanged = true;
188 List<TaskInventoryItem> items = GetInventoryItems();
189 foreach (TaskInventoryItem item in items) 187 foreach (TaskInventoryItem item in items)
190 { 188 {
191 if (ownerId != item.OwnerID) 189 if (ownerId != item.OwnerID)
@@ -234,7 +232,7 @@ namespace OpenSim.Region.Framework.Scenes
234 232
235 private void QueryScriptStates() 233 private void QueryScriptStates()
236 { 234 {
237 if (m_part == null || m_part.ParentGroup == null) 235 if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null)
238 return; 236 return;
239 237
240 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 238 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
@@ -262,19 +260,16 @@ namespace OpenSim.Region.Framework.Scenes
262 Items.LockItemsForRead(false); 260 Items.LockItemsForRead(false);
263 } 261 }
264 262
265 /// <summary> 263 public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
266 /// Start all the scripts contained in this prim's inventory
267 /// </summary>
268 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
269 { 264 {
270 Items.LockItemsForRead(true); 265 int scriptsValidForStarting = 0;
271 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 266
272 Items.LockItemsForRead(false); 267 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
273 foreach (TaskInventoryItem item in items) 268 foreach (TaskInventoryItem item in scripts)
274 { 269 if (CreateScriptInstance(item, startParam, postOnRez, engine, stateSource))
275 if ((int)InventoryType.LSL == item.InvType) 270 scriptsValidForStarting++;
276 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 271
277 } 272 return scriptsValidForStarting;
278 } 273 }
279 274
280 public ArrayList GetScriptErrors(UUID itemID) 275 public ArrayList GetScriptErrors(UUID itemID)
@@ -297,7 +292,7 @@ namespace OpenSim.Region.Framework.Scenes
297 } 292 }
298 293
299 /// <summary> 294 /// <summary>
300 /// Stop all the scripts in this prim. 295 /// Stop and remove all the scripts in this prim.
301 /// </summary> 296 /// </summary>
302 /// <param name="sceneObjectBeingDeleted"> 297 /// <param name="sceneObjectBeingDeleted">
303 /// Should be true if these scripts are being removed because the scene 298 /// Should be true if these scripts are being removed because the scene
@@ -305,26 +300,28 @@ namespace OpenSim.Region.Framework.Scenes
305 /// </param> 300 /// </param>
306 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 301 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
307 { 302 {
308 Items.LockItemsForRead(true); 303 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
309 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 304 foreach (TaskInventoryItem item in scripts)
310 Items.LockItemsForRead(false);
311
312 foreach (TaskInventoryItem item in items)
313 { 305 {
314 if ((int)InventoryType.LSL == item.InvType) 306 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
315 { 307 m_part.RemoveScriptEvents(item.ItemID);
316 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
317 m_part.RemoveScriptEvents(item.ItemID);
318 }
319 } 308 }
320 } 309 }
321 310
322 /// <summary> 311 /// <summary>
312 /// Stop all the scripts in this prim.
313 /// </summary>
314 public void StopScriptInstances()
315 {
316 GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i));
317 }
318
319 /// <summary>
323 /// Start a script which is in this prim's inventory. 320 /// Start a script which is in this prim's inventory.
324 /// </summary> 321 /// </summary>
325 /// <param name="item"></param> 322 /// <param name="item"></param>
326 /// <returns></returns> 323 /// <returns>true if the script instance was created, false otherwise</returns>
327 public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource) 324 public bool CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource)
328 { 325 {
329// m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}", 326// m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}",
330// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); 327// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName);
@@ -332,61 +329,70 @@ namespace OpenSim.Region.Framework.Scenes
332 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 329 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
333 { 330 {
334 StoreScriptError(item.ItemID, "no permission"); 331 StoreScriptError(item.ItemID, "no permission");
335 return; 332 return false;
336 } 333 }
337 334
338 m_part.AddFlag(PrimFlags.Scripted); 335 m_part.AddFlag(PrimFlags.Scripted);
339 336
340 if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) 337 if (m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts)
338 return false;
339
340 if (stateSource == 2 && // Prim crossing
341 m_part.ParentGroup.Scene.m_trustBinaries)
341 { 342 {
342 if (stateSource == 2 && // Prim crossing 343 m_items.LockItemsForWrite(true);
343 m_part.ParentGroup.Scene.m_trustBinaries) 344 m_items[item.ItemID].PermsMask = 0;
344 { 345 m_items[item.ItemID].PermsGranter = UUID.Zero;
345 m_items.LockItemsForWrite(true); 346 m_items.LockItemsForWrite(false);
346 m_items[item.ItemID].PermsMask = 0; 347 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
347 m_items[item.ItemID].PermsGranter = UUID.Zero; 348 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
348 m_items.LockItemsForWrite(false); 349 StoreScriptErrors(item.ItemID, null);
349 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 350 m_part.ParentGroup.AddActiveScriptCount(1);
350 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 351 m_part.ScheduleFullUpdate();
351 StoreScriptErrors(item.ItemID, null); 352 return true;
352 m_part.ParentGroup.AddActiveScriptCount(1); 353 }
353 m_part.ScheduleFullUpdate();
354 return;
355 }
356 354
357 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 355 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
358 if (null == asset) 356 if (null == asset)
359 { 357 {
360 string msg = String.Format("asset ID {0} could not be found", item.AssetID); 358 m_log.ErrorFormat(
361 StoreScriptError(item.ItemID, msg); 359 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
362 m_log.ErrorFormat( 360 item.Name, item.ItemID, m_part.AbsolutePosition,
361 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
362
363 return false;
364 }
365 else
366 {
367 if (m_part.ParentGroup.m_savedScriptState != null)
368 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID);
369
370 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
371 StoreScriptError(item.ItemID, msg);
372 m_log.ErrorFormat(
363 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 373 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
364 item.Name, item.ItemID, m_part.AbsolutePosition, 374 item.Name, item.ItemID, m_part.AbsolutePosition,
365 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); 375 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
366 }
367 else
368 {
369 if (m_part.ParentGroup.m_savedScriptState != null)
370 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID);
371 376
372 m_items.LockItemsForWrite(true); 377 m_items.LockItemsForWrite(true);
373 378
374 m_items[item.ItemID].OldItemID = item.OldItemID; 379 m_items[item.ItemID].OldItemID = item.OldItemID;
375 m_items[item.ItemID].PermsMask = 0; 380 m_items[item.ItemID].PermsMask = 0;
376 m_items[item.ItemID].PermsGranter = UUID.Zero; 381 m_items[item.ItemID].PermsGranter = UUID.Zero;
377 382
378 m_items.LockItemsForWrite(false); 383 m_items.LockItemsForWrite(false);
379 384
380 string script = Utils.BytesToString(asset.Data); 385 string script = Utils.BytesToString(asset.Data);
381 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 386 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
382 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 387 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
383 StoreScriptErrors(item.ItemID, null); 388 StoreScriptErrors(item.ItemID, null);
384 if (!item.ScriptRunning) 389 if (!item.ScriptRunning)
385 m_part.ParentGroup.Scene.EventManager.TriggerStopScript( 390 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
386 m_part.LocalId, item.ItemID); 391 m_part.LocalId, item.ItemID);
387 m_part.ParentGroup.AddActiveScriptCount(1); 392 m_part.ParentGroup.AddActiveScriptCount(1);
388 m_part.ScheduleFullUpdate(); 393 m_part.ScheduleFullUpdate();
389 } 394
395 return true;
390 } 396 }
391 } 397 }
392 398
@@ -459,7 +465,7 @@ namespace OpenSim.Region.Framework.Scenes
459 /// <param name="itemId"> 465 /// <param name="itemId">
460 /// A <see cref="UUID"/> 466 /// A <see cref="UUID"/>
461 /// </param> 467 /// </param>
462 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 468 public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
463 { 469 {
464 lock (m_scriptErrors) 470 lock (m_scriptErrors)
465 { 471 {
@@ -467,6 +473,7 @@ namespace OpenSim.Region.Framework.Scenes
467 m_scriptErrors.Remove(itemId); 473 m_scriptErrors.Remove(itemId);
468 } 474 }
469 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); 475 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
476 return true;
470 } 477 }
471 478
472 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 479 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
@@ -597,7 +604,7 @@ namespace OpenSim.Region.Framework.Scenes
597 } 604 }
598 605
599 /// <summary> 606 /// <summary>
600 /// Stop a script which is in this prim's inventory. 607 /// Stop and remove a script which is in this prim's inventory.
601 /// </summary> 608 /// </summary>
602 /// <param name="itemId"></param> 609 /// <param name="itemId"></param>
603 /// <param name="sceneObjectBeingDeleted"> 610 /// <param name="sceneObjectBeingDeleted">
@@ -616,7 +623,7 @@ namespace OpenSim.Region.Framework.Scenes
616 } 623 }
617 else 624 else
618 { 625 {
619 m_log.ErrorFormat( 626 m_log.WarnFormat(
620 "[PRIM INVENTORY]: " + 627 "[PRIM INVENTORY]: " +
621 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 628 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
622 itemId, m_part.Name, m_part.UUID, 629 itemId, m_part.Name, m_part.UUID,
@@ -625,6 +632,51 @@ namespace OpenSim.Region.Framework.Scenes
625 } 632 }
626 633
627 /// <summary> 634 /// <summary>
635 /// Stop a script which is in this prim's inventory.
636 /// </summary>
637 /// <param name="itemId"></param>
638 /// <param name="sceneObjectBeingDeleted">
639 /// Should be true if this script is being removed because the scene
640 /// object is being deleted. This will prevent spurious updates to the client.
641 /// </param>
642 public void StopScriptInstance(UUID itemId)
643 {
644 TaskInventoryItem scriptItem;
645
646 lock (m_items)
647 m_items.TryGetValue(itemId, out scriptItem);
648
649 if (scriptItem != null)
650 {
651 StopScriptInstance(scriptItem);
652 }
653 else
654 {
655 m_log.WarnFormat(
656 "[PRIM INVENTORY]: " +
657 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
658 itemId, m_part.Name, m_part.UUID,
659 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
660 }
661 }
662
663 /// <summary>
664 /// Stop a script which is in this prim's inventory.
665 /// </summary>
666 /// <param name="itemId"></param>
667 /// <param name="sceneObjectBeingDeleted">
668 /// Should be true if this script is being removed because the scene
669 /// object is being deleted. This will prevent spurious updates to the client.
670 /// </param>
671 public void StopScriptInstance(TaskInventoryItem item)
672 {
673 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
674
675 // At the moment, even stopped scripts are counted as active, which is probably wrong.
676// m_part.ParentGroup.AddActiveScriptCount(-1);
677 }
678
679 /// <summary>
628 /// Check if the inventory holds an item with a given name. 680 /// Check if the inventory holds an item with a given name.
629 /// </summary> 681 /// </summary>
630 /// <param name="name"></param> 682 /// <param name="name"></param>
@@ -770,14 +822,22 @@ namespace OpenSim.Region.Framework.Scenes
770 return item; 822 return item;
771 } 823 }
772 824
773 /// <summary> 825 public TaskInventoryItem GetInventoryItem(string name)
774 /// Get inventory items by name. 826 {
775 /// </summary> 827 m_items.LockItemsForRead(true);
776 /// <param name="name"></param> 828 foreach (TaskInventoryItem item in m_items.Values)
777 /// <returns> 829 {
778 /// A list of inventory items with that name. 830 if (item.Name == name)
779 /// If no inventory item has that name then an empty list is returned. 831 {
780 /// </returns> 832 m_items.LockItemsForRead(false);
833 return item;
834 }
835 }
836 m_items.LockItemsForRead(false);
837
838 return null;
839 }
840
781 public List<TaskInventoryItem> GetInventoryItems(string name) 841 public List<TaskInventoryItem> GetInventoryItems(string name)
782 { 842 {
783 List<TaskInventoryItem> items = new List<TaskInventoryItem>(); 843 List<TaskInventoryItem> items = new List<TaskInventoryItem>();
@@ -1247,10 +1307,10 @@ namespace OpenSim.Region.Framework.Scenes
1247 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) 1307 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1248 item.CurrentPermissions &= ~(uint)PermissionMask.Modify; 1308 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1249 } 1309 }
1250 item.OwnerChanged = true;
1251 item.CurrentPermissions &= item.NextPermissions; 1310 item.CurrentPermissions &= item.NextPermissions;
1252 item.BasePermissions &= item.NextPermissions; 1311 item.BasePermissions &= item.NextPermissions;
1253 item.EveryonePermissions &= item.NextPermissions; 1312 item.EveryonePermissions &= item.NextPermissions;
1313 item.OwnerChanged = true;
1254 item.PermsMask = 0; 1314 item.PermsMask = 0;
1255 item.PermsGranter = UUID.Zero; 1315 item.PermsGranter = UUID.Zero;
1256 } 1316 }
@@ -1281,9 +1341,57 @@ namespace OpenSim.Region.Framework.Scenes
1281 return true; 1341 return true;
1282 } 1342 }
1283 } 1343 }
1344
1284 return false; 1345 return false;
1285 } 1346 }
1286 1347
1348 /// <summary>
1349 /// Returns the count of scripts in this parts inventory.
1350 /// </summary>
1351 /// <returns></returns>
1352 public int ScriptCount()
1353 {
1354 int count = 0;
1355 Items.LockItemsForRead(true);
1356 foreach (TaskInventoryItem item in m_items.Values)
1357 {
1358 if (item.InvType == (int)InventoryType.LSL)
1359 {
1360 count++;
1361 }
1362 }
1363 Items.LockItemsForRead(false);
1364 return count;
1365 }
1366 /// <summary>
1367 /// Returns the count of running scripts in this parts inventory.
1368 /// </summary>
1369 /// <returns></returns>
1370 public int RunningScriptCount()
1371 {
1372 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1373 if (engines.Length == 0)
1374 return 0;
1375
1376 int count = 0;
1377 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1378
1379 foreach (TaskInventoryItem item in scripts)
1380 {
1381 foreach (IScriptModule engine in engines)
1382 {
1383 if (engine != null)
1384 {
1385 if (engine.GetScriptState(item.ItemID))
1386 {
1387 count++;
1388 }
1389 }
1390 }
1391 }
1392 return count;
1393 }
1394
1287 public List<UUID> GetInventoryList() 1395 public List<UUID> GetInventoryList()
1288 { 1396 {
1289 List<UUID> ret = new List<UUID>(); 1397 List<UUID> ret = new List<UUID>();
@@ -1298,22 +1406,24 @@ namespace OpenSim.Region.Framework.Scenes
1298 { 1406 {
1299 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1407 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1300 1408
1301 lock (m_items) 1409 Items.LockItemsForRead(true);
1302 ret = new List<TaskInventoryItem>(m_items.Values); 1410 ret = new List<TaskInventoryItem>(m_items.Values);
1411 Items.LockItemsForRead(false);
1303 1412
1304 return ret; 1413 return ret;
1305 } 1414 }
1306 1415
1307 public List<TaskInventoryItem> GetInventoryScripts() 1416 public List<TaskInventoryItem> GetInventoryItems(InventoryType type)
1308 { 1417 {
1309 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1418 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1310 1419
1311 lock (m_items) 1420 Items.LockItemsForRead(true);
1312 { 1421
1313 foreach (TaskInventoryItem item in m_items.Values) 1422 foreach (TaskInventoryItem item in m_items.Values)
1314 if (item.InvType == (int)InventoryType.LSL) 1423 if (item.InvType == (int)type)
1315 ret.Add(item); 1424 ret.Add(item);
1316 } 1425
1426 Items.LockItemsForRead(false);
1317 1427
1318 return ret; 1428 return ret;
1319 } 1429 }
@@ -1335,35 +1445,36 @@ namespace OpenSim.Region.Framework.Scenes
1335 if (engines.Length == 0) // No engine at all 1445 if (engines.Length == 0) // No engine at all
1336 return ret; 1446 return ret;
1337 1447
1338 Items.LockItemsForRead(true); 1448 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1339 foreach (TaskInventoryItem item in m_items.Values) 1449
1450 foreach (TaskInventoryItem item in scripts)
1340 { 1451 {
1341 if (item.InvType == (int)InventoryType.LSL) 1452 foreach (IScriptModule e in engines)
1342 { 1453 {
1343 foreach (IScriptModule e in engines) 1454 if (e != null)
1344 { 1455 {
1345 if (e != null) 1456// m_log.DebugFormat(
1457// "[PRIM INVENTORY]: Getting script state from engine {0} for {1} in part {2} in group {3} in {4}",
1458// e.Name, item.Name, m_part.Name, m_part.ParentGroup.Name, m_part.ParentGroup.Scene.Name);
1459
1460 string n = e.GetXMLState(item.ItemID);
1461 if (n != String.Empty)
1346 { 1462 {
1347 string n = e.GetXMLState(item.ItemID); 1463 if (oldIDs)
1348 if (n != String.Empty) 1464 {
1465 if (!ret.ContainsKey(item.OldItemID))
1466 ret[item.OldItemID] = n;
1467 }
1468 else
1349 { 1469 {
1350 if (oldIDs) 1470 if (!ret.ContainsKey(item.ItemID))
1351 { 1471 ret[item.ItemID] = n;
1352 if (!ret.ContainsKey(item.OldItemID))
1353 ret[item.OldItemID] = n;
1354 }
1355 else
1356 {
1357 if (!ret.ContainsKey(item.ItemID))
1358 ret[item.ItemID] = n;
1359 }
1360 break;
1361 } 1472 }
1473 break;
1362 } 1474 }
1363 } 1475 }
1364 } 1476 }
1365 } 1477 }
1366 Items.LockItemsForRead(false);
1367 return ret; 1478 return ret;
1368 } 1479 }
1369 1480
@@ -1373,27 +1484,27 @@ namespace OpenSim.Region.Framework.Scenes
1373 if (engines.Length == 0) 1484 if (engines.Length == 0)
1374 return; 1485 return;
1375 1486
1487 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1376 1488
1377 Items.LockItemsForRead(true); 1489 foreach (TaskInventoryItem item in scripts)
1378
1379 foreach (TaskInventoryItem item in m_items.Values)
1380 { 1490 {
1381 if (item.InvType == (int)InventoryType.LSL) 1491 foreach (IScriptModule engine in engines)
1382 { 1492 {
1383 foreach (IScriptModule engine in engines) 1493 if (engine != null)
1384 { 1494 {
1385 if (engine != null) 1495// m_log.DebugFormat(
1386 { 1496// "[PRIM INVENTORY]: Resuming script {0} {1} for {2}, OwnerChanged {3}",
1387 if (item.OwnerChanged) 1497// item.Name, item.ItemID, item.OwnerID, item.OwnerChanged);
1388 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1498
1389 item.OwnerChanged = false; 1499 engine.ResumeScript(item.ItemID);
1390 engine.ResumeScript(item.ItemID); 1500
1391 } 1501 if (item.OwnerChanged)
1502 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1503
1504 item.OwnerChanged = false;
1392 } 1505 }
1393 } 1506 }
1394 } 1507 }
1395
1396 Items.LockItemsForRead(false);
1397 } 1508 }
1398 } 1509 }
1399} 1510}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4940063..e27d309 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -45,6 +45,7 @@ using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
45 45
46namespace OpenSim.Region.Framework.Scenes 46namespace OpenSim.Region.Framework.Scenes
47{ 47{
48 [Flags]
48 enum ScriptControlled : uint 49 enum ScriptControlled : uint
49 { 50 {
50 CONTROL_ZERO = 0, 51 CONTROL_ZERO = 0,
@@ -76,6 +77,11 @@ namespace OpenSim.Region.Framework.Scenes
76// { 77// {
77// m_log.Debug("[SCENE PRESENCE] Destructor called"); 78// m_log.Debug("[SCENE PRESENCE] Destructor called");
78// } 79// }
80 private void TriggerScenePresenceUpdated()
81 {
82 if (m_scene != null)
83 m_scene.EventManager.TriggerScenePresenceUpdated(this);
84 }
79 85
80 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 86 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
81 87
@@ -497,6 +503,7 @@ namespace OpenSim.Region.Framework.Scenes
497 //m_log.DebugFormat( 503 //m_log.DebugFormat(
498 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 504 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
499 // Scene.RegionInfo.RegionName, Name, m_pos); 505 // Scene.RegionInfo.RegionName, Name, m_pos);
506 TriggerScenePresenceUpdated();
500 } 507 }
501 } 508 }
502 509
@@ -516,6 +523,7 @@ namespace OpenSim.Region.Framework.Scenes
516 return; 523 return;
517 524
518 m_pos = value; 525 m_pos = value;
526 TriggerScenePresenceUpdated();
519 } 527 }
520 } 528 }
521 529
@@ -586,6 +594,12 @@ namespace OpenSim.Region.Framework.Scenes
586 private UUID m_parentUUID = UUID.Zero; 594 private UUID m_parentUUID = UUID.Zero;
587 595
588 /// <summary> 596 /// <summary>
597 /// Are we sitting on an object?
598 /// </summary>
599 /// <remarks>A more readable way of testing presence sit status than ParentID == 0</remarks>
600 public bool IsSatOnObject { get { return ParentID != 0; } }
601
602 /// <summary>
589 /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null. 603 /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null.
590 /// </summary> 604 /// </summary>
591 /// <remarks> 605 /// <remarks>
@@ -1087,23 +1101,13 @@ namespace OpenSim.Region.Framework.Scenes
1087 /// <param name="pos"></param> 1101 /// <param name="pos"></param>
1088 public void Teleport(Vector3 pos) 1102 public void Teleport(Vector3 pos)
1089 { 1103 {
1090 bool isFlying = Flying; 1104 TeleportWithMomentum(pos, Vector3.Zero);
1091 RemoveFromPhysicalScene();
1092 Velocity = Vector3.Zero;
1093 CheckLandingPoint(ref pos);
1094 AbsolutePosition = pos;
1095 AddToPhysicalScene(isFlying);
1096
1097 SendTerseUpdateToAllClients();
1098 }
1099
1100 public void TeleportWithMomentum(Vector3 pos)
1101 {
1102 TeleportWithMomentum(pos, null);
1103 } 1105 }
1104 1106
1105 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1107 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
1106 { 1108 {
1109 if (ParentID != (uint)0)
1110 StandUp();
1107 bool isFlying = Flying; 1111 bool isFlying = Flying;
1108 Vector3 vel = Velocity; 1112 Vector3 vel = Velocity;
1109 RemoveFromPhysicalScene(); 1113 RemoveFromPhysicalScene();
@@ -1283,17 +1287,33 @@ namespace OpenSim.Region.Framework.Scenes
1283 1287
1284 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1288 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1285 MakeRootAgent(AbsolutePosition, flying); 1289 MakeRootAgent(AbsolutePosition, flying);
1290 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1291
1292// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1286 1293
1287 if ((m_callbackURI != null) && !m_callbackURI.Equals("")) 1294 if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
1288 { 1295 {
1289 m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); 1296 // We cannot sleep here since this would hold up the inbound packet processing thread, as
1297 // CompleteMovement() is executed synchronously. However, it might be better to delay the release
1298 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
1299 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
1300 // region as the current region, meaning that a close sent before then will fail the teleport.
1301// System.Threading.Thread.Sleep(2000);
1302
1303 m_log.DebugFormat(
1304 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1305 client.Name, client.AgentId, m_callbackURI);
1306
1290 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); 1307 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
1291 m_callbackURI = null; 1308 m_callbackURI = null;
1292 } 1309 }
1310// else
1311// {
1312// m_log.DebugFormat(
1313// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
1314// client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
1315// }
1293 1316
1294// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1295
1296 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1297 ValidateAndSendAppearanceAndAgentData(); 1317 ValidateAndSendAppearanceAndAgentData();
1298 1318
1299 // Create child agents in neighbouring regions 1319 // Create child agents in neighbouring regions
@@ -1308,7 +1328,6 @@ namespace OpenSim.Region.Framework.Scenes
1308 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1328 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1309 } 1329 }
1310 1330
1311
1312// m_log.DebugFormat( 1331// m_log.DebugFormat(
1313// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1332// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1314// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 1333// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
@@ -1361,7 +1380,7 @@ namespace OpenSim.Region.Framework.Scenes
1361 { 1380 {
1362// m_log.DebugFormat( 1381// m_log.DebugFormat(
1363// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", 1382// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
1364// Scene.RegionInfo.RegionName, remoteClient.Name, agentData.ControlFlags); 1383// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
1365 1384
1366 if (IsChildAgent) 1385 if (IsChildAgent)
1367 { 1386 {
@@ -1471,14 +1490,8 @@ namespace OpenSim.Region.Framework.Scenes
1471 } 1490 }
1472 } 1491 }
1473 1492
1474 lock (scriptedcontrols) 1493 uint flagsForScripts = (uint)flags;
1475 { 1494 flags = RemoveIgnoredControls(flags, IgnoredControls);
1476 if (scriptedcontrols.Count > 0)
1477 {
1478 SendControlToScripts((uint)flags);
1479 flags = RemoveIgnoredControls(flags, IgnoredControls);
1480 }
1481 }
1482 1495
1483 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1496 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1484 HandleAgentSitOnGround(); 1497 HandleAgentSitOnGround();
@@ -1492,6 +1505,7 @@ namespace OpenSim.Region.Framework.Scenes
1492 PhysicsActor actor = PhysicsActor; 1505 PhysicsActor actor = PhysicsActor;
1493 if (actor == null) 1506 if (actor == null)
1494 { 1507 {
1508 SendControlsToScripts(flagsForScripts);
1495 return; 1509 return;
1496 } 1510 }
1497 1511
@@ -1571,7 +1585,7 @@ namespace OpenSim.Region.Framework.Scenes
1571 MovementFlag |= (byte)nudgehack; 1585 MovementFlag |= (byte)nudgehack;
1572 } 1586 }
1573 1587
1574// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); 1588 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
1575 MovementFlag += (byte)(uint)DCF; 1589 MovementFlag += (byte)(uint)DCF;
1576 update_movementflag = true; 1590 update_movementflag = true;
1577 } 1591 }
@@ -1584,7 +1598,7 @@ namespace OpenSim.Region.Framework.Scenes
1584 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1598 && ((MovementFlag & (byte)nudgehack) == nudgehack))
1585 ) // This or is for Nudge forward 1599 ) // This or is for Nudge forward
1586 { 1600 {
1587// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1601 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
1588 MovementFlag -= ((byte)(uint)DCF); 1602 MovementFlag -= ((byte)(uint)DCF);
1589 update_movementflag = true; 1603 update_movementflag = true;
1590 1604
@@ -1665,11 +1679,14 @@ namespace OpenSim.Region.Framework.Scenes
1665// } 1679// }
1666// } 1680// }
1667 1681
1668// if (update_movementflag && ParentID == 0) 1682 if (update_movementflag && ParentID == 0)
1669// Animator.UpdateMovementAnimations(); 1683 Animator.UpdateMovementAnimations();
1684
1685 SendControlsToScripts(flagsForScripts);
1670 } 1686 }
1671 1687
1672 m_scene.EventManager.TriggerOnClientMovement(this); 1688 m_scene.EventManager.TriggerOnClientMovement(this);
1689 TriggerScenePresenceUpdated();
1673 } 1690 }
1674 1691
1675 /// <summary> 1692 /// <summary>
@@ -1929,10 +1946,6 @@ namespace OpenSim.Region.Framework.Scenes
1929 } 1946 }
1930 } 1947 }
1931 1948
1932 // Reset sit target.
1933 if (part.SitTargetAvatar == UUID)
1934 part.SitTargetAvatar = UUID.Zero;
1935
1936 part.ParentGroup.DeleteAvatar(UUID); 1949 part.ParentGroup.DeleteAvatar(UUID);
1937// ParentPosition = part.GetWorldPosition(); 1950// ParentPosition = part.GetWorldPosition();
1938 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1951 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
@@ -1950,6 +1963,8 @@ namespace OpenSim.Region.Framework.Scenes
1950 SendAvatarDataToAllAgents(); 1963 SendAvatarDataToAllAgents();
1951 m_requestedSitTargetID = 0; 1964 m_requestedSitTargetID = 0;
1952 1965
1966 part.RemoveSittingAvatar(UUID);
1967
1953 if (part != null) 1968 if (part != null)
1954 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 1969 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1955 } 1970 }
@@ -1983,15 +1998,7 @@ namespace OpenSim.Region.Framework.Scenes
1983 //look for prims with explicit sit targets that are available 1998 //look for prims with explicit sit targets that are available
1984 foreach (SceneObjectPart part in partArray) 1999 foreach (SceneObjectPart part in partArray)
1985 { 2000 {
1986 // Is a sit target available? 2001 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
1987 Vector3 avSitOffset = part.SitTargetPosition;
1988 Quaternion avSitOrientation = part.SitTargetOrientation;
1989 UUID avOnTargetAlready = part.SitTargetAvatar;
1990
1991 bool SitTargetUnOccupied = avOnTargetAlready == UUID.Zero;
1992 bool SitTargetisSet = avSitOffset != Vector3.Zero || avSitOrientation != Quaternion.Identity;
1993
1994 if (SitTargetisSet && SitTargetUnOccupied)
1995 { 2002 {
1996 //switch the target to this prim 2003 //switch the target to this prim
1997 return part; 2004 return part;
@@ -2002,10 +2009,8 @@ namespace OpenSim.Region.Framework.Scenes
2002 return targetPart; 2009 return targetPart;
2003 } 2010 }
2004 2011
2005 private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2012 private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion sitOrientation)
2006 { 2013 {
2007 Vector3 pos = new Vector3();
2008 Quaternion sitOrientation = pSitOrientation;
2009 Vector3 cameraEyeOffset = Vector3.Zero; 2014 Vector3 cameraEyeOffset = Vector3.Zero;
2010 Vector3 cameraAtOffset = Vector3.Zero; 2015 Vector3 cameraAtOffset = Vector3.Zero;
2011 bool forceMouselook = false; 2016 bool forceMouselook = false;
@@ -2017,54 +2022,39 @@ namespace OpenSim.Region.Framework.Scenes
2017 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2022 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2018 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2023 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2019 2024
2020 // Is a sit target available?
2021 Vector3 avSitOffSet = part.SitTargetPosition;
2022 Quaternion avSitOrientation = part.SitTargetOrientation;
2023 UUID avOnTargetAlready = part.SitTargetAvatar;
2024
2025 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
2026 bool SitTargetisSet =
2027 (!(avSitOffSet == Vector3.Zero &&
2028 (
2029 avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
2030 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
2031 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
2032 )
2033 ));
2034
2035// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
2036
2037 if (PhysicsActor != null) 2025 if (PhysicsActor != null)
2038 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; 2026 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2039 2027
2040 bool canSit = false; 2028 bool canSit = false;
2041 pos = part.AbsolutePosition + offset; 2029 Vector3 pos = part.AbsolutePosition + offset;
2042 2030
2043 if (SitTargetisSet) 2031 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
2044 { 2032 {
2045 if (SitTargetUnOccupied) 2033// m_log.DebugFormat(
2046 { 2034// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
2047 m_log.DebugFormat( 2035// Name, part.Name, part.LocalId);
2048 "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
2049 Name, part.Name, part.LocalId);
2050 2036
2051 part.SitTargetAvatar = UUID; 2037 offset = part.SitTargetPosition;
2052 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 2038 sitOrientation = part.SitTargetOrientation;
2053 sitOrientation = avSitOrientation; 2039 canSit = true;
2054 canSit = true;
2055 }
2056 } 2040 }
2057 else 2041 else
2058 { 2042 {
2059 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2043 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2060 { 2044 {
2061 m_log.DebugFormat( 2045// m_log.DebugFormat(
2062 "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", 2046// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2063 Name, part.Name, part.LocalId); 2047// Name, part.Name, part.LocalId);
2064 2048
2065 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2049 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2066 canSit = true; 2050 canSit = true;
2067 } 2051 }
2052// else
2053// {
2054// m_log.DebugFormat(
2055// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2056// Name, part.Name, part.LocalId);
2057// }
2068 } 2058 }
2069 2059
2070 if (canSit) 2060 if (canSit)
@@ -2075,6 +2065,8 @@ namespace OpenSim.Region.Framework.Scenes
2075 RemoveFromPhysicalScene(); 2065 RemoveFromPhysicalScene();
2076 } 2066 }
2077 2067
2068 part.AddSittingAvatar(UUID);
2069
2078 cameraAtOffset = part.GetCameraAtOffset(); 2070 cameraAtOffset = part.GetCameraAtOffset();
2079 cameraEyeOffset = part.GetCameraEyeOffset(); 2071 cameraEyeOffset = part.GetCameraEyeOffset();
2080 forceMouselook = part.GetForceMouselook(); 2072 forceMouselook = part.GetForceMouselook();
@@ -2351,6 +2343,15 @@ namespace OpenSim.Region.Framework.Scenes
2351 2343
2352 if (part != null) 2344 if (part != null)
2353 { 2345 {
2346 if (part.ParentGroup.IsAttachment)
2347 {
2348 m_log.WarnFormat(
2349 "[SCENE PRESENCE]: Avatar {0} tried to sit on part {1} from object {2} in {3} but this is an attachment for avatar id {4}",
2350 Name, part.Name, part.ParentGroup.Name, Scene.Name, part.ParentGroup.AttachedAvatar);
2351
2352 return;
2353 }
2354
2354 if (part.SitTargetAvatar == UUID) 2355 if (part.SitTargetAvatar == UUID)
2355 { 2356 {
2356 Vector3 sitTargetPos = part.SitTargetPosition; 2357 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2616,6 +2617,7 @@ namespace OpenSim.Region.Framework.Scenes
2616 2617
2617 m_scene.ForEachClient(SendTerseUpdateToClient); 2618 m_scene.ForEachClient(SendTerseUpdateToClient);
2618 } 2619 }
2620 TriggerScenePresenceUpdated();
2619 } 2621 }
2620 2622
2621 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2623 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -2694,7 +2696,7 @@ namespace OpenSim.Region.Framework.Scenes
2694 // If we are using the the cached appearance then send it out to everyone 2696 // If we are using the the cached appearance then send it out to everyone
2695 if (cachedappearance) 2697 if (cachedappearance)
2696 { 2698 {
2697 m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); 2699 m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name);
2698 2700
2699 // If the avatars baked textures are all in the cache, then we have a 2701 // If the avatars baked textures are all in the cache, then we have a
2700 // complete appearance... send it out, if not, then we'll send it when 2702 // complete appearance... send it out, if not, then we'll send it when
@@ -3099,8 +3101,8 @@ namespace OpenSim.Region.Framework.Scenes
3099 x = x / Constants.RegionSize; 3101 x = x / Constants.RegionSize;
3100 y = y / Constants.RegionSize; 3102 y = y / Constants.RegionSize;
3101 3103
3102 //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); 3104// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
3103 //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); 3105// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
3104 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) 3106 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY))
3105 { 3107 {
3106 byebyeRegions.Add(handle); 3108 byebyeRegions.Add(handle);
@@ -3157,7 +3159,7 @@ namespace OpenSim.Region.Framework.Scenes
3157 3159
3158 public void ChildAgentDataUpdate(AgentData cAgentData) 3160 public void ChildAgentDataUpdate(AgentData cAgentData)
3159 { 3161 {
3160 //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); 3162// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
3161 if (!IsChildAgent) 3163 if (!IsChildAgent)
3162 return; 3164 return;
3163 3165
@@ -3269,31 +3271,8 @@ namespace OpenSim.Region.Framework.Scenes
3269 catch { } 3271 catch { }
3270 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; 3272 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation;
3271 3273
3272 // Attachment objects 3274 if (Scene.AttachmentsModule != null)
3273 List<SceneObjectGroup> attachments = GetAttachments(); 3275 Scene.AttachmentsModule.CopyAttachments(this, cAgent);
3274 if (attachments.Count > 0)
3275 {
3276 cAgent.AttachmentObjects = new List<ISceneObject>();
3277 cAgent.AttachmentObjectStates = new List<string>();
3278// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
3279 InTransitScriptStates.Clear();
3280
3281 foreach (SceneObjectGroup sog in attachments)
3282 {
3283 // We need to make a copy and pass that copy
3284 // because of transfers withn the same sim
3285 ISceneObject clone = sog.CloneForNewScene();
3286 // Attachment module assumes that GroupPosition holds the offsets...!
3287 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
3288 ((SceneObjectGroup)clone).IsAttachment = false;
3289 cAgent.AttachmentObjects.Add(clone);
3290 string state = sog.GetStateSnapshot();
3291 cAgent.AttachmentObjectStates.Add(state);
3292 InTransitScriptStates.Add(state);
3293 // Let's remove the scripts of the original object here
3294 sog.RemoveScriptInstances(true);
3295 }
3296 }
3297 } 3276 }
3298 3277
3299 private void CopyFrom(AgentData cAgent) 3278 private void CopyFrom(AgentData cAgent)
@@ -3301,6 +3280,9 @@ namespace OpenSim.Region.Framework.Scenes
3301 m_originRegionID = cAgent.RegionID; 3280 m_originRegionID = cAgent.RegionID;
3302 3281
3303 m_callbackURI = cAgent.CallbackURI; 3282 m_callbackURI = cAgent.CallbackURI;
3283// m_log.DebugFormat(
3284// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
3285// Name, m_scene.RegionInfo.RegionName, m_callbackURI);
3304 3286
3305 m_pos = cAgent.Position; 3287 m_pos = cAgent.Position;
3306 m_velocity = cAgent.Velocity; 3288 m_velocity = cAgent.Velocity;
@@ -3365,18 +3347,8 @@ namespace OpenSim.Region.Framework.Scenes
3365 if (cAgent.DefaultAnim != null) 3347 if (cAgent.DefaultAnim != null)
3366 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); 3348 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
3367 3349
3368 if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0) 3350 if (Scene.AttachmentsModule != null)
3369 { 3351 Scene.AttachmentsModule.CopyAttachments(cAgent, this);
3370 m_attachments = new List<SceneObjectGroup>();
3371 int i = 0;
3372 foreach (ISceneObject so in cAgent.AttachmentObjects)
3373 {
3374 ((SceneObjectGroup)so).LocalId = 0;
3375 ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
3376 so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
3377 m_scene.IncomingCreateObject(Vector3.Zero, so);
3378 }
3379 }
3380 } 3352 }
3381 3353
3382 public bool CopyAgent(out IAgentData agent) 3354 public bool CopyAgent(out IAgentData agent)
@@ -3402,6 +3374,7 @@ namespace OpenSim.Region.Framework.Scenes
3402 Velocity = force; 3374 Velocity = force;
3403 3375
3404 m_forceToApply = null; 3376 m_forceToApply = null;
3377 TriggerScenePresenceUpdated();
3405 } 3378 }
3406 } 3379 }
3407 3380
@@ -3509,23 +3482,53 @@ namespace OpenSim.Region.Framework.Scenes
3509 3482
3510 RaiseCollisionScriptEvents(coldata); 3483 RaiseCollisionScriptEvents(coldata);
3511 3484
3512 if (Invulnerable || GodLevel >= 200) 3485 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3486 if (Invulnerable || GodLevel > 0)
3513 return; 3487 return;
3514 3488
3489 // The following may be better in the ICombatModule
3490 // probably tweaking of the values for ground and normal prim collisions will be needed
3515 float starthealth = Health; 3491 float starthealth = Health;
3516 uint killerObj = 0; 3492 uint killerObj = 0;
3493 SceneObjectPart part = null;
3517 foreach (uint localid in coldata.Keys) 3494 foreach (uint localid in coldata.Keys)
3518 { 3495 {
3519 SceneObjectPart part = Scene.GetSceneObjectPart(localid); 3496 if (localid == 0)
3520 3497 {
3521 if (part != null && part.ParentGroup.Damage != -1.0f) 3498 part = null;
3522 Health -= part.ParentGroup.Damage; 3499 }
3500 else
3501 {
3502 part = Scene.GetSceneObjectPart(localid);
3503 }
3504 if (part != null)
3505 {
3506 // Ignore if it has been deleted or volume detect
3507 if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect)
3508 {
3509 if (part.ParentGroup.Damage > 0.0f)
3510 {
3511 // Something with damage...
3512 Health -= part.ParentGroup.Damage;
3513 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
3514 }
3515 else
3516 {
3517 // An ordinary prim
3518 if (coldata[localid].PenetrationDepth >= 0.10f)
3519 Health -= coldata[localid].PenetrationDepth * 5.0f;
3520 }
3521 }
3522 }
3523 else 3523 else
3524 { 3524 {
3525 if (coldata[localid].PenetrationDepth >= 0.10f) 3525 // 0 is the ground
3526 // what about collisions with other avatars?
3527 if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
3526 Health -= coldata[localid].PenetrationDepth * 5.0f; 3528 Health -= coldata[localid].PenetrationDepth * 5.0f;
3527 } 3529 }
3528 3530
3531
3529 if (Health <= 0.0f) 3532 if (Health <= 0.0f)
3530 { 3533 {
3531 if (localid != 0) 3534 if (localid != 0)
@@ -3541,7 +3544,16 @@ namespace OpenSim.Region.Framework.Scenes
3541 ControllingClient.SendHealth(Health); 3544 ControllingClient.SendHealth(Health);
3542 } 3545 }
3543 if (Health <= 0) 3546 if (Health <= 0)
3547 {
3544 m_scene.EventManager.TriggerAvatarKill(killerObj, this); 3548 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
3549 }
3550 if (starthealth == Health && Health < 100.0f)
3551 {
3552 Health += 0.03f;
3553 if (Health > 100.0f)
3554 Health = 100.0f;
3555 ControllingClient.SendHealth(Health);
3556 }
3545 } 3557 }
3546 } 3558 }
3547 3559
@@ -3553,9 +3565,6 @@ namespace OpenSim.Region.Framework.Scenes
3553 3565
3554 public void Close() 3566 public void Close()
3555 { 3567 {
3556 if (!IsChildAgent)
3557 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
3558
3559 // Clear known regions 3568 // Clear known regions
3560 KnownRegions = new Dictionary<ulong, string>(); 3569 KnownRegions = new Dictionary<ulong, string>();
3561 3570
@@ -3624,6 +3633,63 @@ namespace OpenSim.Region.Framework.Scenes
3624 return m_attachments.Count > 0; 3633 return m_attachments.Count > 0;
3625 } 3634 }
3626 3635
3636 /// <summary>
3637 /// Returns the total count of scripts in all parts inventories.
3638 /// </summary>
3639 public int ScriptCount()
3640 {
3641 int count = 0;
3642 lock (m_attachments)
3643 {
3644 foreach (SceneObjectGroup gobj in m_attachments)
3645 {
3646 if (gobj != null)
3647 {
3648 count += gobj.ScriptCount();
3649 }
3650 }
3651 }
3652 return count;
3653 }
3654
3655 /// <summary>
3656 /// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
3657 /// </summary>
3658 public float ScriptExecutionTime()
3659 {
3660 float time = 0.0f;
3661 lock (m_attachments)
3662 {
3663 foreach (SceneObjectGroup gobj in m_attachments)
3664 {
3665 if (gobj != null)
3666 {
3667 time += gobj.ScriptExecutionTime();
3668 }
3669 }
3670 }
3671 return time;
3672 }
3673
3674 /// <summary>
3675 /// Returns the total count of running scripts in all parts.
3676 /// </summary>
3677 public int RunningScriptCount()
3678 {
3679 int count = 0;
3680 lock (m_attachments)
3681 {
3682 foreach (SceneObjectGroup gobj in m_attachments)
3683 {
3684 if (gobj != null)
3685 {
3686 count += gobj.RunningScriptCount();
3687 }
3688 }
3689 }
3690 return count;
3691 }
3692
3627 public bool HasScriptedAttachments() 3693 public bool HasScriptedAttachments()
3628 { 3694 {
3629 lock (m_attachments) 3695 lock (m_attachments)
@@ -3841,77 +3907,92 @@ namespace OpenSim.Region.Framework.Scenes
3841 } 3907 }
3842 } 3908 }
3843 3909
3844 internal void SendControlToScripts(uint flags) 3910 private void SendControlsToScripts(uint flags)
3845 { 3911 {
3846 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; 3912 // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script
3847 3913 // (e.g., a walking script) checks which animation is active it will be the correct animation.
3848 if (MouseDown) 3914 lock (scriptedcontrols)
3849 { 3915 {
3850 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); 3916 if (scriptedcontrols.Count <= 0)
3851 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) 3917 return;
3918
3919 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO;
3920
3921 if (MouseDown)
3852 { 3922 {
3853 allflags = ScriptControlled.CONTROL_ZERO; 3923 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
3924 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
3925 {
3926 allflags = ScriptControlled.CONTROL_ZERO;
3927 MouseDown = true;
3928 }
3929 }
3930
3931 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
3932 {
3933 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
3854 MouseDown = true; 3934 MouseDown = true;
3855 } 3935 }
3856 } 3936
3937 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
3938 {
3939 allflags |= ScriptControlled.CONTROL_LBUTTON;
3940 MouseDown = true;
3941 }
3942
3943 // find all activated controls, whether the scripts are interested in them or not
3944 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
3945 {
3946 allflags |= ScriptControlled.CONTROL_FWD;
3947 }
3948
3949 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3950 {
3951 allflags |= ScriptControlled.CONTROL_BACK;
3952 }
3953
3954 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3955 {
3956 allflags |= ScriptControlled.CONTROL_UP;
3957 }
3958
3959 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3960 {
3961 allflags |= ScriptControlled.CONTROL_DOWN;
3962 }
3857 3963
3858 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) 3964 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3859 { 3965 {
3860 allflags |= ScriptControlled.CONTROL_ML_LBUTTON; 3966 allflags |= ScriptControlled.CONTROL_LEFT;
3861 MouseDown = true; 3967 }
3862 } 3968
3863 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) 3969 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3864 { 3970 {
3865 allflags |= ScriptControlled.CONTROL_LBUTTON; 3971 allflags |= ScriptControlled.CONTROL_RIGHT;
3866 MouseDown = true; 3972 }
3867 } 3973
3974 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
3975 {
3976 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
3977 }
3978
3979 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
3980 {
3981 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
3982 }
3868 3983
3869 // find all activated controls, whether the scripts are interested in them or not 3984 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3870 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) 3985 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3871 {
3872 allflags |= ScriptControlled.CONTROL_FWD;
3873 }
3874 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3875 {
3876 allflags |= ScriptControlled.CONTROL_BACK;
3877 }
3878 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3879 {
3880 allflags |= ScriptControlled.CONTROL_UP;
3881 }
3882 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3883 {
3884 allflags |= ScriptControlled.CONTROL_DOWN;
3885 }
3886 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3887 {
3888 allflags |= ScriptControlled.CONTROL_LEFT;
3889 }
3890 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3891 {
3892 allflags |= ScriptControlled.CONTROL_RIGHT;
3893 }
3894 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
3895 {
3896 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
3897 }
3898 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
3899 {
3900 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
3901 }
3902 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3903 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3904 {
3905 lock (scriptedcontrols)
3906 { 3986 {
3907 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) 3987 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
3908 { 3988 {
3909 UUID scriptUUID = kvp.Key; 3989 UUID scriptUUID = kvp.Key;
3910 ScriptControllers scriptControlData = kvp.Value; 3990 ScriptControllers scriptControlData = kvp.Value;
3911 3991
3912 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us 3992 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
3913 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle 3993 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
3914 ScriptControlled localChange = localHeld ^ localLast; // the changed bits 3994 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
3995
3915 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) 3996 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
3916 { 3997 {
3917 // only send if still pressed or just changed 3998 // only send if still pressed or just changed
@@ -3919,9 +4000,9 @@ namespace OpenSim.Region.Framework.Scenes
3919 } 4000 }
3920 } 4001 }
3921 } 4002 }
4003
4004 LastCommands = allflags;
3922 } 4005 }
3923
3924 LastCommands = allflags;
3925 } 4006 }
3926 4007
3927 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) 4008 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
@@ -4001,7 +4082,7 @@ namespace OpenSim.Region.Framework.Scenes
4001 land.LandData.UserLocation != Vector3.Zero && 4082 land.LandData.UserLocation != Vector3.Zero &&
4002 land.LandData.OwnerID != m_uuid && 4083 land.LandData.OwnerID != m_uuid &&
4003 (!m_scene.Permissions.IsGod(m_uuid)) && 4084 (!m_scene.Permissions.IsGod(m_uuid)) &&
4004 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) 4085 (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
4005 { 4086 {
4006 float curr = Vector3.Distance(AbsolutePosition, pos); 4087 float curr = Vector3.Distance(AbsolutePosition, pos);
4007 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) 4088 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
@@ -4015,13 +4096,13 @@ namespace OpenSim.Region.Framework.Scenes
4015 { 4096 {
4016 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == 4097 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
4017 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || 4098 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
4018 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || 4099 (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) ||
4019 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4100 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4020 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) 4101 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
4021 { 4102 {
4022 if (GodLevel < 200 && 4103 if (GodLevel < 200 &&
4023 ((!m_scene.Permissions.IsGod(m_uuid) && 4104 ((!m_scene.Permissions.IsGod(m_uuid) &&
4024 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4105 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4025 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4106 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4026 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4107 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4027 { 4108 {
@@ -4029,28 +4110,92 @@ namespace OpenSim.Region.Framework.Scenes
4029 if (spawnPoints.Length == 0) 4110 if (spawnPoints.Length == 0)
4030 return; 4111 return;
4031 4112
4032 float distance = 9999; 4113 int index;
4033 int closest = -1; 4114 bool selected = false;
4034 4115
4035 for (int i = 0 ; i < spawnPoints.Length ; i++) 4116 switch (m_scene.SpawnPointRouting)
4036 { 4117 {
4037 Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4118 case "random":
4038 Vector3 offset = spawnPosition - pos;
4039 float d = Vector3.Mag(offset);
4040 if (d >= distance)
4041 continue;
4042 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4043 if (land == null)
4044 continue;
4045 if (land.IsEitherBannedOrRestricted(UUID))
4046 continue;
4047 distance = d;
4048 closest = i;
4049 }
4050 if (closest == -1)
4051 return;
4052 4119
4053 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4120 do
4121 {
4122 index = Util.RandomClass.Next(spawnPoints.Length - 1);
4123
4124 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4125 telehub.AbsolutePosition,
4126 telehub.GroupRotation
4127 );
4128 // SpawnPoint sp = spawnPoints[index];
4129
4130 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4131 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4132 selected = false;
4133 else
4134 selected = true;
4135
4136 } while ( selected == false);
4137
4138 pos = spawnPoints[index].GetLocation(
4139 telehub.AbsolutePosition,
4140 telehub.GroupRotation
4141 );
4142 return;
4143
4144 case "sequence":
4145
4146 do
4147 {
4148 index = m_scene.SpawnPoint();
4149
4150 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4151 telehub.AbsolutePosition,
4152 telehub.GroupRotation
4153 );
4154 // SpawnPoint sp = spawnPoints[index];
4155
4156 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4157 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4158 selected = false;
4159 else
4160 selected = true;
4161
4162 } while (selected == false);
4163
4164 pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4165 ;
4166 return;
4167
4168 default:
4169 case "closest":
4170
4171 float distance = 9999;
4172 int closest = -1;
4173
4174 for (int i = 0; i < spawnPoints.Length; i++)
4175 {
4176 Vector3 spawnPosition = spawnPoints[i].GetLocation(
4177 telehub.AbsolutePosition,
4178 telehub.GroupRotation
4179 );
4180 Vector3 offset = spawnPosition - pos;
4181 float d = Vector3.Mag(offset);
4182 if (d >= distance)
4183 continue;
4184 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4185 if (land == null)
4186 continue;
4187 if (land.IsEitherBannedOrRestricted(UUID))
4188 continue;
4189 distance = d;
4190 closest = i;
4191 }
4192 if (closest == -1)
4193 return;
4194
4195 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4196 return;
4197
4198 }
4054 } 4199 }
4055 } 4200 }
4056 } 4201 }
@@ -4095,7 +4240,7 @@ namespace OpenSim.Region.Framework.Scenes
4095 GodLevel < 200 && 4240 GodLevel < 200 &&
4096 ((land.LandData.OwnerID != m_uuid && 4241 ((land.LandData.OwnerID != m_uuid &&
4097 !m_scene.Permissions.IsGod(m_uuid) && 4242 !m_scene.Permissions.IsGod(m_uuid) &&
4098 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4243 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4099 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4244 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4100 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4245 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4101 { 4246 {
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
index 55455cc..a4f730d 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
@@ -47,14 +47,30 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
47 /// </remarks> 47 /// </remarks>
48 public class CoalescedSceneObjectsSerializer 48 public class CoalescedSceneObjectsSerializer
49 { 49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 /// <summary> 52 /// <summary>
53 /// Serialize coalesced objects to Xml 53 /// Serialize coalesced objects to Xml
54 /// </summary> 54 /// </summary>
55 /// <param name="coa"></param> 55 /// <param name="coa"></param>
56 /// <param name="doScriptStates">
57 /// If true then serialize script states. This will halt any running scripts
58 /// </param>
56 /// <returns></returns> 59 /// <returns></returns>
57 public static string ToXml(CoalescedSceneObjects coa) 60 public static string ToXml(CoalescedSceneObjects coa)
61 {
62 return ToXml(coa, true);
63 }
64
65 /// <summary>
66 /// Serialize coalesced objects to Xml
67 /// </summary>
68 /// <param name="coa"></param>
69 /// <param name="doScriptStates">
70 /// If true then serialize script states. This will halt any running scripts
71 /// </param>
72 /// <returns></returns>
73 public static string ToXml(CoalescedSceneObjects coa, bool doScriptStates)
58 { 74 {
59 using (StringWriter sw = new StringWriter()) 75 using (StringWriter sw = new StringWriter())
60 { 76 {
@@ -91,7 +107,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
91 writer.WriteAttributeString("offsety", offsets[i].Y.ToString()); 107 writer.WriteAttributeString("offsety", offsets[i].Y.ToString());
92 writer.WriteAttributeString("offsetz", offsets[i].Z.ToString()); 108 writer.WriteAttributeString("offsetz", offsets[i].Z.ToString());
93 109
94 SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, true); 110 SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates);
95 111
96 writer.WriteEndElement(); // SceneObjectGroup 112 writer.WriteEndElement(); // SceneObjectGroup
97 } 113 }
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index abca14f..2372d6b 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -1537,51 +1537,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1537 } 1537 }
1538 } 1538 }
1539 1539
1540 //////// Read /////////
1541 public static bool Xml2ToSOG(XmlTextReader reader, SceneObjectGroup sog)
1542 {
1543 reader.Read();
1544 reader.ReadStartElement("SceneObjectGroup");
1545 SceneObjectPart root = Xml2ToSOP(reader);
1546 if (root != null)
1547 sog.SetRootPart(root);
1548 else
1549 {
1550 return false;
1551 }
1552
1553 if (sog.UUID == UUID.Zero)
1554 sog.UUID = sog.RootPart.UUID;
1555
1556 reader.Read(); // OtherParts
1557
1558 while (!reader.EOF)
1559 {
1560 switch (reader.NodeType)
1561 {
1562 case XmlNodeType.Element:
1563 if (reader.Name == "SceneObjectPart")
1564 {
1565 SceneObjectPart child = Xml2ToSOP(reader);
1566 if (child != null)
1567 sog.AddPart(child);
1568 }
1569 else
1570 {
1571 //Logger.Log("Found unexpected prim XML element " + reader.Name, Helpers.LogLevel.Debug);
1572 reader.Read();
1573 }
1574 break;
1575 case XmlNodeType.EndElement:
1576 default:
1577 reader.Read();
1578 break;
1579 }
1580
1581 }
1582 return true;
1583 }
1584
1585 public static SceneObjectPart Xml2ToSOP(XmlTextReader reader) 1540 public static SceneObjectPart Xml2ToSOP(XmlTextReader reader)
1586 { 1541 {
1587 SceneObjectPart obj = new SceneObjectPart(); 1542 SceneObjectPart obj = new SceneObjectPart();
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
index d214eba..a3485d2 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
@@ -223,50 +223,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
223 223
224 public static SceneObjectGroup DeserializeGroupFromXml2(string xmlString) 224 public static SceneObjectGroup DeserializeGroupFromXml2(string xmlString)
225 { 225 {
226 XmlDocument doc = new XmlDocument(); 226 return SceneObjectSerializer.FromXml2Format(xmlString);
227 XmlNode rootNode;
228
229 XmlTextReader reader = new XmlTextReader(new StringReader(xmlString));
230 reader.WhitespaceHandling = WhitespaceHandling.None;
231 doc.Load(reader);
232 reader.Close();
233 rootNode = doc.FirstChild;
234
235 // This is to deal with neighbouring regions that are still surrounding the group xml with the <scene>
236 // tag. It should be possible to remove the first part of this if statement once we go past 0.5.9 (or
237 // when some other changes forces all regions to upgrade).
238 // This might seem rather pointless since prim crossing from this revision to an earlier revision remains
239 // broken. But it isn't much work to accomodate the old format here.
240 if (rootNode.LocalName.Equals("scene"))
241 {
242 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
243 {
244 // There is only ever one prim. This oddity should be removeable post 0.5.9
245 //return SceneObjectSerializer.FromXml2Format(aPrimNode.OuterXml);
246 using (reader = new XmlTextReader(new StringReader(aPrimNode.OuterXml)))
247 {
248 SceneObjectGroup obj = new SceneObjectGroup();
249 if (SceneObjectSerializer.Xml2ToSOG(reader, obj))
250 return obj;
251
252 return null;
253 }
254 }
255
256 return null;
257 }
258 else
259 {
260 //return SceneObjectSerializer.FromXml2Format(rootNode.OuterXml);
261 using (reader = new XmlTextReader(new StringReader(rootNode.OuterXml)))
262 {
263 SceneObjectGroup obj = new SceneObjectGroup();
264 if (SceneObjectSerializer.Xml2ToSOG(reader, obj))
265 return obj;
266
267 return null;
268 }
269 }
270 } 227 }
271 228
272 /// <summary> 229 /// <summary>
@@ -307,8 +264,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
307 ICollection<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 264 ICollection<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
308 foreach (XmlNode aPrimNode in rootNode.ChildNodes) 265 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
309 { 266 {
310 SceneObjectGroup obj = CreatePrimFromXml2(scene, aPrimNode.OuterXml); 267 SceneObjectGroup obj = DeserializeGroupFromXml2(aPrimNode.OuterXml);
311 if (obj != null && startScripts) 268 if (startScripts)
312 sceneObjects.Add(obj); 269 sceneObjects.Add(obj);
313 } 270 }
314 271
@@ -319,27 +276,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
319 } 276 }
320 } 277 }
321 278
322 /// <summary>
323 /// Create a prim from the xml2 representation.
324 /// </summary>
325 /// <param name="scene"></param>
326 /// <param name="xmlData"></param>
327 /// <returns>The scene object created. null if the scene object already existed</returns>
328 protected static SceneObjectGroup CreatePrimFromXml2(Scene scene, string xmlData)
329 {
330 //SceneObjectGroup obj = SceneObjectSerializer.FromXml2Format(xmlData);
331 using (XmlTextReader reader = new XmlTextReader(new StringReader(xmlData)))
332 {
333 SceneObjectGroup obj = new SceneObjectGroup();
334 SceneObjectSerializer.Xml2ToSOG(reader, obj);
335
336 if (scene.AddRestoredSceneObject(obj, true, false))
337 return obj;
338 else
339 return null;
340 }
341 }
342
343 #endregion 279 #endregion
344 } 280 }
345} 281} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index a4afd47..18e6ece 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -26,7 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29//using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Timers; 30using System.Timers;
31using OpenMetaverse.Packets; 31using OpenMetaverse.Packets;
32using OpenSim.Framework; 32using OpenSim.Framework;
@@ -35,10 +35,18 @@ using OpenSim.Region.Framework.Interfaces;
35 35
36namespace OpenSim.Region.Framework.Scenes 36namespace OpenSim.Region.Framework.Scenes
37{ 37{
38 /// <summary>
39 /// Collect statistics from the scene to send to the client and for access by other monitoring tools.
40 /// </summary>
41 /// <remarks>
42 /// FIXME: This should be a monitoring region module
43 /// </remarks>
38 public class SimStatsReporter 44 public class SimStatsReporter
39 { 45 {
40// private static readonly log4net.ILog m_log 46 private static readonly log4net.ILog m_log
41// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 47 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
48
49 public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates";
42 50
43 public delegate void SendStatResult(SimStats stats); 51 public delegate void SendStatResult(SimStats stats);
44 52
@@ -48,10 +56,17 @@ namespace OpenSim.Region.Framework.Scenes
48 56
49 public event YourStatsAreWrong OnStatsIncorrect; 57 public event YourStatsAreWrong OnStatsIncorrect;
50 58
51 private SendStatResult handlerSendStatResult = null; 59 private SendStatResult handlerSendStatResult;
52 60
53 private YourStatsAreWrong handlerStatsIncorrect = null; 61 private YourStatsAreWrong handlerStatsIncorrect;
54 62
63 /// <summary>
64 /// These are the IDs of stats sent in the StatsPacket to the viewer.
65 /// </summary>
66 /// <remarks>
67 /// Some of these are not relevant to OpenSimulator since it is architected differently to other simulators
68 /// (e.g. script instructions aren't executed as part of the frame loop so 'script time' is tricky).
69 /// </remarks>
55 public enum Stats : uint 70 public enum Stats : uint
56 { 71 {
57 TimeDilation = 0, 72 TimeDilation = 0,
@@ -75,20 +90,20 @@ namespace OpenSim.Region.Framework.Scenes
75 OutPacketsPerSecond = 18, 90 OutPacketsPerSecond = 18,
76 PendingDownloads = 19, 91 PendingDownloads = 19,
77 PendingUploads = 20, 92 PendingUploads = 20,
78 VirtualSizeKB = 21, 93 VirtualSizeKb = 21,
79 ResidentSizeKB = 22, 94 ResidentSizeKb = 22,
80 PendingLocalUploads = 23, 95 PendingLocalUploads = 23,
81 UnAckedBytes = 24, 96 UnAckedBytes = 24,
82 PhysicsPinnedTasks = 25, 97 PhysicsPinnedTasks = 25,
83 PhysicsLODTasks = 26, 98 PhysicsLodTasks = 26,
84 PhysicsStepMS = 27, 99 SimPhysicsStepMs = 27,
85 PhysicsShapeMS = 28, 100 SimPhysicsShapeMs = 28,
86 PhysicsOtherMS = 29, 101 SimPhysicsOtherMs = 29,
87 PhysicsMemory = 30, 102 SimPhysicsMemory = 30,
88 ScriptEPS = 31, 103 ScriptEps = 31,
89 SimSpareTime = 32, 104 SimSpareMs = 32,
90 SimSleepTime = 33, 105 SimSleepMs = 33,
91 IOPumpTime = 34 106 SimIoPumpTime = 34
92 } 107 }
93 108
94 /// <summary> 109 /// <summary>
@@ -113,11 +128,24 @@ namespace OpenSim.Region.Framework.Scenes
113 get { return lastReportedSimStats; } 128 get { return lastReportedSimStats; }
114 } 129 }
115 130
131 /// <summary>
132 /// Extra sim statistics that are used by monitors but not sent to the client.
133 /// </summary>
134 /// <value>
135 /// The keys are the stat names.
136 /// </value>
137 private Dictionary<string, float> m_lastReportedExtraSimStats = new Dictionary<string, float>();
138
116 // Sending a stats update every 3 seconds- 139 // Sending a stats update every 3 seconds-
117 private int statsUpdatesEveryMS = 3000; 140 private int m_statsUpdatesEveryMS = 3000;
118 private float statsUpdateFactor = 0; 141 private float m_statsUpdateFactor;
119 private float m_timeDilation = 0; 142 private float m_timeDilation;
120 private int m_fps = 0; 143 private int m_fps;
144
145 /// <summary>
146 /// Number of the last frame on which we processed a stats udpate.
147 /// </summary>
148 private uint m_lastUpdateFrame;
121 149
122 /// <summary> 150 /// <summary>
123 /// Our nominal fps target, as expected in fps stats when a sim is running normally. 151 /// Our nominal fps target, as expected in fps stats when a sim is running normally.
@@ -135,43 +163,42 @@ namespace OpenSim.Region.Framework.Scenes
135 private float m_reportedFpsCorrectionFactor = 5; 163 private float m_reportedFpsCorrectionFactor = 5;
136 164
137 // saved last reported value so there is something available for llGetRegionFPS 165 // saved last reported value so there is something available for llGetRegionFPS
138 private float lastReportedSimFPS = 0; 166 private float lastReportedSimFPS;
139 private float[] lastReportedSimStats = new float[23]; 167 private float[] lastReportedSimStats = new float[22];
140 private float m_pfps = 0; 168 private float m_pfps;
141 169
142 /// <summary> 170 /// <summary>
143 /// Number of agent updates requested in this stats cycle 171 /// Number of agent updates requested in this stats cycle
144 /// </summary> 172 /// </summary>
145 private int m_agentUpdates = 0; 173 private int m_agentUpdates;
146 174
147 /// <summary> 175 /// <summary>
148 /// Number of object updates requested in this stats cycle 176 /// Number of object updates requested in this stats cycle
149 /// </summary> 177 /// </summary>
150 private int m_objectUpdates; 178 private int m_objectUpdates;
151 179
152 private int m_frameMS = 0; 180 private int m_frameMS;
153 private int m_netMS = 0; 181 private int m_spareMS;
154 private int m_agentMS = 0; 182 private int m_netMS;
155 private int m_physicsMS = 0; 183 private int m_agentMS;
156 private int m_imageMS = 0; 184 private int m_physicsMS;
157 private int m_otherMS = 0; 185 private int m_imageMS;
158 private int m_sleeptimeMS = 0; 186 private int m_otherMS;
159
160 187
161//Ckrinke: (3-21-08) Comment out to remove a compiler warning. Bring back into play when needed. 188//Ckrinke: (3-21-08) Comment out to remove a compiler warning. Bring back into play when needed.
162//Ckrinke private int m_scriptMS = 0; 189//Ckrinke private int m_scriptMS = 0;
163 190
164 private int m_rootAgents = 0; 191 private int m_rootAgents;
165 private int m_childAgents = 0; 192 private int m_childAgents;
166 private int m_numPrim = 0; 193 private int m_numPrim;
167 private int m_inPacketsPerSecond = 0; 194 private int m_inPacketsPerSecond;
168 private int m_outPacketsPerSecond = 0; 195 private int m_outPacketsPerSecond;
169 private int m_activePrim = 0; 196 private int m_activePrim;
170 private int m_unAckedBytes = 0; 197 private int m_unAckedBytes;
171 private int m_pendingDownloads = 0; 198 private int m_pendingDownloads;
172 private int m_pendingUploads = 0; 199 private int m_pendingUploads = 0; // FIXME: Not currently filled in
173 private int m_activeScripts = 0; 200 private int m_activeScripts;
174 private int m_scriptLinesPerSecond = 0; 201 private int m_scriptLinesPerSecond;
175 202
176 private int m_objectCapacity = 45000; 203 private int m_objectCapacity = 45000;
177 204
@@ -187,13 +214,13 @@ namespace OpenSim.Region.Framework.Scenes
187 { 214 {
188 m_scene = scene; 215 m_scene = scene;
189 m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps; 216 m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps;
190 statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000); 217 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
191 ReportingRegion = scene.RegionInfo; 218 ReportingRegion = scene.RegionInfo;
192 219
193 m_objectCapacity = scene.RegionInfo.ObjectCapacity; 220 m_objectCapacity = scene.RegionInfo.ObjectCapacity;
194 m_report.AutoReset = true; 221 m_report.AutoReset = true;
195 m_report.Interval = statsUpdatesEveryMS; 222 m_report.Interval = m_statsUpdatesEveryMS;
196 m_report.Elapsed += statsHeartBeat; 223 m_report.Elapsed += TriggerStatsHeartbeat;
197 m_report.Enabled = true; 224 m_report.Enabled = true;
198 225
199 if (StatsManager.SimExtraStats != null) 226 if (StatsManager.SimExtraStats != null)
@@ -202,20 +229,38 @@ namespace OpenSim.Region.Framework.Scenes
202 229
203 public void Close() 230 public void Close()
204 { 231 {
205 m_report.Elapsed -= statsHeartBeat; 232 m_report.Elapsed -= TriggerStatsHeartbeat;
206 m_report.Close(); 233 m_report.Close();
207 } 234 }
208 235
236 /// <summary>
237 /// Sets the number of milliseconds between stat updates.
238 /// </summary>
239 /// <param name='ms'></param>
209 public void SetUpdateMS(int ms) 240 public void SetUpdateMS(int ms)
210 { 241 {
211 statsUpdatesEveryMS = ms; 242 m_statsUpdatesEveryMS = ms;
212 statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000); 243 m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000);
213 m_report.Interval = statsUpdatesEveryMS; 244 m_report.Interval = m_statsUpdatesEveryMS;
245 }
246
247 private void TriggerStatsHeartbeat(object sender, EventArgs args)
248 {
249 try
250 {
251 statsHeartBeat(sender, args);
252 }
253 catch (Exception e)
254 {
255 m_log.Warn(string.Format(
256 "[SIM STATS REPORTER] Update for {0} failed with exception ",
257 m_scene.RegionInfo.RegionName), e);
258 }
214 } 259 }
215 260
216 private void statsHeartBeat(object sender, EventArgs e) 261 private void statsHeartBeat(object sender, EventArgs e)
217 { 262 {
218 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[23]; 263 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[22];
219 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock(); 264 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
220 265
221 // Know what's not thread safe in Mono... modifying timers. 266 // Know what's not thread safe in Mono... modifying timers.
@@ -242,7 +287,7 @@ namespace OpenSim.Region.Framework.Scenes
242 int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor); 287 int reportedFPS = (int)(m_fps * m_reportedFpsCorrectionFactor);
243 288
244 // save the reported value so there is something available for llGetRegionFPS 289 // save the reported value so there is something available for llGetRegionFPS
245 lastReportedSimFPS = reportedFPS / statsUpdateFactor; 290 lastReportedSimFPS = reportedFPS / m_statsUpdateFactor;
246 291
247 float physfps = ((m_pfps / 1000)); 292 float physfps = ((m_pfps / 1000));
248 293
@@ -253,7 +298,6 @@ namespace OpenSim.Region.Framework.Scenes
253 physfps = 0; 298 physfps = 0;
254 299
255#endregion 300#endregion
256 float factor = 1 / statsUpdateFactor;
257 if (reportedFPS <= 0) 301 if (reportedFPS <= 0)
258 reportedFPS = 1; 302 reportedFPS = 1;
259 303
@@ -264,32 +308,38 @@ namespace OpenSim.Region.Framework.Scenes
264 float targetframetime = 1100.0f / (float)m_nominalReportedFps; 308 float targetframetime = 1100.0f / (float)m_nominalReportedFps;
265 309
266 float sparetime; 310 float sparetime;
267 float sleeptime;
268 if (TotalFrameTime > targetframetime) 311 if (TotalFrameTime > targetframetime)
269 { 312 {
270 sparetime = 0; 313 sparetime = 0;
271 sleeptime = 0;
272 }
273 else
274 {
275 sparetime = m_frameMS - m_physicsMS - m_agentMS;
276 sparetime *= perframe;
277 if (sparetime < 0)
278 sparetime = 0;
279 else if (sparetime > TotalFrameTime)
280 sparetime = TotalFrameTime;
281 sleeptime = m_sleeptimeMS * perframe;
282 } 314 }
315
316 m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
317 m_childAgents = m_scene.SceneGraph.GetChildAgentCount();
318 m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount();
319 m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount();
320 m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
321
322 // FIXME: Checking for stat sanity is a complex approach. What we really need to do is fix the code
323 // so that stat numbers are always consistent.
324 CheckStatSanity();
283 325
284 // other MS is actually simulation time 326 // other MS is actually simulation time
285 // m_otherMS = m_frameMS - m_physicsMS - m_imageMS - m_netMS - m_agentMS; 327 // m_otherMS = m_frameMS - m_physicsMS - m_imageMS - m_netMS - m_agentMS;
286 // m_imageMS m_netMS are not included in m_frameMS 328 // m_imageMS m_netMS are not included in m_frameMS
287 329
288 m_otherMS = m_frameMS - m_physicsMS - m_agentMS - m_sleeptimeMS; 330 m_otherMS = m_frameMS - m_physicsMS - m_agentMS;
289 if (m_otherMS < 0) 331 if (m_otherMS < 0)
290 m_otherMS = 0; 332 m_otherMS = 0;
291 333
292 for (int i = 0; i < 23; i++) 334 uint thisFrame = m_scene.Frame;
335 float framesUpdated = (float)(thisFrame - m_lastUpdateFrame) * m_reportedFpsCorrectionFactor;
336 m_lastUpdateFrame = thisFrame;
337
338 // Avoid div-by-zero if somehow we've not updated any frames.
339 if (framesUpdated == 0)
340 framesUpdated = 1;
341
342 for (int i = 0; i < 22; i++)
293 { 343 {
294 sb[i] = new SimStatsPacket.StatBlock(); 344 sb[i] = new SimStatsPacket.StatBlock();
295 } 345 }
@@ -298,13 +348,13 @@ namespace OpenSim.Region.Framework.Scenes
298 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor)); 348 sb[0].StatValue = (Single.IsNaN(m_timeDilation)) ? 0.1f : m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
299 349
300 sb[1].StatID = (uint) Stats.SimFPS; 350 sb[1].StatID = (uint) Stats.SimFPS;
301 sb[1].StatValue = reportedFPS / statsUpdateFactor; 351 sb[1].StatValue = reportedFPS / m_statsUpdateFactor;
302 352
303 sb[2].StatID = (uint) Stats.PhysicsFPS; 353 sb[2].StatID = (uint) Stats.PhysicsFPS;
304 sb[2].StatValue = physfps / statsUpdateFactor; 354 sb[2].StatValue = physfps / m_statsUpdateFactor;
305 355
306 sb[3].StatID = (uint) Stats.AgentUpdates; 356 sb[3].StatID = (uint) Stats.AgentUpdates;
307 sb[3].StatValue = (m_agentUpdates / statsUpdateFactor); 357 sb[3].StatValue = (m_agentUpdates / m_statsUpdateFactor);
308 358
309 sb[4].StatID = (uint) Stats.Agents; 359 sb[4].StatID = (uint) Stats.Agents;
310 sb[4].StatValue = m_rootAgents; 360 sb[4].StatValue = m_rootAgents;
@@ -319,38 +369,31 @@ namespace OpenSim.Region.Framework.Scenes
319 sb[7].StatValue = m_activePrim; 369 sb[7].StatValue = m_activePrim;
320 370
321 sb[8].StatID = (uint)Stats.FrameMS; 371 sb[8].StatID = (uint)Stats.FrameMS;
322 // sb[8].StatValue = m_frameMS / statsUpdateFactor; 372 sb[8].StatValue = m_frameMS / framesUpdated;
323 sb[8].StatValue = TotalFrameTime;
324 373
325 sb[9].StatID = (uint)Stats.NetMS; 374 sb[9].StatID = (uint)Stats.NetMS;
326 // sb[9].StatValue = m_netMS / statsUpdateFactor; 375 sb[9].StatValue = m_netMS / framesUpdated;
327 sb[9].StatValue = m_netMS * perframe;
328 376
329 sb[10].StatID = (uint)Stats.PhysicsMS; 377 sb[10].StatID = (uint)Stats.PhysicsMS;
330 // sb[10].StatValue = m_physicsMS / statsUpdateFactor; 378 sb[10].StatValue = m_physicsMS / framesUpdated;
331 sb[10].StatValue = m_physicsMS * perframe;
332 379
333 sb[11].StatID = (uint)Stats.ImageMS ; 380 sb[11].StatID = (uint)Stats.ImageMS ;
334 // sb[11].StatValue = m_imageMS / statsUpdateFactor; 381 sb[11].StatValue = m_imageMS / framesUpdated;
335 sb[11].StatValue = m_imageMS * perframe;
336 382
337 sb[12].StatID = (uint)Stats.OtherMS; 383 sb[12].StatID = (uint)Stats.OtherMS;
338 // sb[12].StatValue = m_otherMS / statsUpdateFactor; 384 sb[12].StatValue = m_otherMS / framesUpdated;
339 sb[12].StatValue = m_otherMS * perframe;
340
341 385
342 sb[13].StatID = (uint)Stats.InPacketsPerSecond; 386 sb[13].StatID = (uint)Stats.InPacketsPerSecond;
343 sb[13].StatValue = (m_inPacketsPerSecond / statsUpdateFactor); 387 sb[13].StatValue = (m_inPacketsPerSecond / m_statsUpdateFactor);
344 388
345 sb[14].StatID = (uint)Stats.OutPacketsPerSecond; 389 sb[14].StatID = (uint)Stats.OutPacketsPerSecond;
346 sb[14].StatValue = (m_outPacketsPerSecond / statsUpdateFactor); 390 sb[14].StatValue = (m_outPacketsPerSecond / m_statsUpdateFactor);
347 391
348 sb[15].StatID = (uint)Stats.UnAckedBytes; 392 sb[15].StatID = (uint)Stats.UnAckedBytes;
349 sb[15].StatValue = m_unAckedBytes; 393 sb[15].StatValue = m_unAckedBytes;
350 394
351 sb[16].StatID = (uint)Stats.AgentMS; 395 sb[16].StatID = (uint)Stats.AgentMS;
352// sb[16].StatValue = m_agentMS / statsUpdateFactor; 396 sb[16].StatValue = m_agentMS / framesUpdated;
353 sb[16].StatValue = m_agentMS * perframe;
354 397
355 sb[17].StatID = (uint)Stats.PendingDownloads; 398 sb[17].StatID = (uint)Stats.PendingDownloads;
356 sb[17].StatValue = m_pendingDownloads; 399 sb[17].StatValue = m_pendingDownloads;
@@ -362,15 +405,12 @@ namespace OpenSim.Region.Framework.Scenes
362 sb[19].StatValue = m_activeScripts; 405 sb[19].StatValue = m_activeScripts;
363 406
364 sb[20].StatID = (uint)Stats.ScriptLinesPerSecond; 407 sb[20].StatID = (uint)Stats.ScriptLinesPerSecond;
365 sb[20].StatValue = m_scriptLinesPerSecond / statsUpdateFactor; 408 sb[20].StatValue = m_scriptLinesPerSecond / m_statsUpdateFactor;
366 409
367 sb[21].StatID = (uint)Stats.SimSpareTime; 410 sb[21].StatID = (uint)Stats.SimSpareMs;
368 sb[21].StatValue = sparetime; 411 sb[21].StatValue = m_spareMS / framesUpdated;
369 412
370 sb[22].StatID = (uint)Stats.SimSleepTime; 413 for (int i = 0; i < 22; i++)
371 sb[22].StatValue = sleeptime;
372
373 for (int i = 0; i < 23; i++)
374 { 414 {
375 lastReportedSimStats[i] = sb[i].StatValue; 415 lastReportedSimStats[i] = sb[i].StatValue;
376 } 416 }
@@ -387,13 +427,32 @@ namespace OpenSim.Region.Framework.Scenes
387 } 427 }
388 428
389 // Extra statistics that aren't currently sent to clients 429 // Extra statistics that aren't currently sent to clients
390 LastReportedObjectUpdates = m_objectUpdates / statsUpdateFactor; 430 lock (m_lastReportedExtraSimStats)
431 {
432 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor;
433
434 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
435
436 if (physicsStats != null)
437 {
438 foreach (KeyValuePair<string, float> tuple in physicsStats)
439 {
440 // FIXME: An extremely dirty hack to divide MS stats per frame rather than per second
441 // Need to change things so that stats source can indicate whether they are per second or
442 // per frame.
443 if (tuple.Key.EndsWith("MS"))
444 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / framesUpdated;
445 else
446 m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / m_statsUpdateFactor;
447 }
448 }
449 }
391 450
392 resetvalues(); 451 ResetValues();
393 } 452 }
394 } 453 }
395 454
396 private void resetvalues() 455 private void ResetValues()
397 { 456 {
398 m_timeDilation = 0; 457 m_timeDilation = 0;
399 m_fps = 0; 458 m_fps = 0;
@@ -411,7 +470,7 @@ namespace OpenSim.Region.Framework.Scenes
411 m_physicsMS = 0; 470 m_physicsMS = 0;
412 m_imageMS = 0; 471 m_imageMS = 0;
413 m_otherMS = 0; 472 m_otherMS = 0;
414 m_sleeptimeMS = 0; 473 m_spareMS = 0;
415 474
416//Ckrinke This variable is not used, so comment to remove compiler warning until it is used. 475//Ckrinke This variable is not used, so comment to remove compiler warning until it is used.
417//Ckrinke m_scriptMS = 0; 476//Ckrinke m_scriptMS = 0;
@@ -433,13 +492,6 @@ namespace OpenSim.Region.Framework.Scenes
433 m_timeDilation = td; 492 m_timeDilation = td;
434 } 493 }
435 494
436 public void SetRootAgents(int rootAgents)
437 {
438 m_rootAgents = rootAgents;
439 CheckStatSanity();
440
441 }
442
443 internal void CheckStatSanity() 495 internal void CheckStatSanity()
444 { 496 {
445 if (m_rootAgents < 0 || m_childAgents < 0) 497 if (m_rootAgents < 0 || m_childAgents < 0)
@@ -456,22 +508,6 @@ namespace OpenSim.Region.Framework.Scenes
456 } 508 }
457 } 509 }
458 510
459 public void SetChildAgents(int childAgents)
460 {
461 m_childAgents = childAgents;
462 CheckStatSanity();
463 }
464
465 public void SetObjects(int objects)
466 {
467 m_numPrim = objects;
468 }
469
470 public void SetActiveObjects(int objects)
471 {
472 m_activePrim = objects;
473 }
474
475 public void AddFPS(int frames) 511 public void AddFPS(int frames)
476 { 512 {
477 m_fps += frames; 513 m_fps += frames;
@@ -513,6 +549,11 @@ namespace OpenSim.Region.Framework.Scenes
513 m_frameMS += ms; 549 m_frameMS += ms;
514 } 550 }
515 551
552 public void AddSpareMS(int ms)
553 {
554 m_spareMS += ms;
555 }
556
516 public void addNetMS(int ms) 557 public void addNetMS(int ms)
517 { 558 {
518 m_netMS += ms; 559 m_netMS += ms;
@@ -538,15 +579,13 @@ namespace OpenSim.Region.Framework.Scenes
538 m_otherMS += ms; 579 m_otherMS += ms;
539 } 580 }
540 581
541 public void addSleepMS(int ms)
542 {
543 m_sleeptimeMS += ms;
544 }
545
546 public void AddPendingDownloads(int count) 582 public void AddPendingDownloads(int count)
547 { 583 {
548 m_pendingDownloads += count; 584 m_pendingDownloads += count;
549 if (m_pendingDownloads < 0) m_pendingDownloads = 0; 585
586 if (m_pendingDownloads < 0)
587 m_pendingDownloads = 0;
588
550 //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads); 589 //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads);
551 } 590 }
552 591
@@ -555,11 +594,6 @@ namespace OpenSim.Region.Framework.Scenes
555 m_scriptLinesPerSecond += count; 594 m_scriptLinesPerSecond += count;
556 } 595 }
557 596
558 public void SetActiveScripts(int count)
559 {
560 m_activeScripts = count;
561 }
562
563 public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes) 597 public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes)
564 { 598 {
565 AddInPackets(inPackets); 599 AddInPackets(inPackets);
@@ -568,5 +602,11 @@ namespace OpenSim.Region.Framework.Scenes
568 } 602 }
569 603
570 #endregion 604 #endregion
605
606 public Dictionary<string, float> GetExtraSimStats()
607 {
608 lock (m_lastReportedExtraSimStats)
609 return new Dictionary<string, float>(m_lastReportedExtraSimStats);
610 }
571 } 611 }
572} 612}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
index ab6311b..4a21dc9 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
30using System.Text; 31using System.Text;
31using NUnit.Framework; 32using NUnit.Framework;
32using OpenMetaverse; 33using OpenMetaverse;
@@ -68,11 +69,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
68 Vector3 position = new Vector3(200,200,21); 69 Vector3 position = new Vector3(200,200,21);
69 70
70 foreach (Border b in testborders) 71 foreach (Border b in testborders)
71 {
72 Assert.That(!b.TestCross(position)); 72 Assert.That(!b.TestCross(position));
73 73
74 }
75
76 position = new Vector3(200,280,21); 74 position = new Vector3(200,280,21);
77 Assert.That(NorthBorder.TestCross(position)); 75 Assert.That(NorthBorder.TestCross(position));
78 76
diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
index a5d2b23..ea9fc93 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
45 { 45 {
46 static public Random random; 46 static public Random random;
47 SceneObjectGroup found; 47 SceneObjectGroup found;
48 Scene scene = SceneHelpers.SetupScene(); 48 Scene scene = new SceneHelpers().SetupScene();
49 49
50 [Test] 50 [Test]
51 public void T010_AddObjects() 51 public void T010_AddObjects()
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
index 9a60e50..d23c965 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
@@ -26,7 +26,9 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.IO;
29using System.Reflection; 30using System.Reflection;
31using System.Text;
30using NUnit.Framework; 32using NUnit.Framework;
31using OpenMetaverse; 33using OpenMetaverse;
32using OpenSim.Framework; 34using OpenSim.Framework;
@@ -44,7 +46,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
44 public void TestDuplicateObject() 46 public void TestDuplicateObject()
45 { 47 {
46 TestHelpers.InMethod(); 48 TestHelpers.InMethod();
47 Scene scene = SceneHelpers.SetupScene(); 49// TestHelpers.EnableLogging();
50
51 Scene scene = new SceneHelpers().SetupScene();
48 52
49 UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010"); 53 UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010");
50 string part1Name = "part1"; 54 string part1Name = "part1";
@@ -82,6 +86,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
82 Assert.That(dupePart1.PhysActor, Is.Not.Null); 86 Assert.That(dupePart1.PhysActor, Is.Not.Null);
83 Assert.That(dupePart2.PhysActor, Is.Not.Null); 87 Assert.That(dupePart2.PhysActor, Is.Not.Null);
84 */ 88 */
89
90// TestHelpers.DisableLogging();
85 } 91 }
86 } 92 }
87} \ No newline at end of file 93} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index 7737d8e..3398a53 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -88,7 +88,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
88 { 88 {
89 TestHelpers.InMethod(); 89 TestHelpers.InMethod();
90 90
91 Scene scene = SceneHelpers.SetupScene(); 91 Scene scene = new SceneHelpers().SetupScene();
92 int partsToTestCount = 3; 92 int partsToTestCount = 3;
93 93
94 SceneObjectGroup so 94 SceneObjectGroup so
@@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
118 { 118 {
119 TestHelpers.InMethod(); 119 TestHelpers.InMethod();
120 120
121 Scene scene = SceneHelpers.SetupScene(); 121 Scene scene = new SceneHelpers().SetupScene();
122 122
123 string obj1Name = "Alfred"; 123 string obj1Name = "Alfred";
124 string obj2Name = "Betty"; 124 string obj2Name = "Betty";
@@ -152,7 +152,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
152 { 152 {
153 TestHelpers.InMethod(); 153 TestHelpers.InMethod();
154 154
155 Scene scene = SceneHelpers.SetupScene(); 155 Scene scene = new SceneHelpers().SetupScene();
156 int partsToTestCount = 3; 156 int partsToTestCount = 3;
157 157
158 SceneObjectGroup so 158 SceneObjectGroup so
@@ -185,11 +185,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
185 { 185 {
186 TestHelpers.InMethod(); 186 TestHelpers.InMethod();
187 187
188 TestScene scene = SceneHelpers.SetupScene(); 188 TestScene scene = new SceneHelpers().SetupScene();
189 SceneObjectPart part = SceneHelpers.AddSceneObject(scene); 189 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
190 scene.DeleteSceneObject(part.ParentGroup, false);
191 190
192 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 191 Assert.That(so.IsDeleted, Is.False);
192
193 scene.DeleteSceneObject(so, false);
194
195 Assert.That(so.IsDeleted, Is.True);
196
197 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
193 Assert.That(retrievedPart, Is.Null); 198 Assert.That(retrievedPart, Is.Null);
194 } 199 }
195 200
@@ -204,24 +209,28 @@ namespace OpenSim.Region.Framework.Scenes.Tests
204 209
205 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); 210 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
206 211
207 TestScene scene = SceneHelpers.SetupScene(); 212 TestScene scene = new SceneHelpers().SetupScene();
208 213
209 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 214 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
210 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 215 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
211 sogd.Enabled = false; 216 sogd.Enabled = false;
212 217
213 SceneObjectPart part = SceneHelpers.AddSceneObject(scene); 218 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
214 219
215 IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient; 220 IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
216 scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); 221 scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { so.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero);
217 222
218 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 223 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
219 224
220 Assert.That(retrievedPart, Is.Not.Null); 225 Assert.That(retrievedPart, Is.Not.Null);
221 226
227 Assert.That(so.IsDeleted, Is.False);
228
222 sogd.InventoryDeQueueAndDelete(); 229 sogd.InventoryDeQueueAndDelete();
223 230
224 SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(part.LocalId); 231 Assert.That(so.IsDeleted, Is.True);
232
233 SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId);
225 Assert.That(retrievedPart2, Is.Null); 234 Assert.That(retrievedPart2, Is.Null);
226 } 235 }
227 236
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
index 654b1a2..0076f41 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
61 61
62 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 62 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
63 63
64 TestScene scene = SceneHelpers.SetupScene(); 64 TestScene scene = new SceneHelpers().SetupScene();
65 IConfigSource configSource = new IniConfigSource(); 65 IConfigSource configSource = new IniConfigSource();
66 IConfig config = configSource.AddConfig("Startup"); 66 IConfig config = configSource.AddConfig("Startup");
67 config.Set("serverside_object_permissions", true); 67 config.Set("serverside_object_permissions", true);
@@ -100,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
100 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 100 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
101 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001"); 101 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001");
102 102
103 TestScene scene = SceneHelpers.SetupScene(); 103 TestScene scene = new SceneHelpers().SetupScene();
104 IConfigSource configSource = new IniConfigSource(); 104 IConfigSource configSource = new IniConfigSource();
105 IConfig config = configSource.AddConfig("Startup"); 105 IConfig config = configSource.AddConfig("Startup");
106 config.Set("serverside_object_permissions", true); 106 config.Set("serverside_object_permissions", true);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index be5b4a8..0e525c9 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
55 UUID ownerId = TestHelpers.ParseTail(0x1); 55 UUID ownerId = TestHelpers.ParseTail(0x1);
56 int nParts = 3; 56 int nParts = 3;
57 57
58 TestScene scene = SceneHelpers.SetupScene(); 58 TestScene scene = new SceneHelpers().SetupScene();
59 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10); 59 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10);
60 scene.AddSceneObject(sog1); 60 scene.AddSceneObject(sog1);
61 scene.LinkObjects(ownerId, sog1.LocalId, new List<uint>() { sog1.Parts[1].LocalId }); 61 scene.LinkObjects(ownerId, sog1.LocalId, new List<uint>() { sog1.Parts[1].LocalId });
@@ -71,11 +71,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
71 71
72 bool debugtest = false; 72 bool debugtest = false;
73 73
74 Scene scene = SceneHelpers.SetupScene(); 74 Scene scene = new SceneHelpers().SetupScene();
75 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); 75 SceneObjectGroup grp1 = SceneHelpers.AddSceneObject(scene);
76 SceneObjectGroup grp1 = part1.ParentGroup; 76 SceneObjectPart part1 = grp1.RootPart;
77 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); 77 SceneObjectGroup grp2 = SceneHelpers.AddSceneObject(scene);
78 SceneObjectGroup grp2 = part2.ParentGroup; 78 SceneObjectPart part2 = grp2.RootPart;
79 79
80 grp1.AbsolutePosition = new Vector3(10, 10, 10); 80 grp1.AbsolutePosition = new Vector3(10, 10, 10);
81 grp2.AbsolutePosition = Vector3.Zero; 81 grp2.AbsolutePosition = Vector3.Zero;
@@ -153,15 +153,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests
153 153
154 bool debugtest = false; 154 bool debugtest = false;
155 155
156 Scene scene = SceneHelpers.SetupScene(); 156 Scene scene = new SceneHelpers().SetupScene();
157 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); 157 SceneObjectGroup grp1 = SceneHelpers.AddSceneObject(scene);
158 SceneObjectGroup grp1 = part1.ParentGroup; 158 SceneObjectPart part1 = grp1.RootPart;
159 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); 159 SceneObjectGroup grp2 = SceneHelpers.AddSceneObject(scene);
160 SceneObjectGroup grp2 = part2.ParentGroup; 160 SceneObjectPart part2 = grp2.RootPart;
161 SceneObjectPart part3 = SceneHelpers.AddSceneObject(scene); 161 SceneObjectGroup grp3 = SceneHelpers.AddSceneObject(scene);
162 SceneObjectGroup grp3 = part3.ParentGroup; 162 SceneObjectPart part3 = grp3.RootPart;
163 SceneObjectPart part4 = SceneHelpers.AddSceneObject(scene); 163 SceneObjectGroup grp4 = SceneHelpers.AddSceneObject(scene);
164 SceneObjectGroup grp4 = part4.ParentGroup; 164 SceneObjectPart part4 = grp4.RootPart;
165 165
166 grp1.AbsolutePosition = new Vector3(10, 10, 10); 166 grp1.AbsolutePosition = new Vector3(10, 10, 10);
167 grp2.AbsolutePosition = Vector3.Zero; 167 grp2.AbsolutePosition = Vector3.Zero;
@@ -286,7 +286,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
286 TestHelpers.InMethod(); 286 TestHelpers.InMethod();
287 //log4net.Config.XmlConfigurator.Configure(); 287 //log4net.Config.XmlConfigurator.Configure();
288 288
289 TestScene scene = SceneHelpers.SetupScene(); 289 TestScene scene = new SceneHelpers().SetupScene();
290 290
291 string rootPartName = "rootpart"; 291 string rootPartName = "rootpart";
292 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); 292 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
@@ -325,7 +325,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
325 TestHelpers.InMethod(); 325 TestHelpers.InMethod();
326 //log4net.Config.XmlConfigurator.Configure(); 326 //log4net.Config.XmlConfigurator.Configure();
327 327
328 TestScene scene = SceneHelpers.SetupScene(); 328 TestScene scene = new SceneHelpers().SetupScene();
329 329
330 string rootPartName = "rootpart"; 330 string rootPartName = "rootpart";
331 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); 331 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
index b49c6e7..e931859 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
@@ -52,8 +52,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
52 TestHelpers.InMethod(); 52 TestHelpers.InMethod();
53// log4net.Config.XmlConfigurator.Configure(); 53// log4net.Config.XmlConfigurator.Configure();
54 54
55 Scene scene = SceneHelpers.SetupScene(); 55 Scene scene = new SceneHelpers().SetupScene();
56 SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup; 56 SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene);
57 57
58 g1.GroupResize(new Vector3(2, 3, 4)); 58 g1.GroupResize(new Vector3(2, 3, 4));
59 59
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
75 TestHelpers.InMethod(); 75 TestHelpers.InMethod();
76 //log4net.Config.XmlConfigurator.Configure(); 76 //log4net.Config.XmlConfigurator.Configure();
77 77
78 Scene scene = SceneHelpers.SetupScene(); 78 Scene scene = new SceneHelpers().SetupScene();
79 79
80 SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(2, UUID.Zero); 80 SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(2, UUID.Zero);
81 g1.RootPart.Scale = new Vector3(2, 3, 4); 81 g1.RootPart.Scale = new Vector3(2, 3, 4);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
index c582cf6..d2361f8 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
52// UUID itemId = TestHelpers.ParseTail(0x2); 52// UUID itemId = TestHelpers.ParseTail(0x2);
53 string itemName = "Test Script Item"; 53 string itemName = "Test Script Item";
54 54
55 Scene scene = SceneHelpers.SetupScene(); 55 Scene scene = new SceneHelpers().SetupScene();
56 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); 56 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
57 scene.AddNewSceneObject(so, true); 57 scene.AddNewSceneObject(so, true);
58 58
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
new file mode 100644
index 0000000..6d255aa
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
@@ -0,0 +1,154 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Threading;
31using NUnit.Framework;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38
39namespace OpenSim.Region.Framework.Scenes.Tests
40{
41 /// <summary>
42 /// Spatial scene object tests (will eventually cover root and child part position, rotation properties, etc.)
43 /// </summary>
44 [TestFixture]
45 public class SceneObjectSpatialTests
46 {
47 TestScene m_scene;
48 UUID m_ownerId = TestHelpers.ParseTail(0x1);
49
50 [SetUp]
51 public void SetUp()
52 {
53 m_scene = new SceneHelpers().SetupScene();
54 }
55
56 [Test]
57 public void TestGetSceneObjectGroupPosition()
58 {
59 TestHelpers.InMethod();
60
61 Vector3 position = new Vector3(10, 20, 30);
62
63 SceneObjectGroup so
64 = SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10);
65 so.AbsolutePosition = position;
66 m_scene.AddNewSceneObject(so, false);
67
68 Assert.That(so.AbsolutePosition, Is.EqualTo(position));
69 }
70
71 [Test]
72 public void TestGetRootPartPosition()
73 {
74 TestHelpers.InMethod();
75
76 Vector3 partPosition = new Vector3(10, 20, 30);
77
78 SceneObjectGroup so
79 = SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10);
80 so.AbsolutePosition = partPosition;
81 m_scene.AddNewSceneObject(so, false);
82
83 Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition));
84 Assert.That(so.RootPart.GroupPosition, Is.EqualTo(partPosition));
85 Assert.That(so.RootPart.GetWorldPosition(), Is.EqualTo(partPosition));
86 Assert.That(so.RootPart.RelativePosition, Is.EqualTo(partPosition));
87 Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero));
88 }
89
90 [Test]
91 public void TestGetChildPartPosition()
92 {
93 TestHelpers.InMethod();
94
95 Vector3 rootPartPosition = new Vector3(10, 20, 30);
96 Vector3 childOffsetPosition = new Vector3(2, 3, 4);
97
98 SceneObjectGroup so
99 = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
100 so.AbsolutePosition = rootPartPosition;
101 so.Parts[1].OffsetPosition = childOffsetPosition;
102
103 m_scene.AddNewSceneObject(so, false);
104
105 // Calculate child absolute position.
106 Vector3 childPosition = new Vector3(rootPartPosition + childOffsetPosition);
107
108 SceneObjectPart childPart = so.Parts[1];
109 Assert.That(childPart.AbsolutePosition, Is.EqualTo(childPosition));
110 Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
111 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
112 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
113 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
114 }
115
116 [Test]
117 public void TestGetChildPartPositionAfterObjectRotation()
118 {
119 TestHelpers.InMethod();
120
121 Vector3 rootPartPosition = new Vector3(10, 20, 30);
122 Vector3 childOffsetPosition = new Vector3(2, 3, 4);
123
124 SceneObjectGroup so
125 = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
126 so.AbsolutePosition = rootPartPosition;
127 so.Parts[1].OffsetPosition = childOffsetPosition;
128
129 m_scene.AddNewSceneObject(so, false);
130
131 so.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 0, -90 * Utils.DEG_TO_RAD));
132
133 // Calculate child absolute position.
134 Vector3 rotatedChildOffsetPosition
135 = new Vector3(childOffsetPosition.Y, -childOffsetPosition.X, childOffsetPosition.Z);
136
137 Vector3 childPosition = new Vector3(rootPartPosition + rotatedChildOffsetPosition);
138
139 SceneObjectPart childPart = so.Parts[1];
140
141 // FIXME: Should be childPosition after rotation?
142 Assert.That(childPart.AbsolutePosition, Is.EqualTo(rootPartPosition + childOffsetPosition));
143
144 Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
145 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
146
147 // Relative to root part as (0, 0, 0)
148 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
149
150 // Relative to root part as (0, 0, 0)
151 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
152 }
153 }
154} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
index 2a342d5..742c769 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using NUnit.Framework; 31using NUnit.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
@@ -43,24 +44,141 @@ namespace OpenSim.Region.Framework.Scenes.Tests
43 [TestFixture] 44 [TestFixture]
44 public class SceneObjectStatusTests 45 public class SceneObjectStatusTests
45 { 46 {
47 private TestScene m_scene;
48 private UUID m_ownerId = TestHelpers.ParseTail(0x1);
49 private SceneObjectGroup m_so1;
50 private SceneObjectGroup m_so2;
51
52 [SetUp]
53 public void Init()
54 {
55 m_scene = new SceneHelpers().SetupScene();
56 m_so1 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so1", 0x10);
57 m_so2 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so2", 0x20);
58 }
59
46 [Test] 60 [Test]
47 public void TestSetPhantom() 61 public void TestSetPhantomSinglePrim()
48 { 62 {
49 TestHelpers.InMethod(); 63 TestHelpers.InMethod();
50 64
51// Scene scene = SceneSetupHelpers.SetupScene(); 65 m_scene.AddSceneObject(m_so1);
52 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero); 66
53 SceneObjectPart rootPart = so.RootPart; 67 SceneObjectPart rootPart = m_so1.RootPart;
54 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); 68 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
55 69
56 so.ScriptSetPhantomStatus(true); 70 m_so1.ScriptSetPhantomStatus(true);
57 71
58// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); 72// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
59 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); 73 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom));
60 74
61 so.ScriptSetPhantomStatus(false); 75 m_so1.ScriptSetPhantomStatus(false);
62 76
63 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); 77 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
64 } 78 }
79
80 [Test]
81 public void TestSetPhysicsSinglePrim()
82 {
83 TestHelpers.InMethod();
84
85 m_scene.AddSceneObject(m_so1);
86
87 SceneObjectPart rootPart = m_so1.RootPart;
88 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
89
90 m_so1.ScriptSetPhysicsStatus(true);
91
92// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
93 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Physics));
94
95 m_so1.ScriptSetPhysicsStatus(false);
96
97 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
98 }
99
100 [Test]
101 public void TestSetPhysicsLinkset()
102 {
103 TestHelpers.InMethod();
104
105 m_scene.AddSceneObject(m_so1);
106 m_scene.AddSceneObject(m_so2);
107
108 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
109
110 m_so1.ScriptSetPhysicsStatus(true);
111
112 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
113 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
114
115 m_so1.ScriptSetPhysicsStatus(false);
116
117 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None));
118 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None));
119
120 m_so1.ScriptSetPhysicsStatus(true);
121
122 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
123 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
124 }
125
126 /// <summary>
127 /// Test that linking results in the correct physical status for all linkees.
128 /// </summary>
129 [Test]
130 public void TestLinkPhysicsBothPhysical()
131 {
132 TestHelpers.InMethod();
133
134 m_scene.AddSceneObject(m_so1);
135 m_scene.AddSceneObject(m_so2);
136
137 m_so1.ScriptSetPhysicsStatus(true);
138 m_so2.ScriptSetPhysicsStatus(true);
139
140 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
141
142 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
143 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
144 }
145
146 /// <summary>
147 /// Test that linking results in the correct physical status for all linkees.
148 /// </summary>
149 [Test]
150 public void TestLinkPhysicsRootPhysicalOnly()
151 {
152 TestHelpers.InMethod();
153
154 m_scene.AddSceneObject(m_so1);
155 m_scene.AddSceneObject(m_so2);
156
157 m_so1.ScriptSetPhysicsStatus(true);
158
159 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
160
161 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
162 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
163 }
164
165 /// <summary>
166 /// Test that linking results in the correct physical status for all linkees.
167 /// </summary>
168 [Test]
169 public void TestLinkPhysicsChildPhysicalOnly()
170 {
171 TestHelpers.InMethod();
172
173 m_scene.AddSceneObject(m_so1);
174 m_scene.AddSceneObject(m_so2);
175
176 m_so2.ScriptSetPhysicsStatus(true);
177
178 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
179
180 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None));
181 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None));
182 }
65 } 183 }
66} \ No newline at end of file 184} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
index c13d82e..c7eaff9 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
58 58
59 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 59 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
60 60
61 TestScene scene = SceneHelpers.SetupScene(); 61 TestScene scene = new SceneHelpers().SetupScene();
62 IConfigSource configSource = new IniConfigSource(); 62 IConfigSource configSource = new IniConfigSource();
63 63
64 IConfig startupConfig = configSource.AddConfig("Startup"); 64 IConfig startupConfig = configSource.AddConfig("Startup");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index ed9b179..02c45ef 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -67,10 +67,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests
67 public void Init() 67 public void Init()
68 { 68 {
69 TestHelpers.InMethod(); 69 TestHelpers.InMethod();
70 70
71 scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); 71 SceneHelpers sh = new SceneHelpers();
72 scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); 72
73 scene3 = SceneHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); 73 scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000);
74 scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000);
75 scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000);
74 76
75 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); 77 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
76 interregionComms.Initialise(new IniConfigSource()); 78 interregionComms.Initialise(new IniConfigSource());
@@ -99,9 +101,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
99 public void TestCloseAgent() 101 public void TestCloseAgent()
100 { 102 {
101 TestHelpers.InMethod(); 103 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure(); 104// TestHelpers.EnableLogging();
103 105
104 TestScene scene = SceneHelpers.SetupScene(); 106 TestScene scene = new SceneHelpers().SetupScene();
105 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 107 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
106 108
107 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null); 109 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null);
@@ -112,6 +114,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
112 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); 114 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
113 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); 115 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
114 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(0)); 116 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(0));
117
118// TestHelpers.DisableLogging();
115 } 119 }
116 120
117 [Test] 121 [Test]
@@ -126,7 +130,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
126 IConfig config = configSource.AddConfig("Modules"); 130 IConfig config = configSource.AddConfig("Modules");
127 config.Set("SimulationServices", "LocalSimulationConnectorModule"); 131 config.Set("SimulationServices", "LocalSimulationConnectorModule");
128 132
129 TestScene scene = SceneHelpers.SetupScene(); 133 SceneHelpers sceneHelpers = new SceneHelpers();
134 TestScene scene = sceneHelpers.SetupScene();
130 SceneHelpers.SetupSceneModules(scene, configSource, lsc); 135 SceneHelpers.SetupSceneModules(scene, configSource, lsc);
131 136
132 UUID agentId = TestHelpers.ParseTail(0x01); 137 UUID agentId = TestHelpers.ParseTail(0x01);
@@ -176,8 +181,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
176 181
177// UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); 182// UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001");
178 183
179 TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); 184 TestScene myScene1 = new SceneHelpers().SetupScene("Neighbour y", UUID.Random(), 1000, 1000);
180 TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); 185 TestScene myScene2 = new SceneHelpers().SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000);
181 186
182 IConfigSource configSource = new IniConfigSource(); 187 IConfigSource configSource = new IniConfigSource();
183 IConfig config = configSource.AddConfig("Startup"); 188 IConfig config = configSource.AddConfig("Startup");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
index 89f8007..646e5fa 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
@@ -59,7 +59,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
59 TestHelpers.InMethod(); 59 TestHelpers.InMethod();
60// log4net.Config.XmlConfigurator.Configure(); 60// log4net.Config.XmlConfigurator.Configure();
61 61
62 TestScene scene = SceneHelpers.SetupScene(); 62 TestScene scene = new SceneHelpers().SetupScene();
63 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 63 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
64 sp.Flying = true; 64 sp.Flying = true;
65 sp.PhysicsCollisionUpdate(new CollisionEventUpdate()); 65 sp.PhysicsCollisionUpdate(new CollisionEventUpdate());
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
index cfea10d..1d1ff88 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -64,7 +64,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
64 [SetUp] 64 [SetUp]
65 public void Init() 65 public void Init()
66 { 66 {
67 m_scene = SceneHelpers.SetupScene(); 67 m_scene = new SceneHelpers().SetupScene();
68 } 68 }
69 69
70 [Test] 70 [Test]
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
index b7b8db4..493ab70 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using Nini.Config; 31using Nini.Config;
31using NUnit.Framework; 32using NUnit.Framework;
@@ -50,7 +51,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
50 [SetUp] 51 [SetUp]
51 public void Init() 52 public void Init()
52 { 53 {
53 m_scene = SceneHelpers.SetupScene(); 54 m_scene = new SceneHelpers().SetupScene();
54 m_sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); 55 m_sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
55 } 56 }
56 57
@@ -64,11 +65,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
64 Vector3 startPos = new Vector3(10.1f, 0, 0); 65 Vector3 startPos = new Vector3(10.1f, 0, 0);
65 m_sp.AbsolutePosition = startPos; 66 m_sp.AbsolutePosition = startPos;
66 67
67 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); 68 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
68 69
69 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); 70 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
70 71
71 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); 72 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
73 Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
74 Assert.That(part.GetSittingAvatars(), Is.Null);
72 Assert.That(m_sp.ParentID, Is.EqualTo(0)); 75 Assert.That(m_sp.ParentID, Is.EqualTo(0));
73 } 76 }
74 77
@@ -82,11 +85,17 @@ namespace OpenSim.Region.Framework.Scenes.Tests
82 Vector3 startPos = new Vector3(9.9f, 0, 0); 85 Vector3 startPos = new Vector3(9.9f, 0, 0);
83 m_sp.AbsolutePosition = startPos; 86 m_sp.AbsolutePosition = startPos;
84 87
85 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); 88 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
86 89
87 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); 90 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
88 91
92 Assert.That(m_sp.PhysicsActor, Is.Null);
93
89 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); 94 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
95 Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1));
96 HashSet<UUID> sittingAvatars = part.GetSittingAvatars();
97 Assert.That(sittingAvatars.Count, Is.EqualTo(1));
98 Assert.That(sittingAvatars.Contains(m_sp.UUID));
90 Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); 99 Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
91 } 100 }
92 101
@@ -100,14 +109,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
100 Vector3 startPos = new Vector3(1, 1, 1); 109 Vector3 startPos = new Vector3(1, 1, 1);
101 m_sp.AbsolutePosition = startPos; 110 m_sp.AbsolutePosition = startPos;
102 111
103 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); 112 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
104 113
105 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); 114 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
106 115
107 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
108 Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
109 Assert.That(m_sp.PhysicsActor, Is.Null);
110
111 // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the 116 // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the
112 // default avatar. 117 // default avatar.
113 // Curiously, Vector3.ToString() will not display the last two places of the float. For example, 118 // Curiously, Vector3.ToString() will not display the last two places of the float. For example,
@@ -119,6 +124,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
119 m_sp.StandUp(); 124 m_sp.StandUp();
120 125
121 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); 126 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
127 Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
128 Assert.That(part.GetSittingAvatars(), Is.Null);
122 Assert.That(m_sp.ParentID, Is.EqualTo(0)); 129 Assert.That(m_sp.ParentID, Is.EqualTo(0));
123 Assert.That(m_sp.PhysicsActor, Is.Not.Null); 130 Assert.That(m_sp.PhysicsActor, Is.Not.Null);
124 } 131 }
@@ -133,7 +140,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
133 Vector3 startPos = new Vector3(128, 128, 30); 140 Vector3 startPos = new Vector3(128, 128, 30);
134 m_sp.AbsolutePosition = startPos; 141 m_sp.AbsolutePosition = startPos;
135 142
136 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); 143 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
137 part.SitTargetPosition = new Vector3(0, 0, 1); 144 part.SitTargetPosition = new Vector3(0, 0, 1);
138 145
139 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); 146 m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
@@ -145,11 +152,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
145 Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); 152 Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
146 Assert.That(m_sp.PhysicsActor, Is.Null); 153 Assert.That(m_sp.PhysicsActor, Is.Null);
147 154
155 Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1));
156 HashSet<UUID> sittingAvatars = part.GetSittingAvatars();
157 Assert.That(sittingAvatars.Count, Is.EqualTo(1));
158 Assert.That(sittingAvatars.Contains(m_sp.UUID));
159
148 m_sp.StandUp(); 160 m_sp.StandUp();
149 161
150 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); 162 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
151 Assert.That(m_sp.ParentID, Is.EqualTo(0)); 163 Assert.That(m_sp.ParentID, Is.EqualTo(0));
152 Assert.That(m_sp.PhysicsActor, Is.Not.Null); 164 Assert.That(m_sp.PhysicsActor, Is.Not.Null);
165
166 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
167 Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
168 Assert.That(part.GetSittingAvatars(), Is.Null);
153 } 169 }
154 170
155 [Test] 171 [Test]
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index bebc10c..a407f01 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -34,10 +34,14 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
36using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.CoreModules.Framework;
38using OpenSim.Region.CoreModules.Framework.EntityTransfer;
37using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 39using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
40using OpenSim.Region.CoreModules.World.Permissions;
38using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock; 42using OpenSim.Tests.Common.Mock;
40using System.Threading; 43using System.IO;
44using System.Text;
41 45
42namespace OpenSim.Region.Framework.Scenes.Tests 46namespace OpenSim.Region.Framework.Scenes.Tests
43{ 47{
@@ -47,145 +51,367 @@ namespace OpenSim.Region.Framework.Scenes.Tests
47 [TestFixture] 51 [TestFixture]
48 public class ScenePresenceTeleportTests 52 public class ScenePresenceTeleportTests
49 { 53 {
50 /// <summary> 54 [TestFixtureSetUp]
51 /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. 55 public void FixtureInit()
52 /// </summary> 56 {
53 /// Does not yet do what is says on the tin. 57 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
54 /// Commenting for now 58 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
55 //[Test, LongRunning] 59 }
56 public void TestSimpleNotNeighboursTeleport() 60
61 [TestFixtureTearDown]
62 public void TearDown()
63 {
64 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
65 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
66 // tests really shouldn't).
67 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
68 }
69
70 [Test]
71 public void TestSameRegionTeleport()
57 { 72 {
58 TestHelpers.InMethod(); 73 TestHelpers.InMethod();
59 ThreadRunResults results = new ThreadRunResults(); 74// log4net.Config.XmlConfigurator.Configure();
60 results.Result = false; 75
61 results.Message = "Test did not run"; 76 EntityTransferModule etm = new EntityTransferModule();
62 TestRunning testClass = new TestRunning(results); 77
78 IConfigSource config = new IniConfigSource();
79 config.AddConfig("Modules");
80 // Not strictly necessary since FriendsModule assumes it is the default (!)
81 config.Configs["Modules"].Set("EntityTransferModule", etm.Name);
82
83 TestScene scene = new SceneHelpers().SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
84 SceneHelpers.SetupSceneModules(scene, config, etm);
85
86 Vector3 teleportPosition = new Vector3(10, 11, 12);
87 Vector3 teleportLookAt = new Vector3(20, 21, 22);
88
89 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
90 sp.AbsolutePosition = new Vector3(30, 31, 32);
91 scene.RequestTeleportLocation(
92 sp.ControllingClient,
93 scene.RegionInfo.RegionHandle,
94 teleportPosition,
95 teleportLookAt,
96 (uint)TeleportFlags.ViaLocation);
63 97
64 Thread testThread = new Thread(testClass.run); 98 Assert.That(sp.AbsolutePosition, Is.EqualTo(teleportPosition));
65 99
66 // Seems kind of redundant to start a thread and then join it, however.. We need to protect against 100 Assert.That(scene.GetRootAgentCount(), Is.EqualTo(1));
67 // A thread abort exception in the simulator code. 101 Assert.That(scene.GetChildAgentCount(), Is.EqualTo(0));
68 testThread.Start();
69 testThread.Join();
70 102
71 Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); 103 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
72 // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); 104 // position instead).
105// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
73 } 106 }
74 107
75 [TearDown] 108 [Test]
76 public void TearDown() 109 public void TestSameSimulatorSeparatedRegionsTeleport()
77 { 110 {
78 try 111 TestHelpers.InMethod();
79 { 112// log4net.Config.XmlConfigurator.Configure();
80 if (MainServer.Instance != null) MainServer.Instance.Stop(); 113
81 } 114 UUID userId = TestHelpers.ParseTail(0x1);
82 catch (NullReferenceException) 115
83 { } 116 EntityTransferModule etmA = new EntityTransferModule();
117 EntityTransferModule etmB = new EntityTransferModule();
118 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
119
120 IConfigSource config = new IniConfigSource();
121 IConfig modulesConfig = config.AddConfig("Modules");
122 modulesConfig.Set("EntityTransferModule", etmA.Name);
123 modulesConfig.Set("SimulationServices", lscm.Name);
124 IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
125
126 // In order to run a single threaded regression test we do not want the entity transfer module waiting
127 // for a callback from the destination scene before removing its avatar data.
128 entityTransferConfig.Set("wait_for_callback", false);
129
130 SceneHelpers sh = new SceneHelpers();
131 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
132 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000);
133
134 SceneHelpers.SetupSceneModules(sceneA, config, etmA);
135 SceneHelpers.SetupSceneModules(sceneB, config, etmB);
136 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
137
138 Vector3 teleportPosition = new Vector3(10, 11, 12);
139 Vector3 teleportLookAt = new Vector3(20, 21, 22);
140
141 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
142 sp.AbsolutePosition = new Vector3(30, 31, 32);
143
144 // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole
145 // UDP stack (?)
146// ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB;
147
148 sceneA.RequestTeleportLocation(
149 sp.ControllingClient,
150 sceneB.RegionInfo.RegionHandle,
151 teleportPosition,
152 teleportLookAt,
153 (uint)TeleportFlags.ViaLocation);
154
155 ((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
156
157 Assert.That(sceneA.GetScenePresence(userId), Is.Null);
158
159 ScenePresence sceneBSp = sceneB.GetScenePresence(userId);
160 Assert.That(sceneBSp, Is.Not.Null);
161 Assert.That(sceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
162 Assert.That(sceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
163
164 Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0));
165 Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
166 Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1));
167 Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
168
169 // TODO: Add assertions to check correct circuit details in both scenes.
170
171 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
172 // position instead).
173// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
84 } 174 }
85 175
86 } 176 /// <summary>
177 /// Test teleport procedures when the target simulator returns false when queried about access.
178 /// </summary>
179 [Test]
180 public void TestSameSimulatorSeparatedRegionsQueryAccessFails()
181 {
182 TestHelpers.InMethod();
183// TestHelpers.EnableLogging();
87 184
88 public class ThreadRunResults 185 UUID userId = TestHelpers.ParseTail(0x1);
89 { 186 Vector3 preTeleportPosition = new Vector3(30, 31, 32);
90 public bool Result = false;
91 public string Message = string.Empty;
92 }
93 187
94 public class TestRunning 188 EntityTransferModule etmA = new EntityTransferModule();
95 { 189 EntityTransferModule etmB = new EntityTransferModule();
96 public ThreadRunResults results; 190
97 public TestRunning(ThreadRunResults t) 191 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
192
193 IConfigSource config = new IniConfigSource();
194 config.AddConfig("Modules");
195 config.Configs["Modules"].Set("EntityTransferModule", etmA.Name);
196 config.Configs["Modules"].Set("SimulationServices", lscm.Name);
197
198 config.AddConfig("EntityTransfer");
199
200 // In order to run a single threaded regression test we do not want the entity transfer module waiting
201 // for a callback from the destination scene before removing its avatar data.
202 config.Configs["EntityTransfer"].Set("wait_for_callback", false);
203
204 config.AddConfig("Startup");
205 config.Configs["Startup"].Set("serverside_object_permissions", true);
206
207 SceneHelpers sh = new SceneHelpers();
208 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
209 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000);
210
211 SceneHelpers.SetupSceneModules(sceneA, config, etmA );
212
213 // We need to set up the permisions module on scene B so that our later use of agent limit to deny
214 // QueryAccess won't succeed anyway because administrators are always allowed in and the default
215 // IsAdministrator if no permissions module is present is true.
216 SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule(), etmB });
217
218 // Shared scene modules
219 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
220
221 Vector3 teleportPosition = new Vector3(10, 11, 12);
222 Vector3 teleportLookAt = new Vector3(20, 21, 22);
223
224 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
225 sp.AbsolutePosition = preTeleportPosition;
226
227 // Make sceneB return false on query access
228 sceneB.RegionInfo.RegionSettings.AgentLimit = 0;
229
230 sceneA.RequestTeleportLocation(
231 sp.ControllingClient,
232 sceneB.RegionInfo.RegionHandle,
233 teleportPosition,
234 teleportLookAt,
235 (uint)TeleportFlags.ViaLocation);
236
237// ((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
238
239 Assert.That(sceneB.GetScenePresence(userId), Is.Null);
240
241 ScenePresence sceneASp = sceneA.GetScenePresence(userId);
242 Assert.That(sceneASp, Is.Not.Null);
243 Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
244 Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
245
246 Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1));
247 Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
248 Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(0));
249 Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
250
251 // TODO: Add assertions to check correct circuit details in both scenes.
252
253 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
254 // position instead).
255// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
256
257// TestHelpers.DisableLogging();
258 }
259
260 /// <summary>
261 /// Test teleport procedures when the target simulator create agent step is refused.
262 /// </summary>
263 [Test]
264 public void TestSameSimulatorSeparatedRegionsCreateAgentFails()
98 { 265 {
99 results = t; 266 TestHelpers.InMethod();
267// TestHelpers.EnableLogging();
268
269 UUID userId = TestHelpers.ParseTail(0x1);
270 Vector3 preTeleportPosition = new Vector3(30, 31, 32);
271
272 EntityTransferModule etmA = new EntityTransferModule();
273 EntityTransferModule etmB = new EntityTransferModule();
274 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
275
276 IConfigSource config = new IniConfigSource();
277 config.AddConfig("Modules");
278 config.Configs["Modules"].Set("EntityTransferModule", etmA.Name);
279 config.Configs["Modules"].Set("SimulationServices", lscm.Name);
280
281 config.AddConfig("EntityTransfer");
282
283 // In order to run a single threaded regression test we do not want the entity transfer module waiting
284 // for a callback from the destination scene before removing its avatar data.
285 config.Configs["EntityTransfer"].Set("wait_for_callback", false);
286
287 SceneHelpers sh = new SceneHelpers();
288 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
289 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000);
290
291 SceneHelpers.SetupSceneModules(sceneA, config, etmA);
292 SceneHelpers.SetupSceneModules(sceneB, config, etmB);
293
294 // Shared scene modules
295 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
296
297 Vector3 teleportPosition = new Vector3(10, 11, 12);
298 Vector3 teleportLookAt = new Vector3(20, 21, 22);
299
300 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
301 sp.AbsolutePosition = preTeleportPosition;
302
303 // Make sceneB refuse CreateAgent
304 sceneB.LoginsDisabled = true;
305
306 sceneA.RequestTeleportLocation(
307 sp.ControllingClient,
308 sceneB.RegionInfo.RegionHandle,
309 teleportPosition,
310 teleportLookAt,
311 (uint)TeleportFlags.ViaLocation);
312
313// ((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
314
315 Assert.That(sceneB.GetScenePresence(userId), Is.Null);
316
317 ScenePresence sceneASp = sceneA.GetScenePresence(userId);
318 Assert.That(sceneASp, Is.Not.Null);
319 Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
320 Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
321
322 Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1));
323 Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
324 Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(0));
325 Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
326
327 // TODO: Add assertions to check correct circuit details in both scenes.
328
329 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
330 // position instead).
331// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
332
333// TestHelpers.DisableLogging();
100 } 334 }
101 public void run(object o) 335
336 [Test]
337 public void TestSameSimulatorNeighbouringRegionsTeleport()
102 { 338 {
103 339 TestHelpers.InMethod();
104 //results.Result = true; 340// TestHelpers.EnableLogging();
105 log4net.Config.XmlConfigurator.Configure(); 341
106 342 UUID userId = TestHelpers.ParseTail(0x1);
107 UUID sceneAId = UUID.Parse("00000000-0000-0000-0000-000000000100"); 343
108 UUID sceneBId = UUID.Parse("00000000-0000-0000-0000-000000000200"); 344 EntityTransferModule etmA = new EntityTransferModule();
109 345 EntityTransferModule etmB = new EntityTransferModule();
110 // shared module 346 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
111 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); 347
112 348 IConfigSource config = new IniConfigSource();
113 349 IConfig modulesConfig = config.AddConfig("Modules");
114 Scene sceneB = SceneHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); 350 modulesConfig.Set("EntityTransferModule", etmA.Name);
115 SceneHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); 351 modulesConfig.Set("SimulationServices", lscm.Name);
116 sceneB.RegisterRegionWithGrid(); 352 IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
117 353
118 Scene sceneA = SceneHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); 354 // In order to run a single threaded regression test we do not want the entity transfer module waiting
119 SceneHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); 355 // for a callback from the destination scene before removing its avatar data.
120 sceneA.RegisterRegionWithGrid(); 356 entityTransferConfig.Set("wait_for_callback", false);
121 357
122 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); 358 SceneHelpers sh = new SceneHelpers();
123 TestClient client = (TestClient)SceneHelpers.AddScenePresence(sceneA, agentId).ControllingClient; 359 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
124 360 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
125 ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface<ICapabilitiesModule>(); 361
126 362 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
127 results.Result = (sceneACapsModule.GetCapsPath(agentId) == client.CapsSeedUrl); 363 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
128 364 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
129 if (!results.Result) 365
130 { 366 Vector3 teleportPosition = new Vector3(10, 11, 12);
131 results.Message = "Incorrect caps object path set up in sceneA"; 367 Vector3 teleportLookAt = new Vector3(20, 21, 22);
132 return; 368
133 } 369 ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
134 370 originalSp.AbsolutePosition = new Vector3(30, 31, 32);
135 /* 371
136 Assert.That( 372 ScenePresence beforeSceneASp = sceneA.GetScenePresence(userId);
137 sceneACapsModule.GetCapsPath(agentId), 373 Assert.That(beforeSceneASp, Is.Not.Null);
138 Is.EqualTo(client.CapsSeedUrl), 374 Assert.That(beforeSceneASp.IsChildAgent, Is.False);
139 "Incorrect caps object path set up in sceneA"); 375
140 */ 376 ScenePresence beforeSceneBSp = sceneB.GetScenePresence(userId);
141 // FIXME: This is a hack to get the test working - really the normal OpenSim mechanisms should be used. 377 Assert.That(beforeSceneBSp, Is.Not.Null);
142 378 Assert.That(beforeSceneBSp.IsChildAgent, Is.True);
143 379
144 client.TeleportTargetScene = sceneB; 380 // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole
145 client.Teleport(sceneB.RegionInfo.RegionHandle, new Vector3(100, 100, 100), new Vector3(40, 40, 40)); 381 // UDP stack (?)
146 382// ((TestClient)beforeSceneASp.ControllingClient).TeleportTargetScene = sceneB;
147 results.Result = (sceneB.GetScenePresence(agentId) != null); 383
148 if (!results.Result) 384 sceneA.RequestTeleportLocation(
149 { 385 beforeSceneASp.ControllingClient,
150 results.Message = "Client does not have an agent in sceneB"; 386 sceneB.RegionInfo.RegionHandle,
151 return; 387 teleportPosition,
152 } 388 teleportLookAt,
153 389 (uint)TeleportFlags.ViaLocation);
154 //Assert.That(sceneB.GetScenePresence(agentId), Is.Not.Null, "Client does not have an agent in sceneB"); 390
155 391 ((TestClient)beforeSceneASp.ControllingClient).CompleteTeleportClientSide();
156 //Assert.That(sceneA.GetScenePresence(agentId), Is.Null, "Client still had an agent in sceneA"); 392
157 393 ScenePresence afterSceneASp = sceneA.GetScenePresence(userId);
158 results.Result = (sceneA.GetScenePresence(agentId) == null); 394 Assert.That(afterSceneASp, Is.Not.Null);
159 if (!results.Result) 395 Assert.That(afterSceneASp.IsChildAgent, Is.True);
160 { 396
161 results.Message = "Client still had an agent in sceneA"; 397 ScenePresence afterSceneBSp = sceneB.GetScenePresence(userId);
162 return; 398 Assert.That(afterSceneBSp, Is.Not.Null);
163 } 399 Assert.That(afterSceneBSp.IsChildAgent, Is.False);
164 400 Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
165 ICapabilitiesModule sceneBCapsModule = sceneB.RequestModuleInterface<ICapabilitiesModule>(); 401 Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
166 402
167 403 Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0));
168 results.Result = ("http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + 404 Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(1));
169 "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/" == client.CapsSeedUrl); 405 Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1));
170 if (!results.Result) 406 Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
171 { 407
172 results.Message = "Incorrect caps object path set up in sceneB"; 408 // TODO: Add assertions to check correct circuit details in both scenes.
173 return; 409
174 } 410 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
175 411 // position instead).
176 // Temporary assertion - caps url construction should at least be doable through a method. 412// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
177 /* 413
178 Assert.That( 414// TestHelpers.DisableLogging();
179 "http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/",
180 Is.EqualTo(client.CapsSeedUrl),
181 "Incorrect caps object path set up in sceneB");
182 */
183 // This assertion will currently fail since we don't remove the caps paths when no longer needed
184 //Assert.That(sceneACapsModule.GetCapsPath(agentId), Is.Null, "sceneA still had a caps object path");
185
186 // TODO: Check that more of everything is as it should be
187
188 // TODO: test what happens if we try to teleport to a region that doesn't exist
189 } 415 }
190 } 416 }
191} 417} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 5c9a77d..d722a09 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -60,7 +60,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
60 { 60 {
61 TestHelpers.InMethod(); 61 TestHelpers.InMethod();
62 62
63 Scene scene = SceneHelpers.SetupScene(); 63 Scene scene = new SceneHelpers().SetupScene();
64 scene.Update(1); 64 scene.Update(1);
65 65
66 Assert.That(scene.Frame, Is.EqualTo(1)); 66 Assert.That(scene.Frame, Is.EqualTo(1));
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index 55c80f5..a51e4e3 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Tests
58 TestHelpers.InMethod(); 58 TestHelpers.InMethod();
59// log4net.Config.XmlConfigurator.Configure(); 59// log4net.Config.XmlConfigurator.Configure();
60 60
61 Scene scene = SceneHelpers.SetupScene(); 61 Scene scene = new SceneHelpers().SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
63 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); 63 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
64 SceneObjectPart sop1 = sog1.RootPart; 64 SceneObjectPart sop1 = sog1.RootPart;
@@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Tests
81 TestHelpers.InMethod(); 81 TestHelpers.InMethod();
82// log4net.Config.XmlConfigurator.Configure(); 82// log4net.Config.XmlConfigurator.Configure();
83 83
84 Scene scene = SceneHelpers.SetupScene(); 84 Scene scene = new SceneHelpers().SetupScene();
85 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 85 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
86 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); 86 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
87 SceneObjectPart sop1 = sog1.RootPart; 87 SceneObjectPart sop1 = sog1.RootPart;
@@ -124,11 +124,13 @@ namespace OpenSim.Region.Framework.Tests
124 TestHelpers.InMethod(); 124 TestHelpers.InMethod();
125// log4net.Config.XmlConfigurator.Configure(); 125// log4net.Config.XmlConfigurator.Configure();
126 126
127 Scene scene = SceneHelpers.SetupScene(); 127 Scene scene = new SceneHelpers().SetupScene();
128 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 128 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
129 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); 129 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
130 SceneObjectPart sop1 = sog1.RootPart; 130 SceneObjectPart sop1 = sog1.RootPart;
131 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); 131 TaskInventoryItem sopItem1
132 = TaskInventoryHelpers.AddNotecard(
133 scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900));
132 134
133 InventoryFolderBase folder 135 InventoryFolderBase folder
134 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0]; 136 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0];
@@ -153,11 +155,14 @@ namespace OpenSim.Region.Framework.Tests
153 TestHelpers.InMethod(); 155 TestHelpers.InMethod();
154// log4net.Config.XmlConfigurator.Configure(); 156// log4net.Config.XmlConfigurator.Configure();
155 157
156 Scene scene = SceneHelpers.SetupScene(); 158 Scene scene = new SceneHelpers().SetupScene();
157 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 159 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
158 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); 160 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
161
159 SceneObjectPart sop1 = sog1.RootPart; 162 SceneObjectPart sop1 = sog1.RootPart;
160 TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1); 163 TaskInventoryItem sopItem1
164 = TaskInventoryHelpers.AddNotecard(
165 scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900));
161 166
162 // Perform test 167 // Perform test
163 scene.MoveTaskInventoryItem(user1.PrincipalID, UUID.Zero, sop1, sopItem1.ItemID); 168 scene.MoveTaskInventoryItem(user1.PrincipalID, UUID.Zero, sop1, sopItem1.ItemID);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 55fc1e7..44d2d45 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Tests
58 TestHelpers.InMethod(); 58 TestHelpers.InMethod();
59// log4net.Config.XmlConfigurator.Configure(); 59// log4net.Config.XmlConfigurator.Configure();
60 60
61 Scene scene = SceneHelpers.SetupScene(); 61 Scene scene = new SceneHelpers().SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); 62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); 63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); 64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID);
@@ -85,7 +85,7 @@ namespace OpenSim.Region.Framework.Tests
85 TestHelpers.InMethod(); 85 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 86// log4net.Config.XmlConfigurator.Configure();
87 87
88 Scene scene = SceneHelpers.SetupScene(); 88 Scene scene = new SceneHelpers().SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); 89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); 90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
91 InventoryFolderBase folder1 91 InventoryFolderBase folder1
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index d9fe87c..198e487 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
47 public void Init() 47 public void Init()
48 { 48 {
49 // FIXME: We don't need a full scene here - it would be enough to set up the asset service. 49 // FIXME: We don't need a full scene here - it would be enough to set up the asset service.
50 Scene scene = SceneHelpers.SetupScene(); 50 Scene scene = new SceneHelpers().SetupScene();
51 m_assetService = scene.AssetService; 51 m_assetService = scene.AssetService;
52 m_uuidGatherer = new UuidGatherer(m_assetService); 52 m_uuidGatherer = new UuidGatherer(m_assetService);
53 } 53 }