diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
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 735bd32..bd11cde 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 | ||
46 | namespace OpenSim.Region.Framework.Scenes | 46 | namespace 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 | ||
28 | using System; | 28 | using System; |
29 | //using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Timers; | 30 | using System.Timers; |
31 | using OpenMetaverse.Packets; | 31 | using OpenMetaverse.Packets; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
@@ -35,10 +35,18 @@ using OpenSim.Region.Framework.Interfaces; | |||
35 | 35 | ||
36 | namespace OpenSim.Region.Framework.Scenes | 36 | namespace 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | ||
30 | using System.Text; | 31 | using System.Text; |
31 | using NUnit.Framework; | 32 | using NUnit.Framework; |
32 | using OpenMetaverse; | 33 | using 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 | ||
28 | using System; | 28 | using System; |
29 | using System.IO; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Text; | ||
30 | using NUnit.Framework; | 32 | using NUnit.Framework; |
31 | using OpenMetaverse; | 33 | using OpenMetaverse; |
32 | using OpenSim.Framework; | 34 | using 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 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using System.Threading; | ||
31 | using NUnit.Framework; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Communications; | ||
35 | using OpenSim.Region.Framework.Scenes; | ||
36 | using OpenSim.Tests.Common; | ||
37 | using OpenSim.Tests.Common.Mock; | ||
38 | |||
39 | namespace 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using NUnit.Framework; | 31 | using NUnit.Framework; |
31 | using OpenMetaverse; | 32 | using 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using Nini.Config; | 31 | using Nini.Config; |
31 | using NUnit.Framework; | 32 | using 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; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Framework.Servers; | 35 | using OpenSim.Framework.Servers; |
36 | using OpenSim.Region.Framework.Interfaces; | 36 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.CoreModules.Framework; | ||
38 | using OpenSim.Region.CoreModules.Framework.EntityTransfer; | ||
37 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 39 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
40 | using OpenSim.Region.CoreModules.World.Permissions; | ||
38 | using OpenSim.Tests.Common; | 41 | using OpenSim.Tests.Common; |
39 | using OpenSim.Tests.Common.Mock; | 42 | using OpenSim.Tests.Common.Mock; |
40 | using System.Threading; | 43 | using System.IO; |
44 | using System.Text; | ||
41 | 45 | ||
42 | namespace OpenSim.Region.Framework.Scenes.Tests | 46 | namespace 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 | } |