aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs122
-rw-r--r--OpenSim/Framework/TaskInventoryDictionary.cs111
-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.cs8
-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.cs203
-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
-rw-r--r--bin/OpenSim.ini.example3
36 files changed, 1666 insertions, 788 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/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/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 4221212..ac16b02 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 c773c05..98bb4f7 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -399,6 +399,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
399 #region Queue or Send 399 #region Queue or Send
400 400
401 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); 401 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
402 outgoingPacket.Type = type;
402 403
403 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) 404 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket))
404 SendPacketFinal(outgoingPacket); 405 SendPacketFinal(outgoingPacket);
@@ -510,6 +511,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
510 byte flags = buffer.Data[0]; 511 byte flags = buffer.Data[0];
511 bool isResend = (flags & Helpers.MSG_RESENT) != 0; 512 bool isResend = (flags & Helpers.MSG_RESENT) != 0;
512 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; 513 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
514 bool sendSynchronous = false;
513 LLUDPClient udpClient = outgoingPacket.Client; 515 LLUDPClient udpClient = outgoingPacket.Client;
514 516
515 if (!udpClient.IsConnected) 517 if (!udpClient.IsConnected)
@@ -565,9 +567,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
565 if (isReliable) 567 if (isReliable)
566 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength); 568 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength);
567 569
568 // Put the UDP payload on the wire 570 //Some packet types need to be sent synchonously.
569 AsyncBeginSend(buffer); 571 //Sorry, i know it's not optimal, but until the LL client
572 //manages packets correctly and re-orders them as required, this is necessary.
570 573
574
575 // Put the UDP payload on the wire
576 if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate)
577 {
578 SyncBeginPrioritySend(buffer, 2); // highest priority
579 }
580 else if (outgoingPacket.Type == PacketType.ObjectUpdate
581 || outgoingPacket.Type == PacketType.LayerData)
582 {
583 SyncBeginPrioritySend(buffer, 1); // medium priority
584 }
585 else
586 {
587 SyncBeginPrioritySend(buffer, 0); // normal priority
588 }
589
590 //AsyncBeginSend(buffer);
591
571 // Keep track of when this packet was sent out (right now) 592 // Keep track of when this packet was sent out (right now)
572 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; 593 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
573 } 594 }
@@ -842,7 +863,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
842 863
843 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); 864 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
844 865
845 AsyncBeginSend(buffer); 866 SyncBeginPrioritySend(buffer, 1); //Setting this to a medium priority should help minimise resends
846 } 867 }
847 868
848 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) 869 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 34b81d8..114dd13 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..ba11800 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -156,10 +156,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
157 157
158 // Check control flags 158 // Check control flags
159 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; 159 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; 160 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; 161 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; 162 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; 163 //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; 164 //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; 165 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
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 2558757..3034f9a 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 6ec2a01..f36ff1d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1734,6 +1734,45 @@ namespace OpenSim.Region.Framework.Scenes
1734 } 1734 }
1735 } 1735 }
1736 1736
1737 public void rotLookAt(Quaternion target, float strength, float damping)
1738 {
1739 SceneObjectPart rootpart = m_rootPart;
1740 if (rootpart != null)
1741 {
1742 if (IsAttachment)
1743 {
1744 /*
1745 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1746 if (avatar != null)
1747 {
1748 Rotate the Av?
1749 } */
1750 }
1751 else
1752 {
1753 if (rootpart.PhysActor != null)
1754 {
1755 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1756 rootpart.PhysActor.APIDStrength = strength;
1757 rootpart.PhysActor.APIDDamping = damping;
1758 rootpart.PhysActor.APIDActive = true;
1759 }
1760 }
1761 }
1762 }
1763 public void stopLookAt()
1764 {
1765 SceneObjectPart rootpart = m_rootPart;
1766 if (rootpart != null)
1767 {
1768 if (rootpart.PhysActor != null)
1769 {
1770 rootpart.PhysActor.APIDActive = false;
1771 }
1772 }
1773
1774 }
1775
1737 /// <summary> 1776 /// <summary>
1738 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1777 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1739 /// </summary> 1778 /// </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..a1bb244 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,8 @@ 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 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 94
94 public UUID currentParcelUUID = UUID.Zero; 95 public UUID currentParcelUUID = UUID.Zero;
95 96
@@ -113,7 +114,8 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 114 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 115 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 116 public Vector4 CollisionPlane = Vector4.UnitW;
116 117
118 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
117 private Vector3 m_lastPosition; 119 private Vector3 m_lastPosition;
118 private Quaternion m_lastRotation; 120 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 121 private Vector3 m_lastVelocity;
@@ -144,7 +146,6 @@ namespace OpenSim.Region.Framework.Scenes
144 private int m_perfMonMS; 146 private int m_perfMonMS;
145 147
146 private bool m_setAlwaysRun; 148 private bool m_setAlwaysRun;
147
148 private bool m_forceFly; 149 private bool m_forceFly;
149 private bool m_flyDisabled; 150 private bool m_flyDisabled;
150 151
@@ -168,7 +169,8 @@ namespace OpenSim.Region.Framework.Scenes
168 protected RegionInfo m_regionInfo; 169 protected RegionInfo m_regionInfo;
169 protected ulong crossingFromRegion; 170 protected ulong crossingFromRegion;
170 171
171 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 172 private readonly Vector3[] Dir_Vectors = new Vector3[11];
173 private bool m_isNudging = false;
172 174
173 // Position of agent's camera in world (region cordinates) 175 // Position of agent's camera in world (region cordinates)
174 protected Vector3 m_CameraCenter; 176 protected Vector3 m_CameraCenter;
@@ -232,6 +234,10 @@ namespace OpenSim.Region.Framework.Scenes
232 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 234 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
233 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 235 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
234 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 236 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
237 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
238 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
239 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
240 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 241 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
236 } 242 }
237 243
@@ -716,21 +722,47 @@ namespace OpenSim.Region.Framework.Scenes
716 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 722 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
717 Dir_Vectors[4] = Vector3.UnitZ; //UP 723 Dir_Vectors[4] = Vector3.UnitZ; //UP
718 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 724 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
719 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 725 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
726 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
727 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
728 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
729 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
720 } 730 }
721 731
722 private Vector3[] GetWalkDirectionVectors() 732 private Vector3[] GetWalkDirectionVectors()
723 { 733 {
724 Vector3[] vector = new Vector3[6]; 734 Vector3[] vector = new Vector3[11];
725 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 735 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 736 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
727 vector[2] = Vector3.UnitY; //LEFT 737 vector[2] = Vector3.UnitY; //LEFT
728 vector[3] = -Vector3.UnitY; //RIGHT 738 vector[3] = -Vector3.UnitY; //RIGHT
729 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 739 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 740 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 741 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
742 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
743 vector[8] = Vector3.UnitY; //LEFT_NUDGE
744 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
745 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
732 return vector; 746 return vector;
733 } 747 }
748
749 private bool[] GetDirectionIsNudge()
750 {
751 bool[] isNudge = new bool[11];
752 isNudge[0] = false; //FORWARD
753 isNudge[1] = false; //BACK
754 isNudge[2] = false; //LEFT
755 isNudge[3] = false; //RIGHT
756 isNudge[4] = false; //UP
757 isNudge[5] = false; //DOWN
758 isNudge[6] = true; //FORWARD_NUDGE
759 isNudge[7] = true; //BACK_NUDGE
760 isNudge[8] = true; //LEFT_NUDGE
761 isNudge[9] = true; //RIGHT_NUDGE
762 isNudge[10] = true; //DOWN_Nudge
763 return isNudge;
764 }
765
734 766
735 #endregion 767 #endregion
736 768
@@ -1147,7 +1179,6 @@ namespace OpenSim.Region.Framework.Scenes
1147 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1179 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
1148 // return; 1180 // return;
1149 //} 1181 //}
1150
1151 m_perfMonMS = Environment.TickCount; 1182 m_perfMonMS = Environment.TickCount;
1152 1183
1153 ++m_movementUpdateCount; 1184 ++m_movementUpdateCount;
@@ -1229,7 +1260,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); 1260 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1230 } 1261 }
1231 } 1262 }
1232
1233 lock (scriptedcontrols) 1263 lock (scriptedcontrols)
1234 { 1264 {
1235 if (scriptedcontrols.Count > 0) 1265 if (scriptedcontrols.Count > 0)
@@ -1261,7 +1291,6 @@ namespace OpenSim.Region.Framework.Scenes
1261 { 1291 {
1262 return; 1292 return;
1263 } 1293 }
1264
1265 if (m_allowMovement) 1294 if (m_allowMovement)
1266 { 1295 {
1267 int i = 0; 1296 int i = 0;
@@ -1289,6 +1318,11 @@ namespace OpenSim.Region.Framework.Scenes
1289 update_rotation = true; 1318 update_rotation = true;
1290 } 1319 }
1291 1320
1321 //guilty until proven innocent..
1322 bool Nudging = true;
1323 //Basically, if there is at least one non-nudge control then we don't need
1324 //to worry about stopping the avatar
1325
1292 if (m_parentID == 0) 1326 if (m_parentID == 0)
1293 { 1327 {
1294 bool bAllowUpdateMoveToPosition = false; 1328 bool bAllowUpdateMoveToPosition = false;
@@ -1303,6 +1337,12 @@ namespace OpenSim.Region.Framework.Scenes
1303 else 1337 else
1304 dirVectors = Dir_Vectors; 1338 dirVectors = Dir_Vectors;
1305 1339
1340 bool[] isNudge = GetDirectionIsNudge();
1341
1342
1343
1344
1345
1306 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1346 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1307 { 1347 {
1308 if (((uint)flags & (uint)DCF) != 0) 1348 if (((uint)flags & (uint)DCF) != 0)
@@ -1312,6 +1352,10 @@ namespace OpenSim.Region.Framework.Scenes
1312 try 1352 try
1313 { 1353 {
1314 agent_control_v3 += dirVectors[i]; 1354 agent_control_v3 += dirVectors[i];
1355 if (isNudge[i] == false)
1356 {
1357 Nudging = false;
1358 }
1315 } 1359 }
1316 catch (IndexOutOfRangeException) 1360 catch (IndexOutOfRangeException)
1317 { 1361 {
@@ -1373,6 +1417,9 @@ namespace OpenSim.Region.Framework.Scenes
1373 // Ignore z component of vector 1417 // Ignore z component of vector
1374 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1418 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1375 LocalVectorToTarget2D.Normalize(); 1419 LocalVectorToTarget2D.Normalize();
1420
1421 //We're not nudging
1422 Nudging = false;
1376 agent_control_v3 += LocalVectorToTarget2D; 1423 agent_control_v3 += LocalVectorToTarget2D;
1377 1424
1378 // update avatar movement flags. the avatar coordinate system is as follows: 1425 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1455,7 +1502,7 @@ namespace OpenSim.Region.Framework.Scenes
1455 // m_log.DebugFormat( 1502 // m_log.DebugFormat(
1456 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1503 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1457 1504
1458 AddNewMovement(agent_control_v3, q); 1505 AddNewMovement(agent_control_v3, q, Nudging);
1459 1506
1460 if (update_movementflag) 1507 if (update_movementflag)
1461 Animator.UpdateMovementAnimations(); 1508 Animator.UpdateMovementAnimations();
@@ -1538,7 +1585,7 @@ namespace OpenSim.Region.Framework.Scenes
1538 Velocity = Vector3.Zero; 1585 Velocity = Vector3.Zero;
1539 SendFullUpdateToAllClients(); 1586 SendFullUpdateToAllClients();
1540 1587
1541 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1588 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1542 } 1589 }
1543 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1590 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1544 m_requestedSitTargetUUID = UUID.Zero; 1591 m_requestedSitTargetUUID = UUID.Zero;
@@ -1576,21 +1623,19 @@ namespace OpenSim.Region.Framework.Scenes
1576 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1623 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1577 if (part != null) 1624 if (part != null)
1578 { 1625 {
1626 part.TaskInventory.LockItemsForRead(true);
1579 TaskInventoryDictionary taskIDict = part.TaskInventory; 1627 TaskInventoryDictionary taskIDict = part.TaskInventory;
1580 if (taskIDict != null) 1628 if (taskIDict != null)
1581 { 1629 {
1582 lock (taskIDict) 1630 foreach (UUID taskID in taskIDict.Keys)
1583 { 1631 {
1584 foreach (UUID taskID in taskIDict.Keys) 1632 UnRegisterControlEventsToScript(LocalId, taskID);
1585 { 1633 taskIDict[taskID].PermsMask &= ~(
1586 UnRegisterControlEventsToScript(LocalId, taskID); 1634 2048 | //PERMISSION_CONTROL_CAMERA
1587 taskIDict[taskID].PermsMask &= ~( 1635 4); // PERMISSION_TAKE_CONTROLS
1588 2048 | //PERMISSION_CONTROL_CAMERA
1589 4); // PERMISSION_TAKE_CONTROLS
1590 }
1591 } 1636 }
1592
1593 } 1637 }
1638 part.TaskInventory.LockItemsForRead(false);
1594 // Reset sit target. 1639 // Reset sit target.
1595 if (part.GetAvatarOnSitTarget() == UUID) 1640 if (part.GetAvatarOnSitTarget() == UUID)
1596 part.SetAvatarOnSitTarget(UUID.Zero); 1641 part.SetAvatarOnSitTarget(UUID.Zero);
@@ -1651,7 +1696,7 @@ namespace OpenSim.Region.Framework.Scenes
1651 bool SitTargetisSet = 1696 bool SitTargetisSet =
1652 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f && 1697 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1653 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f)); 1698 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1654 1699 // this test is probably failing
1655 if (SitTargetisSet && SitTargetUnOccupied) 1700 if (SitTargetisSet && SitTargetUnOccupied)
1656 { 1701 {
1657 //switch the target to this prim 1702 //switch the target to this prim
@@ -1678,26 +1723,37 @@ namespace OpenSim.Region.Framework.Scenes
1678 { 1723 {
1679 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1724 // 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 1725 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1681 1726
1727 // part is the prim to sit on
1728 // offset is the vector distance from that prim center to the click-spot
1729 // UUID is the UUID of the Avatar doing the clicking
1730
1731 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1732
1682 // Is a sit target available? 1733 // Is a sit target available?
1683 Vector3 avSitOffSet = part.SitTargetPosition; 1734 Vector3 avSitOffSet = part.SitTargetPosition;
1684 Quaternion avSitOrientation = part.SitTargetOrientation; 1735 Quaternion avSitOrientation = part.SitTargetOrientation;
1685 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1736 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1686 1737
1687 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1738 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1688 bool SitTargetisSet = 1739// bool SitTargetisSet =
1689 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && 1740// (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f &&
1690 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); 1741// avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f));
1691 1742
1743 bool SitTargetisSet = ((Vector3.Zero != avSitOffSet) || (Quaternion.Identity != avSitOrientation));
1744
1745//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied +
1746// " TargSet=" + SitTargetisSet);
1747
1692 if (SitTargetisSet && SitTargetUnOccupied) 1748 if (SitTargetisSet && SitTargetUnOccupied)
1693 { 1749 {
1694 part.SetAvatarOnSitTarget(UUID); 1750 part.SetAvatarOnSitTarget(UUID);
1695 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1751 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1696 sitOrientation = avSitOrientation; 1752 sitOrientation = avSitOrientation;
1697 autopilot = false; 1753 autopilot = false; // Jump direct to scripted llSitPos()
1698 } 1754 }
1699 1755
1700 pos = part.AbsolutePosition + offset; 1756 pos = part.AbsolutePosition + offset; // Region position where clicked
1701 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1757 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1702 //{ 1758 //{
1703 // offset = pos; 1759 // offset = pos;
@@ -1710,17 +1766,17 @@ namespace OpenSim.Region.Framework.Scenes
1710 m_sitAvatarHeight = m_physicsActor.Size.Z; 1766 m_sitAvatarHeight = m_physicsActor.Size.Z;
1711 1767
1712 if (autopilot) 1768 if (autopilot)
1713 { 1769 { // its not a scripted sit
1714 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1770 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5)
1715 { 1771 {
1716 autopilot = false; 1772 autopilot = false; // close enough
1717 1773
1718 RemoveFromPhysicalScene(); 1774 RemoveFromPhysicalScene();
1719 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1775 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to Prim
1720 } 1776 } // else the autopilot will get us close
1721 } 1777 }
1722 else 1778 else
1723 { 1779 { // its a scripted sit
1724 RemoveFromPhysicalScene(); 1780 RemoveFromPhysicalScene();
1725 } 1781 }
1726 } 1782 }
@@ -1823,26 +1879,41 @@ namespace OpenSim.Region.Framework.Scenes
1823 { 1879 {
1824 if (part.GetAvatarOnSitTarget() == UUID) 1880 if (part.GetAvatarOnSitTarget() == UUID)
1825 { 1881 {
1882 // Scripted sit
1826 Vector3 sitTargetPos = part.SitTargetPosition; 1883 Vector3 sitTargetPos = part.SitTargetPosition;
1827 Quaternion sitTargetOrient = part.SitTargetOrientation; 1884 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); 1885 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
1835 m_pos += SIT_TARGET_ADJUSTMENT; 1886 m_pos += SIT_TARGET_ADJUSTMENT;
1836 m_bodyRot = sitTargetOrient; 1887 m_bodyRot = sitTargetOrient;
1837 //Rotation = sitTargetOrient;
1838 m_parentPosition = part.AbsolutePosition; 1888 m_parentPosition = part.AbsolutePosition;
1839
1840 //SendTerseUpdateToAllClients();
1841 } 1889 }
1842 else 1890 else
1843 { 1891 {
1844 m_pos -= part.AbsolutePosition; 1892 // Non-scripted sit by Kitto Flora 21Nov09
1893 // Calculate angle of line from prim to Av
1894 float y_diff = (m_avInitialPos.Y - part.AbsolutePosition.Y);
1895 float x_diff = ( m_avInitialPos.X - part.AbsolutePosition.X);
1896 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
1897 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
1898 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
1899 Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1900 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
1901 // Av sits at world euler <0,0, z>, translated by part rotation
1902 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
1903 m_pos = new Vector3(0f, 0f, 0.05f) +
1904 (new Vector3(0.0f, 0f, 0.625f) * partIRot) +
1905 (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot); // sit at center of prim
1845 m_parentPosition = part.AbsolutePosition; 1906 m_parentPosition = part.AbsolutePosition;
1907 //Set up raytrace to find top surface of prim
1908 Vector3 size = part.Scale;
1909 float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
1910 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
1911 Vector3 down = new Vector3(0f, 0f, -1f);
1912 m_scene.PhysicsScene.RaycastWorld(
1913 start, // Vector3 position,
1914 down, // Vector3 direction,
1915 mag, // float length,
1916 SitAltitudeCallback); // retMethod
1846 } 1917 }
1847 } 1918 }
1848 else 1919 else
@@ -1857,11 +1928,22 @@ namespace OpenSim.Region.Framework.Scenes
1857 1928
1858 Animator.TrySetMovementAnimation(sitAnimation); 1929 Animator.TrySetMovementAnimation(sitAnimation);
1859 SendFullUpdateToAllClients(); 1930 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 } 1931 }
1932
1933 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance)
1934 {
1935// Console.WriteLine("[RAYCASTRESULT]: Hit={0}, Point={1}, ID={2}, Dist={3}", hitYN, collisionPoint, localid, distance);
1936 if(hitYN)
1937 {
1938 // m_pos = Av offset from prim center to make look like on center
1939 // m_parentPosition = Actual center pos of prim
1940 // collisionPoint = spot on prim where we want to sit
1941 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
1942 Vector3 offset = (collisionPoint - m_parentPosition) * Quaternion.Inverse(part.RotationOffset);
1943 m_pos += offset;
1944// Console.WriteLine("m_pos={0}, offset={1} newsit={2}", m_pos, offset, newsit);
1945 }
1946 }
1865 1947
1866 /// <summary> 1948 /// <summary>
1867 /// Event handler for the 'Always run' setting on the client 1949 /// Event handler for the 'Always run' setting on the client
@@ -1891,7 +1973,7 @@ namespace OpenSim.Region.Framework.Scenes
1891 /// </summary> 1973 /// </summary>
1892 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 1974 /// <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. 1975 /// <param name="rotation">The direction in which this avatar should now face.
1894 public void AddNewMovement(Vector3 vec, Quaternion rotation) 1976 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
1895 { 1977 {
1896 if (m_isChildAgent) 1978 if (m_isChildAgent)
1897 { 1979 {
@@ -1965,7 +2047,7 @@ namespace OpenSim.Region.Framework.Scenes
1965 2047
1966 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2048 // TODO: Add the force instead of only setting it to support multiple forces per frame?
1967 m_forceToApply = direc; 2049 m_forceToApply = direc;
1968 2050 m_isNudging = Nudging;
1969 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2051 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
1970 } 2052 }
1971 2053
@@ -1980,7 +2062,7 @@ namespace OpenSim.Region.Framework.Scenes
1980 const float POSITION_TOLERANCE = 0.05f; 2062 const float POSITION_TOLERANCE = 0.05f;
1981 //const int TIME_MS_TOLERANCE = 3000; 2063 //const int TIME_MS_TOLERANCE = 3000;
1982 2064
1983 SendPrimUpdates(); 2065
1984 2066
1985 if (m_newCoarseLocations) 2067 if (m_newCoarseLocations)
1986 { 2068 {
@@ -2016,6 +2098,9 @@ namespace OpenSim.Region.Framework.Scenes
2016 CheckForBorderCrossing(); 2098 CheckForBorderCrossing();
2017 CheckForSignificantMovement(); // sends update to the modules. 2099 CheckForSignificantMovement(); // sends update to the modules.
2018 } 2100 }
2101
2102 //Sending prim updates AFTER the avatar terse updates are sent
2103 SendPrimUpdates();
2019 } 2104 }
2020 2105
2021 #endregion 2106 #endregion
@@ -2869,14 +2954,24 @@ namespace OpenSim.Region.Framework.Scenes
2869 { 2954 {
2870 if (m_forceToApply.HasValue) 2955 if (m_forceToApply.HasValue)
2871 { 2956 {
2872 Vector3 force = m_forceToApply.Value;
2873 2957
2958 Vector3 force = m_forceToApply.Value;
2874 m_updateflag = true; 2959 m_updateflag = true;
2875// movementvector = force;
2876 Velocity = force; 2960 Velocity = force;
2877 2961
2878 m_forceToApply = null; 2962 m_forceToApply = null;
2879 } 2963 }
2964 else
2965 {
2966 if (m_isNudging)
2967 {
2968 Vector3 force = Vector3.Zero;
2969
2970 m_updateflag = true;
2971 Velocity = force;
2972 m_isNudging = false;
2973 }
2974 }
2880 } 2975 }
2881 2976
2882 public override void SetText(string text, Vector3 color, double alpha) 2977 public override void SetText(string text, Vector3 color, double alpha)
@@ -3585,4 +3680,4 @@ namespace OpenSim.Region.Framework.Scenes
3585 } 3680 }
3586 } 3681 }
3587 } 3682 }
3588} \ No newline at end of file 3683}
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 17552d2..b0e9a91 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;
@@ -2816,6 +2875,12 @@ Console.WriteLine(" JointCreateFixed");
2816 } 2875 }
2817 public override bool PIDActive { set { m_usePID = value; } } 2876 public override bool PIDActive { set { m_usePID = value; } }
2818 public override float PIDTau { set { m_PIDTau = value; } } 2877 public override float PIDTau { set { m_PIDTau = value; } }
2878
2879 // For RotLookAt
2880 public override Quaternion APIDTarget { set { m_APIDTarget = value; } }
2881 public override bool APIDActive { set { m_useAPID = value; } }
2882 public override float APIDStrength { set { m_APIDStrength = value; } }
2883 public override float APIDDamping { set { m_APIDDamping = value; } }
2819 2884
2820 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } 2885 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
2821 public override bool PIDHoverActive { set { m_useHoverPID = value; } } 2886 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 5de23ad..8274fbf 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
@@ -2546,12 +2561,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2546 2561
2547 m_host.AddScriptLPS(1); 2562 m_host.AddScriptLPS(1);
2548 2563
2564 m_host.TaskInventory.LockItemsForRead(true);
2549 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2565 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2550 2566 m_host.TaskInventory.LockItemsForRead(false);
2551 lock (m_host.TaskInventory)
2552 {
2553 item = m_host.TaskInventory[invItemID];
2554 }
2555 2567
2556 if (item.PermsGranter == UUID.Zero) 2568 if (item.PermsGranter == UUID.Zero)
2557 return 0; 2569 return 0;
@@ -2626,6 +2638,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2626 if (dist > m_ScriptDistanceFactor * 10.0f) 2638 if (dist > m_ScriptDistanceFactor * 10.0f)
2627 return; 2639 return;
2628 2640
2641 //Clone is thread-safe
2629 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2642 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2630 2643
2631 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2644 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2711,11 +2724,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2711 // Orient the object to the angle calculated 2724 // Orient the object to the angle calculated
2712 llSetRot(rot); 2725 llSetRot(rot);
2713 } 2726 }
2727
2728 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
2729 {
2730 m_host.AddScriptLPS(1);
2731// NotImplemented("llRotLookAt");
2732 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
2733
2734 }
2735
2714 2736
2715 public void llStopLookAt() 2737 public void llStopLookAt()
2716 { 2738 {
2717 m_host.AddScriptLPS(1); 2739 m_host.AddScriptLPS(1);
2718 NotImplemented("llStopLookAt"); 2740// NotImplemented("llStopLookAt");
2741 m_host.StopLookAt();
2719 } 2742 }
2720 2743
2721 public void llSetTimerEvent(double sec) 2744 public void llSetTimerEvent(double sec)
@@ -2749,13 +2772,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2749 { 2772 {
2750 TaskInventoryItem item; 2773 TaskInventoryItem item;
2751 2774
2752 lock (m_host.TaskInventory) 2775 m_host.TaskInventory.LockItemsForRead(true);
2776 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2753 { 2777 {
2754 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2778 m_host.TaskInventory.LockItemsForRead(false);
2755 return; 2779 return;
2756 else 2780 }
2757 item = m_host.TaskInventory[InventorySelf()]; 2781 else
2782 {
2783 item = m_host.TaskInventory[InventorySelf()];
2758 } 2784 }
2785 m_host.TaskInventory.LockItemsForRead(false);
2759 2786
2760 if (item.PermsGranter != UUID.Zero) 2787 if (item.PermsGranter != UUID.Zero)
2761 { 2788 {
@@ -2777,13 +2804,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2777 { 2804 {
2778 TaskInventoryItem item; 2805 TaskInventoryItem item;
2779 2806
2807 m_host.TaskInventory.LockItemsForRead(true);
2780 lock (m_host.TaskInventory) 2808 lock (m_host.TaskInventory)
2781 { 2809 {
2810
2782 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2811 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2812 {
2813 m_host.TaskInventory.LockItemsForRead(false);
2783 return; 2814 return;
2815 }
2784 else 2816 else
2817 {
2785 item = m_host.TaskInventory[InventorySelf()]; 2818 item = m_host.TaskInventory[InventorySelf()];
2819 }
2786 } 2820 }
2821 m_host.TaskInventory.LockItemsForRead(false);
2787 2822
2788 m_host.AddScriptLPS(1); 2823 m_host.AddScriptLPS(1);
2789 2824
@@ -2820,13 +2855,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2820 2855
2821 TaskInventoryItem item; 2856 TaskInventoryItem item;
2822 2857
2823 lock (m_host.TaskInventory) 2858 m_host.TaskInventory.LockItemsForRead(true);
2859
2860 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2824 { 2861 {
2825 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2862 m_host.TaskInventory.LockItemsForRead(false);
2826 return; 2863 return;
2827 else
2828 item = m_host.TaskInventory[InventorySelf()];
2829 } 2864 }
2865 else
2866 {
2867 item = m_host.TaskInventory[InventorySelf()];
2868 }
2869
2870 m_host.TaskInventory.LockItemsForRead(false);
2830 2871
2831 if (item.PermsGranter != m_host.OwnerID) 2872 if (item.PermsGranter != m_host.OwnerID)
2832 return; 2873 return;
@@ -2852,13 +2893,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2852 2893
2853 TaskInventoryItem item; 2894 TaskInventoryItem item;
2854 2895
2855 lock (m_host.TaskInventory) 2896 m_host.TaskInventory.LockItemsForRead(true);
2897
2898 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2856 { 2899 {
2857 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2900 m_host.TaskInventory.LockItemsForRead(false);
2858 return; 2901 return;
2859 else
2860 item = m_host.TaskInventory[InventorySelf()];
2861 } 2902 }
2903 else
2904 {
2905 item = m_host.TaskInventory[InventorySelf()];
2906 }
2907 m_host.TaskInventory.LockItemsForRead(false);
2908
2862 2909
2863 if (item.PermsGranter != m_host.OwnerID) 2910 if (item.PermsGranter != m_host.OwnerID)
2864 return; 2911 return;
@@ -3059,12 +3106,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3059 m_host.AddScriptLPS(1); 3106 m_host.AddScriptLPS(1);
3060 } 3107 }
3061 3108
3062 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3063 {
3064 m_host.AddScriptLPS(1);
3065 NotImplemented("llRotLookAt");
3066 }
3067
3068 public LSL_Integer llStringLength(string str) 3109 public LSL_Integer llStringLength(string str)
3069 { 3110 {
3070 m_host.AddScriptLPS(1); 3111 m_host.AddScriptLPS(1);
@@ -3088,14 +3129,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3088 3129
3089 TaskInventoryItem item; 3130 TaskInventoryItem item;
3090 3131
3091 lock (m_host.TaskInventory) 3132 m_host.TaskInventory.LockItemsForRead(true);
3133 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3092 { 3134 {
3093 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3135 m_host.TaskInventory.LockItemsForRead(false);
3094 return; 3136 return;
3095 else
3096 item = m_host.TaskInventory[InventorySelf()];
3097 } 3137 }
3098 3138 else
3139 {
3140 item = m_host.TaskInventory[InventorySelf()];
3141 }
3142 m_host.TaskInventory.LockItemsForRead(false);
3099 if (item.PermsGranter == UUID.Zero) 3143 if (item.PermsGranter == UUID.Zero)
3100 return; 3144 return;
3101 3145
@@ -3125,13 +3169,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3125 3169
3126 TaskInventoryItem item; 3170 TaskInventoryItem item;
3127 3171
3128 lock (m_host.TaskInventory) 3172 m_host.TaskInventory.LockItemsForRead(true);
3173 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3129 { 3174 {
3130 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3175 m_host.TaskInventory.LockItemsForRead(false);
3131 return; 3176 return;
3132 else 3177 }
3133 item = m_host.TaskInventory[InventorySelf()]; 3178 else
3179 {
3180 item = m_host.TaskInventory[InventorySelf()];
3134 } 3181 }
3182 m_host.TaskInventory.LockItemsForRead(false);
3183
3135 3184
3136 if (item.PermsGranter == UUID.Zero) 3185 if (item.PermsGranter == UUID.Zero)
3137 return; 3186 return;
@@ -3204,10 +3253,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3204 3253
3205 TaskInventoryItem item; 3254 TaskInventoryItem item;
3206 3255
3207 lock (m_host.TaskInventory) 3256
3257 m_host.TaskInventory.LockItemsForRead(true);
3258 if (!m_host.TaskInventory.ContainsKey(invItemID))
3259 {
3260 m_host.TaskInventory.LockItemsForRead(false);
3261 return;
3262 }
3263 else
3208 { 3264 {
3209 item = m_host.TaskInventory[invItemID]; 3265 item = m_host.TaskInventory[invItemID];
3210 } 3266 }
3267 m_host.TaskInventory.LockItemsForRead(false);
3211 3268
3212 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3269 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3213 { 3270 {
@@ -3239,11 +3296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3239 3296
3240 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3297 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3241 { 3298 {
3242 lock (m_host.TaskInventory) 3299 m_host.TaskInventory.LockItemsForWrite(true);
3243 { 3300 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3244 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3301 m_host.TaskInventory[invItemID].PermsMask = perm;
3245 m_host.TaskInventory[invItemID].PermsMask = perm; 3302 m_host.TaskInventory.LockItemsForWrite(false);
3246 }
3247 3303
3248 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3304 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3249 "run_time_permissions", new Object[] { 3305 "run_time_permissions", new Object[] {
@@ -3263,11 +3319,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3263 3319
3264 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3320 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3265 { 3321 {
3266 lock (m_host.TaskInventory) 3322 m_host.TaskInventory.LockItemsForWrite(true);
3267 { 3323 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3268 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3324 m_host.TaskInventory[invItemID].PermsMask = perm;
3269 m_host.TaskInventory[invItemID].PermsMask = perm; 3325 m_host.TaskInventory.LockItemsForWrite(false);
3270 }
3271 3326
3272 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3327 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3273 "run_time_permissions", new Object[] { 3328 "run_time_permissions", new Object[] {
@@ -3288,11 +3343,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3288 3343
3289 if (!m_waitingForScriptAnswer) 3344 if (!m_waitingForScriptAnswer)
3290 { 3345 {
3291 lock (m_host.TaskInventory) 3346 m_host.TaskInventory.LockItemsForWrite(true);
3292 { 3347 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3293 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3348 m_host.TaskInventory[invItemID].PermsMask = 0;
3294 m_host.TaskInventory[invItemID].PermsMask = 0; 3349 m_host.TaskInventory.LockItemsForWrite(false);
3295 }
3296 3350
3297 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3351 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3298 m_waitingForScriptAnswer=true; 3352 m_waitingForScriptAnswer=true;
@@ -3327,10 +3381,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3327 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3381 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3328 llReleaseControls(); 3382 llReleaseControls();
3329 3383
3330 lock (m_host.TaskInventory) 3384
3331 { 3385 m_host.TaskInventory.LockItemsForWrite(true);
3332 m_host.TaskInventory[invItemID].PermsMask = answer; 3386 m_host.TaskInventory[invItemID].PermsMask = answer;
3333 } 3387 m_host.TaskInventory.LockItemsForWrite(false);
3388
3334 3389
3335 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3390 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3336 "run_time_permissions", new Object[] { 3391 "run_time_permissions", new Object[] {
@@ -3342,16 +3397,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3342 { 3397 {
3343 m_host.AddScriptLPS(1); 3398 m_host.AddScriptLPS(1);
3344 3399
3345 lock (m_host.TaskInventory) 3400 m_host.TaskInventory.LockItemsForRead(true);
3401
3402 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3346 { 3403 {
3347 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3404 if (item.Type == 10 && item.ItemID == m_itemID)
3348 { 3405 {
3349 if (item.Type == 10 && item.ItemID == m_itemID) 3406 m_host.TaskInventory.LockItemsForRead(false);
3350 { 3407 return item.PermsGranter.ToString();
3351 return item.PermsGranter.ToString();
3352 }
3353 } 3408 }
3354 } 3409 }
3410 m_host.TaskInventory.LockItemsForRead(false);
3355 3411
3356 return UUID.Zero.ToString(); 3412 return UUID.Zero.ToString();
3357 } 3413 }
@@ -3360,19 +3416,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3360 { 3416 {
3361 m_host.AddScriptLPS(1); 3417 m_host.AddScriptLPS(1);
3362 3418
3363 lock (m_host.TaskInventory) 3419 m_host.TaskInventory.LockItemsForRead(true);
3420
3421 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3364 { 3422 {
3365 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3423 if (item.Type == 10 && item.ItemID == m_itemID)
3366 { 3424 {
3367 if (item.Type == 10 && item.ItemID == m_itemID) 3425 int perms = item.PermsMask;
3368 { 3426 if (m_automaticLinkPermission)
3369 int perms = item.PermsMask; 3427 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3370 if (m_automaticLinkPermission) 3428 m_host.TaskInventory.LockItemsForRead(false);
3371 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3429 return perms;
3372 return perms;
3373 }
3374 } 3430 }
3375 } 3431 }
3432 m_host.TaskInventory.LockItemsForRead(false);
3376 3433
3377 return 0; 3434 return 0;
3378 } 3435 }
@@ -3405,11 +3462,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3405 UUID invItemID = InventorySelf(); 3462 UUID invItemID = InventorySelf();
3406 3463
3407 TaskInventoryItem item; 3464 TaskInventoryItem item;
3408 lock (m_host.TaskInventory) 3465 m_host.TaskInventory.LockItemsForRead(true);
3409 { 3466 item = m_host.TaskInventory[invItemID];
3410 item = m_host.TaskInventory[invItemID]; 3467 m_host.TaskInventory.LockItemsForRead(false);
3411 } 3468
3412
3413 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3469 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3414 && !m_automaticLinkPermission) 3470 && !m_automaticLinkPermission)
3415 { 3471 {
@@ -3462,16 +3518,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3462 m_host.AddScriptLPS(1); 3518 m_host.AddScriptLPS(1);
3463 UUID invItemID = InventorySelf(); 3519 UUID invItemID = InventorySelf();
3464 3520
3465 lock (m_host.TaskInventory) 3521 m_host.TaskInventory.LockItemsForRead(true);
3466 {
3467 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3522 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3468 && !m_automaticLinkPermission) 3523 && !m_automaticLinkPermission)
3469 { 3524 {
3470 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3525 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3526 m_host.TaskInventory.LockItemsForRead(false);
3471 return; 3527 return;
3472 } 3528 }
3473 } 3529 m_host.TaskInventory.LockItemsForRead(false);
3474 3530
3475 if (linknum < ScriptBaseClass.LINK_THIS) 3531 if (linknum < ScriptBaseClass.LINK_THIS)
3476 return; 3532 return;
3477 3533
@@ -3640,17 +3696,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3640 m_host.AddScriptLPS(1); 3696 m_host.AddScriptLPS(1);
3641 int count = 0; 3697 int count = 0;
3642 3698
3643 lock (m_host.TaskInventory) 3699 m_host.TaskInventory.LockItemsForRead(true);
3700 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3644 { 3701 {
3645 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3702 if (inv.Value.Type == type || type == -1)
3646 { 3703 {
3647 if (inv.Value.Type == type || type == -1) 3704 count = count + 1;
3648 {
3649 count = count + 1;
3650 }
3651 } 3705 }
3652 } 3706 }
3653 3707
3708 m_host.TaskInventory.LockItemsForRead(false);
3654 return count; 3709 return count;
3655 } 3710 }
3656 3711
@@ -3659,16 +3714,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3659 m_host.AddScriptLPS(1); 3714 m_host.AddScriptLPS(1);
3660 ArrayList keys = new ArrayList(); 3715 ArrayList keys = new ArrayList();
3661 3716
3662 lock (m_host.TaskInventory) 3717 m_host.TaskInventory.LockItemsForRead(true);
3718 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3663 { 3719 {
3664 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3720 if (inv.Value.Type == type || type == -1)
3665 { 3721 {
3666 if (inv.Value.Type == type || type == -1) 3722 keys.Add(inv.Value.Name);
3667 {
3668 keys.Add(inv.Value.Name);
3669 }
3670 } 3723 }
3671 } 3724 }
3725 m_host.TaskInventory.LockItemsForRead(false);
3672 3726
3673 if (keys.Count == 0) 3727 if (keys.Count == 0)
3674 { 3728 {
@@ -3705,20 +3759,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3705 } 3759 }
3706 3760
3707 // move the first object found with this inventory name 3761 // move the first object found with this inventory name
3708 lock (m_host.TaskInventory) 3762 m_host.TaskInventory.LockItemsForRead(true);
3763 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3709 { 3764 {
3710 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3765 if (inv.Value.Name == inventory)
3711 { 3766 {
3712 if (inv.Value.Name == inventory) 3767 found = true;
3713 { 3768 objId = inv.Key;
3714 found = true; 3769 assetType = inv.Value.Type;
3715 objId = inv.Key; 3770 objName = inv.Value.Name;
3716 assetType = inv.Value.Type; 3771 break;
3717 objName = inv.Value.Name;
3718 break;
3719 }
3720 } 3772 }
3721 } 3773 }
3774 m_host.TaskInventory.LockItemsForRead(false);
3722 3775
3723 if (!found) 3776 if (!found)
3724 { 3777 {
@@ -3763,24 +3816,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3763 ScriptSleep(3000); 3816 ScriptSleep(3000);
3764 } 3817 }
3765 3818
3819 [DebuggerNonUserCode]
3766 public void llRemoveInventory(string name) 3820 public void llRemoveInventory(string name)
3767 { 3821 {
3768 m_host.AddScriptLPS(1); 3822 m_host.AddScriptLPS(1);
3769 3823
3770 lock (m_host.TaskInventory) 3824 m_host.TaskInventory.LockItemsForRead(true);
3825 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3771 { 3826 {
3772 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3827 if (item.Name == name)
3773 { 3828 {
3774 if (item.Name == name) 3829 if (item.ItemID == m_itemID)
3775 { 3830 throw new ScriptDeleteException();
3776 if (item.ItemID == m_itemID) 3831 else
3777 throw new ScriptDeleteException(); 3832 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3778 else 3833
3779 m_host.Inventory.RemoveInventoryItem(item.ItemID); 3834 m_host.TaskInventory.LockItemsForRead(false);
3780 return; 3835 return;
3781 }
3782 } 3836 }
3783 } 3837 }
3838 m_host.TaskInventory.LockItemsForRead(false);
3784 } 3839 }
3785 3840
3786 public void llSetText(string text, LSL_Vector color, double alpha) 3841 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3869,6 +3924,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3869 { 3924 {
3870 m_host.AddScriptLPS(1); 3925 m_host.AddScriptLPS(1);
3871 3926
3927 //Clone is thread safe
3872 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 3928 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3873 3929
3874 foreach (TaskInventoryItem item in itemDictionary.Values) 3930 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -3959,17 +4015,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3959 UUID soundId = UUID.Zero; 4015 UUID soundId = UUID.Zero;
3960 if (!UUID.TryParse(impact_sound, out soundId)) 4016 if (!UUID.TryParse(impact_sound, out soundId))
3961 { 4017 {
3962 lock (m_host.TaskInventory) 4018 m_host.TaskInventory.LockItemsForRead(true);
4019 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3963 { 4020 {
3964 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4021 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
3965 { 4022 {
3966 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4023 soundId = item.AssetID;
3967 { 4024 break;
3968 soundId = item.AssetID;
3969 break;
3970 }
3971 } 4025 }
3972 } 4026 }
4027 m_host.TaskInventory.LockItemsForRead(false);
3973 } 4028 }
3974 m_host.CollisionSound = soundId; 4029 m_host.CollisionSound = soundId;
3975 m_host.CollisionSoundVolume = (float)impact_volume; 4030 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4015,6 +4070,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4015 UUID partItemID; 4070 UUID partItemID;
4016 foreach (SceneObjectPart part in parts) 4071 foreach (SceneObjectPart part in parts)
4017 { 4072 {
4073 //Clone is thread safe
4018 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4074 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4019 4075
4020 foreach (TaskInventoryItem item in itemsDictionary.Values) 4076 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4222,17 +4278,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4222 4278
4223 m_host.AddScriptLPS(1); 4279 m_host.AddScriptLPS(1);
4224 4280
4225 lock (m_host.TaskInventory) 4281 m_host.TaskInventory.LockItemsForRead(true);
4282 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4226 { 4283 {
4227 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4284 if (item.Type == 10 && item.ItemID == m_itemID)
4228 { 4285 {
4229 if (item.Type == 10 && item.ItemID == m_itemID) 4286 result = item.Name!=null?item.Name:String.Empty;
4230 { 4287 break;
4231 result = item.Name!=null?item.Name:String.Empty;
4232 break;
4233 }
4234 } 4288 }
4235 } 4289 }
4290 m_host.TaskInventory.LockItemsForRead(false);
4236 4291
4237 return result; 4292 return result;
4238 } 4293 }
@@ -4490,23 +4545,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4490 { 4545 {
4491 m_host.AddScriptLPS(1); 4546 m_host.AddScriptLPS(1);
4492 4547
4493 lock (m_host.TaskInventory) 4548 m_host.TaskInventory.LockItemsForRead(true);
4549 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4494 { 4550 {
4495 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4551 if (inv.Value.Name == name)
4496 { 4552 {
4497 if (inv.Value.Name == name) 4553 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4498 { 4554 {
4499 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4555 m_host.TaskInventory.LockItemsForRead(false);
4500 { 4556 return inv.Value.AssetID.ToString();
4501 return inv.Value.AssetID.ToString(); 4557 }
4502 } 4558 else
4503 else 4559 {
4504 { 4560 m_host.TaskInventory.LockItemsForRead(false);
4505 return UUID.Zero.ToString(); 4561 return UUID.Zero.ToString();
4506 }
4507 } 4562 }
4508 } 4563 }
4509 } 4564 }
4565 m_host.TaskInventory.LockItemsForRead(false);
4510 4566
4511 return UUID.Zero.ToString(); 4567 return UUID.Zero.ToString();
4512 } 4568 }
@@ -6002,14 +6058,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6002 6058
6003 protected UUID GetTaskInventoryItem(string name) 6059 protected UUID GetTaskInventoryItem(string name)
6004 { 6060 {
6005 lock (m_host.TaskInventory) 6061 m_host.TaskInventory.LockItemsForRead(true);
6062 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6006 { 6063 {
6007 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6064 if (inv.Value.Name == name)
6008 { 6065 {
6009 if (inv.Value.Name == name) 6066 m_host.TaskInventory.LockItemsForRead(false);
6010 return inv.Key; 6067 return inv.Key;
6011 } 6068 }
6012 } 6069 }
6070 m_host.TaskInventory.LockItemsForRead(false);
6013 6071
6014 return UUID.Zero; 6072 return UUID.Zero;
6015 } 6073 }
@@ -6320,22 +6378,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6320 } 6378 }
6321 6379
6322 // copy the first script found with this inventory name 6380 // copy the first script found with this inventory name
6323 lock (m_host.TaskInventory) 6381 m_host.TaskInventory.LockItemsForRead(true);
6382 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6324 { 6383 {
6325 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6384 if (inv.Value.Name == name)
6326 { 6385 {
6327 if (inv.Value.Name == name) 6386 // make sure the object is a script
6387 if (10 == inv.Value.Type)
6328 { 6388 {
6329 // make sure the object is a script 6389 found = true;
6330 if (10 == inv.Value.Type) 6390 srcId = inv.Key;
6331 { 6391 break;
6332 found = true;
6333 srcId = inv.Key;
6334 break;
6335 }
6336 } 6392 }
6337 } 6393 }
6338 } 6394 }
6395 m_host.TaskInventory.LockItemsForRead(false);
6339 6396
6340 if (!found) 6397 if (!found)
6341 { 6398 {
@@ -8138,28 +8195,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8138 { 8195 {
8139 m_host.AddScriptLPS(1); 8196 m_host.AddScriptLPS(1);
8140 8197
8141 lock (m_host.TaskInventory) 8198 m_host.TaskInventory.LockItemsForRead(true);
8199 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8142 { 8200 {
8143 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8201 if (inv.Value.Name == item)
8144 { 8202 {
8145 if (inv.Value.Name == item) 8203 m_host.TaskInventory.LockItemsForRead(false);
8204 switch (mask)
8146 { 8205 {
8147 switch (mask) 8206 case 0:
8148 { 8207 return (int)inv.Value.BasePermissions;
8149 case 0: 8208 case 1:
8150 return (int)inv.Value.BasePermissions; 8209 return (int)inv.Value.CurrentPermissions;
8151 case 1: 8210 case 2:
8152 return (int)inv.Value.CurrentPermissions; 8211 return (int)inv.Value.GroupPermissions;
8153 case 2: 8212 case 3:
8154 return (int)inv.Value.GroupPermissions; 8213 return (int)inv.Value.EveryonePermissions;
8155 case 3: 8214 case 4:
8156 return (int)inv.Value.EveryonePermissions; 8215 return (int)inv.Value.NextPermissions;
8157 case 4:
8158 return (int)inv.Value.NextPermissions;
8159 }
8160 } 8216 }
8161 } 8217 }
8162 } 8218 }
8219 m_host.TaskInventory.LockItemsForRead(false);
8163 8220
8164 return -1; 8221 return -1;
8165 } 8222 }
@@ -8174,16 +8231,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8174 { 8231 {
8175 m_host.AddScriptLPS(1); 8232 m_host.AddScriptLPS(1);
8176 8233
8177 lock (m_host.TaskInventory) 8234 m_host.TaskInventory.LockItemsForRead(true);
8235 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8178 { 8236 {
8179 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8237 if (inv.Value.Name == item)
8180 { 8238 {
8181 if (inv.Value.Name == item) 8239 m_host.TaskInventory.LockItemsForRead(false);
8182 { 8240 return inv.Value.CreatorID.ToString();
8183 return inv.Value.CreatorID.ToString();
8184 }
8185 } 8241 }
8186 } 8242 }
8243 m_host.TaskInventory.LockItemsForRead(false);
8187 8244
8188 llSay(0, "No item name '" + item + "'"); 8245 llSay(0, "No item name '" + item + "'");
8189 8246
@@ -8707,16 +8764,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8707 { 8764 {
8708 m_host.AddScriptLPS(1); 8765 m_host.AddScriptLPS(1);
8709 8766
8710 lock (m_host.TaskInventory) 8767 m_host.TaskInventory.LockItemsForRead(true);
8768 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8711 { 8769 {
8712 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8770 if (inv.Value.Name == name)
8713 { 8771 {
8714 if (inv.Value.Name == name) 8772 m_host.TaskInventory.LockItemsForRead(false);
8715 { 8773 return inv.Value.Type;
8716 return inv.Value.Type;
8717 }
8718 } 8774 }
8719 } 8775 }
8776 m_host.TaskInventory.LockItemsForRead(false);
8720 8777
8721 return -1; 8778 return -1;
8722 } 8779 }
@@ -8747,17 +8804,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8747 if (invItemID == UUID.Zero) 8804 if (invItemID == UUID.Zero)
8748 return new LSL_Vector(); 8805 return new LSL_Vector();
8749 8806
8750 lock (m_host.TaskInventory) 8807 m_host.TaskInventory.LockItemsForRead(true);
8808 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8751 { 8809 {
8752 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 8810 m_host.TaskInventory.LockItemsForRead(false);
8753 return new LSL_Vector(); 8811 return new LSL_Vector();
8812 }
8754 8813
8755 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 8814 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8756 { 8815 {
8757 ShoutError("No permissions to track the camera"); 8816 ShoutError("No permissions to track the camera");
8758 return new LSL_Vector(); 8817 m_host.TaskInventory.LockItemsForRead(false);
8759 } 8818 return new LSL_Vector();
8760 } 8819 }
8820 m_host.TaskInventory.LockItemsForRead(false);
8761 8821
8762 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 8822 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8763 if (presence != null) 8823 if (presence != null)
@@ -8775,17 +8835,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8775 if (invItemID == UUID.Zero) 8835 if (invItemID == UUID.Zero)
8776 return new LSL_Rotation(); 8836 return new LSL_Rotation();
8777 8837
8778 lock (m_host.TaskInventory) 8838 m_host.TaskInventory.LockItemsForRead(true);
8839 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8779 { 8840 {
8780 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 8841 m_host.TaskInventory.LockItemsForRead(false);
8781 return new LSL_Rotation(); 8842 return new LSL_Rotation();
8782
8783 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8784 {
8785 ShoutError("No permissions to track the camera");
8786 return new LSL_Rotation();
8787 }
8788 } 8843 }
8844 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8845 {
8846 ShoutError("No permissions to track the camera");
8847 m_host.TaskInventory.LockItemsForRead(false);
8848 return new LSL_Rotation();
8849 }
8850 m_host.TaskInventory.LockItemsForRead(false);
8789 8851
8790 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 8852 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8791 if (presence != null) 8853 if (presence != null)
@@ -8935,14 +8997,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8935 if (objectID == UUID.Zero) return; 8997 if (objectID == UUID.Zero) return;
8936 8998
8937 UUID agentID; 8999 UUID agentID;
8938 lock (m_host.TaskInventory) 9000 m_host.TaskInventory.LockItemsForRead(true);
8939 { 9001 // we need the permission first, to know which avatar we want to set the camera for
8940 // we need the permission first, to know which avatar we want to set the camera for 9002 agentID = m_host.TaskInventory[invItemID].PermsGranter;
8941 agentID = m_host.TaskInventory[invItemID].PermsGranter;
8942 9003
8943 if (agentID == UUID.Zero) return; 9004 if (agentID == UUID.Zero)
8944 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9005 {
9006 m_host.TaskInventory.LockItemsForRead(false);
9007 return;
8945 } 9008 }
9009 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9010 {
9011 m_host.TaskInventory.LockItemsForRead(false);
9012 return;
9013 }
9014 m_host.TaskInventory.LockItemsForRead(false);
8946 9015
8947 ScenePresence presence = World.GetScenePresence(agentID); 9016 ScenePresence presence = World.GetScenePresence(agentID);
8948 9017
@@ -8992,12 +9061,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8992 9061
8993 // we need the permission first, to know which avatar we want to clear the camera for 9062 // we need the permission first, to know which avatar we want to clear the camera for
8994 UUID agentID; 9063 UUID agentID;
8995 lock (m_host.TaskInventory) 9064 m_host.TaskInventory.LockItemsForRead(true);
9065 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9066 if (agentID == UUID.Zero)
9067 {
9068 m_host.TaskInventory.LockItemsForRead(false);
9069 return;
9070 }
9071 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
8996 { 9072 {
8997 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9073 m_host.TaskInventory.LockItemsForRead(false);
8998 if (agentID == UUID.Zero) return; 9074 return;
8999 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9000 } 9075 }
9076 m_host.TaskInventory.LockItemsForRead(false);
9001 9077
9002 ScenePresence presence = World.GetScenePresence(agentID); 9078 ScenePresence presence = World.GetScenePresence(agentID);
9003 9079
@@ -9454,15 +9530,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9454 9530
9455 internal UUID ScriptByName(string name) 9531 internal UUID ScriptByName(string name)
9456 { 9532 {
9457 lock (m_host.TaskInventory) 9533 m_host.TaskInventory.LockItemsForRead(true);
9534
9535 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9458 { 9536 {
9459 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 9537 if (item.Type == 10 && item.Name == name)
9460 { 9538 {
9461 if (item.Type == 10 && item.Name == name) 9539 m_host.TaskInventory.LockItemsForRead(false);
9462 return item.ItemID; 9540 return item.ItemID;
9463 } 9541 }
9464 } 9542 }
9465 9543
9544 m_host.TaskInventory.LockItemsForRead(false);
9545
9466 return UUID.Zero; 9546 return UUID.Zero;
9467 } 9547 }
9468 9548
@@ -9503,6 +9583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9503 { 9583 {
9504 m_host.AddScriptLPS(1); 9584 m_host.AddScriptLPS(1);
9505 9585
9586 //Clone is thread safe
9506 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 9587 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9507 9588
9508 UUID assetID = UUID.Zero; 9589 UUID assetID = UUID.Zero;
@@ -9565,6 +9646,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9565 { 9646 {
9566 m_host.AddScriptLPS(1); 9647 m_host.AddScriptLPS(1);
9567 9648
9649 //Clone is thread safe
9568 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 9650 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9569 9651
9570 UUID assetID = UUID.Zero; 9652 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 5584f87..2fc2ea1 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);
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 116a8fd..f9d9ca6 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -454,6 +454,9 @@
454 454
455 ; Distance in meters that shouts should travel. Default is 100m 455 ; Distance in meters that shouts should travel. Default is 100m
456 shout_distance = 100 456 shout_distance = 100
457
458 ; Append a prefix to the god avatar names appearing in chat whilst in god mode
459 ; admin_prefix = "@"
457 460
458 461
459[Messaging] 462[Messaging]