aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs124
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs4
-rw-r--r--OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs50
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs32
-rw-r--r--OpenSim/Region/Framework/Interfaces/ITerrainModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs21
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs264
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs41
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs102
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs4
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs4
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs5
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs3
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs10
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs10
23 files changed, 535 insertions, 272 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 6cbf1a6..2b5e632 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -352,6 +352,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
352 private IHyperAssetService m_hyperAssets; 352 private IHyperAssetService m_hyperAssets;
353 private const bool m_checkPackets = true; 353 private const bool m_checkPackets = true;
354 354
355 private Timer m_propertiesPacketTimer;
356 private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>();
357
355 #endregion Class Members 358 #endregion Class Members
356 359
357 #region Properties 360 #region Properties
@@ -433,6 +436,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
433 m_udpClient.OnQueueEmpty += HandleQueueEmpty; 436 m_udpClient.OnQueueEmpty += HandleQueueEmpty;
434 m_udpClient.OnPacketStats += PopulateStats; 437 m_udpClient.OnPacketStats += PopulateStats;
435 438
439 m_propertiesPacketTimer = new Timer(100);
440 m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket;
441
436 RegisterLocalPacketHandlers(); 442 RegisterLocalPacketHandlers();
437 } 443 }
438 444
@@ -3562,42 +3568,88 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3562 string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, 3568 string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask,
3563 uint BaseMask, byte saleType, int salePrice) 3569 uint BaseMask, byte saleType, int salePrice)
3564 { 3570 {
3565 ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 3571 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
3566 // TODO: don't create new blocks if recycling an old packet 3572 // TODO: don't create new blocks if recycling an old packet
3567 3573
3568 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1]; 3574 ObjectPropertiesPacket.ObjectDataBlock block =
3569 proper.ObjectData[0] = new ObjectPropertiesPacket.ObjectDataBlock(); 3575 new ObjectPropertiesPacket.ObjectDataBlock();
3570 proper.ObjectData[0].ItemID = ItemID; 3576
3571 proper.ObjectData[0].CreationDate = CreationDate; 3577 block.ItemID = ItemID;
3572 proper.ObjectData[0].CreatorID = CreatorUUID; 3578 block.CreationDate = CreationDate;
3573 proper.ObjectData[0].FolderID = FolderUUID; 3579 block.CreatorID = CreatorUUID;
3574 proper.ObjectData[0].FromTaskID = FromTaskUUID; 3580 block.FolderID = FolderUUID;
3575 proper.ObjectData[0].GroupID = GroupUUID; 3581 block.FromTaskID = FromTaskUUID;
3576 proper.ObjectData[0].InventorySerial = InventorySerial; 3582 block.GroupID = GroupUUID;
3577 3583 block.InventorySerial = InventorySerial;
3578 proper.ObjectData[0].LastOwnerID = LastOwnerUUID; 3584
3585 block.LastOwnerID = LastOwnerUUID;
3579 // proper.ObjectData[0].LastOwnerID = UUID.Zero; 3586 // proper.ObjectData[0].LastOwnerID = UUID.Zero;
3580 3587
3581 proper.ObjectData[0].ObjectID = ObjectUUID; 3588 block.ObjectID = ObjectUUID;
3582 if (OwnerUUID == GroupUUID) 3589 if (OwnerUUID == GroupUUID)
3583 proper.ObjectData[0].OwnerID = UUID.Zero; 3590 block.OwnerID = UUID.Zero;
3584 else 3591 else
3585 proper.ObjectData[0].OwnerID = OwnerUUID; 3592 block.OwnerID = OwnerUUID;
3586 proper.ObjectData[0].TouchName = Util.StringToBytes256(TouchTitle); 3593 block.TouchName = Util.StringToBytes256(TouchTitle);
3587 proper.ObjectData[0].TextureID = TextureID; 3594 block.TextureID = TextureID;
3588 proper.ObjectData[0].SitName = Util.StringToBytes256(SitTitle); 3595 block.SitName = Util.StringToBytes256(SitTitle);
3589 proper.ObjectData[0].Name = Util.StringToBytes256(ItemName); 3596 block.Name = Util.StringToBytes256(ItemName);
3590 proper.ObjectData[0].Description = Util.StringToBytes256(ItemDescription); 3597 block.Description = Util.StringToBytes256(ItemDescription);
3591 proper.ObjectData[0].OwnerMask = OwnerMask; 3598 block.OwnerMask = OwnerMask;
3592 proper.ObjectData[0].NextOwnerMask = NextOwnerMask; 3599 block.NextOwnerMask = NextOwnerMask;
3593 proper.ObjectData[0].GroupMask = GroupMask; 3600 block.GroupMask = GroupMask;
3594 proper.ObjectData[0].EveryoneMask = EveryoneMask; 3601 block.EveryoneMask = EveryoneMask;
3595 proper.ObjectData[0].BaseMask = BaseMask; 3602 block.BaseMask = BaseMask;
3596 // proper.ObjectData[0].AggregatePerms = 53; 3603 // proper.ObjectData[0].AggregatePerms = 53;
3597 // proper.ObjectData[0].AggregatePermTextures = 0; 3604 // proper.ObjectData[0].AggregatePermTextures = 0;
3598 // proper.ObjectData[0].AggregatePermTexturesOwner = 0; 3605 // proper.ObjectData[0].AggregatePermTexturesOwner = 0;
3599 proper.ObjectData[0].SaleType = saleType; 3606 block.SaleType = saleType;
3600 proper.ObjectData[0].SalePrice = salePrice; 3607 block.SalePrice = salePrice;
3608
3609 lock (m_propertiesPacketTimer)
3610 {
3611 m_propertiesBlocks.Add(block);
3612
3613 int length = 0;
3614 foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks)
3615 {
3616 length += b.Length;
3617 }
3618 if (length > 1100) // FIXME: use real MTU
3619 {
3620 ProcessObjectPropertiesPacket(null, null);
3621 m_propertiesPacketTimer.Stop();
3622 return;
3623 }
3624
3625 m_propertiesPacketTimer.Stop();
3626 m_propertiesPacketTimer.Start();
3627 }
3628
3629 //proper.Header.Zerocoded = true;
3630 //OutPacket(proper, ThrottleOutPacketType.Task);
3631 }
3632
3633 private void ProcessObjectPropertiesPacket(Object sender, ElapsedEventArgs e)
3634 {
3635 ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
3636
3637 lock (m_propertiesPacketTimer)
3638 {
3639 m_propertiesPacketTimer.Stop();
3640
3641 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count];
3642
3643 int index = 0;
3644
3645 foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks)
3646 {
3647 proper.ObjectData[index++] = b;
3648 }
3649
3650 m_propertiesBlocks.Clear();
3651 }
3652
3601 proper.Header.Zerocoded = true; 3653 proper.Header.Zerocoded = true;
3602 OutPacket(proper, ThrottleOutPacketType.Task); 3654 OutPacket(proper, ThrottleOutPacketType.Task);
3603 } 3655 }
@@ -5504,6 +5556,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5504 5556
5505 if (avSetStartLocationRequestPacket.AgentData.AgentID == AgentId && avSetStartLocationRequestPacket.AgentData.SessionID == SessionId) 5557 if (avSetStartLocationRequestPacket.AgentData.AgentID == AgentId && avSetStartLocationRequestPacket.AgentData.SessionID == SessionId)
5506 { 5558 {
5559 // Linden Client limitation..
5560 if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.X == 255.5f
5561 || avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y == 255.5f)
5562 {
5563 ScenePresence avatar = null;
5564 if (((Scene)m_scene).TryGetAvatar(AgentId, out avatar))
5565 {
5566 if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.X == 255.5f)
5567 {
5568 avSetStartLocationRequestPacket.StartLocationData.LocationPos.X = avatar.AbsolutePosition.X;
5569 }
5570 if (avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y == 255.5f)
5571 {
5572 avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y = avatar.AbsolutePosition.Y;
5573 }
5574 }
5575
5576 }
5507 TeleportLocationRequest handlerSetStartLocationRequest = OnSetStartLocationRequest; 5577 TeleportLocationRequest handlerSetStartLocationRequest = OnSetStartLocationRequest;
5508 if (handlerSetStartLocationRequest != null) 5578 if (handlerSetStartLocationRequest != null)
5509 { 5579 {
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 1e5f15a..55d9c9c 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.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 *
@@ -430,7 +430,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
430 // Send the packet 430 // Send the packet
431 m_udpServer.SendPacketFinal(nextPacket); 431 m_udpServer.SendPacketFinal(nextPacket);
432 m_nextPackets[i] = null; 432 m_nextPackets[i] = null;
433 packetSent = true; 433 packetSent = true;
434 this.PacketsSent++; 434 this.PacketsSent++;
435 } 435 }
436 } 436 }
diff --git a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs
index 62500a2..c727cec 100644
--- a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs
+++ b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs
@@ -527,7 +527,6 @@ namespace OpenSim.Region.CoreModules.InterGrid
527 userProfile.Partner = UUID.Zero; 527 userProfile.Partner = UUID.Zero;
528 userProfile.PasswordHash = "$1$"; 528 userProfile.PasswordHash = "$1$";
529 userProfile.PasswordSalt = ""; 529 userProfile.PasswordSalt = "";
530 userProfile.RootInventoryFolderID = UUID.Zero;
531 userProfile.SurName = agentData.lastname; 530 userProfile.SurName = agentData.lastname;
532 userProfile.UserAssetURI = homeScene.CommsManager.NetworkServersInfo.AssetURL; 531 userProfile.UserAssetURI = homeScene.CommsManager.NetworkServersInfo.AssetURL;
533 userProfile.UserFlags = 0; 532 userProfile.UserFlags = 0;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
index fca2df2..68499f3 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
@@ -70,7 +70,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
70 IConfig authorizationConfig = source.Configs["AuthorizationService"]; 70 IConfig authorizationConfig = source.Configs["AuthorizationService"];
71 if (authorizationConfig == null) 71 if (authorizationConfig == null)
72 { 72 {
73 m_log.Error("[REMOTE AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); 73 m_log.Info("[REMOTE AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini");
74 return; 74 return;
75 } 75 }
76 76
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index e3a395e..b1dcb14 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -471,20 +471,45 @@ namespace OpenSim.Region.CoreModules.World.Estate
471 if (terr != null) 471 if (terr != null)
472 { 472 {
473 m_log.Warn("[CLIENT]: Got Request to Send Terrain in region " + m_scene.RegionInfo.RegionName); 473 m_log.Warn("[CLIENT]: Got Request to Send Terrain in region " + m_scene.RegionInfo.RegionName);
474 if (File.Exists(Util.dataDir() + "/terrain.raw")) 474
475 {
476 File.Delete(Util.dataDir() + "/terrain.raw");
477 }
478 try 475 try
479 { 476 {
480 FileStream input = new FileStream(Util.dataDir() + "/terrain.raw", FileMode.CreateNew); 477
478 string localfilename = "terrain.raw";
479
480 if (terrainData.Length == 851968)
481 {
482 localfilename = Path.Combine(Util.dataDir(),"terrain.raw"); // It's a .LLRAW
483 }
484
485 if (terrainData.Length == 196662) // 24-bit 256x256 Bitmap
486 localfilename = Path.Combine(Util.dataDir(), "terrain.bmp");
487
488 if (terrainData.Length == 256 * 256 * 4) // It's a .R32
489 localfilename = Path.Combine(Util.dataDir(), "terrain.r32");
490
491 if (terrainData.Length == 256 * 256 * 8) // It's a .R64
492 localfilename = Path.Combine(Util.dataDir(), "terrain.r64");
493
494 if (File.Exists(localfilename))
495 {
496 File.Delete(localfilename);
497 }
498
499 FileStream input = new FileStream(localfilename, FileMode.CreateNew);
481 input.Write(terrainData, 0, terrainData.Length); 500 input.Write(terrainData, 0, terrainData.Length);
482 input.Close(); 501 input.Close();
502
503 FileInfo x = new FileInfo(localfilename);
504
505 terr.LoadFromFile(localfilename);
506 remoteClient.SendAlertMessage("Your terrain was loaded as a ." + x.Extension + " file. It may take a few moments to appear.");
507
483 } 508 }
484 catch (IOException e) 509 catch (IOException e)
485 { 510 {
486 m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); 511 m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString());
487 remoteClient.SendAlertMessage("There was an IO Exception loading your terrain. Please check free space"); 512 remoteClient.SendAlertMessage("There was an IO Exception loading your terrain. Please check free space.");
488 513
489 return; 514 return;
490 } 515 }
@@ -502,29 +527,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
502 527
503 return; 528 return;
504 } 529 }
505
506
507
508
509 try
510 {
511 terr.LoadFromFile(Util.dataDir() + "/terrain.raw");
512 remoteClient.SendAlertMessage("Your terrain was loaded. Give it a minute or two to apply");
513 }
514 catch (Exception e) 530 catch (Exception e)
515 { 531 {
516 m_log.ErrorFormat("[TERRAIN]: Error loading a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); 532 m_log.ErrorFormat("[TERRAIN]: Error loading a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString());
517 remoteClient.SendAlertMessage("There was a general error loading your terrain. Please fix the terrain file and try again"); 533 remoteClient.SendAlertMessage("There was a general error loading your terrain. Please fix the terrain file and try again");
518 } 534 }
519
520 } 535 }
521 else 536 else
522 { 537 {
523 remoteClient.SendAlertMessage("Unable to apply terrain. Cannot get an instance of the terrain module"); 538 remoteClient.SendAlertMessage("Unable to apply terrain. Cannot get an instance of the terrain module");
524 } 539 }
525
526
527
528 } 540 }
529 541
530 private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) 542 private void handleUploadTerrain(IClientAPI remote_client, string clientFileName)
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index ba271fd..a40828b 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Reflection; 31using System.Reflection;
32using System.Net;
32using log4net; 33using log4net;
33using Nini.Config; 34using Nini.Config;
34using OpenMetaverse; 35using OpenMetaverse;
@@ -259,6 +260,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain
259 } 260 }
260 261
261 /// <summary> 262 /// <summary>
263 /// Loads a terrain file from the specified URI
264 /// </summary>
265 /// <param name="filename">The name of the terrain to load</param>
266 /// <param name="pathToTerrainHeightmap">The URI to the terrain height map</param>
267 public void LoadFromStream(string filename, Uri pathToTerrainHeightmap)
268 {
269 LoadFromStream(filename, URIFetch(pathToTerrainHeightmap));
270 }
271
272 /// <summary>
262 /// Loads a terrain file from a stream and installs it in the scene. 273 /// Loads a terrain file from a stream and installs it in the scene.
263 /// </summary> 274 /// </summary>
264 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> 275 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param>
@@ -267,7 +278,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
267 { 278 {
268 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 279 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
269 { 280 {
270 if (@filename.EndsWith(loader.Key)) 281 if (filename.EndsWith(loader.Key))
271 { 282 {
272 lock (m_scene) 283 lock (m_scene)
273 { 284 {
@@ -295,6 +306,25 @@ namespace OpenSim.Region.CoreModules.World.Terrain
295 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); 306 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename));
296 } 307 }
297 308
309 private static Stream URIFetch(Uri uri)
310 {
311 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
312
313 // request.Credentials = credentials;
314
315 request.ContentLength = 0;
316 request.KeepAlive = false;
317
318 WebResponse response = request.GetResponse();
319 Stream file = response.GetResponseStream();
320
321 if (response.ContentLength == 0)
322 throw new Exception(String.Format("{0} returned an empty file", uri.ToString()));
323
324 // return new BufferedStream(file, (int) response.ContentLength);
325 return new BufferedStream(file, 1000000);
326 }
327
298 /// <summary> 328 /// <summary>
299 /// Modify Land 329 /// Modify Land
300 /// </summary> 330 /// </summary>
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
index 2dcba0c..7caac55 100644
--- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Interfaces
51 /// </param> 51 /// </param>
52 /// <param name="stream"></param> 52 /// <param name="stream"></param>
53 void LoadFromStream(string filename, Stream stream); 53 void LoadFromStream(string filename, Stream stream);
54 54 void LoadFromStream(string filename, System.Uri pathToTerrainHeightmap);
55 /// <summary> 55 /// <summary>
56 /// Save a terrain to a stream. 56 /// Save a terrain to a stream.
57 /// </summary> 57 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index b031f61..50624a1 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -448,5 +448,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
448 448
449 SendAnimPack(animIDs, sequenceNums, objectIDs); 449 SendAnimPack(animIDs, sequenceNums, objectIDs);
450 } 450 }
451
452 public void Close()
453 {
454 m_animations = null;
455 m_scenePresence = null;
456 }
451 } 457 }
452} 458}
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
index 099fcce..c246e32 100644
--- a/OpenSim/Region/Framework/Scenes/EntityManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes
40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>(); 40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>();
41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>(); 41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>();
42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>(); 42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>();
43 private readonly Object m_lock = new Object(); 43 private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim();
44 44
45 [Obsolete("Use Add() instead.")] 45 [Obsolete("Use Add() instead.")]
46 public void Add(UUID id, EntityBase eb) 46 public void Add(UUID id, EntityBase eb)
@@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes
50 50
51 public void Add(EntityBase entity) 51 public void Add(EntityBase entity)
52 { 52 {
53 lock (m_lock) 53 m_lock.EnterWriteLock();
54 try
54 { 55 {
55 try 56 try
56 { 57 {
@@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes
62 m_log.ErrorFormat("Add Entity failed: {0}", e.Message); 63 m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
63 } 64 }
64 } 65 }
66 finally
67 {
68 m_lock.ExitWriteLock();
69 }
65 } 70 }
66 71
67 public void InsertOrReplace(EntityBase entity) 72 public void InsertOrReplace(EntityBase entity)
68 { 73 {
69 lock (m_lock) 74 m_lock.EnterWriteLock();
75 try
70 { 76 {
71 try 77 try
72 { 78 {
@@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes
78 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); 84 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
79 } 85 }
80 } 86 }
87 finally
88 {
89 m_lock.ExitWriteLock();
90 }
81 } 91 }
82 92
83 public void Clear() 93 public void Clear()
84 { 94 {
85 lock (m_lock) 95 m_lock.EnterWriteLock();
96 try
86 { 97 {
87 m_eb_uuid.Clear(); 98 m_eb_uuid.Clear();
88 m_eb_localID.Clear(); 99 m_eb_localID.Clear();
89 } 100 }
101 finally
102 {
103 m_lock.ExitWriteLock();
104 }
90 } 105 }
91 106
92 public int Count 107 public int Count
@@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes
123 138
124 public bool Remove(uint localID) 139 public bool Remove(uint localID)
125 { 140 {
126 lock (m_lock) 141 m_lock.EnterWriteLock();
142 try
127 { 143 {
128 try 144 try
129 { 145 {
@@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes
141 return false; 157 return false;
142 } 158 }
143 } 159 }
160 finally
161 {
162 m_lock.ExitWriteLock();
163 }
144 } 164 }
145 165
146 public bool Remove(UUID id) 166 public bool Remove(UUID id)
147 { 167 {
148 lock (m_lock) 168 m_lock.EnterWriteLock();
169 try
149 { 170 {
150 try 171 try
151 { 172 {
@@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes
163 return false; 184 return false;
164 } 185 }
165 } 186 }
187 finally
188 {
189 m_lock.ExitWriteLock();
190 }
166 } 191 }
167 192
168 public List<EntityBase> GetAllByType<T>() 193 public List<EntityBase> GetAllByType<T>()
169 { 194 {
170 List<EntityBase> tmp = new List<EntityBase>(); 195 List<EntityBase> tmp = new List<EntityBase>();
171 196
172 lock (m_lock) 197 m_lock.EnterReadLock();
198 try
173 { 199 {
174 try 200 try
175 { 201 {
@@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes
187 tmp = null; 213 tmp = null;
188 } 214 }
189 } 215 }
216 finally
217 {
218 m_lock.ExitReadLock();
219 }
190 220
191 return tmp; 221 return tmp;
192 } 222 }
193 223
194 public List<EntityBase> GetEntities() 224 public List<EntityBase> GetEntities()
195 { 225 {
196 lock (m_lock) 226 m_lock.EnterReadLock();
227 try
197 { 228 {
198 return new List<EntityBase>(m_eb_uuid.Values); 229 return new List<EntityBase>(m_eb_uuid.Values);
199 } 230 }
231 finally
232 {
233 m_lock.ExitReadLock();
234 }
200 } 235 }
201 236
202 public EntityBase this[UUID id] 237 public EntityBase this[UUID id]
203 { 238 {
204 get 239 get
205 { 240 {
206 lock (m_lock) 241 m_lock.EnterReadLock();
242 try
207 { 243 {
208 EntityBase entity; 244 EntityBase entity;
209 if (m_eb_uuid.TryGetValue(id, out entity)) 245 if (m_eb_uuid.TryGetValue(id, out entity))
@@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes
211 else 247 else
212 return null; 248 return null;
213 } 249 }
250 finally
251 {
252 m_lock.ExitReadLock();
253 }
214 } 254 }
215 set 255 set
216 { 256 {
@@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes
222 { 262 {
223 get 263 get
224 { 264 {
225 lock (m_lock) 265 m_lock.EnterReadLock();
266 try
226 { 267 {
227 EntityBase entity; 268 EntityBase entity;
228 if (m_eb_localID.TryGetValue(localID, out entity)) 269 if (m_eb_localID.TryGetValue(localID, out entity))
@@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes
230 else 271 else
231 return null; 272 return null;
232 } 273 }
274 finally
275 {
276 m_lock.ExitReadLock();
277 }
233 } 278 }
234 set 279 set
235 { 280 {
@@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes
239 284
240 public bool TryGetValue(UUID key, out EntityBase obj) 285 public bool TryGetValue(UUID key, out EntityBase obj)
241 { 286 {
242 lock (m_lock) 287 m_lock.EnterReadLock();
288 try
243 { 289 {
244 return m_eb_uuid.TryGetValue(key, out obj); 290 return m_eb_uuid.TryGetValue(key, out obj);
245 } 291 }
292 finally
293 {
294 m_lock.ExitReadLock();
295 }
246 } 296 }
247 297
248 public bool TryGetValue(uint key, out EntityBase obj) 298 public bool TryGetValue(uint key, out EntityBase obj)
249 { 299 {
250 lock (m_lock) 300 m_lock.EnterReadLock();
301 try
251 { 302 {
252 return m_eb_localID.TryGetValue(key, out obj); 303 return m_eb_localID.TryGetValue(key, out obj);
253 } 304 }
305 finally
306 {
307 m_lock.ExitReadLock();
308 }
254 } 309 }
255 310
256 /// <summary> 311 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 83208e9..7ca779a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1726,10 +1726,19 @@ namespace OpenSim.Region.Framework.Scenes
1726 1726
1727 if (folderID == UUID.Zero && folder == null) 1727 if (folderID == UUID.Zero && folder == null)
1728 { 1728 {
1729 // Catch all. Use lost & found 1729 if (action == DeRezAction.Delete)
1730 // 1730 {
1731 // Deletes go to trash by default
1732 //
1733 folder = InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
1734 }
1735 else
1736 {
1737 // Catch all. Use lost & found
1738 //
1731 1739
1732 folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 1740 folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
1741 }
1733 } 1742 }
1734 1743
1735 if (folder == null) // None of the above 1744 if (folder == null) // None of the above
@@ -2388,6 +2397,12 @@ namespace OpenSim.Region.Framework.Scenes
2388 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 2397 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
2389 item = InventoryService.GetItem(item); 2398 item = InventoryService.GetItem(item);
2390 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); 2399 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
2400
2401 if (m_AvatarFactory != null)
2402 {
2403 m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
2404 }
2405
2391 } 2406 }
2392 } 2407 }
2393 2408
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f70af27..8d91d65 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3048,6 +3048,7 @@ namespace OpenSim.Region.Framework.Scenes
3048 // TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around. 3048 // TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around.
3049 // TODO: The HomeRegion property can be removed then, too 3049 // TODO: The HomeRegion property can be removed then, too
3050 UserProfile.HomeRegion = RegionInfo.RegionHandle; 3050 UserProfile.HomeRegion = RegionInfo.RegionHandle;
3051
3051 UserProfile.HomeLocation = position; 3052 UserProfile.HomeLocation = position;
3052 UserProfile.HomeLookAt = lookAt; 3053 UserProfile.HomeLookAt = lookAt;
3053 CommsManager.UserService.UpdateUserProfile(UserProfile); 3054 CommsManager.UserService.UpdateUserProfile(UserProfile);
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 2fdb48d..f74fd5d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Threading;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using OpenMetaverse; 32using OpenMetaverse;
@@ -96,6 +97,8 @@ namespace OpenSim.Region.Framework.Scenes
96 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); 97 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>();
97 private readonly Object m_dictionary_lock = new Object(); 98 private readonly Object m_dictionary_lock = new Object();
98 99
100 private Object m_updateLock = new Object();
101
99 #endregion 102 #endregion
100 103
101 protected internal SceneGraph(Scene parent, RegionInfo regInfo) 104 protected internal SceneGraph(Scene parent, RegionInfo regInfo)
@@ -369,6 +372,9 @@ namespace OpenSim.Region.Framework.Scenes
369 /// </summary> 372 /// </summary>
370 protected internal void UpdateObjectGroups() 373 protected internal void UpdateObjectGroups()
371 { 374 {
375 if (!Monitor.TryEnter(m_updateLock))
376 return;
377
372 List<SceneObjectGroup> updates; 378 List<SceneObjectGroup> updates;
373 379
374 // Some updates add more updates to the updateList. 380 // Some updates add more updates to the updateList.
@@ -395,6 +401,7 @@ namespace OpenSim.Region.Framework.Scenes
395 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); 401 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
396 } 402 }
397 } 403 }
404 Monitor.Exit(m_updateLock);
398 } 405 }
399 406
400 protected internal void AddPhysicalPrim(int number) 407 protected internal void AddPhysicalPrim(int number)
@@ -1555,55 +1562,65 @@ namespace OpenSim.Region.Framework.Scenes
1555 /// <param name="childPrims"></param> 1562 /// <param name="childPrims"></param>
1556 protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds) 1563 protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds)
1557 { 1564 {
1558 SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); 1565 Monitor.Enter(m_updateLock);
1559 1566 try
1560 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1561 if (parentGroup != null)
1562 { 1567 {
1563 // We do this in reverse to get the link order of the prims correct 1568 SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId);
1564 for (int i = childPrimIds.Count - 1; i >= 0; i--) 1569
1570 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1571 if (parentGroup != null)
1565 { 1572 {
1566 SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); 1573 // We do this in reverse to get the link order of the prims correct
1567 if (child != null) 1574 for (int i = childPrimIds.Count - 1; i >= 0; i--)
1568 { 1575 {
1569 // Make sure no child prim is set for sale 1576 SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]);
1570 // So that, on delink, no prims are unwittingly 1577 if (child != null)
1571 // left for sale and sold off 1578 {
1572 child.RootPart.ObjectSaleType = 0; 1579 // Make sure no child prim is set for sale
1573 child.RootPart.SalePrice = 10; 1580 // So that, on delink, no prims are unwittingly
1574 childGroups.Add(child); 1581 // left for sale and sold off
1582 child.RootPart.ObjectSaleType = 0;
1583 child.RootPart.SalePrice = 10;
1584 childGroups.Add(child);
1585 }
1575 } 1586 }
1576 } 1587 }
1577 } 1588 else
1578 else 1589 {
1579 { 1590 return; // parent is null so not in this region
1580 return; // parent is null so not in this region 1591 }
1581 }
1582 1592
1583 foreach (SceneObjectGroup child in childGroups) 1593 foreach (SceneObjectGroup child in childGroups)
1584 { 1594 {
1585 parentGroup.LinkToGroup(child); 1595 parentGroup.LinkToGroup(child);
1586 1596
1587 // this is here so physics gets updated! 1597 // this is here so physics gets updated!
1588 // Don't remove! Bad juju! Stay away! or fix physics! 1598 // Don't remove! Bad juju! Stay away! or fix physics!
1589 child.AbsolutePosition = child.AbsolutePosition; 1599 child.AbsolutePosition = child.AbsolutePosition;
1590 } 1600 }
1591 1601
1592 // We need to explicitly resend the newly link prim's object properties since no other actions 1602 // We need to explicitly resend the newly link prim's object properties since no other actions
1593 // occur on link to invoke this elsewhere (such as object selection) 1603 // occur on link to invoke this elsewhere (such as object selection)
1594 parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); 1604 parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected);
1595 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1605 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1596 1606 parentGroup.HasGroupChanged = true;
1597 if (client != null) 1607 parentGroup.ScheduleGroupForFullUpdate();
1598 { 1608
1599 parentGroup.GetProperties(client); 1609// if (client != null)
1610// {
1611// parentGroup.GetProperties(client);
1612// }
1613// else
1614// {
1615// foreach (ScenePresence p in GetScenePresences())
1616// {
1617// parentGroup.GetProperties(p.ControllingClient);
1618// }
1619// }
1600 } 1620 }
1601 else 1621 finally
1602 { 1622 {
1603 foreach (ScenePresence p in GetScenePresences()) 1623 Monitor.Exit(m_updateLock);
1604 {
1605 parentGroup.GetProperties(p.ControllingClient);
1606 }
1607 } 1624 }
1608 } 1625 }
1609 1626
@@ -1618,109 +1635,120 @@ namespace OpenSim.Region.Framework.Scenes
1618 1635
1619 protected internal void DelinkObjects(List<uint> primIds, bool sendEvents) 1636 protected internal void DelinkObjects(List<uint> primIds, bool sendEvents)
1620 { 1637 {
1621 List<SceneObjectPart> childParts = new List<SceneObjectPart>(); 1638 Monitor.Enter(m_updateLock);
1622 List<SceneObjectPart> rootParts = new List<SceneObjectPart>(); 1639 try
1623 List<SceneObjectGroup> affectedGroups = new List<SceneObjectGroup>();
1624 // Look them all up in one go, since that is comparatively expensive
1625 //
1626 foreach (uint primID in primIds)
1627 { 1640 {
1628 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); 1641 List<SceneObjectPart> childParts = new List<SceneObjectPart>();
1629 if (part != null) 1642 List<SceneObjectPart> rootParts = new List<SceneObjectPart>();
1643 List<SceneObjectGroup> affectedGroups = new List<SceneObjectGroup>();
1644 // Look them all up in one go, since that is comparatively expensive
1645 //
1646 foreach (uint primID in primIds)
1630 { 1647 {
1631 if (part.LinkNum < 2) // Root or single 1648 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID);
1632 rootParts.Add(part); 1649 if (part != null)
1650 {
1651 if (part.ParentGroup.Children.Count != 1) // Skip single
1652 {
1653 if (part.LinkNum < 2) // Root
1654 rootParts.Add(part);
1655 else
1656 childParts.Add(part);
1657
1658 SceneObjectGroup group = part.ParentGroup;
1659 if (!affectedGroups.Contains(group))
1660 affectedGroups.Add(group);
1661 }
1662 }
1633 else 1663 else
1634 childParts.Add(part); 1664 {
1635 1665 m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID);
1636 SceneObjectGroup group = part.ParentGroup; 1666 }
1637 if (!affectedGroups.Contains(group))
1638 affectedGroups.Add(group);
1639 } 1667 }
1640 else 1668
1669 foreach (SceneObjectPart child in childParts)
1641 { 1670 {
1642 m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); 1671 // Unlink all child parts from their groups
1672 //
1673 child.ParentGroup.DelinkFromGroup(child, sendEvents);
1643 } 1674 }
1644 }
1645
1646 foreach (SceneObjectPart child in childParts)
1647 {
1648 // Unlink all child parts from their groups
1649 //
1650 child.ParentGroup.DelinkFromGroup(child, sendEvents);
1651 }
1652
1653 foreach (SceneObjectPart root in rootParts)
1654 {
1655 // In most cases, this will run only one time, and the prim
1656 // will be a solo prim
1657 // However, editing linked parts and unlinking may be different
1658 //
1659 SceneObjectGroup group = root.ParentGroup;
1660 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values);
1661 int numChildren = group.Children.Count;
1662 1675
1663 // If there are prims left in a link set, but the root is 1676 foreach (SceneObjectPart root in rootParts)
1664 // slated for unlink, we need to do this
1665 //
1666 if (numChildren != 1)
1667 { 1677 {
1668 // Unlink the remaining set 1678 // In most cases, this will run only one time, and the prim
1679 // will be a solo prim
1680 // However, editing linked parts and unlinking may be different
1669 // 1681 //
1670 bool sendEventsToRemainder = true; 1682 SceneObjectGroup group = root.ParentGroup;
1671 if (numChildren > 1) 1683 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values);
1672 sendEventsToRemainder = false; 1684 int numChildren = group.Children.Count;
1673
1674 foreach (SceneObjectPart p in newSet)
1675 {
1676 if (p != group.RootPart)
1677 group.DelinkFromGroup(p, sendEventsToRemainder);
1678 }
1679 1685
1680 // If there is more than one prim remaining, we 1686 // If there are prims left in a link set, but the root is
1681 // need to re-link 1687 // slated for unlink, we need to do this
1682 // 1688 //
1683 if (numChildren > 2) 1689 if (numChildren != 1)
1684 { 1690 {
1685 // Remove old root 1691 // Unlink the remaining set
1686 // 1692 //
1687 if (newSet.Contains(root)) 1693 bool sendEventsToRemainder = true;
1688 newSet.Remove(root); 1694 if (numChildren > 1)
1695 sendEventsToRemainder = false;
1689 1696
1690 // Preserve link ordering 1697 foreach (SceneObjectPart p in newSet)
1691 //
1692 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1693 { 1698 {
1694 return a.LinkNum.CompareTo(b.LinkNum); 1699 if (p != group.RootPart)
1695 }); 1700 group.DelinkFromGroup(p, sendEventsToRemainder);
1701 }
1696 1702
1697 // Determine new root 1703 // If there is more than one prim remaining, we
1704 // need to re-link
1698 // 1705 //
1699 SceneObjectPart newRoot = newSet[0]; 1706 if (numChildren > 2)
1700 newSet.RemoveAt(0); 1707 {
1708 // Remove old root
1709 //
1710 if (newSet.Contains(root))
1711 newSet.Remove(root);
1712
1713 // Preserve link ordering
1714 //
1715 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1716 {
1717 return a.LinkNum.CompareTo(b.LinkNum);
1718 });
1701 1719
1702 List<uint> linkIDs = new List<uint>(); 1720 // Determine new root
1721 //
1722 SceneObjectPart newRoot = newSet[0];
1723 newSet.RemoveAt(0);
1703 1724
1704 foreach (SceneObjectPart newChild in newSet) 1725 List<uint> linkIDs = new List<uint>();
1705 { 1726
1706 newChild.UpdateFlag = 0; 1727 foreach (SceneObjectPart newChild in newSet)
1707 linkIDs.Add(newChild.LocalId); 1728 {
1708 } 1729 newChild.UpdateFlag = 0;
1730 linkIDs.Add(newChild.LocalId);
1731 }
1709 1732
1710 LinkObjects(null, newRoot.LocalId, linkIDs); 1733 LinkObjects(null, newRoot.LocalId, linkIDs);
1711 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1734 if (!affectedGroups.Contains(newRoot.ParentGroup))
1712 affectedGroups.Add(newRoot.ParentGroup); 1735 affectedGroups.Add(newRoot.ParentGroup);
1736 }
1713 } 1737 }
1714 } 1738 }
1715 }
1716 1739
1717 // Finally, trigger events in the roots 1740 // Finally, trigger events in the roots
1718 // 1741 //
1719 foreach (SceneObjectGroup g in affectedGroups) 1742 foreach (SceneObjectGroup g in affectedGroups)
1743 {
1744 g.TriggerScriptChangedEvent(Changed.LINK);
1745 g.HasGroupChanged = true; // Persist
1746 g.ScheduleGroupForFullUpdate();
1747 }
1748 }
1749 finally
1720 { 1750 {
1721 g.TriggerScriptChangedEvent(Changed.LINK); 1751 Monitor.Exit(m_updateLock);
1722 g.HasGroupChanged = true; // Persist
1723 g.ScheduleGroupForFullUpdate();
1724 } 1752 }
1725 } 1753 }
1726 1754
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 42481ff..eacd219 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -126,7 +126,10 @@ namespace OpenSim.Region.Framework.Scenes
126 } 126 }
127 else 127 else
128 { 128 {
129 m_partsLock.ExitReadLock(); 129 if (m_partsLock.RecursiveReadCount > 0)
130 {
131 m_partsLock.ExitReadLock();
132 }
130 } 133 }
131 } 134 }
132 public void lockPartsForWrite(bool locked) 135 public void lockPartsForWrite(bool locked)
@@ -155,7 +158,10 @@ namespace OpenSim.Region.Framework.Scenes
155 } 158 }
156 else 159 else
157 { 160 {
158 m_partsLock.ExitWriteLock(); 161 if (m_partsLock.RecursiveWriteCount > 0)
162 {
163 m_partsLock.ExitWriteLock();
164 }
159 } 165 }
160 } 166 }
161 167
@@ -2292,14 +2298,14 @@ namespace OpenSim.Region.Framework.Scenes
2292 public void LinkToGroup(SceneObjectGroup objectGroup) 2298 public void LinkToGroup(SceneObjectGroup objectGroup)
2293 { 2299 {
2294 // Make sure we have sent any pending unlinks or stuff. 2300 // Make sure we have sent any pending unlinks or stuff.
2295 if (objectGroup.RootPart.UpdateFlag > 0) 2301 //if (objectGroup.RootPart.UpdateFlag > 0)
2296 { 2302 //{
2297 m_log.WarnFormat( 2303 // m_log.WarnFormat(
2298 "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.", 2304 // "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.",
2299 objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); 2305 // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
2300 2306
2301 objectGroup.RootPart.SendScheduledUpdates(); 2307 // objectGroup.RootPart.SendScheduledUpdates();
2302 } 2308 //}
2303 2309
2304// m_log.DebugFormat( 2310// m_log.DebugFormat(
2305// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", 2311// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
@@ -2389,8 +2395,8 @@ namespace OpenSim.Region.Framework.Scenes
2389 // unmoved prims! 2395 // unmoved prims!
2390 ResetChildPrimPhysicsPositions(); 2396 ResetChildPrimPhysicsPositions();
2391 2397
2392 HasGroupChanged = true; 2398 //HasGroupChanged = true;
2393 ScheduleGroupForFullUpdate(); 2399 //ScheduleGroupForFullUpdate();
2394 } 2400 }
2395 2401
2396 /// <summary> 2402 /// <summary>
@@ -2483,8 +2489,8 @@ namespace OpenSim.Region.Framework.Scenes
2483 2489
2484 linkPart.Rezzed = RootPart.Rezzed; 2490 linkPart.Rezzed = RootPart.Rezzed;
2485 2491
2486 HasGroupChanged = true; 2492 //HasGroupChanged = true;
2487 ScheduleGroupForFullUpdate(); 2493 //ScheduleGroupForFullUpdate();
2488 } 2494 }
2489 2495
2490 /// <summary> 2496 /// <summary>
@@ -2776,8 +2782,13 @@ namespace OpenSim.Region.Framework.Scenes
2776 { 2782 {
2777 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) 2783 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2778 { 2784 {
2779 UsePhysics = false; // Reset physics 2785 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2780 break; 2786 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2787 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2788 {
2789 UsePhysics = false; // Reset physics
2790 break;
2791 }
2781 } 2792 }
2782 } 2793 }
2783 2794
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index eca8588..b57d912 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -269,8 +269,9 @@ namespace OpenSim.Region.Framework.Scenes
269 { 269 {
270 m_log.ErrorFormat( 270 m_log.ErrorFormat(
271 "[PRIM INVENTORY]: " + 271 "[PRIM INVENTORY]: " +
272 "Couldn't start script {0}, {1} since asset ID {2} could not be found", 272 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
273 item.Name, item.ItemID, item.AssetID); 273 item.Name, item.ItemID, m_part.AbsolutePosition,
274 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
274 } 275 }
275 else 276 else
276 { 277 {
@@ -317,9 +318,20 @@ namespace OpenSim.Region.Framework.Scenes
317 m_items.LockItemsForRead(true); 318 m_items.LockItemsForRead(true);
318 if (m_items.ContainsKey(itemId)) 319 if (m_items.ContainsKey(itemId))
319 { 320 {
320 TaskInventoryItem item = m_items[itemId]; 321 if (m_items.ContainsKey(itemId))
321 m_items.LockItemsForRead(false); 322 {
322 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 323 m_items.LockItemsForRead(false);
324 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
325 }
326 else
327 {
328 m_items.LockItemsForRead(false);
329 m_log.ErrorFormat(
330 "[PRIM INVENTORY]: " +
331 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
332 itemId, m_part.Name, m_part.UUID,
333 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
334 }
323 } 335 }
324 else 336 else
325 { 337 {
@@ -347,8 +359,9 @@ namespace OpenSim.Region.Framework.Scenes
347 { 359 {
348 m_log.ErrorFormat( 360 m_log.ErrorFormat(
349 "[PRIM INVENTORY]: " + 361 "[PRIM INVENTORY]: " +
350 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2}", 362 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
351 itemId, m_part.Name, m_part.UUID); 363 itemId, m_part.Name, m_part.UUID,
364 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
352 } 365 }
353 } 366 }
354 367
@@ -542,8 +555,9 @@ namespace OpenSim.Region.Framework.Scenes
542 { 555 {
543 m_log.ErrorFormat( 556 m_log.ErrorFormat(
544 "[PRIM INVENTORY]: " + 557 "[PRIM INVENTORY]: " +
545 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", 558 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
546 item.ItemID, m_part.Name, m_part.UUID); 559 item.ItemID, m_part.Name, m_part.UUID,
560 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
547 } 561 }
548 m_items.LockItemsForWrite(false); 562 m_items.LockItemsForWrite(false);
549 563
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 6812914..f6bcb59 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -790,37 +790,13 @@ namespace OpenSim.Region.Framework.Scenes
790 /// </summary> 790 /// </summary>
791 public void SendPrimUpdates() 791 public void SendPrimUpdates()
792 { 792 {
793 m_perfMonMS = EnvironmentTickCount(); 793 m_perfMonMS = Util.EnvironmentTickCount();
794 794
795 m_sceneViewer.SendPrimUpdates(); 795 m_sceneViewer.SendPrimUpdates();
796 796
797 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); 797 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
798 } 798 }
799 799
800 /// <summary>
801 /// Environment.TickCount is an int but it counts all 32 bits so it goes positive
802 /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap
803 /// for the callers.
804 /// This trims it to a 12 day interval so don't let your frame time get too long.
805 /// </summary>
806 /// <returns></returns>
807 const Int32 EnvironmentTickCountMask = 0x3fffffff;
808 private static Int32 EnvironmentTickCount() {
809 return Environment.TickCount & EnvironmentTickCountMask;
810 }
811
812 /// <summary>
813 /// Environment.TickCount is an int but it counts all 32 bits so it goes positive
814 /// and negative every 24.9 days. Subtracts the passed value (previously fetched by
815 /// 'EnvironmentTickCount()') and accounts for any wrapping.
816 /// </summary>
817 /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
818 private static Int32 EnvironmentTickCountSubtract(Int32 prevValue) {
819 Int32 diff = EnvironmentTickCount() - prevValue;
820 return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
821 }
822
823
824 #region Status Methods 800 #region Status Methods
825 801
826 /// <summary> 802 /// <summary>
@@ -1166,7 +1142,7 @@ namespace OpenSim.Region.Framework.Scenes
1166 /// <param name="collisionPoint"></param> 1142 /// <param name="collisionPoint"></param>
1167 /// <param name="localid"></param> 1143 /// <param name="localid"></param>
1168 /// <param name="distance"></param> 1144 /// <param name="distance"></param>
1169 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) 1145 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1170 { 1146 {
1171 const float POSITION_TOLERANCE = 0.02f; 1147 const float POSITION_TOLERANCE = 0.02f;
1172 const float VELOCITY_TOLERANCE = 0.02f; 1148 const float VELOCITY_TOLERANCE = 0.02f;
@@ -1209,7 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes
1209 // return; 1185 // return;
1210 //} 1186 //}
1211 1187
1212 m_perfMonMS = EnvironmentTickCount(); 1188 m_perfMonMS = Util.EnvironmentTickCount();
1213 1189
1214 ++m_movementUpdateCount; 1190 ++m_movementUpdateCount;
1215 if (m_movementUpdateCount < 1) 1191 if (m_movementUpdateCount < 1)
@@ -1539,7 +1515,7 @@ namespace OpenSim.Region.Framework.Scenes
1539 1515
1540 m_scene.EventManager.TriggerOnClientMovement(this); 1516 m_scene.EventManager.TriggerOnClientMovement(this);
1541 1517
1542 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); 1518 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
1543 } 1519 }
1544 1520
1545 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) 1521 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client)
@@ -1764,11 +1740,14 @@ namespace OpenSim.Region.Framework.Scenes
1764 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1740 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1765 1741
1766 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1742 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1767// bool SitTargetisSet = 1743 bool SitTargetisSet =
1768// (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && 1744 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1769// avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); 1745 (
1770 1746 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1771 bool SitTargetisSet = ((Vector3.Zero != avSitOffSet) || (Quaternion.Identity != avSitOrientation)); 1747 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1748 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1749 )
1750 ));
1772 1751
1773//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied + 1752//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied +
1774// " TargSet=" + SitTargetisSet); 1753// " TargSet=" + SitTargetisSet);
@@ -1850,7 +1829,7 @@ namespace OpenSim.Region.Framework.Scenes
1850 StandUp(); 1829 StandUp();
1851 } 1830 }
1852 m_nextSitAnimation = "SIT"; 1831 m_nextSitAnimation = "SIT";
1853 1832
1854 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1833 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1855 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1834 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1856 1835
@@ -1862,12 +1841,23 @@ namespace OpenSim.Region.Framework.Scenes
1862 } 1841 }
1863 m_requestedSitTargetID = part.LocalId; 1842 m_requestedSitTargetID = part.LocalId;
1864 //m_requestedSitOffset = offset; 1843 //m_requestedSitOffset = offset;
1844 //offset.X += part.Scale.X;// *offset.X;
1845 //offset.Y += part.Scale.Y;// * offset.Y;
1846 //offset.Z += part.Scale.Z;// * offset.Z;
1847 //m_requestedSitOffset = offset;
1848 m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
1865 } 1849 }
1866 else 1850 else
1867 { 1851 {
1868 1852
1869 m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); 1853 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
1870 } 1854 }
1855
1856 if (m_scene.PhysicsScene.SupportsRayCast())
1857 {
1858 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
1859 }
1860
1871 SendSitResponse(remoteClient, targetID, offset); 1861 SendSitResponse(remoteClient, targetID, offset);
1872 } 1862 }
1873 1863
@@ -1982,7 +1972,7 @@ namespace OpenSim.Region.Framework.Scenes
1982 SendFullUpdateToAllClients(); 1972 SendFullUpdateToAllClients();
1983 } 1973 }
1984 1974
1985 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) 1975 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
1986 { 1976 {
1987 if(hitYN) 1977 if(hitYN)
1988 { 1978 {
@@ -2057,7 +2047,7 @@ namespace OpenSim.Region.Framework.Scenes
2057 return; 2047 return;
2058 } 2048 }
2059 2049
2060 m_perfMonMS = EnvironmentTickCount(); 2050 m_perfMonMS = Util.EnvironmentTickCount();
2061 2051
2062 Rotation = rotation; 2052 Rotation = rotation;
2063 Vector3 direc = vec * rotation; 2053 Vector3 direc = vec * rotation;
@@ -2099,7 +2089,7 @@ namespace OpenSim.Region.Framework.Scenes
2099 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2089 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2100 m_forceToApply = direc; 2090 m_forceToApply = direc;
2101 m_isNudging = Nudging; 2091 m_isNudging = Nudging;
2102 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCount() - m_perfMonMS); 2092 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2103 } 2093 }
2104 2094
2105 #endregion 2095 #endregion
@@ -2168,7 +2158,7 @@ namespace OpenSim.Region.Framework.Scenes
2168 // server. 2158 // server.
2169 if (remoteClient.IsActive) 2159 if (remoteClient.IsActive)
2170 { 2160 {
2171 m_perfMonMS = EnvironmentTickCount(); 2161 m_perfMonMS = Util.EnvironmentTickCount();
2172 2162
2173 PhysicsActor actor = m_physicsActor; 2163 PhysicsActor actor = m_physicsActor;
2174 Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; 2164 Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero;
@@ -2181,7 +2171,7 @@ namespace OpenSim.Region.Framework.Scenes
2181 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 2171 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
2182 pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); 2172 pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient)));
2183 2173
2184 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); 2174 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2185 m_scene.StatsReporter.AddAgentUpdates(1); 2175 m_scene.StatsReporter.AddAgentUpdates(1);
2186 } 2176 }
2187 } 2177 }
@@ -2191,11 +2181,11 @@ namespace OpenSim.Region.Framework.Scenes
2191 /// </summary> 2181 /// </summary>
2192 public void SendTerseUpdateToAllClients() 2182 public void SendTerseUpdateToAllClients()
2193 { 2183 {
2194 m_perfMonMS = EnvironmentTickCount(); 2184 m_perfMonMS = Util.EnvironmentTickCount();
2195 2185
2196 m_scene.ForEachClient(SendTerseUpdateToClient); 2186 m_scene.ForEachClient(SendTerseUpdateToClient);
2197 2187
2198 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); 2188 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2199 } 2189 }
2200 2190
2201 public void SendCoarseLocations() 2191 public void SendCoarseLocations()
@@ -2215,7 +2205,7 @@ namespace OpenSim.Region.Framework.Scenes
2215 2205
2216 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p) 2206 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p)
2217 { 2207 {
2218 m_perfMonMS = EnvironmentTickCount(); 2208 m_perfMonMS = Util.EnvironmentTickCount();
2219 2209
2220 List<Vector3> CoarseLocations = new List<Vector3>(); 2210 List<Vector3> CoarseLocations = new List<Vector3>();
2221 List<UUID> AvatarUUIDs = new List<UUID>(); 2211 List<UUID> AvatarUUIDs = new List<UUID>();
@@ -2251,7 +2241,7 @@ namespace OpenSim.Region.Framework.Scenes
2251 2241
2252 m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations); 2242 m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations);
2253 2243
2254 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); 2244 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2255 } 2245 }
2256 2246
2257 public void CoarseLocationChange() 2247 public void CoarseLocationChange()
@@ -2288,7 +2278,7 @@ namespace OpenSim.Region.Framework.Scenes
2288 /// </summary> 2278 /// </summary>
2289 public void SendInitialFullUpdateToAllClients() 2279 public void SendInitialFullUpdateToAllClients()
2290 { 2280 {
2291 m_perfMonMS = EnvironmentTickCount(); 2281 m_perfMonMS = Util.EnvironmentTickCount();
2292 2282
2293 ScenePresence[] avatars = m_scene.GetScenePresences(); 2283 ScenePresence[] avatars = m_scene.GetScenePresences();
2294 2284
@@ -2314,14 +2304,14 @@ namespace OpenSim.Region.Framework.Scenes
2314 } 2304 }
2315 2305
2316 m_scene.StatsReporter.AddAgentUpdates(avatars.Length); 2306 m_scene.StatsReporter.AddAgentUpdates(avatars.Length);
2317 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); 2307 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2318 2308
2319 //Animator.SendAnimPack(); 2309 //Animator.SendAnimPack();
2320 } 2310 }
2321 2311
2322 public void SendFullUpdateToAllClients() 2312 public void SendFullUpdateToAllClients()
2323 { 2313 {
2324 m_perfMonMS = EnvironmentTickCount(); 2314 m_perfMonMS = Util.EnvironmentTickCount();
2325 2315
2326 // only send update from root agents to other clients; children are only "listening posts" 2316 // only send update from root agents to other clients; children are only "listening posts"
2327 List<ScenePresence> avatars = m_scene.GetAvatars(); 2317 List<ScenePresence> avatars = m_scene.GetAvatars();
@@ -2331,7 +2321,7 @@ namespace OpenSim.Region.Framework.Scenes
2331 2321
2332 } 2322 }
2333 m_scene.StatsReporter.AddAgentUpdates(avatars.Count); 2323 m_scene.StatsReporter.AddAgentUpdates(avatars.Count);
2334 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); 2324 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2335 2325
2336 Animator.SendAnimPack(); 2326 Animator.SendAnimPack();
2337 } 2327 }
@@ -2373,7 +2363,7 @@ namespace OpenSim.Region.Framework.Scenes
2373 /// </summary> 2363 /// </summary>
2374 public void SendAppearanceToAllOtherAgents() 2364 public void SendAppearanceToAllOtherAgents()
2375 { 2365 {
2376 m_perfMonMS = EnvironmentTickCount(); 2366 m_perfMonMS = Util.EnvironmentTickCount();
2377 2367
2378 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2368 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2379 { 2369 {
@@ -2382,8 +2372,8 @@ namespace OpenSim.Region.Framework.Scenes
2382 SendAppearanceToOtherAgent(scenePresence); 2372 SendAppearanceToOtherAgent(scenePresence);
2383 } 2373 }
2384 }); 2374 });
2385 2375
2386 m_scene.StatsReporter.AddAgentTime(EnvironmentTickCountSubtract(m_perfMonMS)); 2376 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2387 } 2377 }
2388 2378
2389 /// <summary> 2379 /// <summary>
@@ -3084,7 +3074,9 @@ namespace OpenSim.Region.Framework.Scenes
3084 3074
3085 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( 3075 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3086 // as of this comment the interval is set in AddToPhysicalScene 3076 // as of this comment the interval is set in AddToPhysicalScene
3087 3077 if (Animator!=null)
3078 Animator.UpdateMovementAnimations();
3079
3088 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3080 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3089 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3081 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3090 3082
@@ -3096,7 +3088,7 @@ namespace OpenSim.Region.Framework.Scenes
3096 m_lastColCount = coldata.Count; 3088 m_lastColCount = coldata.Count;
3097 } 3089 }
3098 3090
3099 if (coldata.Count != 0) 3091 if (coldata.Count != 0 && Animator != null)
3100 { 3092 {
3101 switch (Animator.CurrentMovementAnimation) 3093 switch (Animator.CurrentMovementAnimation)
3102 { 3094 {
@@ -3200,11 +3192,13 @@ namespace OpenSim.Region.Framework.Scenes
3200 3192
3201 // I don't get it but mono crashes when you try to dispose of this timer, 3193 // I don't get it but mono crashes when you try to dispose of this timer,
3202 // unsetting the elapsed callback should be enough to allow for cleanup however. 3194 // unsetting the elapsed callback should be enough to allow for cleanup however.
3203 //m_reprioritizationTimer.Dispose(); 3195 // m_reprioritizationTimer.Dispose();
3204 3196
3205 m_sceneViewer.Close(); 3197 m_sceneViewer.Close();
3206 3198
3207 RemoveFromPhysicalScene(); 3199 RemoveFromPhysicalScene();
3200 m_animator.Close();
3201 m_animator = null;
3208 } 3202 }
3209 3203
3210 public ScenePresence() 3204 public ScenePresence()
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index f92f440..e368c2a 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes
75 UnAckedBytes = 24, 75 UnAckedBytes = 24,
76 } 76 }
77 77
78 // Sending a stats update every 3 seconds 78 // Sending a stats update every 3 seconds-
79 private int statsUpdatesEveryMS = 3000; 79 private int statsUpdatesEveryMS = 3000;
80 private float statsUpdateFactor = 0; 80 private float statsUpdateFactor = 0;
81 private float m_timeDilation = 0; 81 private float m_timeDilation = 0;
@@ -240,7 +240,7 @@ namespace OpenSim.Region.Framework.Scenes
240 sb[12].StatID = (uint)Stats.OtherMS; 240 sb[12].StatID = (uint)Stats.OtherMS;
241 sb[12].StatValue = m_otherMS / statsUpdateFactor; 241 sb[12].StatValue = m_otherMS / statsUpdateFactor;
242 242
243 sb[13].StatID = (uint)Stats.InPacketsPerSecond; 243 sb[13].StatID = (uint)Stats.InPacketsPerSecond;
244 sb[13].StatValue = (m_inPacketsPerSecond / statsUpdateFactor); 244 sb[13].StatValue = (m_inPacketsPerSecond / statsUpdateFactor);
245 245
246 sb[14].StatID = (uint)Stats.OutPacketsPerSecond; 246 sb[14].StatID = (uint)Stats.OutPacketsPerSecond;
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 6d515e9..217d307 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -36,7 +36,7 @@ namespace OpenSim.Region.Physics.Manager
36{ 36{
37 public delegate void physicsCrash(); 37 public delegate void physicsCrash();
38 38
39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance); 39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal);
40 40
41 public abstract class PhysicsScene 41 public abstract class PhysicsScene
42 { 42 {
@@ -204,7 +204,7 @@ namespace OpenSim.Region.Physics.Manager
204 public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) 204 public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
205 { 205 {
206 if (retMethod != null) 206 if (retMethod != null)
207 retMethod(false, Vector3.Zero, 0, 999999999999f); 207 retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero);
208 } 208 }
209 209
210 private class NullPhysicsScene : PhysicsScene 210 private class NullPhysicsScene : PhysicsScene
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 905d3ba..b99baa2 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1243,7 +1243,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1243 { 1243 {
1244 if (m_eventsubscription > m_requestedUpdateFrequency) 1244 if (m_eventsubscription > m_requestedUpdateFrequency)
1245 { 1245 {
1246 base.SendCollisionUpdate(CollisionEventsThisFrame); 1246 if (CollisionEventsThisFrame != null)
1247 {
1248 base.SendCollisionUpdate(CollisionEventsThisFrame);
1249 }
1247 CollisionEventsThisFrame = new CollisionEventUpdate(); 1250 CollisionEventsThisFrame = new CollisionEventUpdate();
1248 m_eventsubscription = 0; 1251 m_eventsubscription = 0;
1249 } 1252 }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 8459dab..c27c420 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -743,6 +743,8 @@ namespace OpenSim.Region.Physics.OdePlugin
743 break; 743 break;
744 } 744 }
745 } 745 }
746 if (returnMass > _parent_scene.maximumMassObject)
747 returnMass = _parent_scene.maximumMassObject;
746 return returnMass; 748 return returnMass;
747 }// end CalculateMass 749 }// end CalculateMass
748 750
@@ -753,6 +755,7 @@ namespace OpenSim.Region.Physics.OdePlugin
753 if (Body != (IntPtr) 0) 755 if (Body != (IntPtr) 0)
754 { 756 {
755 float newmass = CalculateMass(); 757 float newmass = CalculateMass();
758
756 //m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString()); 759 //m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString());
757 760
758 d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z); 761 d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z);
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
index c8ae229..732e835 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -145,6 +145,7 @@ namespace OpenSim.Region.Physics.OdePlugin
145 uint hitConsumerID = 0; 145 uint hitConsumerID = 0;
146 float distance = 999999999999f; 146 float distance = 999999999999f;
147 Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f); 147 Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
148 Vector3 snormal = Vector3.Zero;
148 149
149 // Find closest contact and object. 150 // Find closest contact and object.
150 lock (m_contactResults) 151 lock (m_contactResults)
@@ -157,6 +158,7 @@ namespace OpenSim.Region.Physics.OdePlugin
157 hitConsumerID = cResult.ConsumerID; 158 hitConsumerID = cResult.ConsumerID;
158 distance = cResult.Depth; 159 distance = cResult.Depth;
159 hitYN = true; 160 hitYN = true;
161 snormal = cResult.Normal;
160 } 162 }
161 } 163 }
162 164
@@ -165,7 +167,7 @@ namespace OpenSim.Region.Physics.OdePlugin
165 167
166 // Return results 168 // Return results
167 if (req.callbackMethod != null) 169 if (req.callbackMethod != null)
168 req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance); 170 req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal);
169 } 171 }
170 172
171 // This is the standard Near. Uses space AABBs to speed up detection. 173 // This is the standard Near. Uses space AABBs to speed up detection.
@@ -310,7 +312,8 @@ namespace OpenSim.Region.Physics.OdePlugin
310 collisionresult.ConsumerID = ((OdePrim)p1).m_localID; 312 collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
311 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); 313 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
312 collisionresult.Depth = contacts[i].depth; 314 collisionresult.Depth = contacts[i].depth;
313 315 collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
316 contacts[i].normal.Z);
314 lock (m_contactResults) 317 lock (m_contactResults)
315 m_contactResults.Add(collisionresult); 318 m_contactResults.Add(collisionresult);
316 } 319 }
@@ -325,6 +328,8 @@ namespace OpenSim.Region.Physics.OdePlugin
325 collisionresult.ConsumerID = ((OdePrim)p2).m_localID; 328 collisionresult.ConsumerID = ((OdePrim)p2).m_localID;
326 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); 329 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
327 collisionresult.Depth = contacts[i].depth; 330 collisionresult.Depth = contacts[i].depth;
331 collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
332 contacts[i].normal.Z);
328 333
329 lock (m_contactResults) 334 lock (m_contactResults)
330 m_contactResults.Add(collisionresult); 335 m_contactResults.Add(collisionresult);
@@ -358,5 +363,6 @@ namespace OpenSim.Region.Physics.OdePlugin
358 public Vector3 Pos; 363 public Vector3 Pos;
359 public float Depth; 364 public float Depth;
360 public uint ConsumerID; 365 public uint ConsumerID;
366 public Vector3 Normal;
361 } 367 }
362} 368}
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index a0aba2a..0384d6e 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -207,6 +207,7 @@ namespace OpenSim.Region.Physics.OdePlugin
207 private float avMovementDivisorWalk = 1.3f; 207 private float avMovementDivisorWalk = 1.3f;
208 private float avMovementDivisorRun = 0.8f; 208 private float avMovementDivisorRun = 0.8f;
209 private float minimumGroundFlightOffset = 3f; 209 private float minimumGroundFlightOffset = 3f;
210 public float maximumMassObject = 10000.01f;
210 211
211 public bool meshSculptedPrim = true; 212 public bool meshSculptedPrim = true;
212 public bool forceSimplePrimMeshing = false; 213 public bool forceSimplePrimMeshing = false;
@@ -480,6 +481,7 @@ namespace OpenSim.Region.Physics.OdePlugin
480 481
481 m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false); 482 m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false);
482 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); 483 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f);
484 maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f);
483 } 485 }
484 } 486 }
485 487
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 267928b..e694f15 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -3588,6 +3588,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3588 { 3588 {
3589 parentPrim.DelinkFromGroup(part.LocalId, true); 3589 parentPrim.DelinkFromGroup(part.LocalId, true);
3590 } 3590 }
3591 parentPrim.HasGroupChanged = true;
3592 parentPrim.ScheduleGroupForFullUpdate();
3591 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3593 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3592 3594
3593 if (parts.Count > 0) 3595 if (parts.Count > 0)
@@ -3599,6 +3601,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3599 part.UpdateFlag = 0; 3601 part.UpdateFlag = 0;
3600 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3602 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3601 } 3603 }
3604 newRoot.ParentGroup.HasGroupChanged = true;
3605 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3602 } 3606 }
3603 } 3607 }
3604 else 3608 else
@@ -3607,6 +3611,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3607 return; 3611 return;
3608 3612
3609 parentPrim.DelinkFromGroup(childPrim.LocalId, true); 3613 parentPrim.DelinkFromGroup(childPrim.LocalId, true);
3614 parentPrim.HasGroupChanged = true;
3615 parentPrim.ScheduleGroupForFullUpdate();
3610 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3616 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3611 } 3617 }
3612 } 3618 }
@@ -3626,6 +3632,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3626 parentPrim.DelinkFromGroup(part.LocalId, true); 3632 parentPrim.DelinkFromGroup(part.LocalId, true);
3627 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3633 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3628 } 3634 }
3635 parentPrim.HasGroupChanged = true;
3636 parentPrim.ScheduleGroupForFullUpdate();
3629 } 3637 }
3630 3638
3631 public LSL_String llGetLinkKey(int linknum) 3639 public LSL_String llGetLinkKey(int linknum)
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 49c69ab..184af19 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -150,7 +150,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
150 } 150 }
151 else 151 else
152 { 152 {
153 m_scriptsLock.ExitReadLock(); 153 if (m_scriptsLock.RecursiveReadCount > 0)
154 {
155 m_scriptsLock.ExitReadLock();
156 }
154 } 157 }
155 } 158 }
156 private void lockScriptsForWrite(bool locked) 159 private void lockScriptsForWrite(bool locked)
@@ -179,7 +182,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
179 } 182 }
180 else 183 else
181 { 184 {
182 m_scriptsLock.ExitWriteLock(); 185 if (m_scriptsLock.RecursiveWriteCount > 0)
186 {
187 m_scriptsLock.ExitWriteLock();
188 }
183 } 189 }
184 } 190 }
185 191