aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs122
-rw-r--r--OpenSim/Framework/Servers/VersionInfo.cs2
-rw-r--r--OpenSim/Framework/TaskInventoryDictionary.cs111
-rw-r--r--OpenSim/Framework/Util.cs26
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs87
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs27
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs107
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs53
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs27
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs21
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs70
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs389
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs290
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs20
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs6
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs5
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs20
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs13
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs22
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs20
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs93
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSCharacter.cs21
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSPrim.cs20
-rw-r--r--OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs44
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs554
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs36
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs261
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs3
37 files changed, 1749 insertions, 832 deletions
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index 3149eaa..325816d 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -123,6 +123,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
123 availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod; 123 availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod;
124 availableMethods["admin_shutdown"] = XmlRpcShutdownMethod; 124 availableMethods["admin_shutdown"] = XmlRpcShutdownMethod;
125 availableMethods["admin_broadcast"] = XmlRpcAlertMethod; 125 availableMethods["admin_broadcast"] = XmlRpcAlertMethod;
126 availableMethods["admin_dialog"] = XmlRpcDialogMethod;
126 availableMethods["admin_restart"] = XmlRpcRestartMethod; 127 availableMethods["admin_restart"] = XmlRpcRestartMethod;
127 availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; 128 availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod;
128 // User management 129 // User management
@@ -212,9 +213,59 @@ namespace OpenSim.ApplicationPlugins.RemoteController
212 if (!m_app.SceneManager.TryGetScene(regionID, out rebootedScene)) 213 if (!m_app.SceneManager.TryGetScene(regionID, out rebootedScene))
213 throw new Exception("region not found"); 214 throw new Exception("region not found");
214 215
216 int timeout = 30000;
217 string message;
218
219 if (requestData.ContainsKey("restart")
220 && ((string)requestData["restart"] == "delayed")
221 && requestData.ContainsKey("milliseconds"))
222 {
223 timeout = Int32.Parse(requestData["milliseconds"].ToString());
224
225 if (timeout < 15000)
226 {
227 //It must be at least 15 seconds or we'll cancel the reboot request
228 timeout = 15000;
229 }
230
231 message
232 = "Region is restarting in " + ((int)(timeout / 1000)).ToString()
233 + " second(s). Please save what you are doing and log out.";
234 }
235 else
236 {
237 message = "Region is restarting in 30 second(s). Please save what you are doing and log out.";
238 }
239
240 if (requestData.ContainsKey("noticetype")
241 && ((string)requestData["noticetype"] == "dialog"))
242 {
243 m_app.SceneManager.ForEachScene(
244 delegate(Scene scene)
245 {
246 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
247 if (dialogModule != null)
248 dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
249 });
250 }
251 else
252 {
253 if (!requestData.ContainsKey("noticetype")
254 || ((string)requestData["noticetype"] != "none"))
255 {
256 m_app.SceneManager.ForEachScene(
257 delegate(Scene scene)
258 {
259 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
260 if (dialogModule != null)
261 dialogModule.SendGeneralAlert(message);
262 });
263 }
264 }
265
215 responseData["rebooting"] = true; 266 responseData["rebooting"] = true;
216 response.Value = responseData; 267 response.Value = responseData;
217 rebootedScene.Restart(30); 268 rebootedScene.Restart(timeout / 1000,false);
218 } 269 }
219 catch (Exception e) 270 catch (Exception e)
220 { 271 {
@@ -277,6 +328,53 @@ namespace OpenSim.ApplicationPlugins.RemoteController
277 m_log.Info("[RADMIN]: Alert request complete"); 328 m_log.Info("[RADMIN]: Alert request complete");
278 return response; 329 return response;
279 } 330 }
331 public XmlRpcResponse XmlRpcDialogMethod(XmlRpcRequest request, IPEndPoint remoteClient)
332 {
333 XmlRpcResponse response = new XmlRpcResponse();
334 Hashtable responseData = new Hashtable();
335
336 m_log.Info("[RADMIN]: Dialog request started");
337
338 try
339 {
340 Hashtable requestData = (Hashtable)request.Params[0];
341
342 checkStringParameters(request, new string[] { "password", "from", "message" });
343
344 if (m_requiredPassword != String.Empty &&
345 (!requestData.Contains("password") || (string)requestData["password"] != m_requiredPassword))
346 throw new Exception("wrong password");
347
348 string message = (string)requestData["message"];
349 string fromuuid = (string)requestData["from"];
350 m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
351
352 responseData["accepted"] = true;
353 responseData["success"] = true;
354 response.Value = responseData;
355
356 m_app.SceneManager.ForEachScene(
357 delegate(Scene scene)
358 {
359 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
360 if (dialogModule != null)
361 dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
362 });
363 }
364 catch (Exception e)
365 {
366 m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message);
367 m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString());
368
369 responseData["accepted"] = false;
370 responseData["success"] = false;
371 responseData["error"] = e.Message;
372 response.Value = responseData;
373 }
374
375 m_log.Info("[RADMIN]: Alert request complete");
376 return response;
377 }
280 378
281 public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient) 379 public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient)
282 { 380 {
@@ -371,13 +469,33 @@ namespace OpenSim.ApplicationPlugins.RemoteController
371 message = "Region is going down now."; 469 message = "Region is going down now.";
372 } 470 }
373 471
374 m_app.SceneManager.ForEachScene( 472 if (requestData.ContainsKey("noticetype")
473 && ((string) requestData["noticetype"] == "dialog"))
474 {
475 m_app.SceneManager.ForEachScene(
375 delegate(Scene scene) 476 delegate(Scene scene)
376 { 477 {
377 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>(); 478 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
378 if (dialogModule != null) 479 if (dialogModule != null)
480 dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
481 });
482 }
483 else
484 {
485 if (!requestData.ContainsKey("noticetype")
486 || ((string)requestData["noticetype"] != "none"))
487 {
488 m_app.SceneManager.ForEachScene(
489 delegate(Scene scene)
490 {
491 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
492 if (dialogModule != null)
379 dialogModule.SendGeneralAlert(message); 493 dialogModule.SendGeneralAlert(message);
380 }); 494 });
495 }
496 }
497
498
381 499
382 // Perform shutdown 500 // Perform shutdown
383 System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing 501 System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs
index ec94b2d..0d4215b 100644
--- a/OpenSim/Framework/Servers/VersionInfo.cs
+++ b/OpenSim/Framework/Servers/VersionInfo.cs
@@ -29,7 +29,7 @@ namespace OpenSim
29{ 29{
30 public class VersionInfo 30 public class VersionInfo
31 { 31 {
32 private const string VERSION_NUMBER = "0.6.9"; 32 private const string VERSION_NUMBER = "0.6.9-CM";
33 private const Flavour VERSION_FLAVOUR = Flavour.Dev; 33 private const Flavour VERSION_FLAVOUR = Flavour.Dev;
34 34
35 public enum Flavour 35 public enum Flavour
diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs
index 25ae6b0..efe5f0c 100644
--- a/OpenSim/Framework/TaskInventoryDictionary.cs
+++ b/OpenSim/Framework/TaskInventoryDictionary.cs
@@ -27,9 +27,12 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Threading;
31using System.Reflection;
30using System.Xml; 32using System.Xml;
31using System.Xml.Schema; 33using System.Xml.Schema;
32using System.Xml.Serialization; 34using System.Xml.Serialization;
35using log4net;
33using OpenMetaverse; 36using OpenMetaverse;
34 37
35namespace OpenSim.Framework 38namespace OpenSim.Framework
@@ -45,6 +48,105 @@ namespace OpenSim.Framework
45 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 49
47 private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem)); 50 private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem));
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private Thread LockedByThread;
54 /// <value>
55 /// An advanced lock for inventory data
56 /// </value>
57 private System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
58
59 /// <summary>
60 /// Are we readlocked by the calling thread?
61 /// </summary>
62 public bool IsReadLockedByMe()
63 {
64 if (m_itemLock.RecursiveReadCount > 0)
65 {
66 return true;
67 }
68 else
69 {
70 return false;
71 }
72 }
73
74 /// <summary>
75 /// Lock our inventory list for reading (many can read, one can write)
76 /// </summary>
77 public void LockItemsForRead(bool locked)
78 {
79 if (locked)
80 {
81 if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
82 {
83 if (!LockedByThread.IsAlive)
84 {
85 //Locked by dead thread, reset.
86 m_itemLock = new System.Threading.ReaderWriterLockSlim();
87 }
88 }
89
90 if (m_itemLock.RecursiveReadCount > 0)
91 {
92 m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
93 m_itemLock.ExitReadLock();
94 }
95 if (m_itemLock.RecursiveWriteCount > 0)
96 {
97 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
98 m_itemLock.ExitWriteLock();
99 }
100
101 while (!m_itemLock.TryEnterReadLock(60000))
102 {
103 m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
104 if (m_itemLock.IsWriteLockHeld)
105 {
106 m_itemLock = new System.Threading.ReaderWriterLockSlim();
107 }
108 }
109 }
110 else
111 {
112 m_itemLock.ExitReadLock();
113 }
114 }
115
116 /// <summary>
117 /// Lock our inventory list for writing (many can read, one can write)
118 /// </summary>
119 public void LockItemsForWrite(bool locked)
120 {
121 if (locked)
122 {
123 //Enter a write lock, wait indefinately for one to open.
124 if (m_itemLock.RecursiveReadCount > 0)
125 {
126 m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
127 m_itemLock.ExitReadLock();
128 }
129 if (m_itemLock.RecursiveWriteCount > 0)
130 {
131 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
132 m_itemLock.ExitWriteLock();
133 }
134 while (!m_itemLock.TryEnterWriteLock(60000))
135 {
136 m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
137 if (m_itemLock.IsWriteLockHeld)
138 {
139 m_itemLock = new System.Threading.ReaderWriterLockSlim();
140 }
141 }
142
143 LockedByThread = Thread.CurrentThread;
144 }
145 else
146 {
147 m_itemLock.ExitWriteLock();
148 }
149 }
48 150
49 #region ICloneable Members 151 #region ICloneable Members
50 152
@@ -52,13 +154,12 @@ namespace OpenSim.Framework
52 { 154 {
53 TaskInventoryDictionary clone = new TaskInventoryDictionary(); 155 TaskInventoryDictionary clone = new TaskInventoryDictionary();
54 156
55 lock (this) 157 m_itemLock.EnterReadLock();
158 foreach (UUID uuid in Keys)
56 { 159 {
57 foreach (UUID uuid in Keys) 160 clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
58 {
59 clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
60 }
61 } 161 }
162 m_itemLock.ExitReadLock();
62 163
63 return clone; 164 return clone;
64 } 165 }
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 87ba5a8..c052745 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -990,19 +990,19 @@ namespace OpenSim.Framework
990 { 990 {
991 string os = String.Empty; 991 string os = String.Empty;
992 992
993 if (Environment.OSVersion.Platform != PlatformID.Unix) 993// if (Environment.OSVersion.Platform != PlatformID.Unix)
994 { 994// {
995 os = Environment.OSVersion.ToString(); 995// os = Environment.OSVersion.ToString();
996 } 996// }
997 else 997// else
998 { 998// {
999 os = ReadEtcIssue(); 999// os = ReadEtcIssue();
1000 } 1000// }
1001 1001//
1002 if (os.Length > 45) 1002// if (os.Length > 45)
1003 { 1003// {
1004 os = os.Substring(0, 45); 1004// os = os.Substring(0, 45);
1005 } 1005// }
1006 1006
1007 return os; 1007 return os;
1008 } 1008 }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index c2aa8e2..b588a2e 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -785,6 +785,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
785 public virtual void SendLayerData(float[] map) 785 public virtual void SendLayerData(float[] map)
786 { 786 {
787 Util.FireAndForget(DoSendLayerData, map); 787 Util.FireAndForget(DoSendLayerData, map);
788
789 // Send it sync, and async. It's not that much data
790 // and it improves user experience just so much!
791 DoSendLayerData(map);
788 } 792 }
789 793
790 /// <summary> 794 /// <summary>
@@ -797,16 +801,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
797 801
798 try 802 try
799 { 803 {
800 //for (int y = 0; y < 16; y++) 804 for (int y = 0; y < 16; y++)
801 //{ 805 {
802 // for (int x = 0; x < 16; x++) 806 for (int x = 0; x < 16; x+=4)
803 // { 807 {
804 // SendLayerData(x, y, map); 808 SendLayerPacket(x, y, map);
805 // } 809 }
806 //} 810 }
807
808 // Send LayerData in a spiral pattern. Fun!
809 SendLayerTopRight(map, 0, 0, 15, 15);
810 } 811 }
811 catch (Exception e) 812 catch (Exception e)
812 { 813 {
@@ -814,51 +815,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
814 } 815 }
815 } 816 }
816 817
817 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
818 {
819 // Row
820 for (int i = x1; i <= x2; i++)
821 SendLayerData(i, y1, map);
822
823 // Column
824 for (int j = y1 + 1; j <= y2; j++)
825 SendLayerData(x2, j, map);
826
827 if (x2 - x1 > 0)
828 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
829 }
830
831 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
832 {
833 // Row in reverse
834 for (int i = x2; i >= x1; i--)
835 SendLayerData(i, y2, map);
836
837 // Column in reverse
838 for (int j = y2 - 1; j >= y1; j--)
839 SendLayerData(x1, j, map);
840
841 if (x2 - x1 > 0)
842 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
843 }
844
845 /// <summary> 818 /// <summary>
846 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 819 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
847 /// </summary> 820 /// </summary>
848 /// <param name="map">heightmap</param> 821 /// <param name="map">heightmap</param>
849 /// <param name="px">X coordinate for patches 0..12</param> 822 /// <param name="px">X coordinate for patches 0..12</param>
850 /// <param name="py">Y coordinate for patches 0..15</param> 823 /// <param name="py">Y coordinate for patches 0..15</param>
851 // private void SendLayerPacket(float[] map, int y, int x) 824 private void SendLayerPacket(int x, int y, float[] map)
852 // { 825 {
853 // int[] patches = new int[4]; 826 int[] patches = new int[4];
854 // patches[0] = x + 0 + y * 16; 827 patches[0] = x + 0 + y * 16;
855 // patches[1] = x + 1 + y * 16; 828 patches[1] = x + 1 + y * 16;
856 // patches[2] = x + 2 + y * 16; 829 patches[2] = x + 2 + y * 16;
857 // patches[3] = x + 3 + y * 16; 830 patches[3] = x + 3 + y * 16;
858 831
859 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 832 float[] heightmap = (map.Length == 65536) ?
860 // OutPacket(layerpack, ThrottleOutPacketType.Land); 833 map :
861 // } 834 LLHeightFieldMoronize(map);
835
836 try
837 {
838 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
839 OutPacket(layerpack, ThrottleOutPacketType.Land);
840 }
841 catch
842 {
843 for (int px = x ; px < x + 4 ; px++)
844 SendLayerData(px, y, map);
845 }
846 }
862 847
863 /// <summary> 848 /// <summary>
864 /// Sends a specified patch to a client 849 /// Sends a specified patch to a client
@@ -3136,7 +3121,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3136 3121
3137 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3122 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3138 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); 3123 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
3139
3140 OutPacket(objupdate, ThrottleOutPacketType.Task); 3124 OutPacket(objupdate, ThrottleOutPacketType.Task);
3141 } 3125 }
3142 3126
@@ -3187,8 +3171,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3187 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3171 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3188 } 3172 }
3189 3173
3190 // HACK: Using the task category until the tiered reprioritization code is in 3174 OutPacket(terse, ThrottleOutPacketType.State);
3191 OutPacket(terse, ThrottleOutPacketType.Task);
3192 } 3175 }
3193 3176
3194 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3177 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 338f2bb..85961b9 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -402,6 +402,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
402 #region Queue or Send 402 #region Queue or Send
403 403
404 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); 404 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
405 outgoingPacket.Type = type;
405 406
406 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) 407 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket))
407 SendPacketFinal(outgoingPacket); 408 SendPacketFinal(outgoingPacket);
@@ -513,6 +514,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 byte flags = buffer.Data[0]; 514 byte flags = buffer.Data[0];
514 bool isResend = (flags & Helpers.MSG_RESENT) != 0; 515 bool isResend = (flags & Helpers.MSG_RESENT) != 0;
515 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; 516 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
517 bool sendSynchronous = false;
516 LLUDPClient udpClient = outgoingPacket.Client; 518 LLUDPClient udpClient = outgoingPacket.Client;
517 519
518 if (!udpClient.IsConnected) 520 if (!udpClient.IsConnected)
@@ -568,9 +570,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
568 if (isReliable) 570 if (isReliable)
569 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength); 571 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength);
570 572
571 // Put the UDP payload on the wire 573 //Some packet types need to be sent synchonously.
572 AsyncBeginSend(buffer); 574 //Sorry, i know it's not optimal, but until the LL client
575 //manages packets correctly and re-orders them as required, this is necessary.
573 576
577
578 // Put the UDP payload on the wire
579 if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate)
580 {
581 SyncBeginPrioritySend(buffer, 2); // highest priority
582 }
583 else if (outgoingPacket.Type == PacketType.ObjectUpdate
584 || outgoingPacket.Type == PacketType.LayerData)
585 {
586 SyncBeginPrioritySend(buffer, 1); // medium priority
587 }
588 else
589 {
590 SyncBeginPrioritySend(buffer, 0); // normal priority
591 }
592
593 //AsyncBeginSend(buffer);
594
574 // Keep track of when this packet was sent out (right now) 595 // Keep track of when this packet was sent out (right now)
575 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; 596 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
576 } 597 }
@@ -851,7 +872,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
851 872
852 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); 873 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
853 874
854 AsyncBeginSend(buffer); 875 SyncBeginPrioritySend(buffer, 1); //Setting this to a medium priority should help minimise resends
855 } 876 }
856 877
857 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) 878 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index d2779ba..de2cd24 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
@@ -29,6 +29,7 @@ using System;
29using System.Net; 29using System.Net;
30using System.Net.Sockets; 30using System.Net.Sockets;
31using System.Threading; 31using System.Threading;
32using System.Collections.Generic;
32using log4net; 33using log4net;
33 34
34namespace OpenMetaverse 35namespace OpenMetaverse
@@ -52,12 +53,30 @@ namespace OpenMetaverse
52 /// <summary>Local IP address to bind to in server mode</summary> 53 /// <summary>Local IP address to bind to in server mode</summary>
53 protected IPAddress m_localBindAddress; 54 protected IPAddress m_localBindAddress;
54 55
56 /// <summary>
57 /// Standard queue for our outgoing SyncBeginPrioritySend
58 /// </summary>
59 private List<UDPPacketBuffer> m_standardQueue = new List<UDPPacketBuffer>();
60
61 /// <summary>
62 /// Medium priority queue for our outgoing SyncBeginPrioritySend
63 /// </summary>
64 private List<UDPPacketBuffer> m_mediumPriorityQueue = new List<UDPPacketBuffer>();
65
66 /// <summary>
67 /// Prioritised queue for our outgoing SyncBeginPrioritySend
68 /// </summary>
69 private List<UDPPacketBuffer> m_priorityQueue = new List<UDPPacketBuffer>();
70
55 /// <summary>UDP socket, used in either client or server mode</summary> 71 /// <summary>UDP socket, used in either client or server mode</summary>
56 private Socket m_udpSocket; 72 private Socket m_udpSocket;
57 73
58 /// <summary>Flag to process packets asynchronously or synchronously</summary> 74 /// <summary>Flag to process packets asynchronously or synchronously</summary>
59 private bool m_asyncPacketHandling; 75 private bool m_asyncPacketHandling;
60 76
77 /// <summary>Are we currently sending data asynchronously?</summary>
78 private volatile bool m_sendingData = false;
79
61 /// <summary>The all important shutdown flag</summary> 80 /// <summary>The all important shutdown flag</summary>
62 private volatile bool m_shutdownFlag = true; 81 private volatile bool m_shutdownFlag = true;
63 82
@@ -246,7 +265,51 @@ namespace OpenMetaverse
246 } 265 }
247 } 266 }
248 267
249 public void AsyncBeginSend(UDPPacketBuffer buf) 268 public void SyncBeginPrioritySend(UDPPacketBuffer buf, int Priority)
269 {
270 if (!m_shutdownFlag)
271 {
272 if (!m_sendingData)
273 {
274 m_sendingData = true;
275 try
276 {
277 AsyncBeginSend(buf);
278 }
279 catch (SocketException) { }
280 catch (ObjectDisposedException) { }
281 }
282 else
283 {
284 if (Priority == 2)
285 {
286 lock (m_priorityQueue)
287 {
288 m_priorityQueue.Add(buf);
289 }
290 }
291 else
292 {
293 if (Priority != 0)
294 {
295 lock (m_mediumPriorityQueue)
296 {
297 m_mediumPriorityQueue.Add(buf);
298 }
299 }
300 else
301 {
302 lock (m_standardQueue)
303 {
304 m_standardQueue.Add(buf);
305 }
306 }
307 }
308 }
309 }
310 }
311
312 private void AsyncBeginSend(UDPPacketBuffer buf)
250 { 313 {
251 if (!m_shutdownFlag) 314 if (!m_shutdownFlag)
252 { 315 {
@@ -270,8 +333,48 @@ namespace OpenMetaverse
270 { 333 {
271 try 334 try
272 { 335 {
273// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
274 m_udpSocket.EndSendTo(result); 336 m_udpSocket.EndSendTo(result);
337
338 if (m_sendingData)
339 {
340 lock (m_priorityQueue)
341 {
342 if (m_priorityQueue.Count > 0)
343 {
344 UDPPacketBuffer buf = m_priorityQueue[0];
345 m_priorityQueue.RemoveAt(0);
346 AsyncBeginSend(buf);
347 }
348 else
349 {
350 lock (m_mediumPriorityQueue)
351 {
352 if (m_mediumPriorityQueue.Count > 0)
353 {
354 UDPPacketBuffer buf = m_mediumPriorityQueue[0];
355 m_mediumPriorityQueue.RemoveAt(0);
356 AsyncBeginSend(buf);
357 }
358 else
359 {
360 lock (m_standardQueue)
361 {
362 if (m_standardQueue.Count > 0)
363 {
364 UDPPacketBuffer buf = m_standardQueue[0];
365 m_standardQueue.RemoveAt(0);
366 AsyncBeginSend(buf);
367 }
368 else
369 {
370 m_sendingData = false;
371 }
372 }
373 }
374 }
375 }
376 }
377 }
275 } 378 }
276 catch (SocketException) { } 379 catch (SocketException) { }
277 catch (ObjectDisposedException) { } 380 catch (ObjectDisposedException) { }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
index 1a1a1cb..7dc42d3 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using OpenSim.Framework; 29using OpenSim.Framework;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenMetaverse.Packets;
31 32
32namespace OpenSim.Region.ClientStack.LindenUDP 33namespace OpenSim.Region.ClientStack.LindenUDP
33{ 34{
@@ -52,7 +53,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
52 public int TickCount; 53 public int TickCount;
53 /// <summary>Category this packet belongs to</summary> 54 /// <summary>Category this packet belongs to</summary>
54 public ThrottleOutPacketType Category; 55 public ThrottleOutPacketType Category;
55 56 /// <summary>The type of packet so its delivery method can be determined</summary>
57 public PacketType Type;
56 /// <summary> 58 /// <summary>
57 /// Default constructor 59 /// Default constructor
58 /// </summary> 60 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 6dacbba..e3e8718 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
49 private int m_shoutdistance = 100; 49 private int m_shoutdistance = 100;
50 private int m_whisperdistance = 10; 50 private int m_whisperdistance = 10;
51 private List<Scene> m_scenes = new List<Scene>(); 51 private List<Scene> m_scenes = new List<Scene>();
52 52 private string m_adminPrefix = "";
53 internal object m_syncy = new object(); 53 internal object m_syncy = new object();
54 54
55 internal IConfig m_config; 55 internal IConfig m_config;
@@ -76,6 +76,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
76 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 76 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
77 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 77 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
78 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 78 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
79 m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
79 } 80 }
80 81
81 public virtual void AddRegion(Scene scene) 82 public virtual void AddRegion(Scene scene)
@@ -185,6 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
185 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) 186 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
186 { 187 {
187 string fromName = c.From; 188 string fromName = c.From;
189 string fromNamePrefix = "";
188 UUID fromID = UUID.Zero; 190 UUID fromID = UUID.Zero;
189 string message = c.Message; 191 string message = c.Message;
190 IScene scene = c.Scene; 192 IScene scene = c.Scene;
@@ -207,7 +209,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
207 fromPos = avatar.AbsolutePosition; 209 fromPos = avatar.AbsolutePosition;
208 fromName = avatar.Name; 210 fromName = avatar.Name;
209 fromID = c.Sender.AgentId; 211 fromID = c.Sender.AgentId;
210 212 if (avatar.GodLevel > 200)
213 {
214 fromNamePrefix = m_adminPrefix;
215 }
211 break; 216 break;
212 217
213 case ChatSourceType.Object: 218 case ChatSourceType.Object:
@@ -227,7 +232,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
227 s.ForEachScenePresence( 232 s.ForEachScenePresence(
228 delegate(ScenePresence presence) 233 delegate(ScenePresence presence)
229 { 234 {
230 TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType); 235 TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix+fromName, c.Type, message, sourceType);
231 } 236 }
232 ); 237 );
233 } 238 }
@@ -266,25 +271,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
266 } 271 }
267 272
268 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 273 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
269 274 if (c.Scene != null)
270 ((Scene)c.Scene).ForEachScenePresence( 275 {
271 delegate(ScenePresence presence) 276 ((Scene)c.Scene).ForEachScenePresence
272 { 277 (
273 // ignore chat from child agents 278 delegate(ScenePresence presence)
274 if (presence.IsChildAgent) return; 279 {
275 280 // ignore chat from child agents
276 IClientAPI client = presence.ControllingClient; 281 if (presence.IsChildAgent) return;
277 282
278 // don't forward SayOwner chat from objects to 283 IClientAPI client = presence.ControllingClient;
279 // non-owner agents 284
280 if ((c.Type == ChatTypeEnum.Owner) && 285 // don't forward SayOwner chat from objects to
281 (null != c.SenderObject) && 286 // non-owner agents
282 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 287 if ((c.Type == ChatTypeEnum.Owner) &&
283 return; 288 (null != c.SenderObject) &&
284 289 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
285 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, 290 return;
286 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 291
287 }); 292 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
293 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
294 }
295 );
296 }
288 } 297 }
289 298
290 299
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 1614b70..7f9e5af 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -164,19 +164,22 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
164 List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>( 164 List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
165 "POST", m_RestURL+"/RetrieveMessages/", client.AgentId); 165 "POST", m_RestURL+"/RetrieveMessages/", client.AgentId);
166 166
167 foreach (GridInstantMessage im in msglist) 167 if (msglist != null)
168 { 168 {
169 // client.SendInstantMessage(im); 169 foreach (GridInstantMessage im in msglist)
170 170 {
171 // Send through scene event manager so all modules get a chance 171 // client.SendInstantMessage(im);
172 // to look at this message before it gets delivered. 172
173 // 173 // Send through scene event manager so all modules get a chance
174 // Needed for proper state management for stored group 174 // to look at this message before it gets delivered.
175 // invitations 175 //
176 // 176 // Needed for proper state management for stored group
177 Scene s = FindScene(client.AgentId); 177 // invitations
178 if (s != null) 178 //
179 s.EventManager.TriggerIncomingInstantMessage(im); 179 Scene s = FindScene(client.AgentId);
180 if (s != null)
181 s.EventManager.TriggerIncomingInstantMessage(im);
182 }
180 } 183 }
181 } 184 }
182 185
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index d9a021f..b60b32b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -389,7 +389,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
389 { 389 {
390 // Check if this is ours to handle 390 // Check if this is ours to handle
391 // 391 //
392 m_log.Info("OnFridInstantMessage"); 392 //m_log.Info("OnFridInstantMessage");
393 if (msg.dialog != (byte) InstantMessageDialog.InventoryOffered) 393 if (msg.dialog != (byte) InstantMessageDialog.InventoryOffered)
394 return; 394 return;
395 395
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index af72968..3c0997c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -247,21 +247,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver
247 // Fix ownership/creator of inventory items 247 // Fix ownership/creator of inventory items
248 // Not doing so results in inventory items 248 // Not doing so results in inventory items
249 // being no copy/no mod for everyone 249 // being no copy/no mod for everyone
250 lock (part.TaskInventory) 250 part.TaskInventory.LockItemsForRead(true);
251 TaskInventoryDictionary inv = part.TaskInventory;
252 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
251 { 253 {
252 TaskInventoryDictionary inv = part.TaskInventory; 254 if (!ResolveUserUuid(kvp.Value.OwnerID))
253 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
254 { 255 {
255 if (!ResolveUserUuid(kvp.Value.OwnerID)) 256 kvp.Value.OwnerID = masterAvatarId;
256 { 257 }
257 kvp.Value.OwnerID = masterAvatarId; 258 if (!ResolveUserUuid(kvp.Value.CreatorID))
258 } 259 {
259 if (!ResolveUserUuid(kvp.Value.CreatorID)) 260 kvp.Value.CreatorID = masterAvatarId;
260 {
261 kvp.Value.CreatorID = masterAvatarId;
262 }
263 } 261 }
264 } 262 }
263 part.TaskInventory.LockItemsForRead(false);
265 } 264 }
266 265
267 if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) 266 if (m_scene.AddRestoredSceneObject(sceneObject, true, false))
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index b37249d..b031f61 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -53,8 +53,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
53 { 53 {
54 get { return m_movementAnimation; } 54 get { return m_movementAnimation; }
55 } 55 }
56 protected string m_movementAnimation = "DEFAULT"; 56 // protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist!
57 57 protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init.
58 private int m_animTickFall; 58 private int m_animTickFall;
59 private int m_animTickJump; 59 private int m_animTickJump;
60 60
@@ -123,17 +123,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation
123 /// </summary> 123 /// </summary>
124 public void TrySetMovementAnimation(string anim) 124 public void TrySetMovementAnimation(string anim)
125 { 125 {
126 //m_log.DebugFormat("Updating movement animation to {0}", anim); 126//Console.WriteLine("Updating movement animation to {0}", anim);
127 127
128 if (!m_scenePresence.IsChildAgent) 128 if (!m_scenePresence.IsChildAgent)
129 { 129 {
130 if (m_animations.TrySetDefaultAnimation( 130 if (m_animations.TrySetDefaultAnimation(
131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero)) 131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero))
132 { 132 {
133//Console.WriteLine("TSMA {0} success.", anim);
133 // 16384 is CHANGED_ANIMATION 134 // 16384 is CHANGED_ANIMATION
134 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); 135 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 });
135 SendAnimPack(); 136 SendAnimPack();
136 } 137 }
138 else
139 {
140//Console.WriteLine("TSMA {0} fail.", anim);
141 }
137 } 142 }
138 } 143 }
139 144
@@ -156,10 +161,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 161 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
157 162
158 // Check control flags 163 // Check control flags
159 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; 164 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
160 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 165 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
161 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 166 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
162 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; 167 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
163 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 168 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
164 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 169 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
165 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 170 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
@@ -312,7 +317,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
312 public void UpdateMovementAnimations() 317 public void UpdateMovementAnimations()
313 { 318 {
314 m_movementAnimation = GetMovementAnimation(); 319 m_movementAnimation = GetMovementAnimation();
315 320//Console.WriteLine("UMA got {0}", m_movementAnimation);
316 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) 321 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
317 { 322 {
318 // This was the previous behavior before PREJUMP 323 // This was the previous behavior before PREJUMP
@@ -444,4 +449,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
444 SendAnimPack(animIDs, sequenceNums, objectIDs); 449 SendAnimPack(animIDs, sequenceNums, objectIDs);
445 } 450 }
446 } 451 }
447} \ No newline at end of file 452}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 66fb918..83208e9 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -840,8 +840,12 @@ namespace OpenSim.Region.Framework.Scenes
840 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 840 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
841 { 841 {
842 SceneObjectPart part = GetSceneObjectPart(localID); 842 SceneObjectPart part = GetSceneObjectPart(localID);
843 SceneObjectGroup group = part.ParentGroup; 843 SceneObjectGroup group = null;
844 if (group != null) 844 if (part != null)
845 {
846 group = part.ParentGroup;
847 }
848 if (part != null && group != null)
845 { 849 {
846 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 850 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
847 if (item == null) 851 if (item == null)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index fbabb5c..c12c81b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -878,6 +878,15 @@ namespace OpenSim.Region.Framework.Scenes
878 /// <param name="seconds">float indicating duration before restart.</param> 878 /// <param name="seconds">float indicating duration before restart.</param>
879 public virtual void Restart(float seconds) 879 public virtual void Restart(float seconds)
880 { 880 {
881 Restart(seconds, true);
882 }
883
884 /// <summary>
885 /// Given float seconds, this will restart the region. showDialog will optionally alert the users.
886 /// </summary>
887 /// <param name="seconds">float indicating duration before restart.</param>
888 public virtual void Restart(float seconds, bool showDialog)
889 {
881 // notifications are done in 15 second increments 890 // notifications are done in 15 second increments
882 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request 891 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
883 // It's a 'Cancel restart' request. 892 // It's a 'Cancel restart' request.
@@ -898,8 +907,11 @@ namespace OpenSim.Region.Framework.Scenes
898 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed); 907 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
899 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes"); 908 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
900 m_restartTimer.Start(); 909 m_restartTimer.Start();
901 m_dialogModule.SendNotificationToUsersInRegion( 910 if (showDialog)
902 UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in 2 Minutes"); 911 {
912 m_dialogModule.SendNotificationToUsersInRegion(
913 UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in " + (seconds / 60).ToString() + " Minutes");
914 }
903 } 915 }
904 } 916 }
905 917
@@ -1169,16 +1181,16 @@ namespace OpenSim.Region.Framework.Scenes
1169 // Check if any objects have reached their targets 1181 // Check if any objects have reached their targets
1170 CheckAtTargets(); 1182 CheckAtTargets();
1171 1183
1172 // Update SceneObjectGroups that have scheduled themselves for updates
1173 // Objects queue their updates onto all scene presences
1174 if (m_frame % m_update_objects == 0)
1175 m_sceneGraph.UpdateObjectGroups();
1176
1177 // Run through all ScenePresences looking for updates 1184 // Run through all ScenePresences looking for updates
1178 // Presence updates and queued object updates for each presence are sent to clients 1185 // Presence updates and queued object updates for each presence are sent to clients
1179 if (m_frame % m_update_presences == 0) 1186 if (m_frame % m_update_presences == 0)
1180 m_sceneGraph.UpdatePresences(); 1187 m_sceneGraph.UpdatePresences();
1181 1188
1189 // Update SceneObjectGroups that have scheduled themselves for updates
1190 // Objects queue their updates onto all scene presences
1191 if (m_frame % m_update_objects == 0)
1192 m_sceneGraph.UpdateObjectGroups();
1193
1182 int TempPhysicsMS2 = Environment.TickCount; 1194 int TempPhysicsMS2 = Environment.TickCount;
1183 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1195 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1184 m_sceneGraph.UpdatePreparePhysics(); 1196 m_sceneGraph.UpdatePreparePhysics();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 7359011..26a843e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1735,6 +1735,45 @@ namespace OpenSim.Region.Framework.Scenes
1735 } 1735 }
1736 } 1736 }
1737 1737
1738 public void rotLookAt(Quaternion target, float strength, float damping)
1739 {
1740 SceneObjectPart rootpart = m_rootPart;
1741 if (rootpart != null)
1742 {
1743 if (IsAttachment)
1744 {
1745 /*
1746 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1747 if (avatar != null)
1748 {
1749 Rotate the Av?
1750 } */
1751 }
1752 else
1753 {
1754 if (rootpart.PhysActor != null)
1755 {
1756 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1757 rootpart.PhysActor.APIDStrength = strength;
1758 rootpart.PhysActor.APIDDamping = damping;
1759 rootpart.PhysActor.APIDActive = true;
1760 }
1761 }
1762 }
1763 }
1764 public void stopLookAt()
1765 {
1766 SceneObjectPart rootpart = m_rootPart;
1767 if (rootpart != null)
1768 {
1769 if (rootpart.PhysActor != null)
1770 {
1771 rootpart.PhysActor.APIDActive = false;
1772 }
1773 }
1774
1775 }
1776
1738 /// <summary> 1777 /// <summary>
1739 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1778 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1740 /// </summary> 1779 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b6916f2..19e3023 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -389,12 +389,16 @@ namespace OpenSim.Region.Framework.Scenes
389 } 389 }
390 390
391 /// <value> 391 /// <value>
392 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 392 /// Get the inventory list
393 /// </value> 393 /// </value>
394 public TaskInventoryDictionary TaskInventory 394 public TaskInventoryDictionary TaskInventory
395 { 395 {
396 get { return m_inventory.Items; } 396 get {
397 set { m_inventory.Items = value; } 397 return m_inventory.Items;
398 }
399 set {
400 m_inventory.Items = value;
401 }
398 } 402 }
399 403
400 public uint ObjectFlags 404 public uint ObjectFlags
@@ -1064,14 +1068,6 @@ namespace OpenSim.Region.Framework.Scenes
1064 } 1068 }
1065 } 1069 }
1066 1070
1067 /// <summary>
1068 /// Clear all pending updates of parts to clients
1069 /// </summary>
1070 private void ClearUpdateSchedule()
1071 {
1072 m_updateFlag = 0;
1073 }
1074
1075 private void SendObjectPropertiesToClient(UUID AgentID) 1071 private void SendObjectPropertiesToClient(UUID AgentID)
1076 { 1072 {
1077 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1073 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -2109,17 +2105,18 @@ namespace OpenSim.Region.Framework.Scenes
2109 //Trys to fetch sound id from prim's inventory. 2105 //Trys to fetch sound id from prim's inventory.
2110 //Prim's inventory doesn't support non script items yet 2106 //Prim's inventory doesn't support non script items yet
2111 2107
2112 lock (TaskInventory) 2108 TaskInventory.LockItemsForRead(true);
2109
2110 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2113 { 2111 {
2114 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2112 if (item.Value.Name == sound)
2115 { 2113 {
2116 if (item.Value.Name == sound) 2114 soundID = item.Value.ItemID;
2117 { 2115 break;
2118 soundID = item.Value.ItemID;
2119 break;
2120 }
2121 } 2116 }
2122 } 2117 }
2118
2119 TaskInventory.LockItemsForRead(false);
2123 } 2120 }
2124 2121
2125 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2122 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2185,6 +2182,11 @@ namespace OpenSim.Region.Framework.Scenes
2185 ParentGroup.HasGroupChanged = true; 2182 ParentGroup.HasGroupChanged = true;
2186 ScheduleFullUpdate(); 2183 ScheduleFullUpdate();
2187 } 2184 }
2185
2186 public void RotLookAt(Quaternion target, float strength, float damping)
2187 {
2188 m_parentGroup.rotLookAt(target, strength, damping);
2189 }
2188 2190
2189 /// <summary> 2191 /// <summary>
2190 /// Schedules this prim for a full update 2192 /// Schedules this prim for a full update
@@ -2389,8 +2391,8 @@ namespace OpenSim.Region.Framework.Scenes
2389 { 2391 {
2390 const float ROTATION_TOLERANCE = 0.01f; 2392 const float ROTATION_TOLERANCE = 0.01f;
2391 const float VELOCITY_TOLERANCE = 0.001f; 2393 const float VELOCITY_TOLERANCE = 0.001f;
2392 const float POSITION_TOLERANCE = 0.05f; 2394 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2393 const int TIME_MS_TOLERANCE = 3000; 2395 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2394 2396
2395 if (m_updateFlag == 1) 2397 if (m_updateFlag == 1)
2396 { 2398 {
@@ -2404,7 +2406,7 @@ namespace OpenSim.Region.Framework.Scenes
2404 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2406 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2405 { 2407 {
2406 AddTerseUpdateToAllAvatars(); 2408 AddTerseUpdateToAllAvatars();
2407 ClearUpdateSchedule(); 2409
2408 2410
2409 // This causes the Scene to 'poll' physical objects every couple of frames 2411 // This causes the Scene to 'poll' physical objects every couple of frames
2410 // bad, so it's been replaced by an event driven method. 2412 // bad, so it's been replaced by an event driven method.
@@ -2422,16 +2424,18 @@ namespace OpenSim.Region.Framework.Scenes
2422 m_lastAngularVelocity = AngularVelocity; 2424 m_lastAngularVelocity = AngularVelocity;
2423 m_lastTerseSent = Environment.TickCount; 2425 m_lastTerseSent = Environment.TickCount;
2424 } 2426 }
2427 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2428 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2425 } 2429 }
2426 else 2430 else
2427 { 2431 {
2428 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2432 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2429 { 2433 {
2430 AddFullUpdateToAllAvatars(); 2434 AddFullUpdateToAllAvatars();
2431 ClearUpdateSchedule(); 2435 m_updateFlag = 0; //Same here
2432 } 2436 }
2433 } 2437 }
2434 ClearUpdateSchedule(); 2438 m_updateFlag = 0;
2435 } 2439 }
2436 2440
2437 /// <summary> 2441 /// <summary>
@@ -2458,17 +2462,16 @@ namespace OpenSim.Region.Framework.Scenes
2458 if (!UUID.TryParse(sound, out soundID)) 2462 if (!UUID.TryParse(sound, out soundID))
2459 { 2463 {
2460 // search sound file from inventory 2464 // search sound file from inventory
2461 lock (TaskInventory) 2465 TaskInventory.LockItemsForRead(true);
2466 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2462 { 2467 {
2463 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2468 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2464 { 2469 {
2465 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2470 soundID = item.Value.ItemID;
2466 { 2471 break;
2467 soundID = item.Value.ItemID;
2468 break;
2469 }
2470 } 2472 }
2471 } 2473 }
2474 TaskInventory.LockItemsForRead(false);
2472 } 2475 }
2473 2476
2474 if (soundID == UUID.Zero) 2477 if (soundID == UUID.Zero)
@@ -2684,6 +2687,13 @@ namespace OpenSim.Region.Framework.Scenes
2684 SetText(text); 2687 SetText(text);
2685 } 2688 }
2686 2689
2690 public void StopLookAt()
2691 {
2692 m_parentGroup.stopLookAt();
2693
2694 m_parentGroup.ScheduleGroupForTerseUpdate();
2695 }
2696
2687 public void StopMoveToTarget() 2697 public void StopMoveToTarget()
2688 { 2698 {
2689 m_parentGroup.stopMoveToTarget(); 2699 m_parentGroup.stopMoveToTarget();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 7a0d7b7..eca8588 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -80,7 +80,9 @@ namespace OpenSim.Region.Framework.Scenes
80 /// </value> 80 /// </value>
81 protected internal TaskInventoryDictionary Items 81 protected internal TaskInventoryDictionary Items
82 { 82 {
83 get { return m_items; } 83 get {
84 return m_items;
85 }
84 set 86 set
85 { 87 {
86 m_items = value; 88 m_items = value;
@@ -116,22 +118,25 @@ namespace OpenSim.Region.Framework.Scenes
116 /// <param name="linkNum">Link number for the part</param> 118 /// <param name="linkNum">Link number for the part</param>
117 public void ResetInventoryIDs() 119 public void ResetInventoryIDs()
118 { 120 {
119 lock (Items) 121 m_items.LockItemsForWrite(true);
122
123 if (0 == Items.Count)
120 { 124 {
121 if (0 == Items.Count) 125 m_items.LockItemsForWrite(false);
122 return; 126 return;
127 }
123 128
124 HasInventoryChanged = true; 129 HasInventoryChanged = true;
125 m_part.ParentGroup.HasGroupChanged = true; 130 m_part.ParentGroup.HasGroupChanged = true;
126 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 131 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
127 Items.Clear(); 132 Items.Clear();
128 133
129 foreach (TaskInventoryItem item in items) 134 foreach (TaskInventoryItem item in items)
130 { 135 {
131 item.ResetIDs(m_part.UUID); 136 item.ResetIDs(m_part.UUID);
132 Items.Add(item.ItemID, item); 137 Items.Add(item.ItemID, item);
133 }
134 } 138 }
139 m_items.LockItemsForWrite(false);
135 } 140 }
136 141
137 /// <summary> 142 /// <summary>
@@ -140,25 +145,25 @@ namespace OpenSim.Region.Framework.Scenes
140 /// <param name="ownerId"></param> 145 /// <param name="ownerId"></param>
141 public void ChangeInventoryOwner(UUID ownerId) 146 public void ChangeInventoryOwner(UUID ownerId)
142 { 147 {
143 lock (Items) 148 m_items.LockItemsForWrite(true);
149 if (0 == Items.Count)
144 { 150 {
145 if (0 == Items.Count) 151 m_items.LockItemsForWrite(false);
146 { 152 return;
147 return; 153 }
148 }
149 154
150 HasInventoryChanged = true; 155 HasInventoryChanged = true;
151 m_part.ParentGroup.HasGroupChanged = true; 156 m_part.ParentGroup.HasGroupChanged = true;
152 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 157 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
153 foreach (TaskInventoryItem item in items) 158 foreach (TaskInventoryItem item in items)
159 {
160 if (ownerId != item.OwnerID)
154 { 161 {
155 if (ownerId != item.OwnerID) 162 item.LastOwnerID = item.OwnerID;
156 { 163 item.OwnerID = ownerId;
157 item.LastOwnerID = item.OwnerID;
158 item.OwnerID = ownerId;
159 }
160 } 164 }
161 } 165 }
166 m_items.LockItemsForWrite(false);
162 } 167 }
163 168
164 /// <summary> 169 /// <summary>
@@ -167,24 +172,24 @@ namespace OpenSim.Region.Framework.Scenes
167 /// <param name="groupID"></param> 172 /// <param name="groupID"></param>
168 public void ChangeInventoryGroup(UUID groupID) 173 public void ChangeInventoryGroup(UUID groupID)
169 { 174 {
170 lock (Items) 175 m_items.LockItemsForWrite(true);
176 if (0 == Items.Count)
171 { 177 {
172 if (0 == Items.Count) 178 m_items.LockItemsForWrite(false);
173 { 179 return;
174 return; 180 }
175 }
176 181
177 HasInventoryChanged = true; 182 HasInventoryChanged = true;
178 m_part.ParentGroup.HasGroupChanged = true; 183 m_part.ParentGroup.HasGroupChanged = true;
179 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 184 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
180 foreach (TaskInventoryItem item in items) 185 foreach (TaskInventoryItem item in items)
186 {
187 if (groupID != item.GroupID)
181 { 188 {
182 if (groupID != item.GroupID) 189 item.GroupID = groupID;
183 {
184 item.GroupID = groupID;
185 }
186 } 190 }
187 } 191 }
192 m_items.LockItemsForWrite(false);
188 } 193 }
189 194
190 /// <summary> 195 /// <summary>
@@ -192,14 +197,14 @@ namespace OpenSim.Region.Framework.Scenes
192 /// </summary> 197 /// </summary>
193 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 198 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
194 { 199 {
195 lock (m_items) 200 Items.LockItemsForRead(true);
201 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
202 Items.LockItemsForRead(false);
203 foreach (TaskInventoryItem item in items)
196 { 204 {
197 foreach (TaskInventoryItem item in Items.Values) 205 if ((int)InventoryType.LSL == item.InvType)
198 { 206 {
199 if ((int)InventoryType.LSL == item.InvType) 207 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
200 {
201 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
202 }
203 } 208 }
204 } 209 }
205 } 210 }
@@ -209,17 +214,20 @@ namespace OpenSim.Region.Framework.Scenes
209 /// </summary> 214 /// </summary>
210 public void RemoveScriptInstances() 215 public void RemoveScriptInstances()
211 { 216 {
212 lock (Items) 217 Items.LockItemsForRead(true);
218 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
219 Items.LockItemsForRead(false);
220
221 foreach (TaskInventoryItem item in items)
213 { 222 {
214 foreach (TaskInventoryItem item in Items.Values) 223 if ((int)InventoryType.LSL == item.InvType)
215 { 224 {
216 if ((int)InventoryType.LSL == item.InvType) 225 RemoveScriptInstance(item.ItemID);
217 { 226 m_part.RemoveScriptEvents(item.ItemID);
218 RemoveScriptInstance(item.ItemID);
219 m_part.RemoveScriptEvents(item.ItemID);
220 }
221 } 227 }
222 } 228 }
229
230
223 } 231 }
224 232
225 /// <summary> 233 /// <summary>
@@ -244,8 +252,10 @@ namespace OpenSim.Region.Framework.Scenes
244 if (stateSource == 1 && // Prim crossing 252 if (stateSource == 1 && // Prim crossing
245 m_part.ParentGroup.Scene.m_trustBinaries) 253 m_part.ParentGroup.Scene.m_trustBinaries)
246 { 254 {
255 m_items.LockItemsForWrite(true);
247 m_items[item.ItemID].PermsMask = 0; 256 m_items[item.ItemID].PermsMask = 0;
248 m_items[item.ItemID].PermsGranter = UUID.Zero; 257 m_items[item.ItemID].PermsGranter = UUID.Zero;
258 m_items.LockItemsForWrite(false);
249 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 259 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
250 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 260 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
251 m_part.ParentGroup.AddActiveScriptCount(1); 261 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -266,8 +276,10 @@ namespace OpenSim.Region.Framework.Scenes
266 { 276 {
267 if (m_part.ParentGroup.m_savedScriptState != null) 277 if (m_part.ParentGroup.m_savedScriptState != null)
268 RestoreSavedScriptState(item.OldItemID, item.ItemID); 278 RestoreSavedScriptState(item.OldItemID, item.ItemID);
279 m_items.LockItemsForWrite(true);
269 m_items[item.ItemID].PermsMask = 0; 280 m_items[item.ItemID].PermsMask = 0;
270 m_items[item.ItemID].PermsGranter = UUID.Zero; 281 m_items[item.ItemID].PermsGranter = UUID.Zero;
282 m_items.LockItemsForWrite(false);
271 string script = Utils.BytesToString(asset.Data); 283 string script = Utils.BytesToString(asset.Data);
272 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 284 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
273 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 285 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
@@ -302,20 +314,22 @@ namespace OpenSim.Region.Framework.Scenes
302 /// </param> 314 /// </param>
303 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 315 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
304 { 316 {
305 lock (m_items) 317 m_items.LockItemsForRead(true);
318 if (m_items.ContainsKey(itemId))
306 { 319 {
307 if (m_items.ContainsKey(itemId)) 320 TaskInventoryItem item = m_items[itemId];
308 { 321 m_items.LockItemsForRead(false);
309 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 322 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
310 }
311 else
312 {
313 m_log.ErrorFormat(
314 "[PRIM INVENTORY]: " +
315 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
316 itemId, m_part.Name, m_part.UUID);
317 }
318 } 323 }
324 else
325 {
326 m_items.LockItemsForRead(false);
327 m_log.ErrorFormat(
328 "[PRIM INVENTORY]: " +
329 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
330 itemId, m_part.Name, m_part.UUID);
331 }
332
319 } 333 }
320 334
321 /// <summary> 335 /// <summary>
@@ -346,11 +360,16 @@ namespace OpenSim.Region.Framework.Scenes
346 /// <returns></returns> 360 /// <returns></returns>
347 private bool InventoryContainsName(string name) 361 private bool InventoryContainsName(string name)
348 { 362 {
349 foreach (TaskInventoryItem item in Items.Values) 363 m_items.LockItemsForRead(true);
364 foreach (TaskInventoryItem item in m_items.Values)
350 { 365 {
351 if (item.Name == name) 366 if (item.Name == name)
367 {
368 m_items.LockItemsForRead(false);
352 return true; 369 return true;
370 }
353 } 371 }
372 m_items.LockItemsForRead(false);
354 return false; 373 return false;
355 } 374 }
356 375
@@ -392,7 +411,9 @@ namespace OpenSim.Region.Framework.Scenes
392 /// <param name="item"></param> 411 /// <param name="item"></param>
393 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 412 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
394 { 413 {
414 m_items.LockItemsForRead(true);
395 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); 415 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
416 m_items.LockItemsForRead(false);
396 foreach (TaskInventoryItem i in il) 417 foreach (TaskInventoryItem i in il)
397 { 418 {
398 if (i.Name == item.Name) 419 if (i.Name == item.Name)
@@ -429,15 +450,14 @@ namespace OpenSim.Region.Framework.Scenes
429 item.ParentPartID = m_part.UUID; 450 item.ParentPartID = m_part.UUID;
430 item.Name = name; 451 item.Name = name;
431 452
432 lock (m_items) 453 m_items.LockItemsForWrite(true);
433 { 454 m_items.Add(item.ItemID, item);
434 m_items.Add(item.ItemID, item); 455 m_items.LockItemsForWrite(false);
435
436 if (allowedDrop) 456 if (allowedDrop)
437 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 457 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
438 else 458 else
439 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 459 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
440 } 460
441 461
442 m_inventorySerial++; 462 m_inventorySerial++;
443 //m_inventorySerial += 2; 463 //m_inventorySerial += 2;
@@ -454,14 +474,13 @@ namespace OpenSim.Region.Framework.Scenes
454 /// <param name="items"></param> 474 /// <param name="items"></param>
455 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 475 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
456 { 476 {
457 lock (m_items) 477 m_items.LockItemsForWrite(true);
478 foreach (TaskInventoryItem item in items)
458 { 479 {
459 foreach (TaskInventoryItem item in items) 480 m_items.Add(item.ItemID, item);
460 { 481 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
461 m_items.Add(item.ItemID, item);
462 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
463 }
464 } 482 }
483 m_items.LockItemsForWrite(false);
465 484
466 m_inventorySerial++; 485 m_inventorySerial++;
467 } 486 }
@@ -474,8 +493,9 @@ namespace OpenSim.Region.Framework.Scenes
474 public TaskInventoryItem GetInventoryItem(UUID itemId) 493 public TaskInventoryItem GetInventoryItem(UUID itemId)
475 { 494 {
476 TaskInventoryItem item; 495 TaskInventoryItem item;
496 m_items.LockItemsForRead(true);
477 m_items.TryGetValue(itemId, out item); 497 m_items.TryGetValue(itemId, out item);
478 498 m_items.LockItemsForRead(false);
479 return item; 499 return item;
480 } 500 }
481 501
@@ -487,45 +507,45 @@ namespace OpenSim.Region.Framework.Scenes
487 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 507 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
488 public bool UpdateInventoryItem(TaskInventoryItem item) 508 public bool UpdateInventoryItem(TaskInventoryItem item)
489 { 509 {
490 lock (m_items) 510 m_items.LockItemsForWrite(true);
511
512 if (m_items.ContainsKey(item.ItemID))
491 { 513 {
492 if (m_items.ContainsKey(item.ItemID)) 514 item.ParentID = m_part.UUID;
515 item.ParentPartID = m_part.UUID;
516 item.Flags = m_items[item.ItemID].Flags;
517 if (item.AssetID == UUID.Zero)
493 { 518 {
494 item.ParentID = m_part.UUID; 519 item.AssetID = m_items[item.ItemID].AssetID;
495 item.ParentPartID = m_part.UUID; 520 }
496 item.Flags = m_items[item.ItemID].Flags; 521 else if ((InventoryType)item.Type == InventoryType.Notecard)
497 if (item.AssetID == UUID.Zero) 522 {
498 { 523 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
499 item.AssetID = m_items[item.ItemID].AssetID;
500 }
501 else if ((InventoryType)item.Type == InventoryType.Notecard)
502 {
503 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
504 524
505 if (presence != null) 525 if (presence != null)
506 { 526 {
507 presence.ControllingClient.SendAgentAlertMessage( 527 presence.ControllingClient.SendAgentAlertMessage(
508 "Notecard saved", false); 528 "Notecard saved", false);
509 }
510 } 529 }
530 }
511 531
512 m_items[item.ItemID] = item; 532 m_items[item.ItemID] = item;
513 m_inventorySerial++; 533 m_inventorySerial++;
514 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 534 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
515
516 HasInventoryChanged = true;
517 m_part.ParentGroup.HasGroupChanged = true;
518 535
519 return true; 536 HasInventoryChanged = true;
520 } 537 m_part.ParentGroup.HasGroupChanged = true;
521 else 538 m_items.LockItemsForWrite(false);
522 { 539 return true;
523 m_log.ErrorFormat( 540 }
524 "[PRIM INVENTORY]: " + 541 else
525 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", 542 {
526 item.ItemID, m_part.Name, m_part.UUID); 543 m_log.ErrorFormat(
527 } 544 "[PRIM INVENTORY]: " +
545 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
546 item.ItemID, m_part.Name, m_part.UUID);
528 } 547 }
548 m_items.LockItemsForWrite(false);
529 549
530 return false; 550 return false;
531 } 551 }
@@ -538,51 +558,54 @@ namespace OpenSim.Region.Framework.Scenes
538 /// in this prim's inventory.</returns> 558 /// in this prim's inventory.</returns>
539 public int RemoveInventoryItem(UUID itemID) 559 public int RemoveInventoryItem(UUID itemID)
540 { 560 {
541 lock (m_items) 561 m_items.LockItemsForRead(true);
562
563 if (m_items.ContainsKey(itemID))
542 { 564 {
543 if (m_items.ContainsKey(itemID)) 565 int type = m_items[itemID].InvType;
566 m_items.LockItemsForRead(false);
567 if (type == 10) // Script
544 { 568 {
545 int type = m_items[itemID].InvType; 569 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
546 if (type == 10) // Script 570 }
547 { 571 m_items.LockItemsForWrite(true);
548 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 572 m_items.Remove(itemID);
549 } 573 m_items.LockItemsForWrite(false);
550 m_items.Remove(itemID); 574 m_inventorySerial++;
551 m_inventorySerial++; 575 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
552 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
553
554 HasInventoryChanged = true;
555 m_part.ParentGroup.HasGroupChanged = true;
556 576
557 int scriptcount = 0; 577 HasInventoryChanged = true;
558 lock (m_items) 578 m_part.ParentGroup.HasGroupChanged = true;
559 {
560 foreach (TaskInventoryItem item in m_items.Values)
561 {
562 if (item.Type == 10)
563 {
564 scriptcount++;
565 }
566 }
567 }
568 579
569 if (scriptcount <= 0) 580 int scriptcount = 0;
581 m_items.LockItemsForRead(true);
582 foreach (TaskInventoryItem item in m_items.Values)
583 {
584 if (item.Type == 10)
570 { 585 {
571 m_part.RemFlag(PrimFlags.Scripted); 586 scriptcount++;
572 } 587 }
573
574 m_part.ScheduleFullUpdate();
575
576 return type;
577 } 588 }
578 else 589 m_items.LockItemsForRead(false);
590
591
592 if (scriptcount <= 0)
579 { 593 {
580 m_log.ErrorFormat( 594 m_part.RemFlag(PrimFlags.Scripted);
581 "[PRIM INVENTORY]: " +
582 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
583 itemID, m_part.Name, m_part.UUID);
584 } 595 }
596
597 m_part.ScheduleFullUpdate();
598
599 return type;
600 }
601 else
602 {
603 m_log.ErrorFormat(
604 "[PRIM INVENTORY]: " +
605 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
606 itemID, m_part.Name, m_part.UUID);
585 } 607 }
608 m_items.LockItemsForWrite(false);
586 609
587 return -1; 610 return -1;
588 } 611 }
@@ -635,52 +658,53 @@ namespace OpenSim.Region.Framework.Scenes
635 // isn't available (such as drag from prim inventory to agent inventory) 658 // isn't available (such as drag from prim inventory to agent inventory)
636 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 659 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
637 660
638 lock (m_items) 661 m_items.LockItemsForRead(true);
662
663 foreach (TaskInventoryItem item in m_items.Values)
639 { 664 {
640 foreach (TaskInventoryItem item in m_items.Values) 665 UUID ownerID = item.OwnerID;
641 { 666 uint everyoneMask = 0;
642 UUID ownerID = item.OwnerID; 667 uint baseMask = item.BasePermissions;
643 uint everyoneMask = 0; 668 uint ownerMask = item.CurrentPermissions;
644 uint baseMask = item.BasePermissions;
645 uint ownerMask = item.CurrentPermissions;
646 669
647 invString.AddItemStart(); 670 invString.AddItemStart();
648 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 671 invString.AddNameValueLine("item_id", item.ItemID.ToString());
649 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 672 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
650 673
651 invString.AddPermissionsStart(); 674 invString.AddPermissionsStart();
652 675
653 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 676 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
654 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 677 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
655 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 678 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
656 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 679 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
657 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 680 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
658 681
659 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 682 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
660 invString.AddNameValueLine("owner_id", ownerID.ToString()); 683 invString.AddNameValueLine("owner_id", ownerID.ToString());
661 684
662 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 685 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
663 686
664 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 687 invString.AddNameValueLine("group_id", item.GroupID.ToString());
665 invString.AddSectionEnd(); 688 invString.AddSectionEnd();
666 689
667 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 690 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
668 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 691 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
669 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 692 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
670 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 693 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
671 694
672 invString.AddSaleStart(); 695 invString.AddSaleStart();
673 invString.AddNameValueLine("sale_type", "not"); 696 invString.AddNameValueLine("sale_type", "not");
674 invString.AddNameValueLine("sale_price", "0"); 697 invString.AddNameValueLine("sale_price", "0");
675 invString.AddSectionEnd(); 698 invString.AddSectionEnd();
676 699
677 invString.AddNameValueLine("name", item.Name + "|"); 700 invString.AddNameValueLine("name", item.Name + "|");
678 invString.AddNameValueLine("desc", item.Description + "|"); 701 invString.AddNameValueLine("desc", item.Description + "|");
679 702
680 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 703 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
681 invString.AddSectionEnd(); 704 invString.AddSectionEnd();
682 }
683 } 705 }
706 int count = m_items.Count;
707 m_items.LockItemsForRead(false);
684 708
685 fileData = Utils.StringToBytes(invString.BuildString); 709 fileData = Utils.StringToBytes(invString.BuildString);
686 710
@@ -701,10 +725,9 @@ namespace OpenSim.Region.Framework.Scenes
701 { 725 {
702 if (HasInventoryChanged) 726 if (HasInventoryChanged)
703 { 727 {
704 lock (Items) 728 Items.LockItemsForRead(true);
705 { 729 datastore.StorePrimInventory(m_part.UUID, Items.Values);
706 datastore.StorePrimInventory(m_part.UUID, Items.Values); 730 Items.LockItemsForRead(false);
707 }
708 731
709 HasInventoryChanged = false; 732 HasInventoryChanged = false;
710 } 733 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5604e3d..cebd108 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -113,7 +115,9 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
117 private Vector3 m_lastPosition; 121 private Vector3 m_lastPosition;
118 private Quaternion m_lastRotation; 122 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 123 private Vector3 m_lastVelocity;
@@ -144,7 +148,6 @@ namespace OpenSim.Region.Framework.Scenes
144 private int m_perfMonMS; 148 private int m_perfMonMS;
145 149
146 private bool m_setAlwaysRun; 150 private bool m_setAlwaysRun;
147
148 private bool m_forceFly; 151 private bool m_forceFly;
149 private bool m_flyDisabled; 152 private bool m_flyDisabled;
150 153
@@ -168,7 +171,8 @@ namespace OpenSim.Region.Framework.Scenes
168 protected RegionInfo m_regionInfo; 171 protected RegionInfo m_regionInfo;
169 protected ulong crossingFromRegion; 172 protected ulong crossingFromRegion;
170 173
171 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 174 private readonly Vector3[] Dir_Vectors = new Vector3[11];
175 private bool m_isNudging = false;
172 176
173 // Position of agent's camera in world (region cordinates) 177 // Position of agent's camera in world (region cordinates)
174 protected Vector3 m_CameraCenter; 178 protected Vector3 m_CameraCenter;
@@ -203,6 +207,9 @@ namespace OpenSim.Region.Framework.Scenes
203 private bool m_followCamAuto; 207 private bool m_followCamAuto;
204 208
205 private int m_movementUpdateCount; 209 private int m_movementUpdateCount;
210 private int m_lastColCount = -1; //KF: Look for Collision chnages
211 private int m_updateCount = 0; //KF: Update Anims for a while
212 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
206 213
207 private const int NumMovementsBetweenRayCast = 5; 214 private const int NumMovementsBetweenRayCast = 5;
208 215
@@ -232,6 +239,10 @@ namespace OpenSim.Region.Framework.Scenes
232 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 239 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
233 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 240 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
234 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 241 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
242 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
243 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
244 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
245 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
235 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 246 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
236 } 247 }
237 248
@@ -658,9 +669,7 @@ namespace OpenSim.Region.Framework.Scenes
658 669
659 AdjustKnownSeeds(); 670 AdjustKnownSeeds();
660 671
661 // TODO: I think, this won't send anything, as we are still a child here... 672 Animator.TrySetMovementAnimation("STAND");
662 Animator.TrySetMovementAnimation("STAND");
663
664 // we created a new ScenePresence (a new child agent) in a fresh region. 673 // we created a new ScenePresence (a new child agent) in a fresh region.
665 // Request info about all the (root) agents in this region 674 // Request info about all the (root) agents in this region
666 // Note: This won't send data *to* other clients in that region (children don't send) 675 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -716,21 +725,47 @@ namespace OpenSim.Region.Framework.Scenes
716 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 725 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
717 Dir_Vectors[4] = Vector3.UnitZ; //UP 726 Dir_Vectors[4] = Vector3.UnitZ; //UP
718 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 727 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
719 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 728 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
729 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
730 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
731 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
732 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
720 } 733 }
721 734
722 private Vector3[] GetWalkDirectionVectors() 735 private Vector3[] GetWalkDirectionVectors()
723 { 736 {
724 Vector3[] vector = new Vector3[6]; 737 Vector3[] vector = new Vector3[11];
725 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 738 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
726 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 739 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
727 vector[2] = Vector3.UnitY; //LEFT 740 vector[2] = Vector3.UnitY; //LEFT
728 vector[3] = -Vector3.UnitY; //RIGHT 741 vector[3] = -Vector3.UnitY; //RIGHT
729 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 742 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
730 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 743 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 744 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
745 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
746 vector[8] = Vector3.UnitY; //LEFT_NUDGE
747 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
748 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
732 return vector; 749 return vector;
733 } 750 }
751
752 private bool[] GetDirectionIsNudge()
753 {
754 bool[] isNudge = new bool[11];
755 isNudge[0] = false; //FORWARD
756 isNudge[1] = false; //BACK
757 isNudge[2] = false; //LEFT
758 isNudge[3] = false; //RIGHT
759 isNudge[4] = false; //UP
760 isNudge[5] = false; //DOWN
761 isNudge[6] = true; //FORWARD_NUDGE
762 isNudge[7] = true; //BACK_NUDGE
763 isNudge[8] = true; //LEFT_NUDGE
764 isNudge[9] = true; //RIGHT_NUDGE
765 isNudge[10] = true; //DOWN_Nudge
766 return isNudge;
767 }
768
734 769
735 #endregion 770 #endregion
736 771
@@ -994,7 +1029,9 @@ namespace OpenSim.Region.Framework.Scenes
994 { 1029 {
995 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1030 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
996 } 1031 }
997 1032
1033 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1034
998 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1035 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
999 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1036 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1000 } 1037 }
@@ -1147,7 +1184,6 @@ namespace OpenSim.Region.Framework.Scenes
1147 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1184 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
1148 // return; 1185 // return;
1149 //} 1186 //}
1150
1151 m_perfMonMS = Environment.TickCount; 1187 m_perfMonMS = Environment.TickCount;
1152 1188
1153 ++m_movementUpdateCount; 1189 ++m_movementUpdateCount;
@@ -1229,7 +1265,6 @@ namespace OpenSim.Region.Framework.Scenes
1229 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1265 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1230 } 1266 }
1231 } 1267 }
1232
1233 lock (scriptedcontrols) 1268 lock (scriptedcontrols)
1234 { 1269 {
1235 if (scriptedcontrols.Count > 0) 1270 if (scriptedcontrols.Count > 0)
@@ -1244,9 +1279,7 @@ namespace OpenSim.Region.Framework.Scenes
1244 1279
1245 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1280 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1246 { 1281 {
1247 // TODO: This doesn't prevent the user from walking yet. 1282 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1248 // Setting parent ID would fix this, if we knew what value
1249 // to use. Or we could add a m_isSitting variable.
1250 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 1283 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1251 } 1284 }
1252 1285
@@ -1261,7 +1294,6 @@ namespace OpenSim.Region.Framework.Scenes
1261 { 1294 {
1262 return; 1295 return;
1263 } 1296 }
1264
1265 if (m_allowMovement) 1297 if (m_allowMovement)
1266 { 1298 {
1267 int i = 0; 1299 int i = 0;
@@ -1289,6 +1321,11 @@ namespace OpenSim.Region.Framework.Scenes
1289 update_rotation = true; 1321 update_rotation = true;
1290 } 1322 }
1291 1323
1324 //guilty until proven innocent..
1325 bool Nudging = true;
1326 //Basically, if there is at least one non-nudge control then we don't need
1327 //to worry about stopping the avatar
1328
1292 if (m_parentID == 0) 1329 if (m_parentID == 0)
1293 { 1330 {
1294 bool bAllowUpdateMoveToPosition = false; 1331 bool bAllowUpdateMoveToPosition = false;
@@ -1303,6 +1340,12 @@ namespace OpenSim.Region.Framework.Scenes
1303 else 1340 else
1304 dirVectors = Dir_Vectors; 1341 dirVectors = Dir_Vectors;
1305 1342
1343 bool[] isNudge = GetDirectionIsNudge();
1344
1345
1346
1347
1348
1306 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1349 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1307 { 1350 {
1308 if (((uint)flags & (uint)DCF) != 0) 1351 if (((uint)flags & (uint)DCF) != 0)
@@ -1312,6 +1355,10 @@ namespace OpenSim.Region.Framework.Scenes
1312 try 1355 try
1313 { 1356 {
1314 agent_control_v3 += dirVectors[i]; 1357 agent_control_v3 += dirVectors[i];
1358 if (isNudge[i] == false)
1359 {
1360 Nudging = false;
1361 }
1315 } 1362 }
1316 catch (IndexOutOfRangeException) 1363 catch (IndexOutOfRangeException)
1317 { 1364 {
@@ -1373,6 +1420,9 @@ namespace OpenSim.Region.Framework.Scenes
1373 // Ignore z component of vector 1420 // Ignore z component of vector
1374 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1421 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1375 LocalVectorToTarget2D.Normalize(); 1422 LocalVectorToTarget2D.Normalize();
1423
1424 //We're not nudging
1425 Nudging = false;
1376 agent_control_v3 += LocalVectorToTarget2D; 1426 agent_control_v3 += LocalVectorToTarget2D;
1377 1427
1378 // update avatar movement flags. the avatar coordinate system is as follows: 1428 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1455,7 +1505,7 @@ namespace OpenSim.Region.Framework.Scenes
1455 // m_log.DebugFormat( 1505 // m_log.DebugFormat(
1456 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1506 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1457 1507
1458 AddNewMovement(agent_control_v3, q); 1508 AddNewMovement(agent_control_v3, q, Nudging);
1459 1509
1460 if (update_movementflag) 1510 if (update_movementflag)
1461 Animator.UpdateMovementAnimations(); 1511 Animator.UpdateMovementAnimations();
@@ -1538,7 +1588,7 @@ namespace OpenSim.Region.Framework.Scenes
1538 Velocity = Vector3.Zero; 1588 Velocity = Vector3.Zero;
1539 SendFullUpdateToAllClients(); 1589 SendFullUpdateToAllClients();
1540 1590
1541 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1591 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1542 } 1592 }
1543 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1593 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1544 m_requestedSitTargetUUID = UUID.Zero; 1594 m_requestedSitTargetUUID = UUID.Zero;
@@ -1576,21 +1626,19 @@ namespace OpenSim.Region.Framework.Scenes
1576 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1626 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1577 if (part != null) 1627 if (part != null)
1578 { 1628 {
1629 part.TaskInventory.LockItemsForRead(true);
1579 TaskInventoryDictionary taskIDict = part.TaskInventory; 1630 TaskInventoryDictionary taskIDict = part.TaskInventory;
1580 if (taskIDict != null) 1631 if (taskIDict != null)
1581 { 1632 {
1582 lock (taskIDict) 1633 foreach (UUID taskID in taskIDict.Keys)
1583 { 1634 {
1584 foreach (UUID taskID in taskIDict.Keys) 1635 UnRegisterControlEventsToScript(LocalId, taskID);
1585 { 1636 taskIDict[taskID].PermsMask &= ~(
1586 UnRegisterControlEventsToScript(LocalId, taskID); 1637 2048 | //PERMISSION_CONTROL_CAMERA
1587 taskIDict[taskID].PermsMask &= ~( 1638 4); // PERMISSION_TAKE_CONTROLS
1588 2048 | //PERMISSION_CONTROL_CAMERA
1589 4); // PERMISSION_TAKE_CONTROLS
1590 }
1591 } 1639 }
1592
1593 } 1640 }
1641 part.TaskInventory.LockItemsForRead(false);
1594 // Reset sit target. 1642 // Reset sit target.
1595 if (part.GetAvatarOnSitTarget() == UUID) 1643 if (part.GetAvatarOnSitTarget() == UUID)
1596 part.SetAvatarOnSitTarget(UUID.Zero); 1644 part.SetAvatarOnSitTarget(UUID.Zero);
@@ -1603,9 +1651,9 @@ namespace OpenSim.Region.Framework.Scenes
1603 { 1651 {
1604 AddToPhysicalScene(false); 1652 AddToPhysicalScene(false);
1605 } 1653 }
1606
1607 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1654 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
1608 m_parentPosition = Vector3.Zero; 1655 m_parentPosition = Vector3.Zero;
1656//Console.WriteLine("Stand Pos {0}", m_pos);
1609 1657
1610 m_parentID = 0; 1658 m_parentID = 0;
1611 SendFullUpdateToAllClients(); 1659 SendFullUpdateToAllClients();
@@ -1651,7 +1699,7 @@ namespace OpenSim.Region.Framework.Scenes
1651 bool SitTargetisSet = 1699 bool SitTargetisSet =
1652 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f && 1700 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1653 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f)); 1701 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1654 1702 // this test is probably failing
1655 if (SitTargetisSet && SitTargetUnOccupied) 1703 if (SitTargetisSet && SitTargetUnOccupied)
1656 { 1704 {
1657 //switch the target to this prim 1705 //switch the target to this prim
@@ -1678,31 +1726,58 @@ namespace OpenSim.Region.Framework.Scenes
1678 { 1726 {
1679 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1727 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1680 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1728 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1681 1729
1730 // part is the prim to sit on
1731 // offset is the vector distance from that prim center to the click-spot
1732 // UUID is the UUID of the Avatar doing the clicking
1733
1734 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1735
1682 // Is a sit target available? 1736 // Is a sit target available?
1683 Vector3 avSitOffSet = part.SitTargetPosition; 1737 Vector3 avSitOffSet = part.SitTargetPosition;
1684 Quaternion avSitOrientation = part.SitTargetOrientation; 1738 Quaternion avSitOrientation = part.SitTargetOrientation;
1685 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1739 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1686 1740
1687 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1741 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1688 bool SitTargetisSet = 1742// bool SitTargetisSet =
1689 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && 1743// (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f &&
1690 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); 1744// avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f));
1691 1745
1692 if (SitTargetisSet && SitTargetUnOccupied) 1746 bool SitTargetisSet = ((Vector3.Zero != avSitOffSet) || (Quaternion.Identity != avSitOrientation));
1693 { 1747
1694 part.SetAvatarOnSitTarget(UUID); 1748//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied +
1695 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1749// " TargSet=" + SitTargetisSet);
1696 sitOrientation = avSitOrientation; 1750 // Sit analysis rewritten by KF 091125
1697 autopilot = false; 1751 if (SitTargetisSet) // scipted sit
1698 } 1752 {
1753 if (SitTargetUnOccupied)
1754 {
1755 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1756 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1757 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1758 autopilot = false; // Jump direct to scripted llSitPos()
1759 }
1760 else return;
1761 }
1762 else // Not Scripted
1763 {
1764 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) // large prim
1765 {
1766 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1767 m_avUnscriptedSitPos = offset * partIRot; // sit where clicked
1768 pos = part.AbsolutePosition + (offset * partIRot);
1769 }
1770 else // small prim
1771 {
1772 if (SitTargetUnOccupied)
1773 {
1774 m_avUnscriptedSitPos = Vector3.Zero; // Sit on unoccupied small prim center
1775 pos = part.AbsolutePosition;
1776 }
1777 else return; // occupied small
1778 } // end large/small
1779 } // end Scripted/not
1699 1780
1700 pos = part.AbsolutePosition + offset;
1701 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1702 //{
1703 // offset = pos;
1704 //autopilot = false;
1705 //}
1706 if (m_physicsActor != null) 1781 if (m_physicsActor != null)
1707 { 1782 {
1708 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1783 // If we're not using the client autopilot, we're immediately warping the avatar to the location
@@ -1710,17 +1785,17 @@ namespace OpenSim.Region.Framework.Scenes
1710 m_sitAvatarHeight = m_physicsActor.Size.Z; 1785 m_sitAvatarHeight = m_physicsActor.Size.Z;
1711 1786
1712 if (autopilot) 1787 if (autopilot)
1713 { 1788 { // its not a scripted sit
1714 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1789 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5)
1715 { 1790 {
1716 autopilot = false; 1791 autopilot = false; // close enough
1717 1792
1718 RemoveFromPhysicalScene(); 1793 RemoveFromPhysicalScene();
1719 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1794 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to Prim
1720 } 1795 } // else the autopilot will get us close
1721 } 1796 }
1722 else 1797 else
1723 { 1798 { // its a scripted sit
1724 RemoveFromPhysicalScene(); 1799 RemoveFromPhysicalScene();
1725 } 1800 }
1726 } 1801 }
@@ -1823,29 +1898,52 @@ namespace OpenSim.Region.Framework.Scenes
1823 { 1898 {
1824 if (part.GetAvatarOnSitTarget() == UUID) 1899 if (part.GetAvatarOnSitTarget() == UUID)
1825 { 1900 {
1901 // Scripted sit
1826 Vector3 sitTargetPos = part.SitTargetPosition; 1902 Vector3 sitTargetPos = part.SitTargetPosition;
1827 Quaternion sitTargetOrient = part.SitTargetOrientation; 1903 Quaternion sitTargetOrient = part.SitTargetOrientation;
1828
1829 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
1830 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
1831
1832 //Quaternion result = (sitTargetOrient * vq) * nq;
1833
1834 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 1904 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
1835 m_pos += SIT_TARGET_ADJUSTMENT; 1905 m_pos += SIT_TARGET_ADJUSTMENT;
1836 m_bodyRot = sitTargetOrient; 1906 m_bodyRot = sitTargetOrient;
1837 //Rotation = sitTargetOrient;
1838 m_parentPosition = part.AbsolutePosition; 1907 m_parentPosition = part.AbsolutePosition;
1839
1840 //SendTerseUpdateToAllClients();
1841 } 1908 }
1842 else 1909 else
1843 { 1910 {
1844 m_pos -= part.AbsolutePosition; 1911 // Non-scripted sit by Kitto Flora 21Nov09
1912 // Calculate angle of line from prim to Av
1913 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
1914 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
1915 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
1916 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
1917 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
1918 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
1919 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1920 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
1921 // Av sits at world euler <0,0, z>, translated by part rotation
1922 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
1845 m_parentPosition = part.AbsolutePosition; 1923 m_parentPosition = part.AbsolutePosition;
1846 } 1924 if(m_avUnscriptedSitPos != Vector3.Zero)
1847 } 1925 { // sit where clicked on big prim
1848 else 1926 m_pos = m_avUnscriptedSitPos + (new Vector3(0.0f, 0f, 0.625f) * partIRot);
1927 }
1928 else
1929 { // sit at center of small prim
1930 m_pos = new Vector3(0f, 0f, 0.05f) +
1931 (new Vector3(0.0f, 0f, 0.625f) * partIRot) +
1932 (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot);
1933 //Set up raytrace to find top surface of prim
1934 Vector3 size = part.Scale;
1935 float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
1936 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
1937 Vector3 down = new Vector3(0f, 0f, -1f);
1938 m_scene.PhysicsScene.RaycastWorld(
1939 start, // Vector3 position,
1940 down, // Vector3 direction,
1941 mag, // float length,
1942 SitAltitudeCallback); // retMethod
1943 } // end small/big
1944 } // end scripted/not
1945 }
1946 else // no Av
1849 { 1947 {
1850 return; 1948 return;
1851 } 1949 }
@@ -1857,11 +1955,21 @@ namespace OpenSim.Region.Framework.Scenes
1857 1955
1858 Animator.TrySetMovementAnimation(sitAnimation); 1956 Animator.TrySetMovementAnimation(sitAnimation);
1859 SendFullUpdateToAllClients(); 1957 SendFullUpdateToAllClients();
1860 // This may seem stupid, but Our Full updates don't send avatar rotation :P
1861 // So we're also sending a terse update (which has avatar rotation)
1862 // [Update] We do now.
1863 //SendTerseUpdateToAllClients();
1864 } 1958 }
1959
1960 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance)
1961 {
1962 if(hitYN)
1963 {
1964 // m_pos = Av offset from prim center to make look like on center
1965 // m_parentPosition = Actual center pos of prim
1966 // collisionPoint = spot on prim where we want to sit
1967 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
1968 Vector3 offset = (collisionPoint - m_parentPosition) * Quaternion.Inverse(part.RotationOffset);
1969 m_pos += offset;
1970// Console.WriteLine("m_pos={0}, offset={1} newsit={2}", m_pos, offset, newsit);
1971 }
1972 }
1865 1973
1866 /// <summary> 1974 /// <summary>
1867 /// Event handler for the 'Always run' setting on the client 1975 /// Event handler for the 'Always run' setting on the client
@@ -1891,7 +1999,7 @@ namespace OpenSim.Region.Framework.Scenes
1891 /// </summary> 1999 /// </summary>
1892 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2000 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
1893 /// <param name="rotation">The direction in which this avatar should now face. 2001 /// <param name="rotation">The direction in which this avatar should now face.
1894 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2002 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
1895 { 2003 {
1896 if (m_isChildAgent) 2004 if (m_isChildAgent)
1897 { 2005 {
@@ -1965,7 +2073,7 @@ namespace OpenSim.Region.Framework.Scenes
1965 2073
1966 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2074 // TODO: Add the force instead of only setting it to support multiple forces per frame?
1967 m_forceToApply = direc; 2075 m_forceToApply = direc;
1968 2076 m_isNudging = Nudging;
1969 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2077 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
1970 } 2078 }
1971 2079
@@ -1980,7 +2088,7 @@ namespace OpenSim.Region.Framework.Scenes
1980 const float POSITION_TOLERANCE = 0.05f; 2088 const float POSITION_TOLERANCE = 0.05f;
1981 //const int TIME_MS_TOLERANCE = 3000; 2089 //const int TIME_MS_TOLERANCE = 3000;
1982 2090
1983 SendPrimUpdates(); 2091
1984 2092
1985 if (m_newCoarseLocations) 2093 if (m_newCoarseLocations)
1986 { 2094 {
@@ -2016,6 +2124,9 @@ namespace OpenSim.Region.Framework.Scenes
2016 CheckForBorderCrossing(); 2124 CheckForBorderCrossing();
2017 CheckForSignificantMovement(); // sends update to the modules. 2125 CheckForSignificantMovement(); // sends update to the modules.
2018 } 2126 }
2127
2128 //Sending prim updates AFTER the avatar terse updates are sent
2129 SendPrimUpdates();
2019 } 2130 }
2020 2131
2021 #endregion 2132 #endregion
@@ -2869,14 +2980,25 @@ namespace OpenSim.Region.Framework.Scenes
2869 { 2980 {
2870 if (m_forceToApply.HasValue) 2981 if (m_forceToApply.HasValue)
2871 { 2982 {
2872 Vector3 force = m_forceToApply.Value;
2873 2983
2984 Vector3 force = m_forceToApply.Value;
2874 m_updateflag = true; 2985 m_updateflag = true;
2875// movementvector = force;
2876 Velocity = force; 2986 Velocity = force;
2877 2987
2878 m_forceToApply = null; 2988 m_forceToApply = null;
2879 } 2989 }
2990 else
2991 {
2992 if (m_isNudging)
2993 {
2994 Vector3 force = Vector3.Zero;
2995
2996 m_updateflag = true;
2997 Velocity = force;
2998 m_isNudging = false;
2999 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3000 }
3001 }
2880 } 3002 }
2881 3003
2882 public override void SetText(string text, Vector3 color, double alpha) 3004 public override void SetText(string text, Vector3 color, double alpha)
@@ -2926,19 +3048,29 @@ namespace OpenSim.Region.Framework.Scenes
2926 // Event called by the physics plugin to tell the avatar about a collision. 3048 // Event called by the physics plugin to tell the avatar about a collision.
2927 private void PhysicsCollisionUpdate(EventArgs e) 3049 private void PhysicsCollisionUpdate(EventArgs e)
2928 { 3050 {
3051 if (m_updateCount > 0) //KF: Update Anims for a short period. Many Anim
3052 { // changes are very asynchronous.
3053 Animator.UpdateMovementAnimations();
3054 m_updateCount--;
3055 }
3056
2929 if (e == null) 3057 if (e == null)
2930 return; 3058 return;
2931 3059
2932 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
2933 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( 3060 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
2934 // as of this comment the interval is set in AddToPhysicalScene 3061 // as of this comment the interval is set in AddToPhysicalScene
2935 Animator.UpdateMovementAnimations(); 3062
2936
2937 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3063 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
2938 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3064 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
2939 3065
2940 CollisionPlane = Vector4.UnitW; 3066 CollisionPlane = Vector4.UnitW;
2941 3067
3068 if (m_lastColCount != coldata.Count)
3069 {
3070 m_updateCount = 10;
3071 m_lastColCount = coldata.Count;
3072 }
3073
2942 if (coldata.Count != 0) 3074 if (coldata.Count != 0)
2943 { 3075 {
2944 switch (Animator.CurrentMovementAnimation) 3076 switch (Animator.CurrentMovementAnimation)
@@ -3585,4 +3717,4 @@ namespace OpenSim.Region.Framework.Scenes
3585 } 3717 }
3586 } 3718 }
3587 } 3719 }
3588} \ No newline at end of file 3720}
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
index 8df997e..f411dd7 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
@@ -303,6 +303,26 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
303 set { return; } 303 set { return; }
304 } 304 }
305 305
306 public override Quaternion APIDTarget
307 {
308 set { return; }
309 }
310
311 public override bool APIDActive
312 {
313 set { return; }
314 }
315
316 public override float APIDStrength
317 {
318 set { return; }
319 }
320
321 public override float APIDDamping
322 {
323 set { return; }
324 }
325
306 public override void SubscribeEvents(int ms) 326 public override void SubscribeEvents(int ms)
307 { 327 {
308 } 328 }
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
index 5ed3b14..98681d6 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs
@@ -619,6 +619,12 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
619 { 619 {
620 set { return; } 620 set { return; }
621 } 621 }
622
623 public override Quaternion APIDTarget { set { return; } }
624 public override bool APIDActive { set { return; } }
625 public override float APIDStrength { set { return; } }
626 public override float APIDDamping { set { return; } }
627
622 628
623 /// <summary> 629 /// <summary>
624 /// Adds the force supplied to the Target Velocity 630 /// Adds the force supplied to the Target Velocity
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
index 5b542db..d931f126 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs
@@ -565,6 +565,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
565 public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } 565 public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
566 public override float PIDHoverTau { set { m_PIDHoverTau = value; } } 566 public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
567 567
568 public override Quaternion APIDTarget { set { return; } }
569 public override bool APIDActive { set { return; } }
570 public override float APIDStrength { set { return; } }
571 public override float APIDDamping { set { return; } }
572
568 573
569 public override void AddForce(Vector3 force, bool pushforce) 574 public override void AddForce(Vector3 force, bool pushforce)
570 { 575 {
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index 1e94ee2..d5d146e 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -1238,6 +1238,26 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1238 public override PIDHoverType PIDHoverType { set { return; } } 1238 public override PIDHoverType PIDHoverType { set { return; } }
1239 public override float PIDHoverTau { set { return; } } 1239 public override float PIDHoverTau { set { return; } }
1240 1240
1241 public override OpenMetaverse.Quaternion APIDTarget
1242 {
1243 set { return; }
1244 }
1245
1246 public override bool APIDActive
1247 {
1248 set { return; }
1249 }
1250
1251 public override float APIDStrength
1252 {
1253 set { return; }
1254 }
1255
1256 public override float APIDDamping
1257 {
1258 set { return; }
1259 }
1260
1241 1261
1242 public override void SubscribeEvents(int ms) 1262 public override void SubscribeEvents(int ms)
1243 { 1263 {
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index f58129d..b82586f 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -243,7 +243,12 @@ namespace OpenSim.Region.Physics.Manager
243 public abstract PIDHoverType PIDHoverType { set;} 243 public abstract PIDHoverType PIDHoverType { set;}
244 public abstract float PIDHoverTau { set;} 244 public abstract float PIDHoverTau { set;}
245 245
246 246 // For RotLookAt
247 public abstract Quaternion APIDTarget { set;}
248 public abstract bool APIDActive { set;}
249 public abstract float APIDStrength { set;}
250 public abstract float APIDDamping { set;}
251
247 public abstract void AddForce(Vector3 force, bool pushforce); 252 public abstract void AddForce(Vector3 force, bool pushforce);
248 public abstract void AddAngularForce(Vector3 force, bool pushforce); 253 public abstract void AddAngularForce(Vector3 force, bool pushforce);
249 public abstract void SetMomentum(Vector3 momentum); 254 public abstract void SetMomentum(Vector3 momentum);
@@ -476,6 +481,12 @@ namespace OpenSim.Region.Physics.Manager
476 public override bool PIDHoverActive { set { return; } } 481 public override bool PIDHoverActive { set { return; } }
477 public override PIDHoverType PIDHoverType { set { return; } } 482 public override PIDHoverType PIDHoverType { set { return; } }
478 public override float PIDHoverTau { set { return; } } 483 public override float PIDHoverTau { set { return; } }
484
485 public override Quaternion APIDTarget { set { return; } }
486 public override bool APIDActive { set { return; } }
487 public override float APIDStrength { set { return; } }
488 public override float APIDDamping { set { return; } }
489
479 490
480 public override void SetMomentum(Vector3 momentum) 491 public override void SetMomentum(Vector3 momentum)
481 { 492 {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 1bc4a25..905d3ba 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1196,6 +1196,28 @@ namespace OpenSim.Region.Physics.OdePlugin
1196 public override bool PIDHoverActive { set { return; } } 1196 public override bool PIDHoverActive { set { return; } }
1197 public override PIDHoverType PIDHoverType { set { return; } } 1197 public override PIDHoverType PIDHoverType { set { return; } }
1198 public override float PIDHoverTau { set { return; } } 1198 public override float PIDHoverTau { set { return; } }
1199
1200 public override Quaternion APIDTarget
1201 {
1202 set { return; }
1203 }
1204
1205 public override bool APIDActive
1206 {
1207 set { return; }
1208 }
1209
1210 public override float APIDStrength
1211 {
1212 set { return; }
1213 }
1214
1215 public override float APIDDamping
1216 {
1217 set { return; }
1218 }
1219
1220
1199 1221
1200 public override void SubscribeEvents(int ms) 1222 public override void SubscribeEvents(int ms)
1201 { 1223 {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
index 39cdc0f..78b15be 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
@@ -23,6 +23,19 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
28 * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
29 * ODEPrim.cs contains methods dealing with Prim editing, Prim
30 * characteristics and Kinetic motion.
31 * ODEDynamics.cs contains methods dealing with Prim Physical motion
32 * (dynamics) and the associated settings. Old Linear and angular
33 * motors for dynamic motion have been replace with MoveLinear()
34 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
35 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
36 * switch between 'VEHICLE' parameter use and general dynamics
37 * settings use.
38 *
26 */ 39 */
27 40
28/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces 41/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
@@ -120,7 +133,7 @@ namespace OpenSim.Region.Physics.OdePlugin
120// private float m_VhoverEfficiency = 0f; 133// private float m_VhoverEfficiency = 0f;
121 private float m_VhoverTimescale = 0f; 134 private float m_VhoverTimescale = 0f;
122 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height 135 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
123 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. 136 private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle.
124 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) 137 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
125 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. 138 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
126 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. 139 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
@@ -479,7 +492,7 @@ namespace OpenSim.Region.Physics.OdePlugin
479 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object 492 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
480 m_dir *= rotq; // apply obj rotation to velocity vector 493 m_dir *= rotq; // apply obj rotation to velocity vector
481 494
482 // add Gravity andBuoyancy 495 // add Gravity and Buoyancy
483 // KF: So far I have found no good method to combine a script-requested 496 // KF: So far I have found no good method to combine a script-requested
484 // .Z velocity and gravity. Therefore only 0g will used script-requested 497 // .Z velocity and gravity. Therefore only 0g will used script-requested
485 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. 498 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
@@ -561,6 +574,7 @@ namespace OpenSim.Region.Physics.OdePlugin
561 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate 574 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
562 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body 575 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
563 */ 576 */
577//if(frcount == 0) Console.WriteLine("MoveAngular ");
564 578
565 // Get what the body is doing, this includes 'external' influences 579 // Get what the body is doing, this includes 'external' influences
566 d.Vector3 angularVelocity = d.BodyGetAngularVel(Body); 580 d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
@@ -636,7 +650,7 @@ namespace OpenSim.Region.Physics.OdePlugin
636 // Deflection section tba 650 // Deflection section tba
637 651
638 // Sum velocities 652 // Sum velocities
639 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection 653 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection
640 654
641 if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 655 if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
642 { 656 {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 9e9c36f..8459dab 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -21,6 +21,18 @@
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
26 * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
27 * ODEPrim.cs contains methods dealing with Prim editing, Prim
28 * characteristics and Kinetic motion.
29 * ODEDynamics.cs contains methods dealing with Prim Physical motion
30 * (dynamics) and the associated settings. Old Linear and angular
31 * motors for dynamic motion have been replace with MoveLinear()
32 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
33 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
34 * switch between 'VEHICLE' parameter use and general dynamics
35 * settings use.
24 */ 36 */
25 37
26/* 38/*
@@ -81,7 +93,12 @@ namespace OpenSim.Region.Physics.OdePlugin
81 private float m_PIDTau; 93 private float m_PIDTau;
82 private float PID_D = 35f; 94 private float PID_D = 35f;
83 private float PID_G = 25f; 95 private float PID_G = 25f;
84 private bool m_usePID; 96 private bool m_usePID = false;
97
98 private Quaternion m_APIDTarget = new Quaternion();
99 private float m_APIDStrength = 0.5f;
100 private float m_APIDDamping = 0.5f;
101 private bool m_useAPID = false;
85 102
86 // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), 103 // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
87 // and are for non-VEHICLES only. 104 // and are for non-VEHICLES only.
@@ -182,6 +199,9 @@ namespace OpenSim.Region.Physics.OdePlugin
182 private ODEDynamics m_vehicle; 199 private ODEDynamics m_vehicle;
183 200
184 internal int m_material = (int)Material.Wood; 201 internal int m_material = (int)Material.Wood;
202
203 private int frcount = 0; // Used to limit dynamics debug output to
204
185 205
186 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, 206 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
187 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) 207 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
@@ -1558,9 +1578,14 @@ Console.WriteLine(" JointCreateFixed");
1558 float fy = 0; 1578 float fy = 0;
1559 float fz = 0; 1579 float fz = 0;
1560 1580
1581 frcount++; // used to limit debug comment output
1582 if (frcount > 100)
1583 frcount = 0;
1561 1584
1562 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. 1585 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
1563 { 1586 {
1587//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type +
1588 // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID);
1564 if (m_vehicle.Type != Vehicle.TYPE_NONE) 1589 if (m_vehicle.Type != Vehicle.TYPE_NONE)
1565 { 1590 {
1566 // 'VEHICLES' are dealt with in ODEDynamics.cs 1591 // 'VEHICLES' are dealt with in ODEDynamics.cs
@@ -1568,7 +1593,6 @@ Console.WriteLine(" JointCreateFixed");
1568 } 1593 }
1569 else 1594 else
1570 { 1595 {
1571//Console.WriteLine("Move " + m_primName);
1572 if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 1596 if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
1573 // NON-'VEHICLES' are dealt with here 1597 // NON-'VEHICLES' are dealt with here
1574 if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) 1598 if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
@@ -1590,21 +1614,18 @@ Console.WriteLine(" JointCreateFixed");
1590 //m_log.Info(m_collisionFlags.ToString()); 1614 //m_log.Info(m_collisionFlags.ToString());
1591 1615
1592 1616
1593 //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 1617 //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle.
1594 // would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ??
1595 // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up 1618 // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up
1596 // gravityz multiplier = 1 - m_buoyancy 1619 // NB Prims in ODE are no subject to global gravity
1597 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; 1620 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass
1598 1621
1599 if (m_usePID) 1622 if (m_usePID)
1600 { 1623 {
1601//Console.WriteLine("PID " + m_primName); 1624//if(frcount == 0) Console.WriteLine("PID " + m_primName);
1602 // KF - this is for object move? eg. llSetPos() ? 1625 // KF - this is for object MoveToTarget.
1626
1603 //if (!d.BodyIsEnabled(Body)) 1627 //if (!d.BodyIsEnabled(Body))
1604 //d.BodySetForce(Body, 0f, 0f, 0f); 1628 //d.BodySetForce(Body, 0f, 0f, 0f);
1605 // If we're using the PID controller, then we have no gravity
1606 //fz = (-1 * _parent_scene.gravityz) * m_mass; //KF: ?? Prims have no global gravity,so simply...
1607 fz = 0f;
1608 1629
1609 // no lock; for now it's only called from within Simulate() 1630 // no lock; for now it's only called from within Simulate()
1610 1631
@@ -1739,7 +1760,7 @@ Console.WriteLine(" JointCreateFixed");
1739 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); 1760 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
1740 d.BodySetLinearVel(Body, vel.X, vel.Y, 0); 1761 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
1741 d.BodyAddForce(Body, 0, 0, fz); 1762 d.BodyAddForce(Body, 0, 0, fz);
1742 return; 1763 //KF this prevents furthur motions return;
1743 } 1764 }
1744 else 1765 else
1745 { 1766 {
@@ -1748,8 +1769,46 @@ Console.WriteLine(" JointCreateFixed");
1748 // We're flying and colliding with something 1769 // We're flying and colliding with something
1749 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); 1770 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
1750 } 1771 }
1751 } 1772 } // end m_useHoverPID && !m_usePID
1752 1773
1774 if (m_useAPID)
1775 {
1776 // RotLookAt, apparently overrides all other rotation sources. Inputs:
1777 // Quaternion m_APIDTarget
1778 // float m_APIDStrength // From SL experiments, this is the time to get there
1779 // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly
1780 // Also in SL the mass of the object has no effect on time to get there.
1781 // Factors:
1782//if(frcount == 0) Console.WriteLine("APID ");
1783 // get present body rotation
1784 float limit = 1.0f;
1785 float scaler = 50f; // adjusts damping time
1786 float RLAservo = 0f;
1787
1788 d.Quaternion rot = d.BodyGetQuaternion(Body);
1789 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
1790 Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget;
1791 float diff_angle;
1792 Vector3 diff_axis;
1793 rot_diff.GetAxisAngle(out diff_axis, out diff_angle);
1794 diff_axis.Normalize();
1795 if(diff_angle > 0.01f) // diff_angle is always +ve
1796 {
1797// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z);
1798 Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z);
1799 rotforce = rotforce * rotq;
1800 if(diff_angle > limit) diff_angle = limit; // cap the rotate rate
1801// RLAservo = timestep / m_APIDStrength * m_mass * scaler;
1802 // rotforce = rotforce * RLAservo * diff_angle ;
1803 // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z);
1804 RLAservo = timestep / m_APIDStrength * scaler;
1805 rotforce = rotforce * RLAservo * diff_angle ;
1806 d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z);
1807//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo);
1808 }
1809//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle);
1810 } // end m_useAPID
1811
1753 fx *= m_mass; 1812 fx *= m_mass;
1754 fy *= m_mass; 1813 fy *= m_mass;
1755 //fz *= m_mass; 1814 //fz *= m_mass;
@@ -2819,6 +2878,12 @@ Console.WriteLine(" JointCreateFixed");
2819 } 2878 }
2820 public override bool PIDActive { set { m_usePID = value; } } 2879 public override bool PIDActive { set { m_usePID = value; } }
2821 public override float PIDTau { set { m_PIDTau = value; } } 2880 public override float PIDTau { set { m_PIDTau = value; } }
2881
2882 // For RotLookAt
2883 public override Quaternion APIDTarget { set { m_APIDTarget = value; } }
2884 public override bool APIDActive { set { m_useAPID = value; } }
2885 public override float APIDStrength { set { m_APIDStrength = value; } }
2886 public override float APIDDamping { set { m_APIDDamping = value; } }
2822 2887
2823 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } 2888 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
2824 public override bool PIDHoverActive { set { m_useHoverPID = value; } } 2889 public override bool PIDHoverActive { set { m_useHoverPID = value; } }
diff --git a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
index 26cd1dd..566b4e7 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs
@@ -304,6 +304,27 @@ namespace OpenSim.Region.Physics.POSPlugin
304 { 304 {
305 set { return; } 305 set { return; }
306 } 306 }
307
308 public override Quaternion APIDTarget
309 {
310 set { return; }
311 }
312
313 public override bool APIDActive
314 {
315 set { return; }
316 }
317
318 public override float APIDStrength
319 {
320 set { return; }
321 }
322
323 public override float APIDDamping
324 {
325 set { return; }
326 }
327
307 328
308 public override void SubscribeEvents(int ms) 329 public override void SubscribeEvents(int ms)
309 { 330 {
diff --git a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
index 96c3e26..847b634 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs
@@ -299,6 +299,26 @@ namespace OpenSim.Region.Physics.POSPlugin
299 { 299 {
300 set { return; } 300 set { return; }
301 } 301 }
302 public override Quaternion APIDTarget
303 {
304 set { return; }
305 }
306
307 public override bool APIDActive
308 {
309 set { return; }
310 }
311
312 public override float APIDStrength
313 {
314 set { return; }
315 }
316
317 public override float APIDDamping
318 {
319 set { return; }
320 }
321
302 322
303 public override void SubscribeEvents(int ms) 323 public override void SubscribeEvents(int ms)
304 { 324 {
diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
index 8bdb18d..24eb6b1 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
@@ -498,6 +498,28 @@ namespace OpenSim.Region.Physics.PhysXPlugin
498 public override bool PIDHoverActive { set { return; } } 498 public override bool PIDHoverActive { set { return; } }
499 public override PIDHoverType PIDHoverType { set { return; } } 499 public override PIDHoverType PIDHoverType { set { return; } }
500 public override float PIDHoverTau { set { return; } } 500 public override float PIDHoverTau { set { return; } }
501
502 public override Quaternion APIDTarget
503 {
504 set { return; }
505 }
506
507 public override bool APIDActive
508 {
509 set { return; }
510 }
511
512 public override float APIDStrength
513 {
514 set { return; }
515 }
516
517 public override float APIDDamping
518 {
519 set { return; }
520 }
521
522
501 523
502 public override void SubscribeEvents(int ms) 524 public override void SubscribeEvents(int ms)
503 { 525 {
@@ -780,6 +802,28 @@ namespace OpenSim.Region.Physics.PhysXPlugin
780 public override bool PIDHoverActive { set { return; } } 802 public override bool PIDHoverActive { set { return; } }
781 public override PIDHoverType PIDHoverType { set { return; } } 803 public override PIDHoverType PIDHoverType { set { return; } }
782 public override float PIDHoverTau { set { return; } } 804 public override float PIDHoverTau { set { return; } }
805
806 public override Quaternion APIDTarget
807 {
808 set { return; }
809 }
810
811 public override bool APIDActive
812 {
813 set { return; }
814 }
815
816 public override float APIDStrength
817 {
818 set { return; }
819 }
820
821 public override float APIDDamping
822 {
823 set { return; }
824 }
825
826
783 827
784 public override void SubscribeEvents(int ms) 828 public override void SubscribeEvents(int ms)
785 { 829 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index d235bac..ec771e3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -151,6 +152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
151 get { return m_ScriptEngine.World; } 152 get { return m_ScriptEngine.World; }
152 } 153 }
153 154
155 [DebuggerNonUserCode]
154 public void state(string newState) 156 public void state(string newState)
155 { 157 {
156 m_ScriptEngine.SetState(m_itemID, newState); 158 m_ScriptEngine.SetState(m_itemID, newState);
@@ -160,6 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
160 /// Reset the named script. The script must be present 162 /// Reset the named script. The script must be present
161 /// in the same prim. 163 /// in the same prim.
162 /// </summary> 164 /// </summary>
165 [DebuggerNonUserCode]
163 public void llResetScript() 166 public void llResetScript()
164 { 167 {
165 m_host.AddScriptLPS(1); 168 m_host.AddScriptLPS(1);
@@ -272,40 +275,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
272 protected UUID InventorySelf() 275 protected UUID InventorySelf()
273 { 276 {
274 UUID invItemID = new UUID(); 277 UUID invItemID = new UUID();
275 278 bool unlock = false;
276 lock (m_host.TaskInventory) 279 if (!m_host.TaskInventory.IsReadLockedByMe())
280 {
281 m_host.TaskInventory.LockItemsForRead(true);
282 unlock = true;
283 }
284 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
277 { 285 {
278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 286 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
279 { 287 {
280 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 288 invItemID = inv.Key;
281 { 289 break;
282 invItemID = inv.Key;
283 break;
284 }
285 } 290 }
286 } 291 }
287 292 if (unlock)
293 {
294 m_host.TaskInventory.LockItemsForRead(false);
295 }
288 return invItemID; 296 return invItemID;
289 } 297 }
290 298
291 protected UUID InventoryKey(string name, int type) 299 protected UUID InventoryKey(string name, int type)
292 { 300 {
293 m_host.AddScriptLPS(1); 301 m_host.AddScriptLPS(1);
294 302 m_host.TaskInventory.LockItemsForRead(true);
295 lock (m_host.TaskInventory) 303
304 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
296 { 305 {
297 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 306 if (inv.Value.Name == name)
298 { 307 {
299 if (inv.Value.Name == name) 308 m_host.TaskInventory.LockItemsForRead(false);
309
310 if (inv.Value.Type != type)
300 { 311 {
301 if (inv.Value.Type != type) 312 return UUID.Zero;
302 return UUID.Zero;
303
304 return inv.Value.AssetID;
305 } 313 }
314
315 return inv.Value.AssetID;
306 } 316 }
307 } 317 }
308 318
319 m_host.TaskInventory.LockItemsForRead(false);
309 return UUID.Zero; 320 return UUID.Zero;
310 } 321 }
311 322
@@ -313,17 +324,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
313 { 324 {
314 m_host.AddScriptLPS(1); 325 m_host.AddScriptLPS(1);
315 326
316 lock (m_host.TaskInventory) 327
328 m_host.TaskInventory.LockItemsForRead(true);
329
330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
317 { 331 {
318 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 332 if (inv.Value.Name == name)
319 { 333 {
320 if (inv.Value.Name == name) 334 m_host.TaskInventory.LockItemsForRead(false);
321 { 335 return inv.Value.AssetID;
322 return inv.Value.AssetID;
323 }
324 } 336 }
325 } 337 }
326 338
339 m_host.TaskInventory.LockItemsForRead(false);
340
341
327 return UUID.Zero; 342 return UUID.Zero;
328 } 343 }
329 344
@@ -2555,12 +2570,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2555 2570
2556 m_host.AddScriptLPS(1); 2571 m_host.AddScriptLPS(1);
2557 2572
2573 m_host.TaskInventory.LockItemsForRead(true);
2558 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2574 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2559 2575 m_host.TaskInventory.LockItemsForRead(false);
2560 lock (m_host.TaskInventory)
2561 {
2562 item = m_host.TaskInventory[invItemID];
2563 }
2564 2576
2565 if (item.PermsGranter == UUID.Zero) 2577 if (item.PermsGranter == UUID.Zero)
2566 return 0; 2578 return 0;
@@ -2635,6 +2647,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2635 if (dist > m_ScriptDistanceFactor * 10.0f) 2647 if (dist > m_ScriptDistanceFactor * 10.0f)
2636 return; 2648 return;
2637 2649
2650 //Clone is thread-safe
2638 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2651 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2639 2652
2640 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2653 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2720,11 +2733,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2720 // Orient the object to the angle calculated 2733 // Orient the object to the angle calculated
2721 llSetRot(rot); 2734 llSetRot(rot);
2722 } 2735 }
2736
2737 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
2738 {
2739 m_host.AddScriptLPS(1);
2740// NotImplemented("llRotLookAt");
2741 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
2742
2743 }
2744
2723 2745
2724 public void llStopLookAt() 2746 public void llStopLookAt()
2725 { 2747 {
2726 m_host.AddScriptLPS(1); 2748 m_host.AddScriptLPS(1);
2727 NotImplemented("llStopLookAt"); 2749// NotImplemented("llStopLookAt");
2750 m_host.StopLookAt();
2728 } 2751 }
2729 2752
2730 public void llSetTimerEvent(double sec) 2753 public void llSetTimerEvent(double sec)
@@ -2758,13 +2781,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2758 { 2781 {
2759 TaskInventoryItem item; 2782 TaskInventoryItem item;
2760 2783
2761 lock (m_host.TaskInventory) 2784 m_host.TaskInventory.LockItemsForRead(true);
2785 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2762 { 2786 {
2763 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2787 m_host.TaskInventory.LockItemsForRead(false);
2764 return; 2788 return;
2765 else 2789 }
2766 item = m_host.TaskInventory[InventorySelf()]; 2790 else
2791 {
2792 item = m_host.TaskInventory[InventorySelf()];
2767 } 2793 }
2794 m_host.TaskInventory.LockItemsForRead(false);
2768 2795
2769 if (item.PermsGranter != UUID.Zero) 2796 if (item.PermsGranter != UUID.Zero)
2770 { 2797 {
@@ -2786,13 +2813,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2786 { 2813 {
2787 TaskInventoryItem item; 2814 TaskInventoryItem item;
2788 2815
2816 m_host.TaskInventory.LockItemsForRead(true);
2789 lock (m_host.TaskInventory) 2817 lock (m_host.TaskInventory)
2790 { 2818 {
2819
2791 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2820 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2821 {
2822 m_host.TaskInventory.LockItemsForRead(false);
2792 return; 2823 return;
2824 }
2793 else 2825 else
2826 {
2794 item = m_host.TaskInventory[InventorySelf()]; 2827 item = m_host.TaskInventory[InventorySelf()];
2828 }
2795 } 2829 }
2830 m_host.TaskInventory.LockItemsForRead(false);
2796 2831
2797 m_host.AddScriptLPS(1); 2832 m_host.AddScriptLPS(1);
2798 2833
@@ -2829,13 +2864,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2829 2864
2830 TaskInventoryItem item; 2865 TaskInventoryItem item;
2831 2866
2832 lock (m_host.TaskInventory) 2867 m_host.TaskInventory.LockItemsForRead(true);
2868
2869 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2833 { 2870 {
2834 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2871 m_host.TaskInventory.LockItemsForRead(false);
2835 return; 2872 return;
2836 else
2837 item = m_host.TaskInventory[InventorySelf()];
2838 } 2873 }
2874 else
2875 {
2876 item = m_host.TaskInventory[InventorySelf()];
2877 }
2878
2879 m_host.TaskInventory.LockItemsForRead(false);
2839 2880
2840 if (item.PermsGranter != m_host.OwnerID) 2881 if (item.PermsGranter != m_host.OwnerID)
2841 return; 2882 return;
@@ -2861,13 +2902,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2861 2902
2862 TaskInventoryItem item; 2903 TaskInventoryItem item;
2863 2904
2864 lock (m_host.TaskInventory) 2905 m_host.TaskInventory.LockItemsForRead(true);
2906
2907 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2865 { 2908 {
2866 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2909 m_host.TaskInventory.LockItemsForRead(false);
2867 return; 2910 return;
2868 else
2869 item = m_host.TaskInventory[InventorySelf()];
2870 } 2911 }
2912 else
2913 {
2914 item = m_host.TaskInventory[InventorySelf()];
2915 }
2916 m_host.TaskInventory.LockItemsForRead(false);
2917
2871 2918
2872 if (item.PermsGranter != m_host.OwnerID) 2919 if (item.PermsGranter != m_host.OwnerID)
2873 return; 2920 return;
@@ -3068,12 +3115,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3068 m_host.AddScriptLPS(1); 3115 m_host.AddScriptLPS(1);
3069 } 3116 }
3070 3117
3071 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3072 {
3073 m_host.AddScriptLPS(1);
3074 NotImplemented("llRotLookAt");
3075 }
3076
3077 public LSL_Integer llStringLength(string str) 3118 public LSL_Integer llStringLength(string str)
3078 { 3119 {
3079 m_host.AddScriptLPS(1); 3120 m_host.AddScriptLPS(1);
@@ -3097,14 +3138,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 3138
3098 TaskInventoryItem item; 3139 TaskInventoryItem item;
3099 3140
3100 lock (m_host.TaskInventory) 3141 m_host.TaskInventory.LockItemsForRead(true);
3142 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3101 { 3143 {
3102 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3144 m_host.TaskInventory.LockItemsForRead(false);
3103 return; 3145 return;
3104 else
3105 item = m_host.TaskInventory[InventorySelf()];
3106 } 3146 }
3107 3147 else
3148 {
3149 item = m_host.TaskInventory[InventorySelf()];
3150 }
3151 m_host.TaskInventory.LockItemsForRead(false);
3108 if (item.PermsGranter == UUID.Zero) 3152 if (item.PermsGranter == UUID.Zero)
3109 return; 3153 return;
3110 3154
@@ -3134,13 +3178,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3134 3178
3135 TaskInventoryItem item; 3179 TaskInventoryItem item;
3136 3180
3137 lock (m_host.TaskInventory) 3181 m_host.TaskInventory.LockItemsForRead(true);
3182 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3138 { 3183 {
3139 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3184 m_host.TaskInventory.LockItemsForRead(false);
3140 return; 3185 return;
3141 else 3186 }
3142 item = m_host.TaskInventory[InventorySelf()]; 3187 else
3188 {
3189 item = m_host.TaskInventory[InventorySelf()];
3143 } 3190 }
3191 m_host.TaskInventory.LockItemsForRead(false);
3192
3144 3193
3145 if (item.PermsGranter == UUID.Zero) 3194 if (item.PermsGranter == UUID.Zero)
3146 return; 3195 return;
@@ -3213,10 +3262,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3213 3262
3214 TaskInventoryItem item; 3263 TaskInventoryItem item;
3215 3264
3216 lock (m_host.TaskInventory) 3265
3266 m_host.TaskInventory.LockItemsForRead(true);
3267 if (!m_host.TaskInventory.ContainsKey(invItemID))
3268 {
3269 m_host.TaskInventory.LockItemsForRead(false);
3270 return;
3271 }
3272 else
3217 { 3273 {
3218 item = m_host.TaskInventory[invItemID]; 3274 item = m_host.TaskInventory[invItemID];
3219 } 3275 }
3276 m_host.TaskInventory.LockItemsForRead(false);
3220 3277
3221 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3278 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3222 { 3279 {
@@ -3248,11 +3305,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3248 3305
3249 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3306 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3250 { 3307 {
3251 lock (m_host.TaskInventory) 3308 m_host.TaskInventory.LockItemsForWrite(true);
3252 { 3309 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3253 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3310 m_host.TaskInventory[invItemID].PermsMask = perm;
3254 m_host.TaskInventory[invItemID].PermsMask = perm; 3311 m_host.TaskInventory.LockItemsForWrite(false);
3255 }
3256 3312
3257 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3313 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3258 "run_time_permissions", new Object[] { 3314 "run_time_permissions", new Object[] {
@@ -3272,11 +3328,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3272 3328
3273 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3329 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3274 { 3330 {
3275 lock (m_host.TaskInventory) 3331 m_host.TaskInventory.LockItemsForWrite(true);
3276 { 3332 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3277 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3333 m_host.TaskInventory[invItemID].PermsMask = perm;
3278 m_host.TaskInventory[invItemID].PermsMask = perm; 3334 m_host.TaskInventory.LockItemsForWrite(false);
3279 }
3280 3335
3281 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3336 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3282 "run_time_permissions", new Object[] { 3337 "run_time_permissions", new Object[] {
@@ -3297,11 +3352,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3297 3352
3298 if (!m_waitingForScriptAnswer) 3353 if (!m_waitingForScriptAnswer)
3299 { 3354 {
3300 lock (m_host.TaskInventory) 3355 m_host.TaskInventory.LockItemsForWrite(true);
3301 { 3356 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3302 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3357 m_host.TaskInventory[invItemID].PermsMask = 0;
3303 m_host.TaskInventory[invItemID].PermsMask = 0; 3358 m_host.TaskInventory.LockItemsForWrite(false);
3304 }
3305 3359
3306 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3360 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3307 m_waitingForScriptAnswer=true; 3361 m_waitingForScriptAnswer=true;
@@ -3336,10 +3390,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3336 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3390 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3337 llReleaseControls(); 3391 llReleaseControls();
3338 3392
3339 lock (m_host.TaskInventory) 3393
3340 { 3394 m_host.TaskInventory.LockItemsForWrite(true);
3341 m_host.TaskInventory[invItemID].PermsMask = answer; 3395 m_host.TaskInventory[invItemID].PermsMask = answer;
3342 } 3396 m_host.TaskInventory.LockItemsForWrite(false);
3397
3343 3398
3344 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3399 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3345 "run_time_permissions", new Object[] { 3400 "run_time_permissions", new Object[] {
@@ -3351,16 +3406,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3351 { 3406 {
3352 m_host.AddScriptLPS(1); 3407 m_host.AddScriptLPS(1);
3353 3408
3354 lock (m_host.TaskInventory) 3409 m_host.TaskInventory.LockItemsForRead(true);
3410
3411 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3355 { 3412 {
3356 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3413 if (item.Type == 10 && item.ItemID == m_itemID)
3357 { 3414 {
3358 if (item.Type == 10 && item.ItemID == m_itemID) 3415 m_host.TaskInventory.LockItemsForRead(false);
3359 { 3416 return item.PermsGranter.ToString();
3360 return item.PermsGranter.ToString();
3361 }
3362 } 3417 }
3363 } 3418 }
3419 m_host.TaskInventory.LockItemsForRead(false);
3364 3420
3365 return UUID.Zero.ToString(); 3421 return UUID.Zero.ToString();
3366 } 3422 }
@@ -3369,19 +3425,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3369 { 3425 {
3370 m_host.AddScriptLPS(1); 3426 m_host.AddScriptLPS(1);
3371 3427
3372 lock (m_host.TaskInventory) 3428 m_host.TaskInventory.LockItemsForRead(true);
3429
3430 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3373 { 3431 {
3374 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3432 if (item.Type == 10 && item.ItemID == m_itemID)
3375 { 3433 {
3376 if (item.Type == 10 && item.ItemID == m_itemID) 3434 int perms = item.PermsMask;
3377 { 3435 if (m_automaticLinkPermission)
3378 int perms = item.PermsMask; 3436 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3379 if (m_automaticLinkPermission) 3437 m_host.TaskInventory.LockItemsForRead(false);
3380 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3438 return perms;
3381 return perms;
3382 }
3383 } 3439 }
3384 } 3440 }
3441 m_host.TaskInventory.LockItemsForRead(false);
3385 3442
3386 return 0; 3443 return 0;
3387 } 3444 }
@@ -3414,11 +3471,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3414 UUID invItemID = InventorySelf(); 3471 UUID invItemID = InventorySelf();
3415 3472
3416 TaskInventoryItem item; 3473 TaskInventoryItem item;
3417 lock (m_host.TaskInventory) 3474 m_host.TaskInventory.LockItemsForRead(true);
3418 { 3475 item = m_host.TaskInventory[invItemID];
3419 item = m_host.TaskInventory[invItemID]; 3476 m_host.TaskInventory.LockItemsForRead(false);
3420 } 3477
3421
3422 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3478 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3423 && !m_automaticLinkPermission) 3479 && !m_automaticLinkPermission)
3424 { 3480 {
@@ -3471,16 +3527,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3471 m_host.AddScriptLPS(1); 3527 m_host.AddScriptLPS(1);
3472 UUID invItemID = InventorySelf(); 3528 UUID invItemID = InventorySelf();
3473 3529
3474 lock (m_host.TaskInventory) 3530 m_host.TaskInventory.LockItemsForRead(true);
3475 {
3476 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3531 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3477 && !m_automaticLinkPermission) 3532 && !m_automaticLinkPermission)
3478 { 3533 {
3479 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3534 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3535 m_host.TaskInventory.LockItemsForRead(false);
3480 return; 3536 return;
3481 } 3537 }
3482 } 3538 m_host.TaskInventory.LockItemsForRead(false);
3483 3539
3484 if (linknum < ScriptBaseClass.LINK_THIS) 3540 if (linknum < ScriptBaseClass.LINK_THIS)
3485 return; 3541 return;
3486 3542
@@ -3649,17 +3705,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3649 m_host.AddScriptLPS(1); 3705 m_host.AddScriptLPS(1);
3650 int count = 0; 3706 int count = 0;
3651 3707
3652 lock (m_host.TaskInventory) 3708 m_host.TaskInventory.LockItemsForRead(true);
3709 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3653 { 3710 {
3654 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3711 if (inv.Value.Type == type || type == -1)
3655 { 3712 {
3656 if (inv.Value.Type == type || type == -1) 3713 count = count + 1;
3657 {
3658 count = count + 1;
3659 }
3660 } 3714 }
3661 } 3715 }
3662 3716
3717 m_host.TaskInventory.LockItemsForRead(false);
3663 return count; 3718 return count;
3664 } 3719 }
3665 3720
@@ -3668,16 +3723,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3668 m_host.AddScriptLPS(1); 3723 m_host.AddScriptLPS(1);
3669 ArrayList keys = new ArrayList(); 3724 ArrayList keys = new ArrayList();
3670 3725
3671 lock (m_host.TaskInventory) 3726 m_host.TaskInventory.LockItemsForRead(true);
3727 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3672 { 3728 {
3673 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3729 if (inv.Value.Type == type || type == -1)
3674 { 3730 {
3675 if (inv.Value.Type == type || type == -1) 3731 keys.Add(inv.Value.Name);
3676 {
3677 keys.Add(inv.Value.Name);
3678 }
3679 } 3732 }
3680 } 3733 }
3734 m_host.TaskInventory.LockItemsForRead(false);
3681 3735
3682 if (keys.Count == 0) 3736 if (keys.Count == 0)
3683 { 3737 {
@@ -3714,20 +3768,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3714 } 3768 }
3715 3769
3716 // move the first object found with this inventory name 3770 // move the first object found with this inventory name
3717 lock (m_host.TaskInventory) 3771 m_host.TaskInventory.LockItemsForRead(true);
3772 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3718 { 3773 {
3719 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3774 if (inv.Value.Name == inventory)
3720 { 3775 {
3721 if (inv.Value.Name == inventory) 3776 found = true;
3722 { 3777 objId = inv.Key;
3723 found = true; 3778 assetType = inv.Value.Type;
3724 objId = inv.Key; 3779 objName = inv.Value.Name;
3725 assetType = inv.Value.Type; 3780 break;
3726 objName = inv.Value.Name;
3727 break;
3728 }
3729 } 3781 }
3730 } 3782 }
3783 m_host.TaskInventory.LockItemsForRead(false);
3731 3784
3732 if (!found) 3785 if (!found)
3733 { 3786 {
@@ -3772,24 +3825,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3772 ScriptSleep(3000); 3825 ScriptSleep(3000);
3773 } 3826 }
3774 3827
3828 [DebuggerNonUserCode]
3775 public void llRemoveInventory(string name) 3829 public void llRemoveInventory(string name)
3776 { 3830 {
3777 m_host.AddScriptLPS(1); 3831 m_host.AddScriptLPS(1);
3778 3832
3779 lock (m_host.TaskInventory) 3833 m_host.TaskInventory.LockItemsForRead(true);
3834 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3780 { 3835 {
3781 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3836 if (item.Name == name)
3782 { 3837 {
3783 if (item.Name == name) 3838 if (item.ItemID == m_itemID)
3784 { 3839 throw new ScriptDeleteException();
3785 if (item.ItemID == m_itemID) 3840 else
3786 throw new ScriptDeleteException(); 3841 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3787 else 3842
3788 m_host.Inventory.RemoveInventoryItem(item.ItemID); 3843 m_host.TaskInventory.LockItemsForRead(false);
3789 return; 3844 return;
3790 }
3791 } 3845 }
3792 } 3846 }
3847 m_host.TaskInventory.LockItemsForRead(false);
3793 } 3848 }
3794 3849
3795 public void llSetText(string text, LSL_Vector color, double alpha) 3850 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3878,6 +3933,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3878 { 3933 {
3879 m_host.AddScriptLPS(1); 3934 m_host.AddScriptLPS(1);
3880 3935
3936 //Clone is thread safe
3881 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 3937 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3882 3938
3883 foreach (TaskInventoryItem item in itemDictionary.Values) 3939 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -3968,17 +4024,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3968 UUID soundId = UUID.Zero; 4024 UUID soundId = UUID.Zero;
3969 if (!UUID.TryParse(impact_sound, out soundId)) 4025 if (!UUID.TryParse(impact_sound, out soundId))
3970 { 4026 {
3971 lock (m_host.TaskInventory) 4027 m_host.TaskInventory.LockItemsForRead(true);
4028 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3972 { 4029 {
3973 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4030 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
3974 { 4031 {
3975 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4032 soundId = item.AssetID;
3976 { 4033 break;
3977 soundId = item.AssetID;
3978 break;
3979 }
3980 } 4034 }
3981 } 4035 }
4036 m_host.TaskInventory.LockItemsForRead(false);
3982 } 4037 }
3983 m_host.CollisionSound = soundId; 4038 m_host.CollisionSound = soundId;
3984 m_host.CollisionSoundVolume = (float)impact_volume; 4039 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4024,6 +4079,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4024 UUID partItemID; 4079 UUID partItemID;
4025 foreach (SceneObjectPart part in parts) 4080 foreach (SceneObjectPart part in parts)
4026 { 4081 {
4082 //Clone is thread safe
4027 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4083 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4028 4084
4029 foreach (TaskInventoryItem item in itemsDictionary.Values) 4085 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4231,17 +4287,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4231 4287
4232 m_host.AddScriptLPS(1); 4288 m_host.AddScriptLPS(1);
4233 4289
4234 lock (m_host.TaskInventory) 4290 m_host.TaskInventory.LockItemsForRead(true);
4291 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4235 { 4292 {
4236 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4293 if (item.Type == 10 && item.ItemID == m_itemID)
4237 { 4294 {
4238 if (item.Type == 10 && item.ItemID == m_itemID) 4295 result = item.Name!=null?item.Name:String.Empty;
4239 { 4296 break;
4240 result = item.Name!=null?item.Name:String.Empty;
4241 break;
4242 }
4243 } 4297 }
4244 } 4298 }
4299 m_host.TaskInventory.LockItemsForRead(false);
4245 4300
4246 return result; 4301 return result;
4247 } 4302 }
@@ -4499,23 +4554,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4499 { 4554 {
4500 m_host.AddScriptLPS(1); 4555 m_host.AddScriptLPS(1);
4501 4556
4502 lock (m_host.TaskInventory) 4557 m_host.TaskInventory.LockItemsForRead(true);
4558 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4503 { 4559 {
4504 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4560 if (inv.Value.Name == name)
4505 { 4561 {
4506 if (inv.Value.Name == name) 4562 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4507 { 4563 {
4508 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4564 m_host.TaskInventory.LockItemsForRead(false);
4509 { 4565 return inv.Value.AssetID.ToString();
4510 return inv.Value.AssetID.ToString(); 4566 }
4511 } 4567 else
4512 else 4568 {
4513 { 4569 m_host.TaskInventory.LockItemsForRead(false);
4514 return UUID.Zero.ToString(); 4570 return UUID.Zero.ToString();
4515 }
4516 } 4571 }
4517 } 4572 }
4518 } 4573 }
4574 m_host.TaskInventory.LockItemsForRead(false);
4519 4575
4520 return UUID.Zero.ToString(); 4576 return UUID.Zero.ToString();
4521 } 4577 }
@@ -6011,14 +6067,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6011 6067
6012 protected UUID GetTaskInventoryItem(string name) 6068 protected UUID GetTaskInventoryItem(string name)
6013 { 6069 {
6014 lock (m_host.TaskInventory) 6070 m_host.TaskInventory.LockItemsForRead(true);
6071 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6015 { 6072 {
6016 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6073 if (inv.Value.Name == name)
6017 { 6074 {
6018 if (inv.Value.Name == name) 6075 m_host.TaskInventory.LockItemsForRead(false);
6019 return inv.Key; 6076 return inv.Key;
6020 } 6077 }
6021 } 6078 }
6079 m_host.TaskInventory.LockItemsForRead(false);
6022 6080
6023 return UUID.Zero; 6081 return UUID.Zero;
6024 } 6082 }
@@ -6329,22 +6387,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6329 } 6387 }
6330 6388
6331 // copy the first script found with this inventory name 6389 // copy the first script found with this inventory name
6332 lock (m_host.TaskInventory) 6390 m_host.TaskInventory.LockItemsForRead(true);
6391 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6333 { 6392 {
6334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6393 if (inv.Value.Name == name)
6335 { 6394 {
6336 if (inv.Value.Name == name) 6395 // make sure the object is a script
6396 if (10 == inv.Value.Type)
6337 { 6397 {
6338 // make sure the object is a script 6398 found = true;
6339 if (10 == inv.Value.Type) 6399 srcId = inv.Key;
6340 { 6400 break;
6341 found = true;
6342 srcId = inv.Key;
6343 break;
6344 }
6345 } 6401 }
6346 } 6402 }
6347 } 6403 }
6404 m_host.TaskInventory.LockItemsForRead(false);
6348 6405
6349 if (!found) 6406 if (!found)
6350 { 6407 {
@@ -8147,28 +8204,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8147 { 8204 {
8148 m_host.AddScriptLPS(1); 8205 m_host.AddScriptLPS(1);
8149 8206
8150 lock (m_host.TaskInventory) 8207 m_host.TaskInventory.LockItemsForRead(true);
8208 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8151 { 8209 {
8152 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8210 if (inv.Value.Name == item)
8153 { 8211 {
8154 if (inv.Value.Name == item) 8212 m_host.TaskInventory.LockItemsForRead(false);
8213 switch (mask)
8155 { 8214 {
8156 switch (mask) 8215 case 0:
8157 { 8216 return (int)inv.Value.BasePermissions;
8158 case 0: 8217 case 1:
8159 return (int)inv.Value.BasePermissions; 8218 return (int)inv.Value.CurrentPermissions;
8160 case 1: 8219 case 2:
8161 return (int)inv.Value.CurrentPermissions; 8220 return (int)inv.Value.GroupPermissions;
8162 case 2: 8221 case 3:
8163 return (int)inv.Value.GroupPermissions; 8222 return (int)inv.Value.EveryonePermissions;
8164 case 3: 8223 case 4:
8165 return (int)inv.Value.EveryonePermissions; 8224 return (int)inv.Value.NextPermissions;
8166 case 4:
8167 return (int)inv.Value.NextPermissions;
8168 }
8169 } 8225 }
8170 } 8226 }
8171 } 8227 }
8228 m_host.TaskInventory.LockItemsForRead(false);
8172 8229
8173 return -1; 8230 return -1;
8174 } 8231 }
@@ -8183,16 +8240,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8183 { 8240 {
8184 m_host.AddScriptLPS(1); 8241 m_host.AddScriptLPS(1);
8185 8242
8186 lock (m_host.TaskInventory) 8243 m_host.TaskInventory.LockItemsForRead(true);
8244 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8187 { 8245 {
8188 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8246 if (inv.Value.Name == item)
8189 { 8247 {
8190 if (inv.Value.Name == item) 8248 m_host.TaskInventory.LockItemsForRead(false);
8191 { 8249 return inv.Value.CreatorID.ToString();
8192 return inv.Value.CreatorID.ToString();
8193 }
8194 } 8250 }
8195 } 8251 }
8252 m_host.TaskInventory.LockItemsForRead(false);
8196 8253
8197 llSay(0, "No item name '" + item + "'"); 8254 llSay(0, "No item name '" + item + "'");
8198 8255
@@ -8716,16 +8773,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8716 { 8773 {
8717 m_host.AddScriptLPS(1); 8774 m_host.AddScriptLPS(1);
8718 8775
8719 lock (m_host.TaskInventory) 8776 m_host.TaskInventory.LockItemsForRead(true);
8777 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8720 { 8778 {
8721 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8779 if (inv.Value.Name == name)
8722 { 8780 {
8723 if (inv.Value.Name == name) 8781 m_host.TaskInventory.LockItemsForRead(false);
8724 { 8782 return inv.Value.Type;
8725 return inv.Value.Type;
8726 }
8727 } 8783 }
8728 } 8784 }
8785 m_host.TaskInventory.LockItemsForRead(false);
8729 8786
8730 return -1; 8787 return -1;
8731 } 8788 }
@@ -8756,17 +8813,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8756 if (invItemID == UUID.Zero) 8813 if (invItemID == UUID.Zero)
8757 return new LSL_Vector(); 8814 return new LSL_Vector();
8758 8815
8759 lock (m_host.TaskInventory) 8816 m_host.TaskInventory.LockItemsForRead(true);
8817 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8760 { 8818 {
8761 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 8819 m_host.TaskInventory.LockItemsForRead(false);
8762 return new LSL_Vector(); 8820 return new LSL_Vector();
8821 }
8763 8822
8764 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 8823 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8765 { 8824 {
8766 ShoutError("No permissions to track the camera"); 8825 ShoutError("No permissions to track the camera");
8767 return new LSL_Vector(); 8826 m_host.TaskInventory.LockItemsForRead(false);
8768 } 8827 return new LSL_Vector();
8769 } 8828 }
8829 m_host.TaskInventory.LockItemsForRead(false);
8770 8830
8771 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 8831 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8772 if (presence != null) 8832 if (presence != null)
@@ -8784,17 +8844,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8784 if (invItemID == UUID.Zero) 8844 if (invItemID == UUID.Zero)
8785 return new LSL_Rotation(); 8845 return new LSL_Rotation();
8786 8846
8787 lock (m_host.TaskInventory) 8847 m_host.TaskInventory.LockItemsForRead(true);
8848 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8788 { 8849 {
8789 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 8850 m_host.TaskInventory.LockItemsForRead(false);
8790 return new LSL_Rotation(); 8851 return new LSL_Rotation();
8791
8792 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8793 {
8794 ShoutError("No permissions to track the camera");
8795 return new LSL_Rotation();
8796 }
8797 } 8852 }
8853 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8854 {
8855 ShoutError("No permissions to track the camera");
8856 m_host.TaskInventory.LockItemsForRead(false);
8857 return new LSL_Rotation();
8858 }
8859 m_host.TaskInventory.LockItemsForRead(false);
8798 8860
8799 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 8861 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8800 if (presence != null) 8862 if (presence != null)
@@ -8944,14 +9006,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8944 if (objectID == UUID.Zero) return; 9006 if (objectID == UUID.Zero) return;
8945 9007
8946 UUID agentID; 9008 UUID agentID;
8947 lock (m_host.TaskInventory) 9009 m_host.TaskInventory.LockItemsForRead(true);
8948 { 9010 // we need the permission first, to know which avatar we want to set the camera for
8949 // we need the permission first, to know which avatar we want to set the camera for 9011 agentID = m_host.TaskInventory[invItemID].PermsGranter;
8950 agentID = m_host.TaskInventory[invItemID].PermsGranter;
8951 9012
8952 if (agentID == UUID.Zero) return; 9013 if (agentID == UUID.Zero)
8953 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9014 {
9015 m_host.TaskInventory.LockItemsForRead(false);
9016 return;
8954 } 9017 }
9018 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9019 {
9020 m_host.TaskInventory.LockItemsForRead(false);
9021 return;
9022 }
9023 m_host.TaskInventory.LockItemsForRead(false);
8955 9024
8956 ScenePresence presence = World.GetScenePresence(agentID); 9025 ScenePresence presence = World.GetScenePresence(agentID);
8957 9026
@@ -9001,12 +9070,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9001 9070
9002 // we need the permission first, to know which avatar we want to clear the camera for 9071 // we need the permission first, to know which avatar we want to clear the camera for
9003 UUID agentID; 9072 UUID agentID;
9004 lock (m_host.TaskInventory) 9073 m_host.TaskInventory.LockItemsForRead(true);
9074 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9075 if (agentID == UUID.Zero)
9076 {
9077 m_host.TaskInventory.LockItemsForRead(false);
9078 return;
9079 }
9080 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9005 { 9081 {
9006 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9082 m_host.TaskInventory.LockItemsForRead(false);
9007 if (agentID == UUID.Zero) return; 9083 return;
9008 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9009 } 9084 }
9085 m_host.TaskInventory.LockItemsForRead(false);
9010 9086
9011 ScenePresence presence = World.GetScenePresence(agentID); 9087 ScenePresence presence = World.GetScenePresence(agentID);
9012 9088
@@ -9463,15 +9539,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9463 9539
9464 internal UUID ScriptByName(string name) 9540 internal UUID ScriptByName(string name)
9465 { 9541 {
9466 lock (m_host.TaskInventory) 9542 m_host.TaskInventory.LockItemsForRead(true);
9543
9544 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9467 { 9545 {
9468 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 9546 if (item.Type == 10 && item.Name == name)
9469 { 9547 {
9470 if (item.Type == 10 && item.Name == name) 9548 m_host.TaskInventory.LockItemsForRead(false);
9471 return item.ItemID; 9549 return item.ItemID;
9472 } 9550 }
9473 } 9551 }
9474 9552
9553 m_host.TaskInventory.LockItemsForRead(false);
9554
9475 return UUID.Zero; 9555 return UUID.Zero;
9476 } 9556 }
9477 9557
@@ -9512,6 +9592,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9512 { 9592 {
9513 m_host.AddScriptLPS(1); 9593 m_host.AddScriptLPS(1);
9514 9594
9595 //Clone is thread safe
9515 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 9596 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9516 9597
9517 UUID assetID = UUID.Zero; 9598 UUID assetID = UUID.Zero;
@@ -9574,6 +9655,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9574 { 9655 {
9575 m_host.AddScriptLPS(1); 9656 m_host.AddScriptLPS(1);
9576 9657
9658 //Clone is thread safe
9577 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 9659 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9578 9660
9579 UUID assetID = UUID.Zero; 9661 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 5501679..7f739b1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -728,18 +728,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
728 if (target != null) 728 if (target != null)
729 { 729 {
730 UUID animID=UUID.Zero; 730 UUID animID=UUID.Zero;
731 lock (m_host.TaskInventory) 731 m_host.TaskInventory.LockItemsForRead(true);
732 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
732 { 733 {
733 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 734 if (inv.Value.Name == animation)
734 { 735 {
735 if (inv.Value.Name == animation) 736 if (inv.Value.Type == (int)AssetType.Animation)
736 { 737 animID = inv.Value.AssetID;
737 if (inv.Value.Type == (int)AssetType.Animation) 738 continue;
738 animID = inv.Value.AssetID;
739 continue;
740 }
741 } 739 }
742 } 740 }
741 m_host.TaskInventory.LockItemsForRead(false);
743 if (animID == UUID.Zero) 742 if (animID == UUID.Zero)
744 target.Animator.AddAnimation(animation, m_host.UUID); 743 target.Animator.AddAnimation(animation, m_host.UUID);
745 else 744 else
@@ -761,18 +760,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
761 if (target != null) 760 if (target != null)
762 { 761 {
763 UUID animID=UUID.Zero; 762 UUID animID=UUID.Zero;
764 lock (m_host.TaskInventory) 763 m_host.TaskInventory.LockItemsForRead(true);
764 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
765 { 765 {
766 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 766 if (inv.Value.Name == animation)
767 { 767 {
768 if (inv.Value.Name == animation) 768 if (inv.Value.Type == (int)AssetType.Animation)
769 { 769 animID = inv.Value.AssetID;
770 if (inv.Value.Type == (int)AssetType.Animation) 770 continue;
771 animID = inv.Value.AssetID;
772 continue;
773 }
774 } 771 }
775 } 772 }
773 m_host.TaskInventory.LockItemsForRead(false);
776 774
777 if (animID == UUID.Zero) 775 if (animID == UUID.Zero)
778 target.Animator.RemoveAnimation(animation); 776 target.Animator.RemoveAnimation(animation);
@@ -1541,6 +1539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1541 1539
1542 if (!UUID.TryParse(name, out assetID)) 1540 if (!UUID.TryParse(name, out assetID))
1543 { 1541 {
1542 m_host.TaskInventory.LockItemsForRead(true);
1544 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1543 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1545 { 1544 {
1546 if (item.Type == 7 && item.Name == name) 1545 if (item.Type == 7 && item.Name == name)
@@ -1548,6 +1547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1548 assetID = item.AssetID; 1547 assetID = item.AssetID;
1549 } 1548 }
1550 } 1549 }
1550 m_host.TaskInventory.LockItemsForRead(false);
1551 } 1551 }
1552 1552
1553 if (assetID == UUID.Zero) 1553 if (assetID == UUID.Zero)
@@ -1594,6 +1594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1594 1594
1595 if (!UUID.TryParse(name, out assetID)) 1595 if (!UUID.TryParse(name, out assetID))
1596 { 1596 {
1597 m_host.TaskInventory.LockItemsForRead(true);
1597 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1598 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1598 { 1599 {
1599 if (item.Type == 7 && item.Name == name) 1600 if (item.Type == 7 && item.Name == name)
@@ -1601,6 +1602,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1601 assetID = item.AssetID; 1602 assetID = item.AssetID;
1602 } 1603 }
1603 } 1604 }
1605 m_host.TaskInventory.LockItemsForRead(false);
1604 } 1606 }
1605 1607
1606 if (assetID == UUID.Zero) 1608 if (assetID == UUID.Zero)
@@ -1651,6 +1653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1651 1653
1652 if (!UUID.TryParse(name, out assetID)) 1654 if (!UUID.TryParse(name, out assetID))
1653 { 1655 {
1656 m_host.TaskInventory.LockItemsForRead(true);
1654 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1657 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1655 { 1658 {
1656 if (item.Type == 7 && item.Name == name) 1659 if (item.Type == 7 && item.Name == name)
@@ -1658,6 +1661,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1658 assetID = item.AssetID; 1661 assetID = item.AssetID;
1659 } 1662 }
1660 } 1663 }
1664 m_host.TaskInventory.LockItemsForRead(false);
1661 } 1665 }
1662 1666
1663 if (assetID == UUID.Zero) 1667 if (assetID == UUID.Zero)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 7f67599..15e0408 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -131,6 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
131 return (eventFlags); 132 return (eventFlags);
132 } 133 }
133 134
135 [DebuggerNonUserCode]
134 public void ExecuteEvent(string state, string FunctionName, object[] args) 136 public void ExecuteEvent(string state, string FunctionName, object[] args)
135 { 137 {
136 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 138 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index 121159c..a44abb0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5c5d57e..8333a27 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -237,13 +238,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
237 238
238 if (part != null) 239 if (part != null)
239 { 240 {
240 lock (part.TaskInventory) 241 part.TaskInventory.LockItemsForRead(true);
242 if (part.TaskInventory.ContainsKey(m_ItemID))
241 { 243 {
242 if (part.TaskInventory.ContainsKey(m_ItemID)) 244 m_thisScriptTask = part.TaskInventory[m_ItemID];
243 {
244 m_thisScriptTask = part.TaskInventory[m_ItemID];
245 }
246 } 245 }
246 part.TaskInventory.LockItemsForRead(false);
247 } 247 }
248 248
249 ApiManager am = new ApiManager(); 249 ApiManager am = new ApiManager();
@@ -428,14 +428,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
428 { 428 {
429 int permsMask; 429 int permsMask;
430 UUID permsGranter; 430 UUID permsGranter;
431 lock (part.TaskInventory) 431 part.TaskInventory.LockItemsForRead(true);
432 if (!part.TaskInventory.ContainsKey(m_ItemID))
432 { 433 {
433 if (!part.TaskInventory.ContainsKey(m_ItemID)) 434 part.TaskInventory.LockItemsForRead(false);
434 return; 435 return;
435
436 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
437 permsMask = part.TaskInventory[m_ItemID].PermsMask;
438 } 436 }
437 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
438 permsMask = part.TaskInventory[m_ItemID].PermsMask;
439 part.TaskInventory.LockItemsForRead(false);
439 440
440 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 441 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
441 { 442 {
@@ -544,6 +545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
544 return true; 545 return true;
545 } 546 }
546 547
548 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
547 public void SetState(string state) 549 public void SetState(string state)
548 { 550 {
549 if (state == State) 551 if (state == State)
@@ -555,7 +557,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
555 new DetectParams[0])); 557 new DetectParams[0]));
556 PostEvent(new EventParams("state_entry", new Object[0], 558 PostEvent(new EventParams("state_entry", new Object[0],
557 new DetectParams[0])); 559 new DetectParams[0]));
558 560
559 throw new EventAbortException(); 561 throw new EventAbortException();
560 } 562 }
561 563
@@ -638,154 +640,158 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
638 /// <returns></returns> 640 /// <returns></returns>
639 public object EventProcessor() 641 public object EventProcessor()
640 { 642 {
643
644 EventParams data = null;
645
646 lock (m_EventQueue)
647 {
641 lock (m_Script) 648 lock (m_Script)
642 { 649 {
643 EventParams data = null; 650 data = (EventParams) m_EventQueue.Dequeue();
644 651 if (data == null) // Shouldn't happen
645 lock (m_EventQueue)
646 { 652 {
647 data = (EventParams) m_EventQueue.Dequeue(); 653 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
648 if (data == null) // Shouldn't happen
649 { 654 {
650 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 655 m_CurrentResult = m_Engine.QueueEventHandler(this);
651 {
652 m_CurrentResult = m_Engine.QueueEventHandler(this);
653 }
654 else
655 {
656 m_CurrentResult = null;
657 }
658 return 0;
659 } 656 }
660 657 else
661 if (data.EventName == "timer")
662 m_TimerQueued = false;
663 if (data.EventName == "control")
664 { 658 {
665 if (m_ControlEventsInQueue > 0) 659 m_CurrentResult = null;
666 m_ControlEventsInQueue--;
667 } 660 }
668 if (data.EventName == "collision") 661 return 0;
669 m_CollisionInQueue = false;
670 } 662 }
671
672 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
673 663
674 m_DetectParams = data.DetectParams; 664 if (data.EventName == "timer")
675 665 m_TimerQueued = false;
676 if (data.EventName == "state") // Hardcoded state change 666 if (data.EventName == "control")
677 { 667 {
678 // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", 668 if (m_ControlEventsInQueue > 0)
679 // m_PrimName, m_ScriptName, data.Params[0].ToString()); 669 m_ControlEventsInQueue--;
680 m_State=data.Params[0].ToString(); 670 }
681 AsyncCommandManager.RemoveScript(m_Engine, 671 if (data.EventName == "collision")
682 m_LocalID, m_ItemID); 672 m_CollisionInQueue = false;
673 }
674 }
675 lock(m_Script)
676 {
677
678 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
683 679
684 SceneObjectPart part = m_Engine.World.GetSceneObjectPart( 680 m_DetectParams = data.DetectParams;
685 m_LocalID); 681
686 if (part != null) 682 if (data.EventName == "state") // Hardcoded state change
687 { 683 {
688 part.SetScriptEvents(m_ItemID, 684// m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
689 (int)m_Script.GetStateEventFlags(State)); 685// m_PrimName, m_ScriptName, data.Params[0].ToString());
690 } 686 m_State=data.Params[0].ToString();
687 AsyncCommandManager.RemoveScript(m_Engine,
688 m_LocalID, m_ItemID);
689
690 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
691 m_LocalID);
692 if (part != null)
693 {
694 part.SetScriptEvents(m_ItemID,
695 (int)m_Script.GetStateEventFlags(State));
691 } 696 }
692 else 697 }
698 else
699 {
700 if (m_Engine.World.PipeEventsForScript(m_LocalID) ||
701 data.EventName == "control") // Don't freeze avies!
693 { 702 {
694 if (m_Engine.World.PipeEventsForScript(m_LocalID) || 703 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
695 data.EventName == "control") // Don't freeze avies! 704 m_LocalID);
696 { 705 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
697 SceneObjectPart part = m_Engine.World.GetSceneObjectPart( 706 // m_PrimName, m_ScriptName, data.EventName, m_State);
698 m_LocalID);
699 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
700 // m_PrimName, m_ScriptName, data.EventName, m_State);
701 707
702 try 708 try
703 { 709 {
704 m_CurrentEvent = data.EventName; 710 m_CurrentEvent = data.EventName;
705 m_EventStart = DateTime.Now; 711 m_EventStart = DateTime.Now;
706 m_InEvent = true; 712 m_InEvent = true;
707 713
708 m_Script.ExecuteEvent(State, data.EventName, data.Params); 714 m_Script.ExecuteEvent(State, data.EventName, data.Params);
709 715
710 m_InEvent = false; 716 m_InEvent = false;
711 m_CurrentEvent = String.Empty; 717 m_CurrentEvent = String.Empty;
712 718
713 if (m_SaveState) 719 if (m_SaveState)
714 { 720 {
715 // This will be the very first event we deliver 721 // This will be the very first event we deliver
716 // (state_entry) in default state 722 // (state_entry) in default state
717 // 723 //
718 724
719 SaveState(m_Assembly); 725 SaveState(m_Assembly);
720 726
721 m_SaveState = false; 727 m_SaveState = false;
722 }
723 } 728 }
724 catch (Exception e) 729 }
725 { 730 catch (Exception e)
726 // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); 731 {
727 m_InEvent = false; 732 // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
728 m_CurrentEvent = String.Empty; 733 m_InEvent = false;
734 m_CurrentEvent = String.Empty;
729 735
730 if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) 736 if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException))
731 { 737 {
732 try 738 try
733 {
734 // DISPLAY ERROR INWORLD
735 string text = FormatException(e);
736
737 if (text.Length > 1000)
738 text = text.Substring(0, 1000);
739 m_Engine.World.SimChat(Utils.StringToBytes(text),
740 ChatTypeEnum.DebugChannel, 2147483647,
741 part.AbsolutePosition,
742 part.Name, part.UUID, false);
743 }
744 catch (Exception)
745 {
746 }
747 // catch (Exception e2) // LEGIT: User Scripting
748 // {
749 // m_log.Error("[SCRIPT]: "+
750 // "Error displaying error in-world: " +
751 // e2.ToString());
752 // m_log.Error("[SCRIPT]: " +
753 // "Errormessage: Error compiling script:\r\n" +
754 // e.ToString());
755 // }
756 }
757 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
758 { 739 {
759 m_InSelfDelete = true; 740 // DISPLAY ERROR INWORLD
760 if (part != null && part.ParentGroup != null) 741 string text = FormatException(e);
761 m_Engine.World.DeleteSceneObject(part.ParentGroup, false); 742
743 if (text.Length > 1000)
744 text = text.Substring(0, 1000);
745 m_Engine.World.SimChat(Utils.StringToBytes(text),
746 ChatTypeEnum.DebugChannel, 2147483647,
747 part.AbsolutePosition,
748 part.Name, part.UUID, false);
762 } 749 }
763 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 750 catch (Exception)
764 { 751 {
765 m_InSelfDelete = true;
766 if (part != null && part.ParentGroup != null)
767 part.Inventory.RemoveInventoryItem(m_ItemID);
768 } 752 }
753 // catch (Exception e2) // LEGIT: User Scripting
754 // {
755 // m_log.Error("[SCRIPT]: "+
756 // "Error displaying error in-world: " +
757 // e2.ToString());
758 // m_log.Error("[SCRIPT]: " +
759 // "Errormessage: Error compiling script:\r\n" +
760 // e.ToString());
761 // }
762 }
763 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
764 {
765 m_InSelfDelete = true;
766 if (part != null && part.ParentGroup != null)
767 m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
768 }
769 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
770 {
771 m_InSelfDelete = true;
772 if (part != null && part.ParentGroup != null)
773 part.Inventory.RemoveInventoryItem(m_ItemID);
769 } 774 }
770 } 775 }
771 } 776 }
777 }
772 778
773 lock (m_EventQueue) 779 lock (m_EventQueue)
780 {
781 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
774 { 782 {
775 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 783 m_CurrentResult = m_Engine.QueueEventHandler(this);
776 { 784 }
777 m_CurrentResult = m_Engine.QueueEventHandler(this); 785 else
778 } 786 {
779 else 787 m_CurrentResult = null;
780 {
781 m_CurrentResult = null;
782 }
783 } 788 }
789 }
784 790
785 m_DetectParams = null; 791 m_DetectParams = null;
786 792
787 return 0; 793 return 0;
788 } 794 }
789 } 795 }
790 796
791 public int EventTime() 797 public int EventTime()
@@ -824,6 +830,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
824 new Object[0], new DetectParams[0])); 830 new Object[0], new DetectParams[0]));
825 } 831 }
826 832
833 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
827 public void ApiResetScript() 834 public void ApiResetScript()
828 { 835 {
829 // bool running = Running; 836 // bool running = Running;
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 3f38bb6..1fc31c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -429,6 +429,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
429 } 429 }
430 } 430 }
431 431
432 public int Size
433 {
434 get { return 0; }
435 }
436
432 public object[] Data 437 public object[] Data
433 { 438 {
434 get { 439 get {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 9030a5c..d997ea3 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -1119,6 +1120,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1119 return false; 1120 return false;
1120 } 1121 }
1121 1122
1123 [DebuggerNonUserCode]
1122 public void ApiResetScript(UUID itemID) 1124 public void ApiResetScript(UUID itemID)
1123 { 1125 {
1124 IScriptInstance instance = GetInstance(itemID); 1126 IScriptInstance instance = GetInstance(itemID);
@@ -1170,6 +1172,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1170 return UUID.Zero; 1172 return UUID.Zero;
1171 } 1173 }
1172 1174
1175 [DebuggerNonUserCode]
1173 public void SetState(UUID itemID, string newState) 1176 public void SetState(UUID itemID, string newState)
1174 { 1177 {
1175 IScriptInstance instance = GetInstance(itemID); 1178 IScriptInstance instance = GetInstance(itemID);