aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs93
-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/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs21
-rw-r--r--OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs274
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs557
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs95
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs380
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs514
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs11
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs2
-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.cs99
-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/CM_Api.cs473
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs565
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs36
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs76
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs76
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp2
-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.cs424
45 files changed, 3218 insertions, 1234 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 4780701..e7ce2e0 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -792,16 +792,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
792 } 792 }
793 } 793 }
794 794
795 public void SendGenericMessage(string method, List<string> message) 795 public void SendGenericMessage(string method, List<byte[]> message)
796 { 796 {
797 GenericMessagePacket gmp = new GenericMessagePacket(); 797 GenericMessagePacket gmp = new GenericMessagePacket();
798 gmp.MethodData.Method = Util.StringToBytes256(method); 798 gmp.MethodData.Method = Util.StringToBytes256(method);
799 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; 799 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
800 int i = 0; 800 int i = 0;
801 foreach (string val in message) 801 foreach (byte[] val in message)
802 { 802 {
803 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); 803 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock();
804 gmp.ParamList[i++].Parameter = Util.StringToBytes256(val); 804 gmp.ParamList[i++].Parameter = val;
805 } 805 }
806 OutPacket(gmp, ThrottleOutPacketType.Task); 806 OutPacket(gmp, ThrottleOutPacketType.Task);
807 } 807 }
@@ -813,6 +813,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
813 public virtual void SendLayerData(float[] map) 813 public virtual void SendLayerData(float[] map)
814 { 814 {
815 Util.FireAndForget(DoSendLayerData, map); 815 Util.FireAndForget(DoSendLayerData, map);
816
817 // Send it sync, and async. It's not that much data
818 // and it improves user experience just so much!
819 DoSendLayerData(map);
816 } 820 }
817 821
818 /// <summary> 822 /// <summary>
@@ -825,16 +829,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
825 829
826 try 830 try
827 { 831 {
828 //for (int y = 0; y < 16; y++) 832 for (int y = 0; y < 16; y++)
829 //{ 833 {
830 // for (int x = 0; x < 16; x++) 834 for (int x = 0; x < 16; x+=4)
831 // { 835 {
832 // SendLayerData(x, y, map); 836 SendLayerPacket(x, y, map);
833 // } 837 }
834 //} 838 }
835
836 // Send LayerData in a spiral pattern. Fun!
837 SendLayerTopRight(map, 0, 0, 15, 15);
838 } 839 }
839 catch (Exception e) 840 catch (Exception e)
840 { 841 {
@@ -842,51 +843,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
842 } 843 }
843 } 844 }
844 845
845 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
846 {
847 // Row
848 for (int i = x1; i <= x2; i++)
849 SendLayerData(i, y1, map);
850
851 // Column
852 for (int j = y1 + 1; j <= y2; j++)
853 SendLayerData(x2, j, map);
854
855 if (x2 - x1 > 0)
856 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
857 }
858
859 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
860 {
861 // Row in reverse
862 for (int i = x2; i >= x1; i--)
863 SendLayerData(i, y2, map);
864
865 // Column in reverse
866 for (int j = y2 - 1; j >= y1; j--)
867 SendLayerData(x1, j, map);
868
869 if (x2 - x1 > 0)
870 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
871 }
872
873 /// <summary> 846 /// <summary>
874 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 847 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
875 /// </summary> 848 /// </summary>
876 /// <param name="map">heightmap</param> 849 /// <param name="map">heightmap</param>
877 /// <param name="px">X coordinate for patches 0..12</param> 850 /// <param name="px">X coordinate for patches 0..12</param>
878 /// <param name="py">Y coordinate for patches 0..15</param> 851 /// <param name="py">Y coordinate for patches 0..15</param>
879 // private void SendLayerPacket(float[] map, int y, int x) 852 private void SendLayerPacket(int x, int y, float[] map)
880 // { 853 {
881 // int[] patches = new int[4]; 854 int[] patches = new int[4];
882 // patches[0] = x + 0 + y * 16; 855 patches[0] = x + 0 + y * 16;
883 // patches[1] = x + 1 + y * 16; 856 patches[1] = x + 1 + y * 16;
884 // patches[2] = x + 2 + y * 16; 857 patches[2] = x + 2 + y * 16;
885 // patches[3] = x + 3 + y * 16; 858 patches[3] = x + 3 + y * 16;
886 859
887 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 860 float[] heightmap = (map.Length == 65536) ?
888 // OutPacket(layerpack, ThrottleOutPacketType.Land); 861 map :
889 // } 862 LLHeightFieldMoronize(map);
863
864 try
865 {
866 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
867 OutPacket(layerpack, ThrottleOutPacketType.Land);
868 }
869 catch
870 {
871 for (int px = x ; px < x + 4 ; px++)
872 SendLayerData(px, y, map);
873 }
874 }
890 875
891 /// <summary> 876 /// <summary>
892 /// Sends a specified patch to a client 877 /// Sends a specified patch to a client
@@ -3164,7 +3149,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3164 3149
3165 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3150 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3166 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); 3151 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
3167
3168 OutPacket(objupdate, ThrottleOutPacketType.Task); 3152 OutPacket(objupdate, ThrottleOutPacketType.Task);
3169 } 3153 }
3170 3154
@@ -3215,8 +3199,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3215 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3199 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3216 } 3200 }
3217 3201
3218 // HACK: Using the task category until the tiered reprioritization code is in 3202 OutPacket(terse, ThrottleOutPacketType.State);
3219 OutPacket(terse, ThrottleOutPacketType.Task);
3220 } 3203 }
3221 3204
3222 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3205 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
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/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs
index 710e3ca..39e2413 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs
@@ -331,12 +331,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion
331 { 331 {
332 //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); 332 //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called");
333 333
334 m_log.Debug("---------------------------"); 334/* m_log.Debug("---------------------------");
335 m_log.Debug(" >> uri=" + request["uri"]); 335 m_log.Debug(" >> uri=" + request["uri"]);
336 m_log.Debug(" >> content-type=" + request["content-type"]); 336 m_log.Debug(" >> content-type=" + request["content-type"]);
337 m_log.Debug(" >> http-method=" + request["http-method"]); 337 m_log.Debug(" >> http-method=" + request["http-method"]);
338 m_log.Debug("---------------------------\n"); 338 m_log.Debug("---------------------------\n"); */
339
340 Hashtable responsedata = new Hashtable(); 339 Hashtable responsedata = new Hashtable();
341 responsedata["content_type"] = "text/html"; 340 responsedata["content_type"] = "text/html";
342 responsedata["keepalive"] = false; 341 responsedata["keepalive"] = false;
@@ -576,11 +575,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion
576 { 575 {
577 m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called"); 576 m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called");
578 577
579 m_log.Debug("---------------------------"); 578 /* m_log.Debug("---------------------------");
580 m_log.Debug(" >> uri=" + request["uri"]); 579 m_log.Debug(" >> uri=" + request["uri"]);
581 m_log.Debug(" >> content-type=" + request["content-type"]); 580 m_log.Debug(" >> content-type=" + request["content-type"]);
582 m_log.Debug(" >> http-method=" + request["http-method"]); 581 m_log.Debug(" >> http-method=" + request["http-method"]);
583 m_log.Debug("---------------------------\n"); 582 m_log.Debug("---------------------------\n"); */
584 583
585 Hashtable responsedata = new Hashtable(); 584 Hashtable responsedata = new Hashtable();
586 responsedata["content_type"] = "text/html"; 585 responsedata["content_type"] = "text/html";
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index af72968..3c0997c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -247,21 +247,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver
247 // Fix ownership/creator of inventory items 247 // Fix ownership/creator of inventory items
248 // Not doing so results in inventory items 248 // Not doing so results in inventory items
249 // being no copy/no mod for everyone 249 // being no copy/no mod for everyone
250 lock (part.TaskInventory) 250 part.TaskInventory.LockItemsForRead(true);
251 TaskInventoryDictionary inv = part.TaskInventory;
252 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
251 { 253 {
252 TaskInventoryDictionary inv = part.TaskInventory; 254 if (!ResolveUserUuid(kvp.Value.OwnerID))
253 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
254 { 255 {
255 if (!ResolveUserUuid(kvp.Value.OwnerID)) 256 kvp.Value.OwnerID = masterAvatarId;
256 { 257 }
257 kvp.Value.OwnerID = masterAvatarId; 258 if (!ResolveUserUuid(kvp.Value.CreatorID))
258 } 259 {
259 if (!ResolveUserUuid(kvp.Value.CreatorID)) 260 kvp.Value.CreatorID = masterAvatarId;
260 {
261 kvp.Value.CreatorID = masterAvatarId;
262 }
263 } 261 }
264 } 262 }
263 part.TaskInventory.LockItemsForRead(false);
265 } 264 }
266 265
267 if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) 266 if (m_scene.AddRestoredSceneObject(sceneObject, true, false))
diff --git a/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs b/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs
new file mode 100644
index 0000000..72b0b38
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs
@@ -0,0 +1,274 @@
1/*
2 * Copyright (c) Thomas Grimshaw and Magne Metaverse Research
3 *
4 * This module is not open source. All rights reserved.
5 * Unauthorised copying, distribution or public display is prohibited.
6 *
7 */
8
9using System;
10using System.Collections.Generic;
11using System.IO;
12using System.Reflection;
13using OpenMetaverse;
14using log4net;
15using Nini.Config;
16using OpenSim.Data;
17using OpenSim.Framework;
18using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
19using OpenSim.Region.Framework.Interfaces;
20using OpenSim.Region.Framework.Scenes;
21
22
23namespace OpenSim.Region.CoreModules.World.Meta7Windlight
24{
25 public class Meta7WindlightModule : IRegionModule, ICommandableModule
26 {
27 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
28 private readonly Commander m_commander = new Commander("windlight");
29 private Scene m_scene;
30 private static bool m_enableWindlight;
31
32 #region ICommandableModule Members
33
34 public ICommander CommandInterface
35 {
36 get { return m_commander; }
37 }
38
39 #endregion
40
41 #region IRegionModule Members
42
43 public static bool EnableWindlight
44 {
45 get
46 {
47 return m_enableWindlight;
48 }
49 set
50 {
51 }
52 }
53
54 public void Initialise(Scene scene, IConfigSource config)
55 {
56 m_scene = scene;
57 m_scene.RegisterModuleInterface<IRegionModule>(this);
58 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
59
60 // ini file settings
61 try
62 {
63 m_enableWindlight = config.Configs["Meta7Windlight"].GetBoolean("enable_windlight", false);
64 }
65 catch (Exception)
66 {
67 m_log.Debug("[WINDLIGHT]: ini failure for enable_windlight - using default");
68 }
69
70 if (m_enableWindlight)
71 {
72 m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent;
73 m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile;
74 m_scene.EventManager.OnSendNewWindlightProfileTargeted += EventManager_OnSendNewWindlightProfileTargeted;
75 }
76
77 InstallCommands();
78
79 m_log.Debug("[WINDLIGHT]: Initialised windlight module");
80 }
81
82 private List<byte[]> compileWindlightSettings(RegionMeta7WindlightData wl)
83 {
84 byte[] mBlock = new Byte[249];
85 int pos = 0;
86
87 wl.waterColor.ToBytes(mBlock, 0); pos += 12;
88 Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4;
89 Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4;
90 wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12;
91 Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4;
92 Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4;
93 Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4;
94 Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4;
95 Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4;
96 wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8;
97 wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8;
98 wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16;
99 wl.horizon.ToBytes(mBlock, pos); pos += 16;
100 Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4;
101 wl.blueDensity.ToBytes(mBlock, pos); pos += 16;
102 Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4;
103 Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4;
104 Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4;
105 wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16;
106 Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4;
107 wl.ambient.ToBytes(mBlock, pos); pos += 16;
108 Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4;
109 Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4;
110 Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4;
111 Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4;
112 Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4;
113 wl.cloudColor.ToBytes(mBlock, pos); pos += 16;
114 wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12;
115 Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4;
116 Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4;
117 wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12;
118 Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4;
119 Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4;
120 Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2;
121 mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++;
122 mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++;
123 mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++;
124 List<byte[]> param = new List<byte[]>();
125 param.Add(mBlock);
126 return param;
127 }
128 public void SendProfileToClient(ScenePresence presence)
129 {
130 IClientAPI client = presence.ControllingClient;
131 if (m_enableWindlight)
132 {
133 if (presence.IsChildAgent == false)
134 {
135 List<byte[]> param = compileWindlightSettings(m_scene.RegionInfo.WindlightSettings);
136 client.SendGenericMessage("Windlight", param);
137 }
138 }
139 else
140 {
141 //We probably don't want to spam chat with this.. probably
142 //m_log.Debug("[WINDLIGHT]: Module disabled");
143 }
144 }
145 public void SendProfileToClient(ScenePresence presence, RegionMeta7WindlightData wl)
146 {
147 IClientAPI client = presence.ControllingClient;
148 if (m_enableWindlight)
149 {
150 if (presence.IsChildAgent == false)
151 {
152 List<byte[]> param = compileWindlightSettings(wl);
153 client.SendGenericMessage("Windlight", param);
154 }
155 }
156 else
157 {
158 //We probably don't want to spam chat with this.. probably
159 //m_log.Debug("[WINDLIGHT]: Module disabled");
160 }
161 }
162 private void EventManager_OnMakeRootAgent(ScenePresence presence)
163 {
164 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
165 SendProfileToClient(presence);
166 }
167 private void EventManager_OnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID pUUID)
168 {
169 ScenePresence Sc;
170 if (m_scene.TryGetAvatar(pUUID,out Sc))
171 {
172 SendProfileToClient(Sc,wl);
173 }
174 }
175 private void EventManager_OnSaveNewWindlightProfile()
176 {
177 m_scene.ForEachScenePresence(SendProfileToClient);
178 }
179
180 public void PostInitialise()
181 {
182
183 }
184
185 public void Close()
186 {
187 }
188
189 public string Name
190 {
191 get { return "Meta7WindlightModule"; }
192 }
193
194 public bool IsSharedModule
195 {
196 get { return false; }
197 }
198
199 #endregion
200
201 #region events
202
203 #endregion
204
205 #region ICommandableModule Members
206
207 private void InstallCommands()
208 {
209 Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast");
210 Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin");
211 Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Enable the windlight plugin");
212
213 m_commander.RegisterCommand("load", wlload);
214 m_commander.RegisterCommand("enable", wlenable);
215 m_commander.RegisterCommand("disable", wldisable);
216
217 m_scene.RegisterModuleCommander(m_commander);
218 }
219
220 private void HandleLoad(Object[] args)
221 {
222 if (!m_enableWindlight)
223 {
224 m_log.InfoFormat("[WINDLIGHT]: Cannot load windlight profile, module disabled. Use 'windlight enable' first.");
225 }
226 else
227 {
228 m_log.InfoFormat("[WINDLIGHT]: Loading Windlight profile from database");
229 m_scene.LoadWindlightProfile();
230 m_log.InfoFormat("[WINDLIGHT]: Load complete");
231 }
232 }
233
234 private void HandleDisable(Object[] args)
235 {
236 m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled");
237 m_enableWindlight=false;
238 }
239
240 private void HandleEnable(Object[] args)
241 {
242 m_log.InfoFormat("[WINDLIGHT]: Plugin now enabled");
243 m_enableWindlight = true;
244 }
245
246 /// <summary>
247 /// Processes commandline input. Do not call directly.
248 /// </summary>
249 /// <param name="args">Commandline arguments</param>
250 private void EventManager_OnPluginConsole(string[] args)
251 {
252 if (args[0] == "windlight")
253 {
254 if (args.Length == 1)
255 {
256 m_commander.ProcessConsoleCommand("add", new string[0]);
257 return;
258 }
259
260 string[] tmpArgs = new string[args.Length - 2];
261 int i;
262 for (i = 2; i < args.Length; i++)
263 {
264 tmpArgs[i - 2] = args[i];
265 }
266
267 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
268 }
269 }
270 #endregion
271
272 }
273}
274
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 9754da3..816060f 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -433,7 +433,7 @@ namespace OpenSim.Region.Examples.SimpleModule
433 433
434 } 434 }
435 435
436 public void SendGenericMessage(string method, List<string> message) 436 public void SendGenericMessage(string method, List<byte[]> message)
437 { 437 {
438 438
439 } 439 }
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
index 78bd622..7312799 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
@@ -103,6 +103,8 @@ namespace OpenSim.Region.Framework.Interfaces
103 103
104 void StoreRegionSettings(RegionSettings rs); 104 void StoreRegionSettings(RegionSettings rs);
105 RegionSettings LoadRegionSettings(UUID regionUUID); 105 RegionSettings LoadRegionSettings(UUID regionUUID);
106 RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID);
107 void StoreRegionWindlightSettings(RegionMeta7WindlightData wl);
106 108
107 void Shutdown(); 109 void Shutdown();
108 } 110 }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index c314596..e98f0e7 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -53,8 +53,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
53 { 53 {
54 get { return m_movementAnimation; } 54 get { return m_movementAnimation; }
55 } 55 }
56 protected string m_movementAnimation = "DEFAULT"; 56 // protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist!
57 57 protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init.
58 private int m_animTickFall; 58 private int m_animTickFall;
59 private int m_animTickJump; 59 private int m_animTickJump;
60 60
@@ -123,17 +123,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation
123 /// </summary> 123 /// </summary>
124 public void TrySetMovementAnimation(string anim) 124 public void TrySetMovementAnimation(string anim)
125 { 125 {
126 //m_log.DebugFormat("Updating movement animation to {0}", anim); 126//Console.WriteLine("Updating movement animation to {0}", anim);
127 127
128 if (!m_scenePresence.IsChildAgent) 128 if (!m_scenePresence.IsChildAgent)
129 { 129 {
130 if (m_animations.TrySetDefaultAnimation( 130 if (m_animations.TrySetDefaultAnimation(
131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) 131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID))
132 { 132 {
133//Console.WriteLine("TSMA {0} success.", anim);
133 // 16384 is CHANGED_ANIMATION 134 // 16384 is CHANGED_ANIMATION
134 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); 135 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 });
135 SendAnimPack(); 136 SendAnimPack();
136 } 137 }
138 else
139 {
140//Console.WriteLine("TSMA {0} fail.", anim);
141 }
137 } 142 }
138 } 143 }
139 144
@@ -156,10 +161,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 161 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
157 162
158 // Check control flags 163 // Check control flags
159 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; 164 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
160 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 165 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
161 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 166 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
162 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; 167 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
163 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 168 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
164 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; 169 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
165 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 170 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
@@ -312,7 +317,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
312 public void UpdateMovementAnimations() 317 public void UpdateMovementAnimations()
313 { 318 {
314 m_movementAnimation = GetMovementAnimation(); 319 m_movementAnimation = GetMovementAnimation();
315 320//Console.WriteLine("UMA got {0}", m_movementAnimation);
316 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) 321 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
317 { 322 {
318 // This was the previous behavior before PREJUMP 323 // This was the previous behavior before PREJUMP
@@ -450,4 +455,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
450 m_scenePresence = null; 455 m_scenePresence = null;
451 } 456 }
452 } 457 }
453} \ No newline at end of file 458}
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
index 099fcce..c246e32 100644
--- a/OpenSim/Region/Framework/Scenes/EntityManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes
40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>(); 40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>();
41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>(); 41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>();
42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>(); 42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>();
43 private readonly Object m_lock = new Object(); 43 private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim();
44 44
45 [Obsolete("Use Add() instead.")] 45 [Obsolete("Use Add() instead.")]
46 public void Add(UUID id, EntityBase eb) 46 public void Add(UUID id, EntityBase eb)
@@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes
50 50
51 public void Add(EntityBase entity) 51 public void Add(EntityBase entity)
52 { 52 {
53 lock (m_lock) 53 m_lock.EnterWriteLock();
54 try
54 { 55 {
55 try 56 try
56 { 57 {
@@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes
62 m_log.ErrorFormat("Add Entity failed: {0}", e.Message); 63 m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
63 } 64 }
64 } 65 }
66 finally
67 {
68 m_lock.ExitWriteLock();
69 }
65 } 70 }
66 71
67 public void InsertOrReplace(EntityBase entity) 72 public void InsertOrReplace(EntityBase entity)
68 { 73 {
69 lock (m_lock) 74 m_lock.EnterWriteLock();
75 try
70 { 76 {
71 try 77 try
72 { 78 {
@@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes
78 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); 84 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
79 } 85 }
80 } 86 }
87 finally
88 {
89 m_lock.ExitWriteLock();
90 }
81 } 91 }
82 92
83 public void Clear() 93 public void Clear()
84 { 94 {
85 lock (m_lock) 95 m_lock.EnterWriteLock();
96 try
86 { 97 {
87 m_eb_uuid.Clear(); 98 m_eb_uuid.Clear();
88 m_eb_localID.Clear(); 99 m_eb_localID.Clear();
89 } 100 }
101 finally
102 {
103 m_lock.ExitWriteLock();
104 }
90 } 105 }
91 106
92 public int Count 107 public int Count
@@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes
123 138
124 public bool Remove(uint localID) 139 public bool Remove(uint localID)
125 { 140 {
126 lock (m_lock) 141 m_lock.EnterWriteLock();
142 try
127 { 143 {
128 try 144 try
129 { 145 {
@@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes
141 return false; 157 return false;
142 } 158 }
143 } 159 }
160 finally
161 {
162 m_lock.ExitWriteLock();
163 }
144 } 164 }
145 165
146 public bool Remove(UUID id) 166 public bool Remove(UUID id)
147 { 167 {
148 lock (m_lock) 168 m_lock.EnterWriteLock();
169 try
149 { 170 {
150 try 171 try
151 { 172 {
@@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes
163 return false; 184 return false;
164 } 185 }
165 } 186 }
187 finally
188 {
189 m_lock.ExitWriteLock();
190 }
166 } 191 }
167 192
168 public List<EntityBase> GetAllByType<T>() 193 public List<EntityBase> GetAllByType<T>()
169 { 194 {
170 List<EntityBase> tmp = new List<EntityBase>(); 195 List<EntityBase> tmp = new List<EntityBase>();
171 196
172 lock (m_lock) 197 m_lock.EnterReadLock();
198 try
173 { 199 {
174 try 200 try
175 { 201 {
@@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes
187 tmp = null; 213 tmp = null;
188 } 214 }
189 } 215 }
216 finally
217 {
218 m_lock.ExitReadLock();
219 }
190 220
191 return tmp; 221 return tmp;
192 } 222 }
193 223
194 public List<EntityBase> GetEntities() 224 public List<EntityBase> GetEntities()
195 { 225 {
196 lock (m_lock) 226 m_lock.EnterReadLock();
227 try
197 { 228 {
198 return new List<EntityBase>(m_eb_uuid.Values); 229 return new List<EntityBase>(m_eb_uuid.Values);
199 } 230 }
231 finally
232 {
233 m_lock.ExitReadLock();
234 }
200 } 235 }
201 236
202 public EntityBase this[UUID id] 237 public EntityBase this[UUID id]
203 { 238 {
204 get 239 get
205 { 240 {
206 lock (m_lock) 241 m_lock.EnterReadLock();
242 try
207 { 243 {
208 EntityBase entity; 244 EntityBase entity;
209 if (m_eb_uuid.TryGetValue(id, out entity)) 245 if (m_eb_uuid.TryGetValue(id, out entity))
@@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes
211 else 247 else
212 return null; 248 return null;
213 } 249 }
250 finally
251 {
252 m_lock.ExitReadLock();
253 }
214 } 254 }
215 set 255 set
216 { 256 {
@@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes
222 { 262 {
223 get 263 get
224 { 264 {
225 lock (m_lock) 265 m_lock.EnterReadLock();
266 try
226 { 267 {
227 EntityBase entity; 268 EntityBase entity;
228 if (m_eb_localID.TryGetValue(localID, out entity)) 269 if (m_eb_localID.TryGetValue(localID, out entity))
@@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes
230 else 271 else
231 return null; 272 return null;
232 } 273 }
274 finally
275 {
276 m_lock.ExitReadLock();
277 }
233 } 278 }
234 set 279 set
235 { 280 {
@@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes
239 284
240 public bool TryGetValue(UUID key, out EntityBase obj) 285 public bool TryGetValue(UUID key, out EntityBase obj)
241 { 286 {
242 lock (m_lock) 287 m_lock.EnterReadLock();
288 try
243 { 289 {
244 return m_eb_uuid.TryGetValue(key, out obj); 290 return m_eb_uuid.TryGetValue(key, out obj);
245 } 291 }
292 finally
293 {
294 m_lock.ExitReadLock();
295 }
246 } 296 }
247 297
248 public bool TryGetValue(uint key, out EntityBase obj) 298 public bool TryGetValue(uint key, out EntityBase obj)
249 { 299 {
250 lock (m_lock) 300 m_lock.EnterReadLock();
301 try
251 { 302 {
252 return m_eb_localID.TryGetValue(key, out obj); 303 return m_eb_localID.TryGetValue(key, out obj);
253 } 304 }
305 finally
306 {
307 m_lock.ExitReadLock();
308 }
254 } 309 }
255 310
256 /// <summary> 311 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 753344d..68e73b1 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -193,7 +193,11 @@ namespace OpenSim.Region.Framework.Scenes
193 public event OnMakeChildAgentDelegate OnMakeChildAgent; 193 public event OnMakeChildAgentDelegate OnMakeChildAgent;
194 194
195 public delegate void OnMakeRootAgentDelegate(ScenePresence presence); 195 public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
196 public delegate void OnSaveNewWindlightProfileDelegate();
197 public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user);
196 public event OnMakeRootAgentDelegate OnMakeRootAgent; 198 public event OnMakeRootAgentDelegate OnMakeRootAgent;
199 public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted;
200 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
197 201
198 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); 202 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
199 203
@@ -411,6 +415,8 @@ namespace OpenSim.Region.Framework.Scenes
411 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage; 415 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage;
412 private ClientClosed handlerClientClosed = null; //OnClientClosed; 416 private ClientClosed handlerClientClosed = null; //OnClientClosed;
413 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; 417 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
418 private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile;
419 private OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = null; //OnSendNewWindlightProfileTargeted;
414 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent; 420 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent;
415 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; 421 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
416 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; 422 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
@@ -772,6 +778,24 @@ namespace OpenSim.Region.Framework.Scenes
772 } 778 }
773 } 779 }
774 780
781 public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user)
782 {
783 handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted;
784 if (handlerSendNewWindlightProfileTargeted != null)
785 {
786 handlerSendNewWindlightProfileTargeted(wl, user);
787 }
788 }
789
790 public void TriggerOnSaveNewWindlightProfile()
791 {
792 handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
793 if (handlerSaveNewWindlightProfile != null)
794 {
795 handlerSaveNewWindlightProfile();
796 }
797 }
798
775 public void TriggerOnMakeRootAgent(ScenePresence presence) 799 public void TriggerOnMakeRootAgent(ScenePresence presence)
776 { 800 {
777 handlerMakeRootAgent = OnMakeRootAgent; 801 handlerMakeRootAgent = OnMakeRootAgent;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 0b0c205..7ca779a 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 f79eb5d..265129c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -539,6 +539,8 @@ namespace OpenSim.Region.Framework.Scenes
539 539
540 // Load region settings 540 // Load region settings
541 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); 541 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
542 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID);
543
542 if (m_storageManager.EstateDataStore != null) 544 if (m_storageManager.EstateDataStore != null)
543 { 545 {
544 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID); 546 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
@@ -886,6 +888,15 @@ namespace OpenSim.Region.Framework.Scenes
886 /// <param name="seconds">float indicating duration before restart.</param> 888 /// <param name="seconds">float indicating duration before restart.</param>
887 public virtual void Restart(float seconds) 889 public virtual void Restart(float seconds)
888 { 890 {
891 Restart(seconds, true);
892 }
893
894 /// <summary>
895 /// Given float seconds, this will restart the region. showDialog will optionally alert the users.
896 /// </summary>
897 /// <param name="seconds">float indicating duration before restart.</param>
898 public virtual void Restart(float seconds, bool showDialog)
899 {
889 // notifications are done in 15 second increments 900 // notifications are done in 15 second increments
890 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request 901 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
891 // It's a 'Cancel restart' request. 902 // It's a 'Cancel restart' request.
@@ -906,8 +917,11 @@ namespace OpenSim.Region.Framework.Scenes
906 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed); 917 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
907 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes"); 918 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
908 m_restartTimer.Start(); 919 m_restartTimer.Start();
909 m_dialogModule.SendNotificationToUsersInRegion( 920 if (showDialog)
921 {
922 m_dialogModule.SendNotificationToUsersInRegion(
910 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0))); 923 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0)));
924 }
911 } 925 }
912 } 926 }
913 927
@@ -1189,16 +1203,16 @@ namespace OpenSim.Region.Framework.Scenes
1189 // Check if any objects have reached their targets 1203 // Check if any objects have reached their targets
1190 CheckAtTargets(); 1204 CheckAtTargets();
1191 1205
1192 // Update SceneObjectGroups that have scheduled themselves for updates
1193 // Objects queue their updates onto all scene presences
1194 if (m_frame % m_update_objects == 0)
1195 m_sceneGraph.UpdateObjectGroups();
1196
1197 // Run through all ScenePresences looking for updates 1206 // Run through all ScenePresences looking for updates
1198 // Presence updates and queued object updates for each presence are sent to clients 1207 // Presence updates and queued object updates for each presence are sent to clients
1199 if (m_frame % m_update_presences == 0) 1208 if (m_frame % m_update_presences == 0)
1200 m_sceneGraph.UpdatePresences(); 1209 m_sceneGraph.UpdatePresences();
1201 1210
1211 // Update SceneObjectGroups that have scheduled themselves for updates
1212 // Objects queue their updates onto all scene presences
1213 if (m_frame % m_update_objects == 0)
1214 m_sceneGraph.UpdateObjectGroups();
1215
1202 int tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1216 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1203 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1217 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1204 m_sceneGraph.UpdatePreparePhysics(); 1218 m_sceneGraph.UpdatePreparePhysics();
@@ -1505,6 +1519,19 @@ namespace OpenSim.Region.Framework.Scenes
1505 public void SaveTerrain() 1519 public void SaveTerrain()
1506 { 1520 {
1507 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1521 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1522 }
1523
1524 public void StoreWindlightProfile(RegionMeta7WindlightData wl)
1525 {
1526 m_regInfo.WindlightSettings = wl;
1527 m_storageManager.DataStore.StoreRegionWindlightSettings(wl);
1528 m_eventManager.TriggerOnSaveNewWindlightProfile();
1529 }
1530
1531 public void LoadWindlightProfile()
1532 {
1533 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(RegionInfo.RegionID);
1534 m_eventManager.TriggerOnSaveNewWindlightProfile();
1508 } 1535 }
1509 1536
1510 /// <summary> 1537 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index cb87212..eacd219 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -98,6 +98,72 @@ namespace OpenSim.Region.Framework.Scenes
98 private bool m_hasGroupChanged = false; 98 private bool m_hasGroupChanged = false;
99 private long timeFirstChanged; 99 private long timeFirstChanged;
100 private long timeLastChanged; 100 private long timeLastChanged;
101 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
102
103 public void lockPartsForRead(bool locked)
104 {
105 if (locked)
106 {
107 if (m_partsLock.RecursiveReadCount > 0)
108 {
109 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
110 m_partsLock.ExitReadLock();
111 }
112 if (m_partsLock.RecursiveWriteCount > 0)
113 {
114 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
115 m_partsLock.ExitWriteLock();
116 }
117
118 while (!m_partsLock.TryEnterReadLock(60000))
119 {
120 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
121 if (m_partsLock.IsWriteLockHeld)
122 {
123 m_partsLock = new System.Threading.ReaderWriterLockSlim();
124 }
125 }
126 }
127 else
128 {
129 if (m_partsLock.RecursiveReadCount > 0)
130 {
131 m_partsLock.ExitReadLock();
132 }
133 }
134 }
135 public void lockPartsForWrite(bool locked)
136 {
137 if (locked)
138 {
139 if (m_partsLock.RecursiveReadCount > 0)
140 {
141 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
142 m_partsLock.ExitReadLock();
143 }
144 if (m_partsLock.RecursiveWriteCount > 0)
145 {
146 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
147 m_partsLock.ExitWriteLock();
148 }
149
150 while (!m_partsLock.TryEnterWriteLock(60000))
151 {
152 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
153 if (m_partsLock.IsWriteLockHeld)
154 {
155 m_partsLock = new System.Threading.ReaderWriterLockSlim();
156 }
157 }
158 }
159 else
160 {
161 if (m_partsLock.RecursiveWriteCount > 0)
162 {
163 m_partsLock.ExitWriteLock();
164 }
165 }
166 }
101 167
102 public bool HasGroupChanged 168 public bool HasGroupChanged
103 { 169 {
@@ -243,13 +309,16 @@ namespace OpenSim.Region.Framework.Scenes
243 set 309 set
244 { 310 {
245 m_regionHandle = value; 311 m_regionHandle = value;
246 lock (m_parts) 312 lockPartsForRead(true);
247 { 313 {
248 foreach (SceneObjectPart part in m_parts.Values) 314 foreach (SceneObjectPart part in m_parts.Values)
249 { 315 {
316
250 part.RegionHandle = m_regionHandle; 317 part.RegionHandle = m_regionHandle;
318
251 } 319 }
252 } 320 }
321 lockPartsForRead(false);
253 } 322 }
254 } 323 }
255 324
@@ -275,13 +344,16 @@ namespace OpenSim.Region.Framework.Scenes
275 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 344 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
276 } 345 }
277 346
278 lock (m_parts) 347 lockPartsForRead(true);
279 { 348 {
280 foreach (SceneObjectPart part in m_parts.Values) 349 foreach (SceneObjectPart part in m_parts.Values)
281 { 350 {
351
282 part.GroupPosition = val; 352 part.GroupPosition = val;
353
283 } 354 }
284 } 355 }
356 lockPartsForRead(false);
285 357
286 //if (m_rootPart.PhysActor != null) 358 //if (m_rootPart.PhysActor != null)
287 //{ 359 //{
@@ -432,13 +504,16 @@ namespace OpenSim.Region.Framework.Scenes
432 504
433 public void SetFromItemID(UUID AssetId) 505 public void SetFromItemID(UUID AssetId)
434 { 506 {
435 lock (m_parts) 507 lockPartsForRead(true);
436 { 508 {
437 foreach (SceneObjectPart part in m_parts.Values) 509 foreach (SceneObjectPart part in m_parts.Values)
438 { 510 {
511
439 part.FromItemID = AssetId; 512 part.FromItemID = AssetId;
513
440 } 514 }
441 } 515 }
516 lockPartsForRead(false);
442 } 517 }
443 518
444 public UUID GetFromItemID() 519 public UUID GetFromItemID()
@@ -505,10 +580,11 @@ namespace OpenSim.Region.Framework.Scenes
505 Vector3 maxScale = Vector3.Zero; 580 Vector3 maxScale = Vector3.Zero;
506 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 581 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
507 582
508 lock (m_parts) 583 lockPartsForRead(true);
509 { 584 {
510 foreach (SceneObjectPart part in m_parts.Values) 585 foreach (SceneObjectPart part in m_parts.Values)
511 { 586 {
587
512 Vector3 partscale = part.Scale; 588 Vector3 partscale = part.Scale;
513 Vector3 partoffset = part.OffsetPosition; 589 Vector3 partoffset = part.OffsetPosition;
514 590
@@ -519,8 +595,11 @@ namespace OpenSim.Region.Framework.Scenes
519 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 595 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
520 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 596 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
521 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 597 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
598
522 } 599 }
523 } 600 }
601 lockPartsForRead(false);
602
524 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 603 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
525 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 604 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
526 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 605 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -536,10 +615,11 @@ namespace OpenSim.Region.Framework.Scenes
536 615
537 EntityIntersection result = new EntityIntersection(); 616 EntityIntersection result = new EntityIntersection();
538 617
539 lock (m_parts) 618 lockPartsForRead(true);
540 { 619 {
541 foreach (SceneObjectPart part in m_parts.Values) 620 foreach (SceneObjectPart part in m_parts.Values)
542 { 621 {
622
543 // Temporary commented to stop compiler warning 623 // Temporary commented to stop compiler warning
544 //Vector3 partPosition = 624 //Vector3 partPosition =
545 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 625 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -567,8 +647,10 @@ namespace OpenSim.Region.Framework.Scenes
567 result.distance = inter.distance; 647 result.distance = inter.distance;
568 } 648 }
569 } 649 }
650
570 } 651 }
571 } 652 }
653 lockPartsForRead(false);
572 return result; 654 return result;
573 } 655 }
574 656
@@ -581,10 +663,11 @@ namespace OpenSim.Region.Framework.Scenes
581 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 663 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
582 { 664 {
583 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 665 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
584 lock (m_parts) 666 lockPartsForRead(true);
585 { 667 {
586 foreach (SceneObjectPart part in m_parts.Values) 668 foreach (SceneObjectPart part in m_parts.Values)
587 { 669 {
670
588 Vector3 worldPos = part.GetWorldPosition(); 671 Vector3 worldPos = part.GetWorldPosition();
589 Vector3 offset = worldPos - AbsolutePosition; 672 Vector3 offset = worldPos - AbsolutePosition;
590 Quaternion worldRot; 673 Quaternion worldRot;
@@ -643,6 +726,8 @@ namespace OpenSim.Region.Framework.Scenes
643 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 726 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
644 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 727 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
645 728
729
730
646 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 731 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
647 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 732 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
648 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 733 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -814,6 +899,7 @@ namespace OpenSim.Region.Framework.Scenes
814 minZ = backBottomLeft.Z; 899 minZ = backBottomLeft.Z;
815 } 900 }
816 } 901 }
902 lockPartsForRead(false);
817 903
818 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 904 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
819 905
@@ -842,17 +928,20 @@ namespace OpenSim.Region.Framework.Scenes
842 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 928 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
843 929
844 // Capture script state while holding the lock 930 // Capture script state while holding the lock
845 lock (m_parts) 931 lockPartsForRead(true);
846 { 932 {
847 foreach (SceneObjectPart part in m_parts.Values) 933 foreach (SceneObjectPart part in m_parts.Values)
848 { 934 {
935
849 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 936 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
850 foreach (UUID itemid in pstates.Keys) 937 foreach (UUID itemid in pstates.Keys)
851 { 938 {
852 states.Add(itemid, pstates[itemid]); 939 states.Add(itemid, pstates[itemid]);
853 } 940 }
941
854 } 942 }
855 } 943 }
944 lockPartsForRead(false);
856 945
857 if (states.Count > 0) 946 if (states.Count > 0)
858 { 947 {
@@ -1014,13 +1103,16 @@ namespace OpenSim.Region.Framework.Scenes
1014 1103
1015 public override void UpdateMovement() 1104 public override void UpdateMovement()
1016 { 1105 {
1017 lock (m_parts) 1106 lockPartsForRead(true);
1018 { 1107 {
1019 foreach (SceneObjectPart part in m_parts.Values) 1108 foreach (SceneObjectPart part in m_parts.Values)
1020 { 1109 {
1110
1021 part.UpdateMovement(); 1111 part.UpdateMovement();
1112
1022 } 1113 }
1023 } 1114 }
1115 lockPartsForRead(false);
1024 } 1116 }
1025 1117
1026 public ushort GetTimeDilation() 1118 public ushort GetTimeDilation()
@@ -1064,7 +1156,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 /// <param name="part"></param> 1156 /// <param name="part"></param>
1065 public void AddPart(SceneObjectPart part) 1157 public void AddPart(SceneObjectPart part)
1066 { 1158 {
1067 lock (m_parts) 1159 lockPartsForWrite(true);
1068 { 1160 {
1069 part.SetParent(this); 1161 part.SetParent(this);
1070 m_parts.Add(part.UUID, part); 1162 m_parts.Add(part.UUID, part);
@@ -1074,6 +1166,7 @@ namespace OpenSim.Region.Framework.Scenes
1074 if (part.LinkNum == 2 && RootPart != null) 1166 if (part.LinkNum == 2 && RootPart != null)
1075 RootPart.LinkNum = 1; 1167 RootPart.LinkNum = 1;
1076 } 1168 }
1169 lockPartsForWrite(false);
1077 } 1170 }
1078 1171
1079 /// <summary> 1172 /// <summary>
@@ -1081,28 +1174,33 @@ namespace OpenSim.Region.Framework.Scenes
1081 /// </summary> 1174 /// </summary>
1082 private void UpdateParentIDs() 1175 private void UpdateParentIDs()
1083 { 1176 {
1084 lock (m_parts) 1177 lockPartsForRead(true);
1085 { 1178 {
1086 foreach (SceneObjectPart part in m_parts.Values) 1179 foreach (SceneObjectPart part in m_parts.Values)
1087 { 1180 {
1181
1088 if (part.UUID != m_rootPart.UUID) 1182 if (part.UUID != m_rootPart.UUID)
1089 { 1183 {
1090 part.ParentID = m_rootPart.LocalId; 1184 part.ParentID = m_rootPart.LocalId;
1091 } 1185 }
1186
1092 } 1187 }
1093 } 1188 }
1189 lockPartsForRead(false);
1094 } 1190 }
1095 1191
1096 public void RegenerateFullIDs() 1192 public void RegenerateFullIDs()
1097 { 1193 {
1098 lock (m_parts) 1194 lockPartsForRead(true);
1099 { 1195 {
1100 foreach (SceneObjectPart part in m_parts.Values) 1196 foreach (SceneObjectPart part in m_parts.Values)
1101 { 1197 {
1198
1102 part.UUID = UUID.Random(); 1199 part.UUID = UUID.Random();
1103 1200
1104 } 1201 }
1105 } 1202 }
1203 lockPartsForRead(false);
1106 } 1204 }
1107 1205
1108 // helper provided for parts. 1206 // helper provided for parts.
@@ -1183,29 +1281,33 @@ namespace OpenSim.Region.Framework.Scenes
1183 1281
1184 DetachFromBackup(); 1282 DetachFromBackup();
1185 1283
1186 lock (m_parts) 1284 lockPartsForRead(true);
1285 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1286 lockPartsForRead(false);
1287
1288 foreach (SceneObjectPart part in values)
1187 { 1289 {
1188 foreach (SceneObjectPart part in m_parts.Values)
1189 {
1190// part.Inventory.RemoveScriptInstances(); 1290// part.Inventory.RemoveScriptInstances();
1191 1291
1192 ScenePresence[] avatars = Scene.GetScenePresences(); 1292 ScenePresence[] avatars = Scene.GetScenePresences();
1193 for (int i = 0; i < avatars.Length; i++) 1293 for (int i = 0; i < avatars.Length; i++)
1294 {
1295 if (avatars[i].ParentID == LocalId)
1194 { 1296 {
1195 if (avatars[i].ParentID == LocalId) 1297 avatars[i].StandUp();
1196 { 1298 }
1197 avatars[i].StandUp();
1198 }
1199 1299
1200 if (!silent) 1300 if (!silent)
1201 { 1301 {
1202 part.UpdateFlag = 0; 1302 part.UpdateFlag = 0;
1203 if (part == m_rootPart) 1303 if (part == m_rootPart)
1204 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1304 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1205 }
1206 } 1305 }
1207 } 1306 }
1307
1208 } 1308 }
1309
1310
1209 } 1311 }
1210 1312
1211 public void AddScriptLPS(int count) 1313 public void AddScriptLPS(int count)
@@ -1230,17 +1332,20 @@ namespace OpenSim.Region.Framework.Scenes
1230 1332
1231 scriptEvents aggregateScriptEvents=0; 1333 scriptEvents aggregateScriptEvents=0;
1232 1334
1233 lock (m_parts) 1335 lockPartsForRead(true);
1234 { 1336 {
1235 foreach (SceneObjectPart part in m_parts.Values) 1337 foreach (SceneObjectPart part in m_parts.Values)
1236 { 1338 {
1339
1237 if (part == null) 1340 if (part == null)
1238 continue; 1341 continue;
1239 if (part != RootPart) 1342 if (part != RootPart)
1240 part.ObjectFlags = objectflagupdate; 1343 part.ObjectFlags = objectflagupdate;
1241 aggregateScriptEvents |= part.AggregateScriptEvents; 1344 aggregateScriptEvents |= part.AggregateScriptEvents;
1345
1242 } 1346 }
1243 } 1347 }
1348 lockPartsForRead(false);
1244 1349
1245 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1350 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1246 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1351 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1273,42 +1378,52 @@ namespace OpenSim.Region.Framework.Scenes
1273 /// <param name="m_physicalPrim"></param> 1378 /// <param name="m_physicalPrim"></param>
1274 public void ApplyPhysics(bool m_physicalPrim) 1379 public void ApplyPhysics(bool m_physicalPrim)
1275 { 1380 {
1276 lock (m_parts) 1381 lockPartsForRead(true);
1382
1383 if (m_parts.Count > 1)
1277 { 1384 {
1278 if (m_parts.Count > 1) 1385 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1386 lockPartsForRead(false);
1387 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1388 foreach (SceneObjectPart part in values)
1279 { 1389 {
1280 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1390
1281 foreach (SceneObjectPart part in m_parts.Values) 1391 if (part.LocalId != m_rootPart.LocalId)
1282 { 1392 {
1283 if (part.LocalId != m_rootPart.LocalId) 1393 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1284 {
1285 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1286 }
1287 } 1394 }
1288 1395
1289 // Hack to get the physics scene geometries in the right spot
1290 ResetChildPrimPhysicsPositions();
1291 }
1292 else
1293 {
1294 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1295 } 1396 }
1397 // Hack to get the physics scene geometries in the right spot
1398 ResetChildPrimPhysicsPositions();
1399 }
1400 else
1401 {
1402 lockPartsForRead(false);
1403 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1296 } 1404 }
1297 } 1405 }
1298 1406
1299 public void SetOwnerId(UUID userId) 1407 public void SetOwnerId(UUID userId)
1300 { 1408 {
1301 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1409 ForEachPart(delegate(SceneObjectPart part)
1410 {
1411
1412 part.OwnerID = userId;
1413
1414 });
1302 } 1415 }
1303 1416
1304 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1417 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1305 { 1418 {
1306 lock (m_parts) 1419 lockPartsForRead(true);
1420 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1421 lockPartsForRead(false);
1422 foreach (SceneObjectPart part in values)
1307 { 1423 {
1308 foreach (SceneObjectPart part in m_parts.Values) 1424
1309 { 1425 whatToDo(part);
1310 whatToDo(part); 1426
1311 }
1312 } 1427 }
1313 } 1428 }
1314 1429
@@ -1407,14 +1522,17 @@ namespace OpenSim.Region.Framework.Scenes
1407 { 1522 {
1408 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1523 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1409 1524
1410 lock (m_parts) 1525 lockPartsForRead(true);
1411 { 1526 {
1412 foreach (SceneObjectPart part in m_parts.Values) 1527 foreach (SceneObjectPart part in m_parts.Values)
1413 { 1528 {
1529
1414 if (part != RootPart) 1530 if (part != RootPart)
1415 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1531 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1532
1416 } 1533 }
1417 } 1534 }
1535 lockPartsForRead(false);
1418 } 1536 }
1419 1537
1420 /// <summary> 1538 /// <summary>
@@ -1509,10 +1627,11 @@ namespace OpenSim.Region.Framework.Scenes
1509 1627
1510 List<SceneObjectPart> partList; 1628 List<SceneObjectPart> partList;
1511 1629
1512 lock (m_parts) 1630 lockPartsForRead(true);
1513 { 1631
1514 partList = new List<SceneObjectPart>(m_parts.Values); 1632 partList = new List<SceneObjectPart>(m_parts.Values);
1515 } 1633
1634 lockPartsForRead(false);
1516 1635
1517 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1636 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1518 { 1637 {
@@ -1735,6 +1854,45 @@ namespace OpenSim.Region.Framework.Scenes
1735 } 1854 }
1736 } 1855 }
1737 1856
1857 public void rotLookAt(Quaternion target, float strength, float damping)
1858 {
1859 SceneObjectPart rootpart = m_rootPart;
1860 if (rootpart != null)
1861 {
1862 if (IsAttachment)
1863 {
1864 /*
1865 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1866 if (avatar != null)
1867 {
1868 Rotate the Av?
1869 } */
1870 }
1871 else
1872 {
1873 if (rootpart.PhysActor != null)
1874 {
1875 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1876 rootpart.PhysActor.APIDStrength = strength;
1877 rootpart.PhysActor.APIDDamping = damping;
1878 rootpart.PhysActor.APIDActive = true;
1879 }
1880 }
1881 }
1882 }
1883 public void stopLookAt()
1884 {
1885 SceneObjectPart rootpart = m_rootPart;
1886 if (rootpart != null)
1887 {
1888 if (rootpart.PhysActor != null)
1889 {
1890 rootpart.PhysActor.APIDActive = false;
1891 }
1892 }
1893
1894 }
1895
1738 /// <summary> 1896 /// <summary>
1739 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1897 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1740 /// </summary> 1898 /// </summary>
@@ -1796,10 +1954,11 @@ namespace OpenSim.Region.Framework.Scenes
1796 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1954 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1797 newPart.SetParent(this); 1955 newPart.SetParent(this);
1798 1956
1799 lock (m_parts) 1957 lockPartsForWrite(true);
1800 { 1958 {
1801 m_parts.Add(newPart.UUID, newPart); 1959 m_parts.Add(newPart.UUID, newPart);
1802 } 1960 }
1961 lockPartsForWrite(false);
1803 1962
1804 SetPartAsNonRoot(newPart); 1963 SetPartAsNonRoot(newPart);
1805 1964
@@ -1862,7 +2021,7 @@ namespace OpenSim.Region.Framework.Scenes
1862 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2021 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1863 // return; 2022 // return;
1864 2023
1865 lock (m_parts) 2024 lockPartsForRead(true);
1866 { 2025 {
1867 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2026 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1868 2027
@@ -1880,34 +2039,43 @@ namespace OpenSim.Region.Framework.Scenes
1880 2039
1881 foreach (SceneObjectPart part in m_parts.Values) 2040 foreach (SceneObjectPart part in m_parts.Values)
1882 { 2041 {
2042
1883 part.SendScheduledUpdates(); 2043 part.SendScheduledUpdates();
2044
1884 } 2045 }
1885 } 2046 }
2047 lockPartsForRead(false);
1886 } 2048 }
1887 2049
1888 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2050 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1889 { 2051 {
1890 RootPart.AddFullUpdateToAvatar(presence); 2052 RootPart.AddFullUpdateToAvatar(presence);
1891 2053
1892 lock (m_parts) 2054 lockPartsForRead(true);
1893 { 2055 {
1894 foreach (SceneObjectPart part in m_parts.Values) 2056 foreach (SceneObjectPart part in m_parts.Values)
1895 { 2057 {
2058
1896 if (part != RootPart) 2059 if (part != RootPart)
1897 part.AddFullUpdateToAvatar(presence); 2060 part.AddFullUpdateToAvatar(presence);
2061
1898 } 2062 }
1899 } 2063 }
2064 lockPartsForRead(false);
1900 } 2065 }
1901 2066
1902 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2067 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1903 { 2068 {
1904 lock (m_parts) 2069 lockPartsForRead(true);
1905 { 2070 {
1906 foreach (SceneObjectPart part in m_parts.Values) 2071 foreach (SceneObjectPart part in m_parts.Values)
1907 { 2072 {
2073
1908 part.AddTerseUpdateToAvatar(presence); 2074 part.AddTerseUpdateToAvatar(presence);
2075
1909 } 2076 }
1910 } 2077 }
2078 lockPartsForRead(false);
1911 } 2079 }
1912 2080
1913 /// <summary> 2081 /// <summary>
@@ -1918,14 +2086,17 @@ namespace OpenSim.Region.Framework.Scenes
1918 checkAtTargets(); 2086 checkAtTargets();
1919 RootPart.ScheduleFullUpdate(); 2087 RootPart.ScheduleFullUpdate();
1920 2088
1921 lock (m_parts) 2089 lockPartsForRead(true);
1922 { 2090 {
1923 foreach (SceneObjectPart part in m_parts.Values) 2091 foreach (SceneObjectPart part in m_parts.Values)
1924 { 2092 {
2093
1925 if (part != RootPart) 2094 if (part != RootPart)
1926 part.ScheduleFullUpdate(); 2095 part.ScheduleFullUpdate();
2096
1927 } 2097 }
1928 } 2098 }
2099 lockPartsForRead(false);
1929 } 2100 }
1930 2101
1931 /// <summary> 2102 /// <summary>
@@ -1933,13 +2104,16 @@ namespace OpenSim.Region.Framework.Scenes
1933 /// </summary> 2104 /// </summary>
1934 public void ScheduleGroupForTerseUpdate() 2105 public void ScheduleGroupForTerseUpdate()
1935 { 2106 {
1936 lock (m_parts) 2107 lockPartsForRead(true);
1937 { 2108 {
1938 foreach (SceneObjectPart part in m_parts.Values) 2109 foreach (SceneObjectPart part in m_parts.Values)
1939 { 2110 {
2111
1940 part.ScheduleTerseUpdate(); 2112 part.ScheduleTerseUpdate();
2113
1941 } 2114 }
1942 } 2115 }
2116 lockPartsForRead(false);
1943 } 2117 }
1944 2118
1945 /// <summary> 2119 /// <summary>
@@ -1952,14 +2126,17 @@ namespace OpenSim.Region.Framework.Scenes
1952 2126
1953 RootPart.SendFullUpdateToAllClients(); 2127 RootPart.SendFullUpdateToAllClients();
1954 2128
1955 lock (m_parts) 2129 lockPartsForRead(true);
1956 { 2130 {
1957 foreach (SceneObjectPart part in m_parts.Values) 2131 foreach (SceneObjectPart part in m_parts.Values)
1958 { 2132 {
2133
1959 if (part != RootPart) 2134 if (part != RootPart)
1960 part.SendFullUpdateToAllClients(); 2135 part.SendFullUpdateToAllClients();
2136
1961 } 2137 }
1962 } 2138 }
2139 lockPartsForRead(false);
1963 } 2140 }
1964 2141
1965 /// <summary> 2142 /// <summary>
@@ -1990,14 +2167,15 @@ namespace OpenSim.Region.Framework.Scenes
1990 { 2167 {
1991 if (IsDeleted) 2168 if (IsDeleted)
1992 return; 2169 return;
1993 2170
1994 lock (m_parts) 2171 lockPartsForRead(true);
1995 { 2172 {
1996 foreach (SceneObjectPart part in m_parts.Values) 2173 foreach (SceneObjectPart part in m_parts.Values)
1997 { 2174 {
1998 part.SendTerseUpdateToAllClients(); 2175 part.SendTerseUpdateToAllClients();
1999 } 2176 }
2000 } 2177 }
2178 lockPartsForRead(false);
2001 } 2179 }
2002 2180
2003 #endregion 2181 #endregion
@@ -2011,16 +2189,18 @@ namespace OpenSim.Region.Framework.Scenes
2011 /// <returns>null if no child part with that linknum or child part</returns> 2189 /// <returns>null if no child part with that linknum or child part</returns>
2012 public SceneObjectPart GetLinkNumPart(int linknum) 2190 public SceneObjectPart GetLinkNumPart(int linknum)
2013 { 2191 {
2014 lock (m_parts) 2192 lockPartsForRead(true);
2015 { 2193 {
2016 foreach (SceneObjectPart part in m_parts.Values) 2194 foreach (SceneObjectPart part in m_parts.Values)
2017 { 2195 {
2018 if (part.LinkNum == linknum) 2196 if (part.LinkNum == linknum)
2019 { 2197 {
2198 lockPartsForRead(false);
2020 return part; 2199 return part;
2021 } 2200 }
2022 } 2201 }
2023 } 2202 }
2203 lockPartsForRead(false);
2024 2204
2025 return null; 2205 return null;
2026 } 2206 }
@@ -2048,17 +2228,19 @@ namespace OpenSim.Region.Framework.Scenes
2048 public SceneObjectPart GetChildPart(uint localID) 2228 public SceneObjectPart GetChildPart(uint localID)
2049 { 2229 {
2050 //m_log.DebugFormat("Entered looking for {0}", localID); 2230 //m_log.DebugFormat("Entered looking for {0}", localID);
2051 lock (m_parts) 2231 lockPartsForRead(true);
2052 { 2232 {
2053 foreach (SceneObjectPart part in m_parts.Values) 2233 foreach (SceneObjectPart part in m_parts.Values)
2054 { 2234 {
2055 //m_log.DebugFormat("Found {0}", part.LocalId); 2235 //m_log.DebugFormat("Found {0}", part.LocalId);
2056 if (part.LocalId == localID) 2236 if (part.LocalId == localID)
2057 { 2237 {
2238 lockPartsForRead(false);
2058 return part; 2239 return part;
2059 } 2240 }
2060 } 2241 }
2061 } 2242 }
2243 lockPartsForRead(false);
2062 2244
2063 return null; 2245 return null;
2064 } 2246 }
@@ -2088,17 +2270,19 @@ namespace OpenSim.Region.Framework.Scenes
2088 public bool HasChildPrim(uint localID) 2270 public bool HasChildPrim(uint localID)
2089 { 2271 {
2090 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2272 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2091 lock (m_parts) 2273 lockPartsForRead(true);
2092 { 2274 {
2093 foreach (SceneObjectPart part in m_parts.Values) 2275 foreach (SceneObjectPart part in m_parts.Values)
2094 { 2276 {
2095 //m_log.DebugFormat("Found {0}", part.LocalId); 2277 //m_log.DebugFormat("Found {0}", part.LocalId);
2096 if (part.LocalId == localID) 2278 if (part.LocalId == localID)
2097 { 2279 {
2280 lockPartsForRead(false);
2098 return true; 2281 return true;
2099 } 2282 }
2100 } 2283 }
2101 } 2284 }
2285 lockPartsForRead(false);
2102 2286
2103 return false; 2287 return false;
2104 } 2288 }
@@ -2148,53 +2332,57 @@ namespace OpenSim.Region.Framework.Scenes
2148 if (m_rootPart.LinkNum == 0) 2332 if (m_rootPart.LinkNum == 0)
2149 m_rootPart.LinkNum = 1; 2333 m_rootPart.LinkNum = 1;
2150 2334
2151 lock (m_parts) 2335 lockPartsForWrite(true);
2152 { 2336
2153 m_parts.Add(linkPart.UUID, linkPart); 2337 m_parts.Add(linkPart.UUID, linkPart);
2338
2339 lockPartsForWrite(false);
2154 2340
2155 // Insert in terms of link numbers, the new links 2341 // Insert in terms of link numbers, the new links
2156 // before the current ones (with the exception of 2342 // before the current ones (with the exception of
2157 // the root prim. Shuffle the old ones up 2343 // the root prim. Shuffle the old ones up
2158 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2344 lockPartsForRead(true);
2345 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2346 {
2347 if (kvp.Value.LinkNum != 1)
2159 { 2348 {
2160 if (kvp.Value.LinkNum != 1) 2349 // Don't update root prim link number
2161 { 2350 kvp.Value.LinkNum += objectGroup.PrimCount;
2162 // Don't update root prim link number
2163 kvp.Value.LinkNum += objectGroup.PrimCount;
2164 }
2165 } 2351 }
2352 }
2353 lockPartsForRead(false);
2166 2354
2167 linkPart.LinkNum = 2; 2355 linkPart.LinkNum = 2;
2168 2356
2169 linkPart.SetParent(this); 2357 linkPart.SetParent(this);
2170 linkPart.AddFlag(PrimFlags.CreateSelected); 2358 linkPart.AddFlag(PrimFlags.CreateSelected);
2171 2359
2172 //if (linkPart.PhysActor != null) 2360 //if (linkPart.PhysActor != null)
2173 //{ 2361 //{
2174 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2362 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2175 2363
2176 //linkPart.PhysActor = null; 2364 //linkPart.PhysActor = null;
2177 //} 2365 //}
2178 2366
2179 //TODO: rest of parts 2367 //TODO: rest of parts
2180 int linkNum = 3; 2368 int linkNum = 3;
2181 foreach (SceneObjectPart part in objectGroup.Children.Values) 2369 foreach (SceneObjectPart part in objectGroup.Children.Values)
2370 {
2371 if (part.UUID != objectGroup.m_rootPart.UUID)
2182 { 2372 {
2183 if (part.UUID != objectGroup.m_rootPart.UUID) 2373 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2184 {
2185 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2186 }
2187 part.ClearUndoState();
2188 } 2374 }
2375 part.ClearUndoState();
2189 } 2376 }
2190 2377
2191 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2378 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2192 objectGroup.m_isDeleted = true; 2379 objectGroup.m_isDeleted = true;
2380
2381 objectGroup.lockPartsForWrite(true);
2193 2382
2194 lock (objectGroup.m_parts) 2383 objectGroup.m_parts.Clear();
2195 { 2384
2196 objectGroup.m_parts.Clear(); 2385 objectGroup.lockPartsForWrite(false);
2197 }
2198 2386
2199 // Can't do this yet since backup still makes use of the root part without any synchronization 2387 // Can't do this yet since backup still makes use of the root part without any synchronization
2200// objectGroup.m_rootPart = null; 2388// objectGroup.m_rootPart = null;
@@ -2253,11 +2441,12 @@ namespace OpenSim.Region.Framework.Scenes
2253 Quaternion worldRot = linkPart.GetWorldRotation(); 2441 Quaternion worldRot = linkPart.GetWorldRotation();
2254 2442
2255 // Remove the part from this object 2443 // Remove the part from this object
2256 lock (m_parts) 2444 lockPartsForWrite(true);
2257 { 2445 {
2258 m_parts.Remove(linkPart.UUID); 2446 m_parts.Remove(linkPart.UUID);
2259 } 2447 }
2260 2448 lockPartsForWrite(false);
2449 lockPartsForRead(true);
2261 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2450 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2262 RootPart.LinkNum = 0; 2451 RootPart.LinkNum = 0;
2263 else 2452 else
@@ -2268,6 +2457,7 @@ namespace OpenSim.Region.Framework.Scenes
2268 p.LinkNum--; 2457 p.LinkNum--;
2269 } 2458 }
2270 } 2459 }
2460 lockPartsForRead(false);
2271 2461
2272 linkPart.ParentID = 0; 2462 linkPart.ParentID = 0;
2273 linkPart.LinkNum = 0; 2463 linkPart.LinkNum = 0;
@@ -2585,9 +2775,12 @@ namespace OpenSim.Region.Framework.Scenes
2585 2775
2586 if (selectionPart != null) 2776 if (selectionPart != null)
2587 { 2777 {
2588 lock (m_parts) 2778 lockPartsForRead(true);
2779 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2780 lockPartsForRead(false);
2781 foreach (SceneObjectPart part in parts)
2589 { 2782 {
2590 foreach (SceneObjectPart part in m_parts.Values) 2783 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2591 { 2784 {
2592 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || 2785 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2593 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || 2786 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
@@ -2597,12 +2790,13 @@ namespace OpenSim.Region.Framework.Scenes
2597 break; 2790 break;
2598 } 2791 }
2599 } 2792 }
2793 }
2600 2794
2601 foreach (SceneObjectPart part in m_parts.Values) 2795 foreach (SceneObjectPart part in parts)
2602 { 2796 {
2603 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2797 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2604 }
2605 } 2798 }
2799
2606 } 2800 }
2607 } 2801 }
2608 2802
@@ -2688,11 +2882,9 @@ namespace OpenSim.Region.Framework.Scenes
2688 scale.Y = m_scene.m_maxNonphys; 2882 scale.Y = m_scene.m_maxNonphys;
2689 if (scale.Z > m_scene.m_maxNonphys) 2883 if (scale.Z > m_scene.m_maxNonphys)
2690 scale.Z = m_scene.m_maxNonphys; 2884 scale.Z = m_scene.m_maxNonphys;
2691
2692 SceneObjectPart part = GetChildPart(localID); 2885 SceneObjectPart part = GetChildPart(localID);
2693 if (part != null) 2886 if (part != null)
2694 { 2887 {
2695 part.Resize(scale);
2696 if (part.PhysActor != null) 2888 if (part.PhysActor != null)
2697 { 2889 {
2698 if (part.PhysActor.IsPhysical) 2890 if (part.PhysActor.IsPhysical)
@@ -2707,7 +2899,7 @@ namespace OpenSim.Region.Framework.Scenes
2707 part.PhysActor.Size = scale; 2899 part.PhysActor.Size = scale;
2708 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2900 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2709 } 2901 }
2710 //if (part.UUID != m_rootPart.UUID) 2902 part.Resize(scale);
2711 2903
2712 HasGroupChanged = true; 2904 HasGroupChanged = true;
2713 ScheduleGroupForFullUpdate(); 2905 ScheduleGroupForFullUpdate();
@@ -2748,77 +2940,76 @@ namespace OpenSim.Region.Framework.Scenes
2748 float y = (scale.Y / part.Scale.Y); 2940 float y = (scale.Y / part.Scale.Y);
2749 float z = (scale.Z / part.Scale.Z); 2941 float z = (scale.Z / part.Scale.Z);
2750 2942
2751 lock (m_parts) 2943 lockPartsForRead(true);
2944 if (x > 1.0f || y > 1.0f || z > 1.0f)
2752 { 2945 {
2753 if (x > 1.0f || y > 1.0f || z > 1.0f) 2946 foreach (SceneObjectPart obPart in m_parts.Values)
2754 { 2947 {
2755 foreach (SceneObjectPart obPart in m_parts.Values) 2948 if (obPart.UUID != m_rootPart.UUID)
2756 { 2949 {
2757 if (obPart.UUID != m_rootPart.UUID) 2950 Vector3 oldSize = new Vector3(obPart.Scale);
2758 {
2759 Vector3 oldSize = new Vector3(obPart.Scale);
2760 2951
2761 float f = 1.0f; 2952 float f = 1.0f;
2762 float a = 1.0f; 2953 float a = 1.0f;
2763 2954
2764 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2955 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2956 {
2957 if (oldSize.X*x > m_scene.m_maxPhys)
2765 { 2958 {
2766 if (oldSize.X*x > m_scene.m_maxPhys) 2959 f = m_scene.m_maxPhys / oldSize.X;
2767 { 2960 a = f / x;
2768 f = m_scene.m_maxPhys / oldSize.X; 2961 x *= a;
2769 a = f / x; 2962 y *= a;
2770 x *= a; 2963 z *= a;
2771 y *= a;
2772 z *= a;
2773 }
2774 if (oldSize.Y*y > m_scene.m_maxPhys)
2775 {
2776 f = m_scene.m_maxPhys / oldSize.Y;
2777 a = f / y;
2778 x *= a;
2779 y *= a;
2780 z *= a;
2781 }
2782 if (oldSize.Z*z > m_scene.m_maxPhys)
2783 {
2784 f = m_scene.m_maxPhys / oldSize.Z;
2785 a = f / z;
2786 x *= a;
2787 y *= a;
2788 z *= a;
2789 }
2790 } 2964 }
2791 else 2965 if (oldSize.Y*y > m_scene.m_maxPhys)
2966 {
2967 f = m_scene.m_maxPhys / oldSize.Y;
2968 a = f / y;
2969 x *= a;
2970 y *= a;
2971 z *= a;
2972 }
2973 if (oldSize.Z*z > m_scene.m_maxPhys)
2974 {
2975 f = m_scene.m_maxPhys / oldSize.Z;
2976 a = f / z;
2977 x *= a;
2978 y *= a;
2979 z *= a;
2980 }
2981 }
2982 else
2983 {
2984 if (oldSize.X*x > m_scene.m_maxNonphys)
2985 {
2986 f = m_scene.m_maxNonphys / oldSize.X;
2987 a = f / x;
2988 x *= a;
2989 y *= a;
2990 z *= a;
2991 }
2992 if (oldSize.Y*y > m_scene.m_maxNonphys)
2993 {
2994 f = m_scene.m_maxNonphys / oldSize.Y;
2995 a = f / y;
2996 x *= a;
2997 y *= a;
2998 z *= a;
2999 }
3000 if (oldSize.Z*z > m_scene.m_maxNonphys)
2792 { 3001 {
2793 if (oldSize.X*x > m_scene.m_maxNonphys) 3002 f = m_scene.m_maxNonphys / oldSize.Z;
2794 { 3003 a = f / z;
2795 f = m_scene.m_maxNonphys / oldSize.X; 3004 x *= a;
2796 a = f / x; 3005 y *= a;
2797 x *= a; 3006 z *= a;
2798 y *= a;
2799 z *= a;
2800 }
2801 if (oldSize.Y*y > m_scene.m_maxNonphys)
2802 {
2803 f = m_scene.m_maxNonphys / oldSize.Y;
2804 a = f / y;
2805 x *= a;
2806 y *= a;
2807 z *= a;
2808 }
2809 if (oldSize.Z*z > m_scene.m_maxNonphys)
2810 {
2811 f = m_scene.m_maxNonphys / oldSize.Z;
2812 a = f / z;
2813 x *= a;
2814 y *= a;
2815 z *= a;
2816 }
2817 } 3007 }
2818 } 3008 }
2819 } 3009 }
2820 } 3010 }
2821 } 3011 }
3012 lockPartsForRead(false);
2822 3013
2823 Vector3 prevScale = part.Scale; 3014 Vector3 prevScale = part.Scale;
2824 prevScale.X *= x; 3015 prevScale.X *= x;
@@ -2826,7 +3017,7 @@ namespace OpenSim.Region.Framework.Scenes
2826 prevScale.Z *= z; 3017 prevScale.Z *= z;
2827 part.Resize(prevScale); 3018 part.Resize(prevScale);
2828 3019
2829 lock (m_parts) 3020 lockPartsForRead(true);
2830 { 3021 {
2831 foreach (SceneObjectPart obPart in m_parts.Values) 3022 foreach (SceneObjectPart obPart in m_parts.Values)
2832 { 3023 {
@@ -2845,6 +3036,7 @@ namespace OpenSim.Region.Framework.Scenes
2845 } 3036 }
2846 } 3037 }
2847 } 3038 }
3039 lockPartsForRead(false);
2848 3040
2849 if (part.PhysActor != null) 3041 if (part.PhysActor != null)
2850 { 3042 {
@@ -2925,7 +3117,7 @@ namespace OpenSim.Region.Framework.Scenes
2925 axDiff *= Quaternion.Inverse(partRotation); 3117 axDiff *= Quaternion.Inverse(partRotation);
2926 diff = axDiff; 3118 diff = axDiff;
2927 3119
2928 lock (m_parts) 3120 lockPartsForRead(true);
2929 { 3121 {
2930 foreach (SceneObjectPart obPart in m_parts.Values) 3122 foreach (SceneObjectPart obPart in m_parts.Values)
2931 { 3123 {
@@ -2935,6 +3127,7 @@ namespace OpenSim.Region.Framework.Scenes
2935 } 3127 }
2936 } 3128 }
2937 } 3129 }
3130 lockPartsForRead(false);
2938 3131
2939 AbsolutePosition = newPos; 3132 AbsolutePosition = newPos;
2940 3133
@@ -3052,7 +3245,7 @@ namespace OpenSim.Region.Framework.Scenes
3052 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3245 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3053 } 3246 }
3054 3247
3055 lock (m_parts) 3248 lockPartsForRead(true);
3056 { 3249 {
3057 foreach (SceneObjectPart prim in m_parts.Values) 3250 foreach (SceneObjectPart prim in m_parts.Values)
3058 { 3251 {
@@ -3070,6 +3263,7 @@ namespace OpenSim.Region.Framework.Scenes
3070 } 3263 }
3071 } 3264 }
3072 } 3265 }
3266 lockPartsForRead(false);
3073 3267
3074 m_rootPart.ScheduleTerseUpdate(); 3268 m_rootPart.ScheduleTerseUpdate();
3075 } 3269 }
@@ -3168,7 +3362,7 @@ namespace OpenSim.Region.Framework.Scenes
3168 if (atTargets.Count > 0) 3362 if (atTargets.Count > 0)
3169 { 3363 {
3170 uint[] localids = new uint[0]; 3364 uint[] localids = new uint[0];
3171 lock (m_parts) 3365 lockPartsForRead(true);
3172 { 3366 {
3173 localids = new uint[m_parts.Count]; 3367 localids = new uint[m_parts.Count];
3174 int cntr = 0; 3368 int cntr = 0;
@@ -3178,6 +3372,7 @@ namespace OpenSim.Region.Framework.Scenes
3178 cntr++; 3372 cntr++;
3179 } 3373 }
3180 } 3374 }
3375 lockPartsForRead(false);
3181 3376
3182 for (int ctr = 0; ctr < localids.Length; ctr++) 3377 for (int ctr = 0; ctr < localids.Length; ctr++)
3183 { 3378 {
@@ -3196,7 +3391,7 @@ namespace OpenSim.Region.Framework.Scenes
3196 { 3391 {
3197 //trigger not_at_target 3392 //trigger not_at_target
3198 uint[] localids = new uint[0]; 3393 uint[] localids = new uint[0];
3199 lock (m_parts) 3394 lockPartsForRead(true);
3200 { 3395 {
3201 localids = new uint[m_parts.Count]; 3396 localids = new uint[m_parts.Count];
3202 int cntr = 0; 3397 int cntr = 0;
@@ -3206,7 +3401,8 @@ namespace OpenSim.Region.Framework.Scenes
3206 cntr++; 3401 cntr++;
3207 } 3402 }
3208 } 3403 }
3209 3404 lockPartsForRead(false);
3405
3210 for (int ctr = 0; ctr < localids.Length; ctr++) 3406 for (int ctr = 0; ctr < localids.Length; ctr++)
3211 { 3407 {
3212 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3408 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3219,19 +3415,20 @@ namespace OpenSim.Region.Framework.Scenes
3219 public float GetMass() 3415 public float GetMass()
3220 { 3416 {
3221 float retmass = 0f; 3417 float retmass = 0f;
3222 lock (m_parts) 3418 lockPartsForRead(true);
3223 { 3419 {
3224 foreach (SceneObjectPart part in m_parts.Values) 3420 foreach (SceneObjectPart part in m_parts.Values)
3225 { 3421 {
3226 retmass += part.GetMass(); 3422 retmass += part.GetMass();
3227 } 3423 }
3228 } 3424 }
3425 lockPartsForRead(false);
3229 return retmass; 3426 return retmass;
3230 } 3427 }
3231 3428
3232 public void CheckSculptAndLoad() 3429 public void CheckSculptAndLoad()
3233 { 3430 {
3234 lock (m_parts) 3431 lockPartsForRead(true);
3235 { 3432 {
3236 if (!IsDeleted) 3433 if (!IsDeleted)
3237 { 3434 {
@@ -3256,6 +3453,7 @@ namespace OpenSim.Region.Framework.Scenes
3256 } 3453 }
3257 } 3454 }
3258 } 3455 }
3456 lockPartsForRead(false);
3259 } 3457 }
3260 3458
3261 protected void AssetReceived(string id, Object sender, AssetBase asset) 3459 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3276,7 +3474,7 @@ namespace OpenSim.Region.Framework.Scenes
3276 /// <param name="client"></param> 3474 /// <param name="client"></param>
3277 public void SetGroup(UUID GroupID, IClientAPI client) 3475 public void SetGroup(UUID GroupID, IClientAPI client)
3278 { 3476 {
3279 lock (m_parts) 3477 lockPartsForRead(true);
3280 { 3478 {
3281 foreach (SceneObjectPart part in m_parts.Values) 3479 foreach (SceneObjectPart part in m_parts.Values)
3282 { 3480 {
@@ -3286,7 +3484,7 @@ namespace OpenSim.Region.Framework.Scenes
3286 3484
3287 HasGroupChanged = true; 3485 HasGroupChanged = true;
3288 } 3486 }
3289 3487 lockPartsForRead(false);
3290 ScheduleGroupForFullUpdate(); 3488 ScheduleGroupForFullUpdate();
3291 } 3489 }
3292 3490
@@ -3305,11 +3503,12 @@ namespace OpenSim.Region.Framework.Scenes
3305 3503
3306 public void SetAttachmentPoint(byte point) 3504 public void SetAttachmentPoint(byte point)
3307 { 3505 {
3308 lock (m_parts) 3506 lockPartsForRead(true);
3309 { 3507 {
3310 foreach (SceneObjectPart part in m_parts.Values) 3508 foreach (SceneObjectPart part in m_parts.Values)
3311 part.SetAttachmentPoint(point); 3509 part.SetAttachmentPoint(point);
3312 } 3510 }
3511 lockPartsForRead(false);
3313 } 3512 }
3314 3513
3315 #region ISceneObject 3514 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b6916f2..0eddbfd 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -212,6 +212,7 @@ namespace OpenSim.Region.Framework.Scenes
212 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 212 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
213 private Vector3 m_sitTargetPosition; 213 private Vector3 m_sitTargetPosition;
214 private string m_sitAnimation = "SIT"; 214 private string m_sitAnimation = "SIT";
215 private bool m_occupied; // KF if any av is sitting on this prim
215 private string m_text = String.Empty; 216 private string m_text = String.Empty;
216 private string m_touchName = String.Empty; 217 private string m_touchName = String.Empty;
217 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 218 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
@@ -389,12 +390,16 @@ namespace OpenSim.Region.Framework.Scenes
389 } 390 }
390 391
391 /// <value> 392 /// <value>
392 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 393 /// Get the inventory list
393 /// </value> 394 /// </value>
394 public TaskInventoryDictionary TaskInventory 395 public TaskInventoryDictionary TaskInventory
395 { 396 {
396 get { return m_inventory.Items; } 397 get {
397 set { m_inventory.Items = value; } 398 return m_inventory.Items;
399 }
400 set {
401 m_inventory.Items = value;
402 }
398 } 403 }
399 404
400 public uint ObjectFlags 405 public uint ObjectFlags
@@ -527,7 +532,6 @@ namespace OpenSim.Region.Framework.Scenes
527 StoreUndoState(); 532 StoreUndoState();
528 533
529 m_groupPosition = value; 534 m_groupPosition = value;
530
531 PhysicsActor actor = PhysActor; 535 PhysicsActor actor = PhysActor;
532 if (actor != null) 536 if (actor != null)
533 { 537 {
@@ -837,7 +841,8 @@ namespace OpenSim.Region.Framework.Scenes
837 if (IsAttachment) 841 if (IsAttachment)
838 return GroupPosition; 842 return GroupPosition;
839 843
840 return m_offsetPosition + m_groupPosition; } 844// return m_offsetPosition + m_groupPosition; }
845 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
841 } 846 }
842 847
843 public SceneObjectGroup ParentGroup 848 public SceneObjectGroup ParentGroup
@@ -989,6 +994,13 @@ namespace OpenSim.Region.Framework.Scenes
989 get { return _flags; } 994 get { return _flags; }
990 set { _flags = value; } 995 set { _flags = value; }
991 } 996 }
997
998 [XmlIgnore]
999 public bool IsOccupied // KF If an av is sittingon this prim
1000 {
1001 get { return m_occupied; }
1002 set { m_occupied = value; }
1003 }
992 1004
993 [XmlIgnore] 1005 [XmlIgnore]
994 public UUID SitTargetAvatar 1006 public UUID SitTargetAvatar
@@ -1064,14 +1076,6 @@ namespace OpenSim.Region.Framework.Scenes
1064 } 1076 }
1065 } 1077 }
1066 1078
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) 1079 private void SendObjectPropertiesToClient(UUID AgentID)
1076 { 1080 {
1077 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1081 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -1737,12 +1741,17 @@ namespace OpenSim.Region.Framework.Scenes
1737 public Vector3 GetWorldPosition() 1741 public Vector3 GetWorldPosition()
1738 { 1742 {
1739 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1743 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1740
1741 Vector3 axPos = OffsetPosition; 1744 Vector3 axPos = OffsetPosition;
1742
1743 axPos *= parentRot; 1745 axPos *= parentRot;
1744 Vector3 translationOffsetPosition = axPos; 1746 Vector3 translationOffsetPosition = axPos;
1745 return GroupPosition + translationOffsetPosition; 1747 if(_parentID == 0)
1748 {
1749 return GroupPosition;
1750 }
1751 else
1752 {
1753 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
1754 }
1746 } 1755 }
1747 1756
1748 /// <summary> 1757 /// <summary>
@@ -1753,7 +1762,7 @@ namespace OpenSim.Region.Framework.Scenes
1753 { 1762 {
1754 Quaternion newRot; 1763 Quaternion newRot;
1755 1764
1756 if (this.LinkNum == 0) 1765 if (this.LinkNum < 2) //KF Single or root prim
1757 { 1766 {
1758 newRot = RotationOffset; 1767 newRot = RotationOffset;
1759 } 1768 }
@@ -2109,17 +2118,18 @@ namespace OpenSim.Region.Framework.Scenes
2109 //Trys to fetch sound id from prim's inventory. 2118 //Trys to fetch sound id from prim's inventory.
2110 //Prim's inventory doesn't support non script items yet 2119 //Prim's inventory doesn't support non script items yet
2111 2120
2112 lock (TaskInventory) 2121 TaskInventory.LockItemsForRead(true);
2122
2123 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2113 { 2124 {
2114 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2125 if (item.Value.Name == sound)
2115 { 2126 {
2116 if (item.Value.Name == sound) 2127 soundID = item.Value.ItemID;
2117 { 2128 break;
2118 soundID = item.Value.ItemID;
2119 break;
2120 }
2121 } 2129 }
2122 } 2130 }
2131
2132 TaskInventory.LockItemsForRead(false);
2123 } 2133 }
2124 2134
2125 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2135 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2185,6 +2195,11 @@ namespace OpenSim.Region.Framework.Scenes
2185 ParentGroup.HasGroupChanged = true; 2195 ParentGroup.HasGroupChanged = true;
2186 ScheduleFullUpdate(); 2196 ScheduleFullUpdate();
2187 } 2197 }
2198
2199 public void RotLookAt(Quaternion target, float strength, float damping)
2200 {
2201 m_parentGroup.rotLookAt(target, strength, damping);
2202 }
2188 2203
2189 /// <summary> 2204 /// <summary>
2190 /// Schedules this prim for a full update 2205 /// Schedules this prim for a full update
@@ -2389,8 +2404,8 @@ namespace OpenSim.Region.Framework.Scenes
2389 { 2404 {
2390 const float ROTATION_TOLERANCE = 0.01f; 2405 const float ROTATION_TOLERANCE = 0.01f;
2391 const float VELOCITY_TOLERANCE = 0.001f; 2406 const float VELOCITY_TOLERANCE = 0.001f;
2392 const float POSITION_TOLERANCE = 0.05f; 2407 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2393 const int TIME_MS_TOLERANCE = 3000; 2408 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2394 2409
2395 if (m_updateFlag == 1) 2410 if (m_updateFlag == 1)
2396 { 2411 {
@@ -2404,7 +2419,7 @@ namespace OpenSim.Region.Framework.Scenes
2404 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2419 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2405 { 2420 {
2406 AddTerseUpdateToAllAvatars(); 2421 AddTerseUpdateToAllAvatars();
2407 ClearUpdateSchedule(); 2422
2408 2423
2409 // This causes the Scene to 'poll' physical objects every couple of frames 2424 // This causes the Scene to 'poll' physical objects every couple of frames
2410 // bad, so it's been replaced by an event driven method. 2425 // bad, so it's been replaced by an event driven method.
@@ -2422,16 +2437,18 @@ namespace OpenSim.Region.Framework.Scenes
2422 m_lastAngularVelocity = AngularVelocity; 2437 m_lastAngularVelocity = AngularVelocity;
2423 m_lastTerseSent = Environment.TickCount; 2438 m_lastTerseSent = Environment.TickCount;
2424 } 2439 }
2440 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2441 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2425 } 2442 }
2426 else 2443 else
2427 { 2444 {
2428 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2445 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2429 { 2446 {
2430 AddFullUpdateToAllAvatars(); 2447 AddFullUpdateToAllAvatars();
2431 ClearUpdateSchedule(); 2448 m_updateFlag = 0; //Same here
2432 } 2449 }
2433 } 2450 }
2434 ClearUpdateSchedule(); 2451 m_updateFlag = 0;
2435 } 2452 }
2436 2453
2437 /// <summary> 2454 /// <summary>
@@ -2458,17 +2475,16 @@ namespace OpenSim.Region.Framework.Scenes
2458 if (!UUID.TryParse(sound, out soundID)) 2475 if (!UUID.TryParse(sound, out soundID))
2459 { 2476 {
2460 // search sound file from inventory 2477 // search sound file from inventory
2461 lock (TaskInventory) 2478 TaskInventory.LockItemsForRead(true);
2479 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2462 { 2480 {
2463 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2481 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2464 { 2482 {
2465 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2483 soundID = item.Value.ItemID;
2466 { 2484 break;
2467 soundID = item.Value.ItemID;
2468 break;
2469 }
2470 } 2485 }
2471 } 2486 }
2487 TaskInventory.LockItemsForRead(false);
2472 } 2488 }
2473 2489
2474 if (soundID == UUID.Zero) 2490 if (soundID == UUID.Zero)
@@ -2684,6 +2700,13 @@ namespace OpenSim.Region.Framework.Scenes
2684 SetText(text); 2700 SetText(text);
2685 } 2701 }
2686 2702
2703 public void StopLookAt()
2704 {
2705 m_parentGroup.stopLookAt();
2706
2707 m_parentGroup.ScheduleGroupForTerseUpdate();
2708 }
2709
2687 public void StopMoveToTarget() 2710 public void StopMoveToTarget()
2688 { 2711 {
2689 m_parentGroup.stopMoveToTarget(); 2712 m_parentGroup.stopMoveToTarget();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 47e4ad0..0321c41 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -81,7 +81,9 @@ namespace OpenSim.Region.Framework.Scenes
81 /// </value> 81 /// </value>
82 protected internal TaskInventoryDictionary Items 82 protected internal TaskInventoryDictionary Items
83 { 83 {
84 get { return m_items; } 84 get {
85 return m_items;
86 }
85 set 87 set
86 { 88 {
87 m_items = value; 89 m_items = value;
@@ -117,22 +119,25 @@ namespace OpenSim.Region.Framework.Scenes
117 /// <param name="linkNum">Link number for the part</param> 119 /// <param name="linkNum">Link number for the part</param>
118 public void ResetInventoryIDs() 120 public void ResetInventoryIDs()
119 { 121 {
120 lock (Items) 122 m_items.LockItemsForWrite(true);
123
124 if (0 == Items.Count)
121 { 125 {
122 if (0 == Items.Count) 126 m_items.LockItemsForWrite(false);
123 return; 127 return;
128 }
124 129
125 HasInventoryChanged = true; 130 HasInventoryChanged = true;
126 m_part.ParentGroup.HasGroupChanged = true; 131 m_part.ParentGroup.HasGroupChanged = true;
127 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 132 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
128 Items.Clear(); 133 Items.Clear();
129 134
130 foreach (TaskInventoryItem item in items) 135 foreach (TaskInventoryItem item in items)
131 { 136 {
132 item.ResetIDs(m_part.UUID); 137 item.ResetIDs(m_part.UUID);
133 Items.Add(item.ItemID, item); 138 Items.Add(item.ItemID, item);
134 }
135 } 139 }
140 m_items.LockItemsForWrite(false);
136 } 141 }
137 142
138 /// <summary> 143 /// <summary>
@@ -141,25 +146,25 @@ namespace OpenSim.Region.Framework.Scenes
141 /// <param name="ownerId"></param> 146 /// <param name="ownerId"></param>
142 public void ChangeInventoryOwner(UUID ownerId) 147 public void ChangeInventoryOwner(UUID ownerId)
143 { 148 {
144 lock (Items) 149 m_items.LockItemsForWrite(true);
150 if (0 == Items.Count)
145 { 151 {
146 if (0 == Items.Count) 152 m_items.LockItemsForWrite(false);
147 { 153 return;
148 return; 154 }
149 }
150 155
151 HasInventoryChanged = true; 156 HasInventoryChanged = true;
152 m_part.ParentGroup.HasGroupChanged = true; 157 m_part.ParentGroup.HasGroupChanged = true;
153 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 158 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
154 foreach (TaskInventoryItem item in items) 159 foreach (TaskInventoryItem item in items)
160 {
161 if (ownerId != item.OwnerID)
155 { 162 {
156 if (ownerId != item.OwnerID) 163 item.LastOwnerID = item.OwnerID;
157 { 164 item.OwnerID = ownerId;
158 item.LastOwnerID = item.OwnerID;
159 item.OwnerID = ownerId;
160 }
161 } 165 }
162 } 166 }
167 m_items.LockItemsForWrite(false);
163 } 168 }
164 169
165 /// <summary> 170 /// <summary>
@@ -168,24 +173,24 @@ namespace OpenSim.Region.Framework.Scenes
168 /// <param name="groupID"></param> 173 /// <param name="groupID"></param>
169 public void ChangeInventoryGroup(UUID groupID) 174 public void ChangeInventoryGroup(UUID groupID)
170 { 175 {
171 lock (Items) 176 m_items.LockItemsForWrite(true);
177 if (0 == Items.Count)
172 { 178 {
173 if (0 == Items.Count) 179 m_items.LockItemsForWrite(false);
174 { 180 return;
175 return; 181 }
176 }
177 182
178 HasInventoryChanged = true; 183 HasInventoryChanged = true;
179 m_part.ParentGroup.HasGroupChanged = true; 184 m_part.ParentGroup.HasGroupChanged = true;
180 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 185 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
181 foreach (TaskInventoryItem item in items) 186 foreach (TaskInventoryItem item in items)
187 {
188 if (groupID != item.GroupID)
182 { 189 {
183 if (groupID != item.GroupID) 190 item.GroupID = groupID;
184 {
185 item.GroupID = groupID;
186 }
187 } 191 }
188 } 192 }
193 m_items.LockItemsForWrite(false);
189 } 194 }
190 195
191 /// <summary> 196 /// <summary>
@@ -193,14 +198,14 @@ namespace OpenSim.Region.Framework.Scenes
193 /// </summary> 198 /// </summary>
194 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 199 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
195 { 200 {
196 lock (m_items) 201 Items.LockItemsForRead(true);
202 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
203 Items.LockItemsForRead(false);
204 foreach (TaskInventoryItem item in items)
197 { 205 {
198 foreach (TaskInventoryItem item in Items.Values) 206 if ((int)InventoryType.LSL == item.InvType)
199 { 207 {
200 if ((int)InventoryType.LSL == item.InvType) 208 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
201 {
202 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
203 }
204 } 209 }
205 } 210 }
206 } 211 }
@@ -210,17 +215,20 @@ namespace OpenSim.Region.Framework.Scenes
210 /// </summary> 215 /// </summary>
211 public void RemoveScriptInstances() 216 public void RemoveScriptInstances()
212 { 217 {
213 lock (Items) 218 Items.LockItemsForRead(true);
219 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
220 Items.LockItemsForRead(false);
221
222 foreach (TaskInventoryItem item in items)
214 { 223 {
215 foreach (TaskInventoryItem item in Items.Values) 224 if ((int)InventoryType.LSL == item.InvType)
216 { 225 {
217 if ((int)InventoryType.LSL == item.InvType) 226 RemoveScriptInstance(item.ItemID);
218 { 227 m_part.RemoveScriptEvents(item.ItemID);
219 RemoveScriptInstance(item.ItemID);
220 m_part.RemoveScriptEvents(item.ItemID);
221 }
222 } 228 }
223 } 229 }
230
231
224 } 232 }
225 233
226 /// <summary> 234 /// <summary>
@@ -245,8 +253,10 @@ namespace OpenSim.Region.Framework.Scenes
245 if (stateSource == 1 && // Prim crossing 253 if (stateSource == 1 && // Prim crossing
246 m_part.ParentGroup.Scene.m_trustBinaries) 254 m_part.ParentGroup.Scene.m_trustBinaries)
247 { 255 {
256 m_items.LockItemsForWrite(true);
248 m_items[item.ItemID].PermsMask = 0; 257 m_items[item.ItemID].PermsMask = 0;
249 m_items[item.ItemID].PermsGranter = UUID.Zero; 258 m_items[item.ItemID].PermsGranter = UUID.Zero;
259 m_items.LockItemsForWrite(false);
250 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 260 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
251 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 261 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
252 m_part.ParentGroup.AddActiveScriptCount(1); 262 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -268,8 +278,10 @@ namespace OpenSim.Region.Framework.Scenes
268 { 278 {
269 if (m_part.ParentGroup.m_savedScriptState != null) 279 if (m_part.ParentGroup.m_savedScriptState != null)
270 RestoreSavedScriptState(item.OldItemID, item.ItemID); 280 RestoreSavedScriptState(item.OldItemID, item.ItemID);
281 m_items.LockItemsForWrite(true);
271 m_items[item.ItemID].PermsMask = 0; 282 m_items[item.ItemID].PermsMask = 0;
272 m_items[item.ItemID].PermsGranter = UUID.Zero; 283 m_items[item.ItemID].PermsGranter = UUID.Zero;
284 m_items.LockItemsForWrite(false);
273 string script = Utils.BytesToString(asset.Data); 285 string script = Utils.BytesToString(asset.Data);
274 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 286 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
275 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 287 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
@@ -344,14 +356,17 @@ namespace OpenSim.Region.Framework.Scenes
344 /// </param> 356 /// </param>
345 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 357 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
346 { 358 {
347 lock (m_items) 359 m_items.LockItemsForRead(true);
360 if (m_items.ContainsKey(itemId))
348 { 361 {
349 if (m_items.ContainsKey(itemId)) 362 if (m_items.ContainsKey(itemId))
350 { 363 {
364 m_items.LockItemsForRead(false);
351 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 365 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
352 } 366 }
353 else 367 else
354 { 368 {
369 m_items.LockItemsForRead(false);
355 m_log.ErrorFormat( 370 m_log.ErrorFormat(
356 "[PRIM INVENTORY]: " + 371 "[PRIM INVENTORY]: " +
357 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 372 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
@@ -359,6 +374,15 @@ namespace OpenSim.Region.Framework.Scenes
359 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 374 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
360 } 375 }
361 } 376 }
377 else
378 {
379 m_items.LockItemsForRead(false);
380 m_log.ErrorFormat(
381 "[PRIM INVENTORY]: " +
382 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
383 itemId, m_part.Name, m_part.UUID);
384 }
385
362 } 386 }
363 387
364 /// <summary> 388 /// <summary>
@@ -390,11 +414,16 @@ namespace OpenSim.Region.Framework.Scenes
390 /// <returns></returns> 414 /// <returns></returns>
391 private bool InventoryContainsName(string name) 415 private bool InventoryContainsName(string name)
392 { 416 {
393 foreach (TaskInventoryItem item in Items.Values) 417 m_items.LockItemsForRead(true);
418 foreach (TaskInventoryItem item in m_items.Values)
394 { 419 {
395 if (item.Name == name) 420 if (item.Name == name)
421 {
422 m_items.LockItemsForRead(false);
396 return true; 423 return true;
424 }
397 } 425 }
426 m_items.LockItemsForRead(false);
398 return false; 427 return false;
399 } 428 }
400 429
@@ -436,7 +465,9 @@ namespace OpenSim.Region.Framework.Scenes
436 /// <param name="item"></param> 465 /// <param name="item"></param>
437 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 466 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
438 { 467 {
468 m_items.LockItemsForRead(true);
439 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); 469 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
470 m_items.LockItemsForRead(false);
440 foreach (TaskInventoryItem i in il) 471 foreach (TaskInventoryItem i in il)
441 { 472 {
442 if (i.Name == item.Name) 473 if (i.Name == item.Name)
@@ -473,15 +504,14 @@ namespace OpenSim.Region.Framework.Scenes
473 item.ParentPartID = m_part.UUID; 504 item.ParentPartID = m_part.UUID;
474 item.Name = name; 505 item.Name = name;
475 506
476 lock (m_items) 507 m_items.LockItemsForWrite(true);
477 { 508 m_items.Add(item.ItemID, item);
478 m_items.Add(item.ItemID, item); 509 m_items.LockItemsForWrite(false);
479
480 if (allowedDrop) 510 if (allowedDrop)
481 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 511 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
482 else 512 else
483 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 513 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
484 } 514
485 515
486 m_inventorySerial++; 516 m_inventorySerial++;
487 //m_inventorySerial += 2; 517 //m_inventorySerial += 2;
@@ -498,14 +528,13 @@ namespace OpenSim.Region.Framework.Scenes
498 /// <param name="items"></param> 528 /// <param name="items"></param>
499 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 529 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
500 { 530 {
501 lock (m_items) 531 m_items.LockItemsForWrite(true);
532 foreach (TaskInventoryItem item in items)
502 { 533 {
503 foreach (TaskInventoryItem item in items) 534 m_items.Add(item.ItemID, item);
504 { 535 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
505 m_items.Add(item.ItemID, item);
506 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
507 }
508 } 536 }
537 m_items.LockItemsForWrite(false);
509 538
510 m_inventorySerial++; 539 m_inventorySerial++;
511 } 540 }
@@ -518,8 +547,9 @@ namespace OpenSim.Region.Framework.Scenes
518 public TaskInventoryItem GetInventoryItem(UUID itemId) 547 public TaskInventoryItem GetInventoryItem(UUID itemId)
519 { 548 {
520 TaskInventoryItem item; 549 TaskInventoryItem item;
550 m_items.LockItemsForRead(true);
521 m_items.TryGetValue(itemId, out item); 551 m_items.TryGetValue(itemId, out item);
522 552 m_items.LockItemsForRead(false);
523 return item; 553 return item;
524 } 554 }
525 555
@@ -531,46 +561,46 @@ namespace OpenSim.Region.Framework.Scenes
531 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 561 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
532 public bool UpdateInventoryItem(TaskInventoryItem item) 562 public bool UpdateInventoryItem(TaskInventoryItem item)
533 { 563 {
534 lock (m_items) 564 m_items.LockItemsForWrite(true);
565
566 if (m_items.ContainsKey(item.ItemID))
535 { 567 {
536 if (m_items.ContainsKey(item.ItemID)) 568 item.ParentID = m_part.UUID;
569 item.ParentPartID = m_part.UUID;
570 item.Flags = m_items[item.ItemID].Flags;
571 if (item.AssetID == UUID.Zero)
537 { 572 {
538 item.ParentID = m_part.UUID; 573 item.AssetID = m_items[item.ItemID].AssetID;
539 item.ParentPartID = m_part.UUID; 574 }
540 item.Flags = m_items[item.ItemID].Flags; 575 else if ((InventoryType)item.Type == InventoryType.Notecard)
541 if (item.AssetID == UUID.Zero) 576 {
542 { 577 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
543 item.AssetID = m_items[item.ItemID].AssetID;
544 }
545 else if ((InventoryType)item.Type == InventoryType.Notecard)
546 {
547 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
548 578
549 if (presence != null) 579 if (presence != null)
550 { 580 {
551 presence.ControllingClient.SendAgentAlertMessage( 581 presence.ControllingClient.SendAgentAlertMessage(
552 "Notecard saved", false); 582 "Notecard saved", false);
553 }
554 } 583 }
584 }
555 585
556 m_items[item.ItemID] = item; 586 m_items[item.ItemID] = item;
557 m_inventorySerial++; 587 m_inventorySerial++;
558 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 588 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
559
560 HasInventoryChanged = true;
561 m_part.ParentGroup.HasGroupChanged = true;
562 589
563 return true; 590 HasInventoryChanged = true;
564 } 591 m_part.ParentGroup.HasGroupChanged = true;
565 else 592 m_items.LockItemsForWrite(false);
566 { 593 return true;
567 m_log.ErrorFormat( 594 }
568 "[PRIM INVENTORY]: " + 595 else
569 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 596 {
570 item.ItemID, m_part.Name, m_part.UUID, 597 m_log.ErrorFormat(
571 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 598 "[PRIM INVENTORY]: " +
572 } 599 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
600 item.ItemID, m_part.Name, m_part.UUID,
601 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
573 } 602 }
603 m_items.LockItemsForWrite(false);
574 604
575 return false; 605 return false;
576 } 606 }
@@ -583,52 +613,54 @@ namespace OpenSim.Region.Framework.Scenes
583 /// in this prim's inventory.</returns> 613 /// in this prim's inventory.</returns>
584 public int RemoveInventoryItem(UUID itemID) 614 public int RemoveInventoryItem(UUID itemID)
585 { 615 {
586 lock (m_items) 616 m_items.LockItemsForRead(true);
617
618 if (m_items.ContainsKey(itemID))
587 { 619 {
588 if (m_items.ContainsKey(itemID)) 620 int type = m_items[itemID].InvType;
621 m_items.LockItemsForRead(false);
622 if (type == 10) // Script
589 { 623 {
590 int type = m_items[itemID].InvType; 624 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
591 if (type == 10) // Script 625 }
592 { 626 m_items.LockItemsForWrite(true);
593 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 627 m_items.Remove(itemID);
594 } 628 m_items.LockItemsForWrite(false);
595 m_items.Remove(itemID); 629 m_inventorySerial++;
596 m_inventorySerial++; 630 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
597 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
598
599 HasInventoryChanged = true;
600 m_part.ParentGroup.HasGroupChanged = true;
601 631
602 int scriptcount = 0; 632 HasInventoryChanged = true;
603 lock (m_items) 633 m_part.ParentGroup.HasGroupChanged = true;
604 {
605 foreach (TaskInventoryItem item in m_items.Values)
606 {
607 if (item.Type == 10)
608 {
609 scriptcount++;
610 }
611 }
612 }
613 634
614 if (scriptcount <= 0) 635 int scriptcount = 0;
636 m_items.LockItemsForRead(true);
637 foreach (TaskInventoryItem item in m_items.Values)
638 {
639 if (item.Type == 10)
615 { 640 {
616 m_part.RemFlag(PrimFlags.Scripted); 641 scriptcount++;
617 } 642 }
618
619 m_part.ScheduleFullUpdate();
620
621 return type;
622 } 643 }
623 else 644 m_items.LockItemsForRead(false);
645
646
647 if (scriptcount <= 0)
624 { 648 {
625 m_log.ErrorFormat( 649 m_part.RemFlag(PrimFlags.Scripted);
626 "[PRIM INVENTORY]: " +
627 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
628 itemID, m_part.Name, m_part.UUID,
629 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
630 } 650 }
651
652 m_part.ScheduleFullUpdate();
653
654 return type;
655 }
656 else
657 {
658 m_log.ErrorFormat(
659 "[PRIM INVENTORY]: " +
660 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
661 itemID, m_part.Name, m_part.UUID);
631 } 662 }
663 m_items.LockItemsForWrite(false);
632 664
633 return -1; 665 return -1;
634 } 666 }
@@ -681,52 +713,53 @@ namespace OpenSim.Region.Framework.Scenes
681 // isn't available (such as drag from prim inventory to agent inventory) 713 // isn't available (such as drag from prim inventory to agent inventory)
682 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 714 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
683 715
684 lock (m_items) 716 m_items.LockItemsForRead(true);
717
718 foreach (TaskInventoryItem item in m_items.Values)
685 { 719 {
686 foreach (TaskInventoryItem item in m_items.Values) 720 UUID ownerID = item.OwnerID;
687 { 721 uint everyoneMask = 0;
688 UUID ownerID = item.OwnerID; 722 uint baseMask = item.BasePermissions;
689 uint everyoneMask = 0; 723 uint ownerMask = item.CurrentPermissions;
690 uint baseMask = item.BasePermissions;
691 uint ownerMask = item.CurrentPermissions;
692 724
693 invString.AddItemStart(); 725 invString.AddItemStart();
694 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 726 invString.AddNameValueLine("item_id", item.ItemID.ToString());
695 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 727 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
696 728
697 invString.AddPermissionsStart(); 729 invString.AddPermissionsStart();
698 730
699 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 731 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
700 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 732 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
701 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 733 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
702 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 734 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
703 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 735 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
704 736
705 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 737 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
706 invString.AddNameValueLine("owner_id", ownerID.ToString()); 738 invString.AddNameValueLine("owner_id", ownerID.ToString());
707 739
708 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 740 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
709 741
710 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 742 invString.AddNameValueLine("group_id", item.GroupID.ToString());
711 invString.AddSectionEnd(); 743 invString.AddSectionEnd();
712 744
713 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 745 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
714 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 746 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
715 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 747 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
716 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 748 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
717 749
718 invString.AddSaleStart(); 750 invString.AddSaleStart();
719 invString.AddNameValueLine("sale_type", "not"); 751 invString.AddNameValueLine("sale_type", "not");
720 invString.AddNameValueLine("sale_price", "0"); 752 invString.AddNameValueLine("sale_price", "0");
721 invString.AddSectionEnd(); 753 invString.AddSectionEnd();
722 754
723 invString.AddNameValueLine("name", item.Name + "|"); 755 invString.AddNameValueLine("name", item.Name + "|");
724 invString.AddNameValueLine("desc", item.Description + "|"); 756 invString.AddNameValueLine("desc", item.Description + "|");
725 757
726 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 758 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
727 invString.AddSectionEnd(); 759 invString.AddSectionEnd();
728 }
729 } 760 }
761 int count = m_items.Count;
762 m_items.LockItemsForRead(false);
730 763
731 fileData = Utils.StringToBytes(invString.BuildString); 764 fileData = Utils.StringToBytes(invString.BuildString);
732 765
@@ -747,10 +780,9 @@ namespace OpenSim.Region.Framework.Scenes
747 { 780 {
748 if (HasInventoryChanged) 781 if (HasInventoryChanged)
749 { 782 {
750 lock (Items) 783 Items.LockItemsForRead(true);
751 { 784 datastore.StorePrimInventory(m_part.UUID, Items.Values);
752 datastore.StorePrimInventory(m_part.UUID, Items.Values); 785 Items.LockItemsForRead(false);
753 }
754 786
755 HasInventoryChanged = false; 787 HasInventoryChanged = false;
756 } 788 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 289ba47..a3ad7ca 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -113,8 +115,11 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
117 private Vector3 m_lastPosition; 119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
121 private Vector3 m_lastPosition;
122 private Vector3 m_lastWorldPosition;
118 private Quaternion m_lastRotation; 123 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 124 private Vector3 m_lastVelocity;
120 //private int m_lastTerseSent; 125 //private int m_lastTerseSent;
@@ -145,7 +150,6 @@ namespace OpenSim.Region.Framework.Scenes
145 private int m_perfMonMS; 150 private int m_perfMonMS;
146 151
147 private bool m_setAlwaysRun; 152 private bool m_setAlwaysRun;
148
149 private bool m_forceFly; 153 private bool m_forceFly;
150 private bool m_flyDisabled; 154 private bool m_flyDisabled;
151 155
@@ -169,7 +173,8 @@ namespace OpenSim.Region.Framework.Scenes
169 protected RegionInfo m_regionInfo; 173 protected RegionInfo m_regionInfo;
170 protected ulong crossingFromRegion; 174 protected ulong crossingFromRegion;
171 175
172 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 176 private readonly Vector3[] Dir_Vectors = new Vector3[11];
177 private bool m_isNudging = false;
173 178
174 // Position of agent's camera in world (region cordinates) 179 // Position of agent's camera in world (region cordinates)
175 protected Vector3 m_CameraCenter; 180 protected Vector3 m_CameraCenter;
@@ -194,6 +199,7 @@ namespace OpenSim.Region.Framework.Scenes
194 private bool m_autopilotMoving; 199 private bool m_autopilotMoving;
195 private Vector3 m_autoPilotTarget; 200 private Vector3 m_autoPilotTarget;
196 private bool m_sitAtAutoTarget; 201 private bool m_sitAtAutoTarget;
202 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
197 203
198 private string m_nextSitAnimation = String.Empty; 204 private string m_nextSitAnimation = String.Empty;
199 205
@@ -204,6 +210,9 @@ namespace OpenSim.Region.Framework.Scenes
204 private bool m_followCamAuto; 210 private bool m_followCamAuto;
205 211
206 private int m_movementUpdateCount; 212 private int m_movementUpdateCount;
213 private int m_lastColCount = -1; //KF: Look for Collision chnages
214 private int m_updateCount = 0; //KF: Update Anims for a while
215 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
207 216
208 private const int NumMovementsBetweenRayCast = 5; 217 private const int NumMovementsBetweenRayCast = 5;
209 218
@@ -233,6 +242,10 @@ namespace OpenSim.Region.Framework.Scenes
233 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 242 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
234 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 243 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
235 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 244 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
245 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
246 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
247 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
248 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
236 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 249 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
237 } 250 }
238 251
@@ -658,10 +671,7 @@ namespace OpenSim.Region.Framework.Scenes
658 671
659 672
660 AdjustKnownSeeds(); 673 AdjustKnownSeeds();
661
662 // TODO: I think, this won't send anything, as we are still a child here...
663 Animator.TrySetMovementAnimation("STAND"); 674 Animator.TrySetMovementAnimation("STAND");
664
665 // we created a new ScenePresence (a new child agent) in a fresh region. 675 // we created a new ScenePresence (a new child agent) in a fresh region.
666 // Request info about all the (root) agents in this region 676 // Request info about all the (root) agents in this region
667 // Note: This won't send data *to* other clients in that region (children don't send) 677 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -717,21 +727,47 @@ namespace OpenSim.Region.Framework.Scenes
717 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 727 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
718 Dir_Vectors[4] = Vector3.UnitZ; //UP 728 Dir_Vectors[4] = Vector3.UnitZ; //UP
719 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 729 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
720 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 730 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
731 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
732 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
733 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
734 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
721 } 735 }
722 736
723 private Vector3[] GetWalkDirectionVectors() 737 private Vector3[] GetWalkDirectionVectors()
724 { 738 {
725 Vector3[] vector = new Vector3[6]; 739 Vector3[] vector = new Vector3[11];
726 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 740 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
727 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK 741 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
728 vector[2] = Vector3.UnitY; //LEFT 742 vector[2] = Vector3.UnitY; //LEFT
729 vector[3] = -Vector3.UnitY; //RIGHT 743 vector[3] = -Vector3.UnitY; //RIGHT
730 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 744 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
731 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 745 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
732 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 746 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
747 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
748 vector[8] = Vector3.UnitY; //LEFT_NUDGE
749 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
750 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
733 return vector; 751 return vector;
734 } 752 }
753
754 private bool[] GetDirectionIsNudge()
755 {
756 bool[] isNudge = new bool[11];
757 isNudge[0] = false; //FORWARD
758 isNudge[1] = false; //BACK
759 isNudge[2] = false; //LEFT
760 isNudge[3] = false; //RIGHT
761 isNudge[4] = false; //UP
762 isNudge[5] = false; //DOWN
763 isNudge[6] = true; //FORWARD_NUDGE
764 isNudge[7] = true; //BACK_NUDGE
765 isNudge[8] = true; //LEFT_NUDGE
766 isNudge[9] = true; //RIGHT_NUDGE
767 isNudge[10] = true; //DOWN_Nudge
768 return isNudge;
769 }
770
735 771
736 #endregion 772 #endregion
737 773
@@ -995,7 +1031,9 @@ namespace OpenSim.Region.Framework.Scenes
995 { 1031 {
996 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1032 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
997 } 1033 }
998 1034
1035 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1036
999 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1037 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1000 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1038 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1001 } 1039 }
@@ -1230,7 +1268,6 @@ namespace OpenSim.Region.Framework.Scenes
1230 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1268 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1231 } 1269 }
1232 } 1270 }
1233
1234 lock (scriptedcontrols) 1271 lock (scriptedcontrols)
1235 { 1272 {
1236 if (scriptedcontrols.Count > 0) 1273 if (scriptedcontrols.Count > 0)
@@ -1245,9 +1282,7 @@ namespace OpenSim.Region.Framework.Scenes
1245 1282
1246 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1283 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1247 { 1284 {
1248 // TODO: This doesn't prevent the user from walking yet. 1285 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1249 // Setting parent ID would fix this, if we knew what value
1250 // to use. Or we could add a m_isSitting variable.
1251 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 1286 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1252 } 1287 }
1253 1288
@@ -1292,6 +1327,11 @@ namespace OpenSim.Region.Framework.Scenes
1292 update_rotation = true; 1327 update_rotation = true;
1293 } 1328 }
1294 1329
1330 //guilty until proven innocent..
1331 bool Nudging = true;
1332 //Basically, if there is at least one non-nudge control then we don't need
1333 //to worry about stopping the avatar
1334
1295 if (m_parentID == 0) 1335 if (m_parentID == 0)
1296 { 1336 {
1297 bool bAllowUpdateMoveToPosition = false; 1337 bool bAllowUpdateMoveToPosition = false;
@@ -1306,6 +1346,12 @@ namespace OpenSim.Region.Framework.Scenes
1306 else 1346 else
1307 dirVectors = Dir_Vectors; 1347 dirVectors = Dir_Vectors;
1308 1348
1349 bool[] isNudge = GetDirectionIsNudge();
1350
1351
1352
1353
1354
1309 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1355 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1310 { 1356 {
1311 if (((uint)flags & (uint)DCF) != 0) 1357 if (((uint)flags & (uint)DCF) != 0)
@@ -1315,6 +1361,10 @@ namespace OpenSim.Region.Framework.Scenes
1315 try 1361 try
1316 { 1362 {
1317 agent_control_v3 += dirVectors[i]; 1363 agent_control_v3 += dirVectors[i];
1364 if (isNudge[i] == false)
1365 {
1366 Nudging = false;
1367 }
1318 } 1368 }
1319 catch (IndexOutOfRangeException) 1369 catch (IndexOutOfRangeException)
1320 { 1370 {
@@ -1376,6 +1426,9 @@ namespace OpenSim.Region.Framework.Scenes
1376 // Ignore z component of vector 1426 // Ignore z component of vector
1377 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1427 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1378 LocalVectorToTarget2D.Normalize(); 1428 LocalVectorToTarget2D.Normalize();
1429
1430 //We're not nudging
1431 Nudging = false;
1379 agent_control_v3 += LocalVectorToTarget2D; 1432 agent_control_v3 += LocalVectorToTarget2D;
1380 1433
1381 // update avatar movement flags. the avatar coordinate system is as follows: 1434 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1464,7 +1517,7 @@ namespace OpenSim.Region.Framework.Scenes
1464 // m_log.DebugFormat( 1517 // m_log.DebugFormat(
1465 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1518 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1466 1519
1467 AddNewMovement(agent_control_v3, q); 1520 AddNewMovement(agent_control_v3, q, Nudging);
1468 1521
1469 1522
1470 } 1523 }
@@ -1485,7 +1538,6 @@ namespace OpenSim.Region.Framework.Scenes
1485 m_sitAtAutoTarget = false; 1538 m_sitAtAutoTarget = false;
1486 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1539 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1487 //proxy.PCode = (byte)PCode.ParticleSystem; 1540 //proxy.PCode = (byte)PCode.ParticleSystem;
1488
1489 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1541 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1490 proxyObjectGroup.AttachToScene(m_scene); 1542 proxyObjectGroup.AttachToScene(m_scene);
1491 1543
@@ -1527,7 +1579,7 @@ namespace OpenSim.Region.Framework.Scenes
1527 } 1579 }
1528 m_moveToPositionInProgress = true; 1580 m_moveToPositionInProgress = true;
1529 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1581 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1530 } 1582 }
1531 catch (Exception ex) 1583 catch (Exception ex)
1532 { 1584 {
1533 //Why did I get this error? 1585 //Why did I get this error?
@@ -1549,7 +1601,7 @@ namespace OpenSim.Region.Framework.Scenes
1549 Velocity = Vector3.Zero; 1601 Velocity = Vector3.Zero;
1550 SendFullUpdateToAllClients(); 1602 SendFullUpdateToAllClients();
1551 1603
1552 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1604 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1553 } 1605 }
1554 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1606 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1555 m_requestedSitTargetUUID = UUID.Zero; 1607 m_requestedSitTargetUUID = UUID.Zero;
@@ -1587,46 +1639,79 @@ namespace OpenSim.Region.Framework.Scenes
1587 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1639 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1588 if (part != null) 1640 if (part != null)
1589 { 1641 {
1642 part.TaskInventory.LockItemsForRead(true);
1590 TaskInventoryDictionary taskIDict = part.TaskInventory; 1643 TaskInventoryDictionary taskIDict = part.TaskInventory;
1591 if (taskIDict != null) 1644 if (taskIDict != null)
1592 { 1645 {
1593 lock (taskIDict) 1646 foreach (UUID taskID in taskIDict.Keys)
1594 { 1647 {
1595 foreach (UUID taskID in taskIDict.Keys) 1648 UnRegisterControlEventsToScript(LocalId, taskID);
1596 { 1649 taskIDict[taskID].PermsMask &= ~(
1597 UnRegisterControlEventsToScript(LocalId, taskID); 1650 2048 | //PERMISSION_CONTROL_CAMERA
1598 taskIDict[taskID].PermsMask &= ~( 1651 4); // PERMISSION_TAKE_CONTROLS
1599 2048 | //PERMISSION_CONTROL_CAMERA
1600 4); // PERMISSION_TAKE_CONTROLS
1601 }
1602 } 1652 }
1603
1604 } 1653 }
1654 part.TaskInventory.LockItemsForRead(false);
1605 // Reset sit target. 1655 // Reset sit target.
1606 if (part.GetAvatarOnSitTarget() == UUID) 1656 if (part.GetAvatarOnSitTarget() == UUID)
1607 part.SetAvatarOnSitTarget(UUID.Zero); 1657 part.SetAvatarOnSitTarget(UUID.Zero);
1608
1609 m_parentPosition = part.GetWorldPosition(); 1658 m_parentPosition = part.GetWorldPosition();
1610 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1659 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1611 } 1660 }
1612 1661 // part.GetWorldRotation() is the rotation of the object being sat on
1613 if (m_physicsActor == null) 1662 // Rotation is the sittiing Av's rotation
1614 { 1663
1615 AddToPhysicalScene(false); 1664 Quaternion partRot;
1665// if (part.LinkNum == 1)
1666// { // Root prim of linkset
1667// partRot = part.ParentGroup.RootPart.RotationOffset;
1668// }
1669// else
1670// { // single or child prim
1671
1672// }
1673 if (part == null) //CW: Part may be gone. llDie() for example.
1674 {
1675 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1676 }
1677 else
1678 {
1679 partRot = part.GetWorldRotation();
1680 }
1681
1682 Quaternion partIRot = Quaternion.Inverse(partRot);
1683
1684 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1685 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1686
1687
1688 if (m_physicsActor == null)
1689 {
1690 AddToPhysicalScene(false);
1691 }
1692 //CW: If the part isn't null then we can set the current position
1693 if (part != null)
1694 {
1695 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset!
1696 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1697 part.IsOccupied = false;
1698 }
1699 else
1700 {
1701 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
1702 AbsolutePosition = m_lastWorldPosition;
1616 } 1703 }
1617 1704
1618 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 1705 m_parentPosition = Vector3.Zero;
1619 m_parentPosition = Vector3.Zero; 1706 m_parentID = 0;
1620
1621 m_parentID = 0;
1622 SendFullUpdateToAllClients(); 1707 SendFullUpdateToAllClients();
1623 m_requestedSitTargetID = 0; 1708 m_requestedSitTargetID = 0;
1709
1624 if ((m_physicsActor != null) && (m_avHeight > 0)) 1710 if ((m_physicsActor != null) && (m_avHeight > 0))
1625 { 1711 {
1626 SetHeight(m_avHeight); 1712 SetHeight(m_avHeight);
1627 } 1713 }
1628 } 1714 }
1629
1630 Animator.TrySetMovementAnimation("STAND"); 1715 Animator.TrySetMovementAnimation("STAND");
1631 } 1716 }
1632 1717
@@ -1657,13 +1742,9 @@ namespace OpenSim.Region.Framework.Scenes
1657 Vector3 avSitOffSet = part.SitTargetPosition; 1742 Vector3 avSitOffSet = part.SitTargetPosition;
1658 Quaternion avSitOrientation = part.SitTargetOrientation; 1743 Quaternion avSitOrientation = part.SitTargetOrientation;
1659 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1744 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1660 1745 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1661 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1746 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1662 bool SitTargetisSet = 1747 if (SitTargetisSet && !SitTargetOccupied)
1663 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1664 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1665
1666 if (SitTargetisSet && SitTargetUnOccupied)
1667 { 1748 {
1668 //switch the target to this prim 1749 //switch the target to this prim
1669 return part; 1750 return part;
@@ -1677,84 +1758,152 @@ namespace OpenSim.Region.Framework.Scenes
1677 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1758 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1678 { 1759 {
1679 bool autopilot = true; 1760 bool autopilot = true;
1761 Vector3 autopilotTarget = new Vector3();
1762 Quaternion sitOrientation = Quaternion.Identity;
1680 Vector3 pos = new Vector3(); 1763 Vector3 pos = new Vector3();
1681 Quaternion sitOrientation = pSitOrientation;
1682 Vector3 cameraEyeOffset = Vector3.Zero; 1764 Vector3 cameraEyeOffset = Vector3.Zero;
1683 Vector3 cameraAtOffset = Vector3.Zero; 1765 Vector3 cameraAtOffset = Vector3.Zero;
1684 bool forceMouselook = false; 1766 bool forceMouselook = false;
1685 1767
1686 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1768 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1687 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1769 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1688 if (part != null) 1770 if (part == null) return;
1689 { 1771
1690 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1772 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
1691 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 1773 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1692 1774
1693 // Is a sit target available? 1775 // part is the prim to sit on
1694 Vector3 avSitOffSet = part.SitTargetPosition; 1776 // offset is the world-ref vector distance from that prim center to the click-spot
1695 Quaternion avSitOrientation = part.SitTargetOrientation; 1777 // UUID is the UUID of the Avatar doing the clicking
1696 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1778
1697 1779 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1698 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1780
1699 bool SitTargetisSet = 1781 // Is a sit target available?
1700 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1782 Vector3 avSitOffSet = part.SitTargetPosition;
1701 ( 1783 Quaternion avSitOrientation = part.SitTargetOrientation;
1702 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1784
1703 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1785 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1704 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion 1786 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1705 ) 1787 Quaternion partRot;
1706 )); 1788// if (part.LinkNum == 1)
1707 1789// { // Root prim of linkset
1708 if (SitTargetisSet && SitTargetUnOccupied) 1790// partRot = part.ParentGroup.RootPart.RotationOffset;
1709 { 1791// }
1710 part.SetAvatarOnSitTarget(UUID); 1792// else
1711 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1793// { // single or child prim
1712 sitOrientation = avSitOrientation; 1794 partRot = part.GetWorldRotation();
1713 autopilot = false; 1795// }
1714 } 1796 Quaternion partIRot = Quaternion.Inverse(partRot);
1715 1797//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1716 pos = part.AbsolutePosition + offset; 1798 // Sit analysis rewritten by KF 091125
1717 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1799 if (SitTargetisSet) // scipted sit
1718 //{ 1800 {
1719 // offset = pos; 1801 if (!part.IsOccupied)
1720 //autopilot = false; 1802 {
1721 //} 1803//Console.WriteLine("Scripted, unoccupied");
1722 if (m_physicsActor != null) 1804 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1723 { 1805 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1724 // If we're not using the client autopilot, we're immediately warping the avatar to the location 1806 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1725 // We can remove the physicsActor until they stand up. 1807 autopilot = false; // Jump direct to scripted llSitPos()
1726 m_sitAvatarHeight = m_physicsActor.Size.Z; 1808 }
1727 1809 else
1728 if (autopilot) 1810 {
1729 { 1811//Console.WriteLine("Scripted, occupied");
1730 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1812 return;
1731 { 1813 }
1732 autopilot = false; 1814 }
1815 else // Not Scripted
1816 {
1817 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1818 {
1819 // large prim & offset, ignore if other Avs sitting
1820// offset.Z -= 0.05f;
1821 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1822 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1823
1824//Console.WriteLine(" offset ={0}", offset);
1825//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1826//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1827
1828 }
1829 else // small offset
1830 {
1831//Console.WriteLine("Small offset");
1832 if (!part.IsOccupied)
1833 {
1834 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1835 autopilotTarget = part.AbsolutePosition;
1836 }
1837 else return; // occupied small
1838 } // end large/small
1839 } // end Scripted/not
1840 cameraAtOffset = part.GetCameraAtOffset();
1841 cameraEyeOffset = part.GetCameraEyeOffset();
1842 forceMouselook = part.GetForceMouselook();
1843 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1844 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1733 1845
1734 RemoveFromPhysicalScene(); 1846 if (m_physicsActor != null)
1735 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1847 {
1736 } 1848 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1737 } 1849 // We can remove the physicsActor until they stand up.
1738 else 1850 m_sitAvatarHeight = m_physicsActor.Size.Z;
1851 if (autopilot)
1852 { // its not a scripted sit
1853// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1854 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1739 { 1855 {
1856 autopilot = false; // close enough
1857 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1858 Not using the part's position because returning the AV to the last known standing
1859 position is likely to be more friendly, isn't it? */
1740 RemoveFromPhysicalScene(); 1860 RemoveFromPhysicalScene();
1741 } 1861 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1862 } // else the autopilot will get us close
1863 }
1864 else
1865 { // its a scripted sit
1866 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
1867 I *am* using the part's position this time because we have no real idea how far away
1868 the avatar is from the sit target. */
1869 RemoveFromPhysicalScene();
1742 } 1870 }
1743
1744 cameraAtOffset = part.GetCameraAtOffset();
1745 cameraEyeOffset = part.GetCameraEyeOffset();
1746 forceMouselook = part.GetForceMouselook();
1747 } 1871 }
1748 1872 else return; // physactor is null!
1749 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1873
1750 m_requestedSitTargetUUID = targetID; 1874 Vector3 offsetr; // = offset * partIRot;
1875 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1876 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1877 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
1878 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1879 offsetr = offset * partIRot;
1880//
1881 // else
1882 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1883 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1884 // (offset * partRot);
1885 // }
1886
1887//Console.WriteLine(" ");
1888//Console.WriteLine("link number ={0}", part.LinkNum);
1889//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1890//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1891//Console.WriteLine("Click offst ={0}", offset);
1892//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1893//Console.WriteLine("offsetr ={0}", offsetr);
1894//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1895//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1896
1897 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1898 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1751 // This calls HandleAgentSit twice, once from here, and the client calls 1899 // This calls HandleAgentSit twice, once from here, and the client calls
1752 // HandleAgentSit itself after it gets to the location 1900 // HandleAgentSit itself after it gets to the location
1753 // It doesn't get to the location until we've moved them there though 1901 // It doesn't get to the location until we've moved them there though
1754 // which happens in HandleAgentSit :P 1902 // which happens in HandleAgentSit :P
1755 m_autopilotMoving = autopilot; 1903 m_autopilotMoving = autopilot;
1756 m_autoPilotTarget = pos; 1904 m_autoPilotTarget = autopilotTarget;
1757 m_sitAtAutoTarget = autopilot; 1905 m_sitAtAutoTarget = autopilot;
1906 m_initialSitTarget = autopilotTarget;
1758 if (!autopilot) 1907 if (!autopilot)
1759 HandleAgentSit(remoteClient, UUID); 1908 HandleAgentSit(remoteClient, UUID);
1760 } 1909 }
@@ -2049,31 +2198,65 @@ namespace OpenSim.Region.Framework.Scenes
2049 { 2198 {
2050 if (part != null) 2199 if (part != null)
2051 { 2200 {
2201//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation());
2052 if (part.GetAvatarOnSitTarget() == UUID) 2202 if (part.GetAvatarOnSitTarget() == UUID)
2053 { 2203 {
2204//Console.WriteLine("Scripted Sit");
2205 // Scripted sit
2054 Vector3 sitTargetPos = part.SitTargetPosition; 2206 Vector3 sitTargetPos = part.SitTargetPosition;
2055 Quaternion sitTargetOrient = part.SitTargetOrientation; 2207 Quaternion sitTargetOrient = part.SitTargetOrientation;
2056
2057 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2058 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2059
2060 //Quaternion result = (sitTargetOrient * vq) * nq;
2061
2062 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2208 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2063 m_pos += SIT_TARGET_ADJUSTMENT; 2209 m_pos += SIT_TARGET_ADJUSTMENT;
2064 m_bodyRot = sitTargetOrient; 2210 m_bodyRot = sitTargetOrient;
2065 //Rotation = sitTargetOrient;
2066 m_parentPosition = part.AbsolutePosition; 2211 m_parentPosition = part.AbsolutePosition;
2067 2212 part.IsOccupied = true;
2068 //SendTerseUpdateToAllClients();
2069 } 2213 }
2070 else 2214 else
2071 { 2215 {
2072 m_pos -= part.AbsolutePosition; 2216 // if m_avUnscriptedSitPos is zero then Av sits above center
2217 // Else Av sits at m_avUnscriptedSitPos
2218
2219 // Non-scripted sit by Kitto Flora 21Nov09
2220 // Calculate angle of line from prim to Av
2221 Quaternion partIRot;
2222// if (part.LinkNum == 1)
2223// { // Root prim of linkset
2224// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2225// }
2226// else
2227// { // single or child prim
2228 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2229// }
2230 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2231 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2232 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2233 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2234 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2235 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2236 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2237 // Av sits at world euler <0,0, z>, translated by part rotation
2238 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2239
2073 m_parentPosition = part.AbsolutePosition; 2240 m_parentPosition = part.AbsolutePosition;
2074 } 2241 part.IsOccupied = true;
2075 } 2242 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2076 else 2243 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2244 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2245 m_avUnscriptedSitPos; // adds click offset, if any
2246 //Set up raytrace to find top surface of prim
2247 Vector3 size = part.Scale;
2248 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2249 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2250 Vector3 down = new Vector3(0f, 0f, -1f);
2251//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2252 m_scene.PhysicsScene.RaycastWorld(
2253 start, // Vector3 position,
2254 down, // Vector3 direction,
2255 mag, // float length,
2256 SitAltitudeCallback); // retMethod
2257 } // end scripted/not
2258 }
2259 else // no Av
2077 { 2260 {
2078 return; 2261 return;
2079 } 2262 }
@@ -2085,11 +2268,36 @@ namespace OpenSim.Region.Framework.Scenes
2085 2268
2086 Animator.TrySetMovementAnimation(sitAnimation); 2269 Animator.TrySetMovementAnimation(sitAnimation);
2087 SendFullUpdateToAllClients(); 2270 SendFullUpdateToAllClients();
2088 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2089 // So we're also sending a terse update (which has avatar rotation)
2090 // [Update] We do now.
2091 //SendTerseUpdateToAllClients();
2092 } 2271 }
2272
2273 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2274 {
2275 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2276 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2277 if(hitYN)
2278 {
2279 // m_pos = Av offset from prim center to make look like on center
2280 // m_parentPosition = Actual center pos of prim
2281 // collisionPoint = spot on prim where we want to sit
2282 // collisionPoint.Z = global sit surface height
2283 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2284 Quaternion partIRot;
2285// if (part.LinkNum == 1)
2286/// { // Root prim of linkset
2287// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2288// }
2289// else
2290// { // single or child prim
2291 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2292// }
2293 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2294 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2295//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2296 m_pos += offset;
2297// ControllingClient.SendClearFollowCamProperties(part.UUID);
2298
2299 }
2300 } // End SitAltitudeCallback KF.
2093 2301
2094 /// <summary> 2302 /// <summary>
2095 /// Event handler for the 'Always run' setting on the client 2303 /// Event handler for the 'Always run' setting on the client
@@ -2119,7 +2327,7 @@ namespace OpenSim.Region.Framework.Scenes
2119 /// </summary> 2327 /// </summary>
2120 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2328 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2121 /// <param name="rotation">The direction in which this avatar should now face. 2329 /// <param name="rotation">The direction in which this avatar should now face.
2122 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2330 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2123 { 2331 {
2124 if (m_isChildAgent) 2332 if (m_isChildAgent)
2125 { 2333 {
@@ -2193,7 +2401,7 @@ namespace OpenSim.Region.Framework.Scenes
2193 2401
2194 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2402 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2195 m_forceToApply = direc; 2403 m_forceToApply = direc;
2196 2404 m_isNudging = Nudging;
2197 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2405 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2198 } 2406 }
2199 2407
@@ -2208,7 +2416,7 @@ namespace OpenSim.Region.Framework.Scenes
2208 const float POSITION_TOLERANCE = 0.05f; 2416 const float POSITION_TOLERANCE = 0.05f;
2209 //const int TIME_MS_TOLERANCE = 3000; 2417 //const int TIME_MS_TOLERANCE = 3000;
2210 2418
2211 SendPrimUpdates(); 2419
2212 2420
2213 if (m_newCoarseLocations) 2421 if (m_newCoarseLocations)
2214 { 2422 {
@@ -2244,6 +2452,9 @@ namespace OpenSim.Region.Framework.Scenes
2244 CheckForBorderCrossing(); 2452 CheckForBorderCrossing();
2245 CheckForSignificantMovement(); // sends update to the modules. 2453 CheckForSignificantMovement(); // sends update to the modules.
2246 } 2454 }
2455
2456 //Sending prim updates AFTER the avatar terse updates are sent
2457 SendPrimUpdates();
2247 } 2458 }
2248 2459
2249 #endregion 2460 #endregion
@@ -3097,14 +3308,25 @@ namespace OpenSim.Region.Framework.Scenes
3097 { 3308 {
3098 if (m_forceToApply.HasValue) 3309 if (m_forceToApply.HasValue)
3099 { 3310 {
3100 Vector3 force = m_forceToApply.Value;
3101 3311
3312 Vector3 force = m_forceToApply.Value;
3102 m_updateflag = true; 3313 m_updateflag = true;
3103// movementvector = force;
3104 Velocity = force; 3314 Velocity = force;
3105 3315
3106 m_forceToApply = null; 3316 m_forceToApply = null;
3107 } 3317 }
3318 else
3319 {
3320 if (m_isNudging)
3321 {
3322 Vector3 force = Vector3.Zero;
3323
3324 m_updateflag = true;
3325 Velocity = force;
3326 m_isNudging = false;
3327 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3328 }
3329 }
3108 } 3330 }
3109 3331
3110 public override void SetText(string text, Vector3 color, double alpha) 3332 public override void SetText(string text, Vector3 color, double alpha)
@@ -3156,18 +3378,29 @@ namespace OpenSim.Region.Framework.Scenes
3156 { 3378 {
3157 if (e == null) 3379 if (e == null)
3158 return; 3380 return;
3159 3381
3160 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3382 // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3161 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3162 // as of this comment the interval is set in AddToPhysicalScene 3383 // as of this comment the interval is set in AddToPhysicalScene
3163 if (Animator!=null) 3384 if (Animator!=null)
3164 Animator.UpdateMovementAnimations(); 3385 {
3386 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3387 { // else its will lock out other animation changes, like ground sit.
3388 Animator.UpdateMovementAnimations();
3389 m_updateCount--;
3390 }
3391 }
3165 3392
3166 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3393 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3167 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3394 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3168 3395
3169 CollisionPlane = Vector4.UnitW; 3396 CollisionPlane = Vector4.UnitW;
3170 3397
3398 if (m_lastColCount != coldata.Count)
3399 {
3400 m_updateCount = UPDATE_COUNT;
3401 m_lastColCount = coldata.Count;
3402 }
3403
3171 if (coldata.Count != 0 && Animator != null) 3404 if (coldata.Count != 0 && Animator != null)
3172 { 3405 {
3173 switch (Animator.CurrentMovementAnimation) 3406 switch (Animator.CurrentMovementAnimation)
@@ -3815,5 +4048,16 @@ namespace OpenSim.Region.Framework.Scenes
3815 m_reprioritization_called = false; 4048 m_reprioritization_called = false;
3816 } 4049 }
3817 } 4050 }
4051
4052 private Vector3 Quat2Euler(Quaternion rot){
4053 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4054 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4055 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4056 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4057 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4058 return(new Vector3(x,y,z));
4059 }
4060
4061
3818 } 4062 }
3819} \ No newline at end of file 4063}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 8a27b7b..5abbb82 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -101,7 +101,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
101 { 101 {
102 throw new NotImplementedException(); 102 throw new NotImplementedException();
103 } 103 }
104 104 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
105 {
106 //This connector doesn't support the windlight module yet
107 //Return default LL windlight settings
108 return new RegionMeta7WindlightData();
109 }
110 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
111 {
112 //This connector doesn't support the windlight module yet
113 }
105 public RegionSettings LoadRegionSettings(UUID regionUUID) 114 public RegionSettings LoadRegionSettings(UUID regionUUID)
106 { 115 {
107 return null; 116 return null;
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 6c3e7eb..bdf1574 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -936,7 +936,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
936 // TODO 936 // TODO
937 } 937 }
938 938
939 public void SendGenericMessage(string method, List<string> message) 939 public void SendGenericMessage(string method, List<byte[]> message)
940 { 940 {
941 941
942 } 942 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index cf36d08..975033a 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -522,7 +522,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
522 522
523 } 523 }
524 524
525 public void SendGenericMessage(string method, List<string> message) 525 public void SendGenericMessage(string method, List<byte[]> message)
526 { 526 {
527 527
528 } 528 }
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 40fbde1..b99baa2 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 d241574..688be83 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)
@@ -1561,9 +1581,14 @@ Console.WriteLine(" JointCreateFixed");
1561 float fy = 0; 1581 float fy = 0;
1562 float fz = 0; 1582 float fz = 0;
1563 1583
1584 frcount++; // used to limit debug comment output
1585 if (frcount > 100)
1586 frcount = 0;
1564 1587
1565 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. 1588 if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
1566 { 1589 {
1590//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type +
1591 // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID);
1567 if (m_vehicle.Type != Vehicle.TYPE_NONE) 1592 if (m_vehicle.Type != Vehicle.TYPE_NONE)
1568 { 1593 {
1569 // 'VEHICLES' are dealt with in ODEDynamics.cs 1594 // 'VEHICLES' are dealt with in ODEDynamics.cs
@@ -1571,7 +1596,6 @@ Console.WriteLine(" JointCreateFixed");
1571 } 1596 }
1572 else 1597 else
1573 { 1598 {
1574//Console.WriteLine("Move " + m_primName);
1575 if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 1599 if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
1576 // NON-'VEHICLES' are dealt with here 1600 // NON-'VEHICLES' are dealt with here
1577 if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) 1601 if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
@@ -1593,21 +1617,18 @@ Console.WriteLine(" JointCreateFixed");
1593 //m_log.Info(m_collisionFlags.ToString()); 1617 //m_log.Info(m_collisionFlags.ToString());
1594 1618
1595 1619
1596 //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. 1620 //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle.
1597 // would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ??
1598 // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up 1621 // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up
1599 // gravityz multiplier = 1 - m_buoyancy 1622 // NB Prims in ODE are no subject to global gravity
1600 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; 1623 fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass
1601 1624
1602 if (m_usePID) 1625 if (m_usePID)
1603 { 1626 {
1604//Console.WriteLine("PID " + m_primName); 1627//if(frcount == 0) Console.WriteLine("PID " + m_primName);
1605 // KF - this is for object move? eg. llSetPos() ? 1628 // KF - this is for object MoveToTarget.
1629
1606 //if (!d.BodyIsEnabled(Body)) 1630 //if (!d.BodyIsEnabled(Body))
1607 //d.BodySetForce(Body, 0f, 0f, 0f); 1631 //d.BodySetForce(Body, 0f, 0f, 0f);
1608 // If we're using the PID controller, then we have no gravity
1609 //fz = (-1 * _parent_scene.gravityz) * m_mass; //KF: ?? Prims have no global gravity,so simply...
1610 fz = 0f;
1611 1632
1612 // no lock; for now it's only called from within Simulate() 1633 // no lock; for now it's only called from within Simulate()
1613 1634
@@ -1742,7 +1763,7 @@ Console.WriteLine(" JointCreateFixed");
1742 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); 1763 d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
1743 d.BodySetLinearVel(Body, vel.X, vel.Y, 0); 1764 d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
1744 d.BodyAddForce(Body, 0, 0, fz); 1765 d.BodyAddForce(Body, 0, 0, fz);
1745 return; 1766 //KF this prevents furthur motions return;
1746 } 1767 }
1747 else 1768 else
1748 { 1769 {
@@ -1751,8 +1772,46 @@ Console.WriteLine(" JointCreateFixed");
1751 // We're flying and colliding with something 1772 // We're flying and colliding with something
1752 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); 1773 fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
1753 } 1774 }
1754 } 1775 } // end m_useHoverPID && !m_usePID
1755 1776
1777 if (m_useAPID)
1778 {
1779 // RotLookAt, apparently overrides all other rotation sources. Inputs:
1780 // Quaternion m_APIDTarget
1781 // float m_APIDStrength // From SL experiments, this is the time to get there
1782 // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly
1783 // Also in SL the mass of the object has no effect on time to get there.
1784 // Factors:
1785//if(frcount == 0) Console.WriteLine("APID ");
1786 // get present body rotation
1787 float limit = 1.0f;
1788 float scaler = 50f; // adjusts damping time
1789 float RLAservo = 0f;
1790
1791 d.Quaternion rot = d.BodyGetQuaternion(Body);
1792 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
1793 Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget;
1794 float diff_angle;
1795 Vector3 diff_axis;
1796 rot_diff.GetAxisAngle(out diff_axis, out diff_angle);
1797 diff_axis.Normalize();
1798 if(diff_angle > 0.01f) // diff_angle is always +ve
1799 {
1800// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z);
1801 Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z);
1802 rotforce = rotforce * rotq;
1803 if(diff_angle > limit) diff_angle = limit; // cap the rotate rate
1804// RLAservo = timestep / m_APIDStrength * m_mass * scaler;
1805 // rotforce = rotforce * RLAservo * diff_angle ;
1806 // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z);
1807 RLAservo = timestep / m_APIDStrength * scaler;
1808 rotforce = rotforce * RLAservo * diff_angle ;
1809 d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z);
1810//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo);
1811 }
1812//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle);
1813 } // end m_useAPID
1814
1756 fx *= m_mass; 1815 fx *= m_mass;
1757 fy *= m_mass; 1816 fy *= m_mass;
1758 //fz *= m_mass; 1817 //fz *= m_mass;
@@ -2614,7 +2673,7 @@ Console.WriteLine(" JointCreateFixed");
2614 2673
2615 m_lastposition = _position; 2674 m_lastposition = _position;
2616 m_lastorientation = _orientation; 2675 m_lastorientation = _orientation;
2617 2676
2618 l_position.X = vec.X; 2677 l_position.X = vec.X;
2619 l_position.Y = vec.Y; 2678 l_position.Y = vec.Y;
2620 l_position.Z = vec.Z; 2679 l_position.Z = vec.Z;
@@ -2622,6 +2681,10 @@ Console.WriteLine(" JointCreateFixed");
2622 l_orientation.Y = ori.Y; 2681 l_orientation.Y = ori.Y;
2623 l_orientation.Z = ori.Z; 2682 l_orientation.Z = ori.Z;
2624 l_orientation.W = ori.W; 2683 l_orientation.W = ori.W;
2684
2685// if(l_position.Y != m_lastposition.Y){
2686// Console.WriteLine("UP&V {0} {1}", m_primName, l_position);
2687// }
2625 2688
2626 if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) 2689 if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
2627 { 2690 {
@@ -2822,6 +2885,12 @@ Console.WriteLine(" JointCreateFixed");
2822 } 2885 }
2823 public override bool PIDActive { set { m_usePID = value; } } 2886 public override bool PIDActive { set { m_usePID = value; } }
2824 public override float PIDTau { set { m_PIDTau = value; } } 2887 public override float PIDTau { set { m_PIDTau = value; } }
2888
2889 // For RotLookAt
2890 public override Quaternion APIDTarget { set { m_APIDTarget = value; } }
2891 public override bool APIDActive { set { m_useAPID = value; } }
2892 public override float APIDStrength { set { m_APIDStrength = value; } }
2893 public override float APIDDamping { set { m_APIDDamping = value; } }
2825 2894
2826 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } 2895 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
2827 public override bool PIDHoverActive { set { m_useHoverPID = value; } } 2896 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/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..d4250c1
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,473 @@
1using System;
2using System.Reflection;
3using System.Collections;
4using System.Collections.Generic;
5using System.Runtime.Remoting.Lifetime;
6using OpenMetaverse;
7using Nini.Config;
8using OpenSim;
9using OpenSim.Framework;
10using OpenSim.Region.CoreModules.World.Meta7Windlight;
11using OpenSim.Region.Framework.Interfaces;
12using OpenSim.Region.Framework.Scenes;
13using OpenSim.Region.ScriptEngine.Shared;
14using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
15using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
16using OpenSim.Region.ScriptEngine.Interfaces;
17using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
18
19using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
20using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
21using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
22using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
23using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
24using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
25using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
26
27namespace OpenSim.Region.ScriptEngine.Shared.Api
28{
29 [Serializable]
30 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
31 {
32 internal IScriptEngine m_ScriptEngine;
33 internal SceneObjectPart m_host;
34 internal uint m_localID;
35 internal UUID m_itemID;
36 internal bool m_CMFunctionsEnabled = false;
37 internal IScriptModuleComms m_comms = null;
38
39 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
40 {
41 m_ScriptEngine = ScriptEngine;
42 m_host = host;
43 m_localID = localID;
44 m_itemID = itemID;
45
46 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
47 m_CMFunctionsEnabled = true;
48
49 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
50 if (m_comms == null)
51 m_CMFunctionsEnabled = false;
52 }
53
54 public override Object InitializeLifetimeService()
55 {
56 ILease lease = (ILease)base.InitializeLifetimeService();
57
58 if (lease.CurrentState == LeaseState.Initial)
59 {
60 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
61 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
62 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
63 }
64 return lease;
65 }
66
67 public Scene World
68 {
69 get { return m_ScriptEngine.World; }
70 }
71
72 //
73 //Dumps an error message on the debug console.
74 //
75
76 internal void CMShoutError(string message)
77 {
78 if (message.Length > 1023)
79 message = message.Substring(0, 1023);
80
81 World.SimChat(Utils.StringToBytes(message),
82 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
83
84 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
85 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
86 }
87
88 /// <summary>
89 /// Get the current Windlight scene
90 /// </summary>
91 /// <returns>List of windlight parameters</returns>
92 public LSL_List cmGetWindlightScene(LSL_List rules)
93 {
94 if (!m_CMFunctionsEnabled)
95 {
96 CMShoutError("Careminster functions are not enabled.");
97 return new LSL_List();
98 }
99 m_host.AddScriptLPS(1);
100 RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings;
101
102 LSL_List values = new LSL_List();
103 int idx = 0;
104 while (idx < rules.Length)
105 {
106 uint rule = (uint)rules.GetLSLIntegerItem(idx);
107 LSL_List toadd = new LSL_List();
108
109 switch (rule)
110 {
111 case (int)ScriptBaseClass.WL_AMBIENT:
112 toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W));
113 break;
114 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
115 toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f));
116 break;
117 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
118 toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W));
119 break;
120 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
121 toadd.Add(new LSL_Float(wl.blurMultiplier));
122 break;
123 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
124 toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W));
125 break;
126 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
127 toadd.Add(new LSL_Float(wl.cloudCoverage));
128 break;
129 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
130 toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z));
131 break;
132 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
133 toadd.Add(new LSL_Float(wl.cloudScale));
134 break;
135 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
136 toadd.Add(new LSL_Float(wl.cloudScrollX));
137 break;
138 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
139 toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0));
140 break;
141 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
142 toadd.Add(new LSL_Float(wl.cloudScrollY));
143 break;
144 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
145 toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0));
146 break;
147 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
148 toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z));
149 break;
150 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
151 toadd.Add(new LSL_Float(wl.densityMultiplier));
152 break;
153 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
154 toadd.Add(new LSL_Float(wl.distanceMultiplier));
155 break;
156 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
157 toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0));
158 break;
159 case (int)ScriptBaseClass.WL_EAST_ANGLE:
160 toadd.Add(new LSL_Float(wl.eastAngle));
161 break;
162 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
163 toadd.Add(new LSL_Float(wl.fresnelOffset));
164 break;
165 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
166 toadd.Add(new LSL_Float(wl.fresnelScale));
167 break;
168 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
169 toadd.Add(new LSL_Float(wl.hazeDensity));
170 break;
171 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
172 toadd.Add(new LSL_Float(wl.hazeHorizon));
173 break;
174 case (int)ScriptBaseClass.WL_HORIZON:
175 toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W));
176 break;
177 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
178 toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f));
179 break;
180 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
181 toadd.Add(new LSL_Integer(wl.maxAltitude));
182 break;
183 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
184 toadd.Add(new LSL_Key(wl.normalMapTexture.ToString()));
185 break;
186 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
187 toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z));
188 break;
189 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
190 toadd.Add(new LSL_Float(wl.refractScaleAbove));
191 break;
192 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
193 toadd.Add(new LSL_Float(wl.refractScaleBelow));
194 break;
195 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
196 toadd.Add(new LSL_Float(wl.sceneGamma));
197 break;
198 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
199 toadd.Add(new LSL_Float(wl.starBrightness));
200 break;
201 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
202 toadd.Add(new LSL_Float(wl.sunGlowFocus));
203 break;
204 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
205 toadd.Add(new LSL_Float(wl.sunGlowSize));
206 break;
207 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
208 toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W));
209 break;
210 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
211 toadd.Add(new LSL_Float(wl.underwaterFogModifier));
212 break;
213 case (int)ScriptBaseClass.WL_WATER_COLOR:
214 toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z));
215 break;
216 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
217 toadd.Add(new LSL_Float(wl.waterFogDensityExponent));
218 break;
219 }
220
221 if (toadd.Length > 0)
222 {
223 values.Add(rule);
224 values.Add(toadd.Data[0]);
225 }
226 idx++;
227 }
228
229
230 return values;
231
232 }
233
234 private RegionMeta7WindlightData getWindlightProfileFromRules(LSL_List rules)
235 {
236 RegionMeta7WindlightData wl = (RegionMeta7WindlightData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone();
237
238 LSL_List values = new LSL_List();
239 int idx = 0;
240 while (idx < rules.Length)
241 {
242 uint rule = (uint)rules.GetLSLIntegerItem(idx);
243 LSL_Types.Quaternion iQ;
244 LSL_Types.Vector3 iV;
245 switch (rule)
246 {
247 case (int)ScriptBaseClass.WL_AMBIENT:
248 idx++;
249 iQ = rules.GetQuaternionItem(idx);
250 wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
251 break;
252 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
253 idx++;
254 iV = rules.GetVector3Item(idx);
255 wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y);
256 break;
257 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
258 idx++;
259 iQ = rules.GetQuaternionItem(idx);
260 wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
261 break;
262 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
263 idx++;
264 wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx);
265 break;
266 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
267 idx++;
268 iQ = rules.GetQuaternionItem(idx);
269 wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
270 break;
271 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
272 idx++;
273 wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx);
274 break;
275 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
276 idx++;
277 iV = rules.GetVector3Item(idx);
278 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
279 break;
280 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
281 idx++;
282 wl.cloudScale = (float)rules.GetLSLFloatItem(idx);
283 break;
284 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
285 idx++;
286 wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx);
287 break;
288 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
289 idx++;
290 wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
291 break;
292 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
293 idx++;
294 wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx);
295 break;
296 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
297 idx++;
298 wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
299 break;
300 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
301 idx++;
302 iV = rules.GetVector3Item(idx);
303 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
304 break;
305 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
306 idx++;
307 wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx);
308 break;
309 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
310 idx++;
311 wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx);
312 break;
313 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
314 idx++;
315 wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
316 break;
317 case (int)ScriptBaseClass.WL_EAST_ANGLE:
318 idx++;
319 wl.eastAngle = (float)rules.GetLSLFloatItem(idx);
320 break;
321 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
322 idx++;
323 wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx);
324 break;
325 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
326 idx++;
327 wl.fresnelScale = (float)rules.GetLSLFloatItem(idx);
328 break;
329 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
330 idx++;
331 wl.hazeDensity = (float)rules.GetLSLFloatItem(idx);
332 break;
333 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
334 idx++;
335 wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx);
336 break;
337 case (int)ScriptBaseClass.WL_HORIZON:
338 idx++;
339 iQ = rules.GetQuaternionItem(idx);
340 wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
341 break;
342 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
343 idx++;
344 iV = rules.GetVector3Item(idx);
345 wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y);
346 break;
347 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
348 idx++;
349 wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value;
350 break;
351 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
352 idx++;
353 wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string);
354 break;
355 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
356 idx++;
357 iV = rules.GetVector3Item(idx);
358 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
359 break;
360 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
361 idx++;
362 wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx);
363 break;
364 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
365 idx++;
366 wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx);
367 break;
368 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
369 idx++;
370 wl.sceneGamma = (float)rules.GetLSLFloatItem(idx);
371 break;
372 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
373 idx++;
374 wl.starBrightness = (float)rules.GetLSLFloatItem(idx);
375 break;
376 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
377 idx++;
378 wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx);
379 break;
380 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
381 idx++;
382 wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx);
383 break;
384 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
385 idx++;
386 iQ = rules.GetQuaternionItem(idx);
387 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
388 break;
389 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
390 idx++;
391 wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx);
392 break;
393 case (int)ScriptBaseClass.WL_WATER_COLOR:
394 idx++;
395 iV = rules.GetVector3Item(idx);
396 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
397 break;
398 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
399 idx++;
400 wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx);
401 break;
402 }
403 idx++;
404 }
405 return wl;
406 }
407 /// <summary>
408 /// Set the current Windlight scene
409 /// </summary>
410 /// <param name="rules"></param>
411 /// <returns>success: true or false</returns>
412 public int cmSetWindlightScene(LSL_List rules)
413 {
414 if (!m_CMFunctionsEnabled)
415 {
416 CMShoutError("Careminster functions are not enabled.");
417 return 0;
418 }
419 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
420 {
421 CMShoutError("cmSetWindlightScene can only be used by estate managers or owners.");
422 return 0;
423 }
424 int success = 0;
425 m_host.AddScriptLPS(1);
426 if (Meta7WindlightModule.EnableWindlight)
427 {
428 RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules);
429 m_host.ParentGroup.Scene.StoreWindlightProfile(wl);
430 success = 1;
431 }
432 else
433 {
434 CMShoutError("Windlight module is disabled");
435 return 0;
436 }
437 return success;
438 }
439 /// <summary>
440 /// Set the current Windlight scene to a target avatar
441 /// </summary>
442 /// <param name="rules"></param>
443 /// <returns>success: true or false</returns>
444 public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target)
445 {
446 if (!m_CMFunctionsEnabled)
447 {
448 CMShoutError("Careminster functions are not enabled.");
449 return 0;
450 }
451 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
452 {
453 CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners.");
454 return 0;
455 }
456 int success = 0;
457 m_host.AddScriptLPS(1);
458 if (Meta7WindlightModule.EnableWindlight)
459 {
460 RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules);
461 World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string));
462 success = 1;
463 }
464 else
465 {
466 CMShoutError("Windlight module is disabled");
467 return 0;
468 }
469 return success;
470 }
471
472 }
473}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 7f71d09..2da498a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -151,6 +152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
151 get { return m_ScriptEngine.World; } 152 get { return m_ScriptEngine.World; }
152 } 153 }
153 154
155 [DebuggerNonUserCode]
154 public void state(string newState) 156 public void state(string newState)
155 { 157 {
156 m_ScriptEngine.SetState(m_itemID, newState); 158 m_ScriptEngine.SetState(m_itemID, newState);
@@ -160,6 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
160 /// Reset the named script. The script must be present 162 /// Reset the named script. The script must be present
161 /// in the same prim. 163 /// in the same prim.
162 /// </summary> 164 /// </summary>
165 [DebuggerNonUserCode]
163 public void llResetScript() 166 public void llResetScript()
164 { 167 {
165 m_host.AddScriptLPS(1); 168 m_host.AddScriptLPS(1);
@@ -272,40 +275,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
272 protected UUID InventorySelf() 275 protected UUID InventorySelf()
273 { 276 {
274 UUID invItemID = new UUID(); 277 UUID invItemID = new UUID();
275 278 bool unlock = false;
276 lock (m_host.TaskInventory) 279 if (!m_host.TaskInventory.IsReadLockedByMe())
280 {
281 m_host.TaskInventory.LockItemsForRead(true);
282 unlock = true;
283 }
284 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
277 { 285 {
278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 286 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
279 { 287 {
280 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 288 invItemID = inv.Key;
281 { 289 break;
282 invItemID = inv.Key;
283 break;
284 }
285 } 290 }
286 } 291 }
287 292 if (unlock)
293 {
294 m_host.TaskInventory.LockItemsForRead(false);
295 }
288 return invItemID; 296 return invItemID;
289 } 297 }
290 298
291 protected UUID InventoryKey(string name, int type) 299 protected UUID InventoryKey(string name, int type)
292 { 300 {
293 m_host.AddScriptLPS(1); 301 m_host.AddScriptLPS(1);
294 302 m_host.TaskInventory.LockItemsForRead(true);
295 lock (m_host.TaskInventory) 303
304 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
296 { 305 {
297 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 306 if (inv.Value.Name == name)
298 { 307 {
299 if (inv.Value.Name == name) 308 m_host.TaskInventory.LockItemsForRead(false);
309
310 if (inv.Value.Type != type)
300 { 311 {
301 if (inv.Value.Type != type) 312 return UUID.Zero;
302 return UUID.Zero;
303
304 return inv.Value.AssetID;
305 } 313 }
314
315 return inv.Value.AssetID;
306 } 316 }
307 } 317 }
308 318
319 m_host.TaskInventory.LockItemsForRead(false);
309 return UUID.Zero; 320 return UUID.Zero;
310 } 321 }
311 322
@@ -313,17 +324,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
313 { 324 {
314 m_host.AddScriptLPS(1); 325 m_host.AddScriptLPS(1);
315 326
316 lock (m_host.TaskInventory) 327
328 m_host.TaskInventory.LockItemsForRead(true);
329
330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
317 { 331 {
318 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 332 if (inv.Value.Name == name)
319 { 333 {
320 if (inv.Value.Name == name) 334 m_host.TaskInventory.LockItemsForRead(false);
321 { 335 return inv.Value.AssetID;
322 return inv.Value.AssetID;
323 }
324 } 336 }
325 } 337 }
326 338
339 m_host.TaskInventory.LockItemsForRead(false);
340
341
327 return UUID.Zero; 342 return UUID.Zero;
328 } 343 }
329 344
@@ -2555,12 +2570,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2555 2570
2556 m_host.AddScriptLPS(1); 2571 m_host.AddScriptLPS(1);
2557 2572
2573 m_host.TaskInventory.LockItemsForRead(true);
2558 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2574 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2559 2575 m_host.TaskInventory.LockItemsForRead(false);
2560 lock (m_host.TaskInventory)
2561 {
2562 item = m_host.TaskInventory[invItemID];
2563 }
2564 2576
2565 if (item.PermsGranter == UUID.Zero) 2577 if (item.PermsGranter == UUID.Zero)
2566 return 0; 2578 return 0;
@@ -2635,6 +2647,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2635 if (dist > m_ScriptDistanceFactor * 10.0f) 2647 if (dist > m_ScriptDistanceFactor * 10.0f)
2636 return; 2648 return;
2637 2649
2650 //Clone is thread-safe
2638 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2651 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2639 2652
2640 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2653 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2720,11 +2733,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2720 // Orient the object to the angle calculated 2733 // Orient the object to the angle calculated
2721 llSetRot(rot); 2734 llSetRot(rot);
2722 } 2735 }
2736
2737 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
2738 {
2739 m_host.AddScriptLPS(1);
2740// NotImplemented("llRotLookAt");
2741 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
2742
2743 }
2744
2723 2745
2724 public void llStopLookAt() 2746 public void llStopLookAt()
2725 { 2747 {
2726 m_host.AddScriptLPS(1); 2748 m_host.AddScriptLPS(1);
2727 NotImplemented("llStopLookAt"); 2749// NotImplemented("llStopLookAt");
2750 m_host.StopLookAt();
2728 } 2751 }
2729 2752
2730 public void llSetTimerEvent(double sec) 2753 public void llSetTimerEvent(double sec)
@@ -2758,13 +2781,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2758 { 2781 {
2759 TaskInventoryItem item; 2782 TaskInventoryItem item;
2760 2783
2761 lock (m_host.TaskInventory) 2784 m_host.TaskInventory.LockItemsForRead(true);
2785 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2762 { 2786 {
2763 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2787 m_host.TaskInventory.LockItemsForRead(false);
2764 return; 2788 return;
2765 else 2789 }
2766 item = m_host.TaskInventory[InventorySelf()]; 2790 else
2791 {
2792 item = m_host.TaskInventory[InventorySelf()];
2767 } 2793 }
2794 m_host.TaskInventory.LockItemsForRead(false);
2768 2795
2769 if (item.PermsGranter != UUID.Zero) 2796 if (item.PermsGranter != UUID.Zero)
2770 { 2797 {
@@ -2786,13 +2813,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2786 { 2813 {
2787 TaskInventoryItem item; 2814 TaskInventoryItem item;
2788 2815
2816 m_host.TaskInventory.LockItemsForRead(true);
2789 lock (m_host.TaskInventory) 2817 lock (m_host.TaskInventory)
2790 { 2818 {
2819
2791 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2820 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2821 {
2822 m_host.TaskInventory.LockItemsForRead(false);
2792 return; 2823 return;
2824 }
2793 else 2825 else
2826 {
2794 item = m_host.TaskInventory[InventorySelf()]; 2827 item = m_host.TaskInventory[InventorySelf()];
2828 }
2795 } 2829 }
2830 m_host.TaskInventory.LockItemsForRead(false);
2796 2831
2797 m_host.AddScriptLPS(1); 2832 m_host.AddScriptLPS(1);
2798 2833
@@ -2829,14 +2864,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2829 2864
2830 TaskInventoryItem item; 2865 TaskInventoryItem item;
2831 2866
2832 lock (m_host.TaskInventory) 2867 m_host.TaskInventory.LockItemsForRead(true);
2868
2869 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2833 { 2870 {
2834 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2871 m_host.TaskInventory.LockItemsForRead(false);
2835 return; 2872 return;
2836 else 2873 }
2837 item = m_host.TaskInventory[InventorySelf()]; 2874 else
2875 {
2876 item = m_host.TaskInventory[InventorySelf()];
2838 } 2877 }
2839 2878
2879 m_host.TaskInventory.LockItemsForRead(false);
2880
2840 if (item.PermsGranter != m_host.OwnerID) 2881 if (item.PermsGranter != m_host.OwnerID)
2841 return; 2882 return;
2842 2883
@@ -2861,13 +2902,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2861 2902
2862 TaskInventoryItem item; 2903 TaskInventoryItem item;
2863 2904
2864 lock (m_host.TaskInventory) 2905 m_host.TaskInventory.LockItemsForRead(true);
2906
2907 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2865 { 2908 {
2866 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 2909 m_host.TaskInventory.LockItemsForRead(false);
2867 return; 2910 return;
2868 else
2869 item = m_host.TaskInventory[InventorySelf()];
2870 } 2911 }
2912 else
2913 {
2914 item = m_host.TaskInventory[InventorySelf()];
2915 }
2916 m_host.TaskInventory.LockItemsForRead(false);
2917
2871 2918
2872 if (item.PermsGranter != m_host.OwnerID) 2919 if (item.PermsGranter != m_host.OwnerID)
2873 return; 2920 return;
@@ -2903,8 +2950,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2903 return m_host.OwnerID.ToString(); 2950 return m_host.OwnerID.ToString();
2904 } 2951 }
2905 2952
2953 [DebuggerNonUserCode]
2906 public void llInstantMessage(string user, string message) 2954 public void llInstantMessage(string user, string message)
2907 { 2955 {
2956 UUID result;
2957 if (!UUID.TryParse(user, out result))
2958 {
2959 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
2960 return;
2961 }
2962
2963
2908 m_host.AddScriptLPS(1); 2964 m_host.AddScriptLPS(1);
2909 2965
2910 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 2966 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -2919,7 +2975,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2919 UUID friendTransactionID = UUID.Random(); 2975 UUID friendTransactionID = UUID.Random();
2920 2976
2921 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 2977 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
2922 2978
2923 GridInstantMessage msg = new GridInstantMessage(); 2979 GridInstantMessage msg = new GridInstantMessage();
2924 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 2980 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
2925 msg.toAgentID = new Guid(user); // toAgentID.Guid; 2981 msg.toAgentID = new Guid(user); // toAgentID.Guid;
@@ -3068,12 +3124,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3068 m_host.AddScriptLPS(1); 3124 m_host.AddScriptLPS(1);
3069 } 3125 }
3070 3126
3071 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3072 {
3073 m_host.AddScriptLPS(1);
3074 NotImplemented("llRotLookAt");
3075 }
3076
3077 public LSL_Integer llStringLength(string str) 3127 public LSL_Integer llStringLength(string str)
3078 { 3128 {
3079 m_host.AddScriptLPS(1); 3129 m_host.AddScriptLPS(1);
@@ -3097,14 +3147,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 3147
3098 TaskInventoryItem item; 3148 TaskInventoryItem item;
3099 3149
3100 lock (m_host.TaskInventory) 3150 m_host.TaskInventory.LockItemsForRead(true);
3151 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3101 { 3152 {
3102 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3153 m_host.TaskInventory.LockItemsForRead(false);
3103 return; 3154 return;
3104 else
3105 item = m_host.TaskInventory[InventorySelf()];
3106 } 3155 }
3107 3156 else
3157 {
3158 item = m_host.TaskInventory[InventorySelf()];
3159 }
3160 m_host.TaskInventory.LockItemsForRead(false);
3108 if (item.PermsGranter == UUID.Zero) 3161 if (item.PermsGranter == UUID.Zero)
3109 return; 3162 return;
3110 3163
@@ -3134,13 +3187,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3134 3187
3135 TaskInventoryItem item; 3188 TaskInventoryItem item;
3136 3189
3137 lock (m_host.TaskInventory) 3190 m_host.TaskInventory.LockItemsForRead(true);
3191 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3138 { 3192 {
3139 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3193 m_host.TaskInventory.LockItemsForRead(false);
3140 return; 3194 return;
3141 else
3142 item = m_host.TaskInventory[InventorySelf()];
3143 } 3195 }
3196 else
3197 {
3198 item = m_host.TaskInventory[InventorySelf()];
3199 }
3200 m_host.TaskInventory.LockItemsForRead(false);
3201
3144 3202
3145 if (item.PermsGranter == UUID.Zero) 3203 if (item.PermsGranter == UUID.Zero)
3146 return; 3204 return;
@@ -3213,10 +3271,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3213 3271
3214 TaskInventoryItem item; 3272 TaskInventoryItem item;
3215 3273
3216 lock (m_host.TaskInventory) 3274
3275 m_host.TaskInventory.LockItemsForRead(true);
3276 if (!m_host.TaskInventory.ContainsKey(invItemID))
3277 {
3278 m_host.TaskInventory.LockItemsForRead(false);
3279 return;
3280 }
3281 else
3217 { 3282 {
3218 item = m_host.TaskInventory[invItemID]; 3283 item = m_host.TaskInventory[invItemID];
3219 } 3284 }
3285 m_host.TaskInventory.LockItemsForRead(false);
3220 3286
3221 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3287 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3222 { 3288 {
@@ -3248,11 +3314,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3248 3314
3249 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3315 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3250 { 3316 {
3251 lock (m_host.TaskInventory) 3317 m_host.TaskInventory.LockItemsForWrite(true);
3252 { 3318 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3253 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3319 m_host.TaskInventory[invItemID].PermsMask = perm;
3254 m_host.TaskInventory[invItemID].PermsMask = perm; 3320 m_host.TaskInventory.LockItemsForWrite(false);
3255 }
3256 3321
3257 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3322 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3258 "run_time_permissions", new Object[] { 3323 "run_time_permissions", new Object[] {
@@ -3272,11 +3337,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3272 3337
3273 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3338 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3274 { 3339 {
3275 lock (m_host.TaskInventory) 3340 m_host.TaskInventory.LockItemsForWrite(true);
3276 { 3341 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3277 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3342 m_host.TaskInventory[invItemID].PermsMask = perm;
3278 m_host.TaskInventory[invItemID].PermsMask = perm; 3343 m_host.TaskInventory.LockItemsForWrite(false);
3279 }
3280 3344
3281 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3345 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3282 "run_time_permissions", new Object[] { 3346 "run_time_permissions", new Object[] {
@@ -3297,11 +3361,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3297 3361
3298 if (!m_waitingForScriptAnswer) 3362 if (!m_waitingForScriptAnswer)
3299 { 3363 {
3300 lock (m_host.TaskInventory) 3364 m_host.TaskInventory.LockItemsForWrite(true);
3301 { 3365 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3302 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3366 m_host.TaskInventory[invItemID].PermsMask = 0;
3303 m_host.TaskInventory[invItemID].PermsMask = 0; 3367 m_host.TaskInventory.LockItemsForWrite(false);
3304 }
3305 3368
3306 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3369 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3307 m_waitingForScriptAnswer=true; 3370 m_waitingForScriptAnswer=true;
@@ -3336,10 +3399,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3336 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3399 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3337 llReleaseControls(); 3400 llReleaseControls();
3338 3401
3339 lock (m_host.TaskInventory) 3402
3340 { 3403 m_host.TaskInventory.LockItemsForWrite(true);
3341 m_host.TaskInventory[invItemID].PermsMask = answer; 3404 m_host.TaskInventory[invItemID].PermsMask = answer;
3342 } 3405 m_host.TaskInventory.LockItemsForWrite(false);
3406
3343 3407
3344 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3408 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3345 "run_time_permissions", new Object[] { 3409 "run_time_permissions", new Object[] {
@@ -3351,16 +3415,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3351 { 3415 {
3352 m_host.AddScriptLPS(1); 3416 m_host.AddScriptLPS(1);
3353 3417
3354 lock (m_host.TaskInventory) 3418 m_host.TaskInventory.LockItemsForRead(true);
3419
3420 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3355 { 3421 {
3356 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3422 if (item.Type == 10 && item.ItemID == m_itemID)
3357 { 3423 {
3358 if (item.Type == 10 && item.ItemID == m_itemID) 3424 m_host.TaskInventory.LockItemsForRead(false);
3359 { 3425 return item.PermsGranter.ToString();
3360 return item.PermsGranter.ToString();
3361 }
3362 } 3426 }
3363 } 3427 }
3428 m_host.TaskInventory.LockItemsForRead(false);
3364 3429
3365 return UUID.Zero.ToString(); 3430 return UUID.Zero.ToString();
3366 } 3431 }
@@ -3369,19 +3434,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3369 { 3434 {
3370 m_host.AddScriptLPS(1); 3435 m_host.AddScriptLPS(1);
3371 3436
3372 lock (m_host.TaskInventory) 3437 m_host.TaskInventory.LockItemsForRead(true);
3438
3439 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3373 { 3440 {
3374 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3441 if (item.Type == 10 && item.ItemID == m_itemID)
3375 { 3442 {
3376 if (item.Type == 10 && item.ItemID == m_itemID) 3443 int perms = item.PermsMask;
3377 { 3444 if (m_automaticLinkPermission)
3378 int perms = item.PermsMask; 3445 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3379 if (m_automaticLinkPermission) 3446 m_host.TaskInventory.LockItemsForRead(false);
3380 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3447 return perms;
3381 return perms;
3382 }
3383 } 3448 }
3384 } 3449 }
3450 m_host.TaskInventory.LockItemsForRead(false);
3385 3451
3386 return 0; 3452 return 0;
3387 } 3453 }
@@ -3414,11 +3480,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3414 UUID invItemID = InventorySelf(); 3480 UUID invItemID = InventorySelf();
3415 3481
3416 TaskInventoryItem item; 3482 TaskInventoryItem item;
3417 lock (m_host.TaskInventory) 3483 m_host.TaskInventory.LockItemsForRead(true);
3418 { 3484 item = m_host.TaskInventory[invItemID];
3419 item = m_host.TaskInventory[invItemID]; 3485 m_host.TaskInventory.LockItemsForRead(false);
3420 } 3486
3421
3422 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3487 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3423 && !m_automaticLinkPermission) 3488 && !m_automaticLinkPermission)
3424 { 3489 {
@@ -3471,16 +3536,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3471 m_host.AddScriptLPS(1); 3536 m_host.AddScriptLPS(1);
3472 UUID invItemID = InventorySelf(); 3537 UUID invItemID = InventorySelf();
3473 3538
3474 lock (m_host.TaskInventory) 3539 m_host.TaskInventory.LockItemsForRead(true);
3475 {
3476 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3540 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3477 && !m_automaticLinkPermission) 3541 && !m_automaticLinkPermission)
3478 { 3542 {
3479 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3543 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3544 m_host.TaskInventory.LockItemsForRead(false);
3480 return; 3545 return;
3481 } 3546 }
3482 } 3547 m_host.TaskInventory.LockItemsForRead(false);
3483 3548
3484 if (linknum < ScriptBaseClass.LINK_THIS) 3549 if (linknum < ScriptBaseClass.LINK_THIS)
3485 return; 3550 return;
3486 3551
@@ -3657,17 +3722,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3657 m_host.AddScriptLPS(1); 3722 m_host.AddScriptLPS(1);
3658 int count = 0; 3723 int count = 0;
3659 3724
3660 lock (m_host.TaskInventory) 3725 m_host.TaskInventory.LockItemsForRead(true);
3726 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3661 { 3727 {
3662 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3728 if (inv.Value.Type == type || type == -1)
3663 { 3729 {
3664 if (inv.Value.Type == type || type == -1) 3730 count = count + 1;
3665 {
3666 count = count + 1;
3667 }
3668 } 3731 }
3669 } 3732 }
3670 3733
3734 m_host.TaskInventory.LockItemsForRead(false);
3671 return count; 3735 return count;
3672 } 3736 }
3673 3737
@@ -3676,16 +3740,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3676 m_host.AddScriptLPS(1); 3740 m_host.AddScriptLPS(1);
3677 ArrayList keys = new ArrayList(); 3741 ArrayList keys = new ArrayList();
3678 3742
3679 lock (m_host.TaskInventory) 3743 m_host.TaskInventory.LockItemsForRead(true);
3744 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3680 { 3745 {
3681 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3746 if (inv.Value.Type == type || type == -1)
3682 { 3747 {
3683 if (inv.Value.Type == type || type == -1) 3748 keys.Add(inv.Value.Name);
3684 {
3685 keys.Add(inv.Value.Name);
3686 }
3687 } 3749 }
3688 } 3750 }
3751 m_host.TaskInventory.LockItemsForRead(false);
3689 3752
3690 if (keys.Count == 0) 3753 if (keys.Count == 0)
3691 { 3754 {
@@ -3722,20 +3785,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3722 } 3785 }
3723 3786
3724 // move the first object found with this inventory name 3787 // move the first object found with this inventory name
3725 lock (m_host.TaskInventory) 3788 m_host.TaskInventory.LockItemsForRead(true);
3789 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3726 { 3790 {
3727 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3791 if (inv.Value.Name == inventory)
3728 { 3792 {
3729 if (inv.Value.Name == inventory) 3793 found = true;
3730 { 3794 objId = inv.Key;
3731 found = true; 3795 assetType = inv.Value.Type;
3732 objId = inv.Key; 3796 objName = inv.Value.Name;
3733 assetType = inv.Value.Type; 3797 break;
3734 objName = inv.Value.Name;
3735 break;
3736 }
3737 } 3798 }
3738 } 3799 }
3800 m_host.TaskInventory.LockItemsForRead(false);
3739 3801
3740 if (!found) 3802 if (!found)
3741 { 3803 {
@@ -3780,24 +3842,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3780 ScriptSleep(3000); 3842 ScriptSleep(3000);
3781 } 3843 }
3782 3844
3845 [DebuggerNonUserCode]
3783 public void llRemoveInventory(string name) 3846 public void llRemoveInventory(string name)
3784 { 3847 {
3785 m_host.AddScriptLPS(1); 3848 m_host.AddScriptLPS(1);
3786 3849
3787 lock (m_host.TaskInventory) 3850 m_host.TaskInventory.LockItemsForRead(true);
3851 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3788 { 3852 {
3789 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3853 if (item.Name == name)
3790 { 3854 {
3791 if (item.Name == name) 3855 if (item.ItemID == m_itemID)
3792 { 3856 throw new ScriptDeleteException();
3793 if (item.ItemID == m_itemID) 3857 else
3794 throw new ScriptDeleteException(); 3858 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3795 else 3859
3796 m_host.Inventory.RemoveInventoryItem(item.ItemID); 3860 m_host.TaskInventory.LockItemsForRead(false);
3797 return; 3861 return;
3798 }
3799 } 3862 }
3800 } 3863 }
3864 m_host.TaskInventory.LockItemsForRead(false);
3801 } 3865 }
3802 3866
3803 public void llSetText(string text, LSL_Vector color, double alpha) 3867 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -3886,6 +3950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3886 { 3950 {
3887 m_host.AddScriptLPS(1); 3951 m_host.AddScriptLPS(1);
3888 3952
3953 //Clone is thread safe
3889 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 3954 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
3890 3955
3891 foreach (TaskInventoryItem item in itemDictionary.Values) 3956 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -3976,17 +4041,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3976 UUID soundId = UUID.Zero; 4041 UUID soundId = UUID.Zero;
3977 if (!UUID.TryParse(impact_sound, out soundId)) 4042 if (!UUID.TryParse(impact_sound, out soundId))
3978 { 4043 {
3979 lock (m_host.TaskInventory) 4044 m_host.TaskInventory.LockItemsForRead(true);
4045 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3980 { 4046 {
3981 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4047 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
3982 { 4048 {
3983 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4049 soundId = item.AssetID;
3984 { 4050 break;
3985 soundId = item.AssetID;
3986 break;
3987 }
3988 } 4051 }
3989 } 4052 }
4053 m_host.TaskInventory.LockItemsForRead(false);
3990 } 4054 }
3991 m_host.CollisionSound = soundId; 4055 m_host.CollisionSound = soundId;
3992 m_host.CollisionSoundVolume = (float)impact_volume; 4056 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4032,6 +4096,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4032 UUID partItemID; 4096 UUID partItemID;
4033 foreach (SceneObjectPart part in parts) 4097 foreach (SceneObjectPart part in parts)
4034 { 4098 {
4099 //Clone is thread safe
4035 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4100 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4036 4101
4037 foreach (TaskInventoryItem item in itemsDictionary.Values) 4102 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4239,17 +4304,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4239 4304
4240 m_host.AddScriptLPS(1); 4305 m_host.AddScriptLPS(1);
4241 4306
4242 lock (m_host.TaskInventory) 4307 m_host.TaskInventory.LockItemsForRead(true);
4308 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4243 { 4309 {
4244 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4310 if (item.Type == 10 && item.ItemID == m_itemID)
4245 { 4311 {
4246 if (item.Type == 10 && item.ItemID == m_itemID) 4312 result = item.Name!=null?item.Name:String.Empty;
4247 { 4313 break;
4248 result = item.Name!=null?item.Name:String.Empty;
4249 break;
4250 }
4251 } 4314 }
4252 } 4315 }
4316 m_host.TaskInventory.LockItemsForRead(false);
4253 4317
4254 return result; 4318 return result;
4255 } 4319 }
@@ -4507,23 +4571,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4507 { 4571 {
4508 m_host.AddScriptLPS(1); 4572 m_host.AddScriptLPS(1);
4509 4573
4510 lock (m_host.TaskInventory) 4574 m_host.TaskInventory.LockItemsForRead(true);
4575 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4511 { 4576 {
4512 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4577 if (inv.Value.Name == name)
4513 { 4578 {
4514 if (inv.Value.Name == name) 4579 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4515 { 4580 {
4516 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4581 m_host.TaskInventory.LockItemsForRead(false);
4517 { 4582 return inv.Value.AssetID.ToString();
4518 return inv.Value.AssetID.ToString(); 4583 }
4519 } 4584 else
4520 else 4585 {
4521 { 4586 m_host.TaskInventory.LockItemsForRead(false);
4522 return UUID.Zero.ToString(); 4587 return UUID.Zero.ToString();
4523 }
4524 } 4588 }
4525 } 4589 }
4526 } 4590 }
4591 m_host.TaskInventory.LockItemsForRead(false);
4527 4592
4528 return UUID.Zero.ToString(); 4593 return UUID.Zero.ToString();
4529 } 4594 }
@@ -6019,14 +6084,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6019 6084
6020 protected UUID GetTaskInventoryItem(string name) 6085 protected UUID GetTaskInventoryItem(string name)
6021 { 6086 {
6022 lock (m_host.TaskInventory) 6087 m_host.TaskInventory.LockItemsForRead(true);
6088 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6023 { 6089 {
6024 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6090 if (inv.Value.Name == name)
6025 { 6091 {
6026 if (inv.Value.Name == name) 6092 m_host.TaskInventory.LockItemsForRead(false);
6027 return inv.Key; 6093 return inv.Key;
6028 } 6094 }
6029 } 6095 }
6096 m_host.TaskInventory.LockItemsForRead(false);
6030 6097
6031 return UUID.Zero; 6098 return UUID.Zero;
6032 } 6099 }
@@ -6337,22 +6404,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6337 } 6404 }
6338 6405
6339 // copy the first script found with this inventory name 6406 // copy the first script found with this inventory name
6340 lock (m_host.TaskInventory) 6407 m_host.TaskInventory.LockItemsForRead(true);
6408 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6341 { 6409 {
6342 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6410 if (inv.Value.Name == name)
6343 { 6411 {
6344 if (inv.Value.Name == name) 6412 // make sure the object is a script
6413 if (10 == inv.Value.Type)
6345 { 6414 {
6346 // make sure the object is a script 6415 found = true;
6347 if (10 == inv.Value.Type) 6416 srcId = inv.Key;
6348 { 6417 break;
6349 found = true;
6350 srcId = inv.Key;
6351 break;
6352 }
6353 } 6418 }
6354 } 6419 }
6355 } 6420 }
6421 m_host.TaskInventory.LockItemsForRead(false);
6356 6422
6357 if (!found) 6423 if (!found)
6358 { 6424 {
@@ -8155,28 +8221,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8155 { 8221 {
8156 m_host.AddScriptLPS(1); 8222 m_host.AddScriptLPS(1);
8157 8223
8158 lock (m_host.TaskInventory) 8224 m_host.TaskInventory.LockItemsForRead(true);
8225 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8159 { 8226 {
8160 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8227 if (inv.Value.Name == item)
8161 { 8228 {
8162 if (inv.Value.Name == item) 8229 m_host.TaskInventory.LockItemsForRead(false);
8230 switch (mask)
8163 { 8231 {
8164 switch (mask) 8232 case 0:
8165 { 8233 return (int)inv.Value.BasePermissions;
8166 case 0: 8234 case 1:
8167 return (int)inv.Value.BasePermissions; 8235 return (int)inv.Value.CurrentPermissions;
8168 case 1: 8236 case 2:
8169 return (int)inv.Value.CurrentPermissions; 8237 return (int)inv.Value.GroupPermissions;
8170 case 2: 8238 case 3:
8171 return (int)inv.Value.GroupPermissions; 8239 return (int)inv.Value.EveryonePermissions;
8172 case 3: 8240 case 4:
8173 return (int)inv.Value.EveryonePermissions; 8241 return (int)inv.Value.NextPermissions;
8174 case 4:
8175 return (int)inv.Value.NextPermissions;
8176 }
8177 } 8242 }
8178 } 8243 }
8179 } 8244 }
8245 m_host.TaskInventory.LockItemsForRead(false);
8180 8246
8181 return -1; 8247 return -1;
8182 } 8248 }
@@ -8191,16 +8257,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8191 { 8257 {
8192 m_host.AddScriptLPS(1); 8258 m_host.AddScriptLPS(1);
8193 8259
8194 lock (m_host.TaskInventory) 8260 m_host.TaskInventory.LockItemsForRead(true);
8261 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8195 { 8262 {
8196 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8263 if (inv.Value.Name == item)
8197 { 8264 {
8198 if (inv.Value.Name == item) 8265 m_host.TaskInventory.LockItemsForRead(false);
8199 { 8266 return inv.Value.CreatorID.ToString();
8200 return inv.Value.CreatorID.ToString();
8201 }
8202 } 8267 }
8203 } 8268 }
8269 m_host.TaskInventory.LockItemsForRead(false);
8204 8270
8205 llSay(0, "No item name '" + item + "'"); 8271 llSay(0, "No item name '" + item + "'");
8206 8272
@@ -8724,16 +8790,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8724 { 8790 {
8725 m_host.AddScriptLPS(1); 8791 m_host.AddScriptLPS(1);
8726 8792
8727 lock (m_host.TaskInventory) 8793 m_host.TaskInventory.LockItemsForRead(true);
8794 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8728 { 8795 {
8729 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 8796 if (inv.Value.Name == name)
8730 { 8797 {
8731 if (inv.Value.Name == name) 8798 m_host.TaskInventory.LockItemsForRead(false);
8732 { 8799 return inv.Value.Type;
8733 return inv.Value.Type;
8734 }
8735 } 8800 }
8736 } 8801 }
8802 m_host.TaskInventory.LockItemsForRead(false);
8737 8803
8738 return -1; 8804 return -1;
8739 } 8805 }
@@ -8764,17 +8830,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8764 if (invItemID == UUID.Zero) 8830 if (invItemID == UUID.Zero)
8765 return new LSL_Vector(); 8831 return new LSL_Vector();
8766 8832
8767 lock (m_host.TaskInventory) 8833 m_host.TaskInventory.LockItemsForRead(true);
8834 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8768 { 8835 {
8769 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 8836 m_host.TaskInventory.LockItemsForRead(false);
8770 return new LSL_Vector(); 8837 return new LSL_Vector();
8838 }
8771 8839
8772 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 8840 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8773 { 8841 {
8774 ShoutError("No permissions to track the camera"); 8842 ShoutError("No permissions to track the camera");
8775 return new LSL_Vector(); 8843 m_host.TaskInventory.LockItemsForRead(false);
8776 } 8844 return new LSL_Vector();
8777 } 8845 }
8846 m_host.TaskInventory.LockItemsForRead(false);
8778 8847
8779 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 8848 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8780 if (presence != null) 8849 if (presence != null)
@@ -8792,17 +8861,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8792 if (invItemID == UUID.Zero) 8861 if (invItemID == UUID.Zero)
8793 return new LSL_Rotation(); 8862 return new LSL_Rotation();
8794 8863
8795 lock (m_host.TaskInventory) 8864 m_host.TaskInventory.LockItemsForRead(true);
8865 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
8796 { 8866 {
8797 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 8867 m_host.TaskInventory.LockItemsForRead(false);
8798 return new LSL_Rotation(); 8868 return new LSL_Rotation();
8799
8800 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8801 {
8802 ShoutError("No permissions to track the camera");
8803 return new LSL_Rotation();
8804 }
8805 } 8869 }
8870 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
8871 {
8872 ShoutError("No permissions to track the camera");
8873 m_host.TaskInventory.LockItemsForRead(false);
8874 return new LSL_Rotation();
8875 }
8876 m_host.TaskInventory.LockItemsForRead(false);
8806 8877
8807 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 8878 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
8808 if (presence != null) 8879 if (presence != null)
@@ -8952,14 +9023,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8952 if (objectID == UUID.Zero) return; 9023 if (objectID == UUID.Zero) return;
8953 9024
8954 UUID agentID; 9025 UUID agentID;
8955 lock (m_host.TaskInventory) 9026 m_host.TaskInventory.LockItemsForRead(true);
8956 { 9027 // we need the permission first, to know which avatar we want to set the camera for
8957 // we need the permission first, to know which avatar we want to set the camera for 9028 agentID = m_host.TaskInventory[invItemID].PermsGranter;
8958 agentID = m_host.TaskInventory[invItemID].PermsGranter;
8959 9029
8960 if (agentID == UUID.Zero) return; 9030 if (agentID == UUID.Zero)
8961 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9031 {
9032 m_host.TaskInventory.LockItemsForRead(false);
9033 return;
8962 } 9034 }
9035 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9036 {
9037 m_host.TaskInventory.LockItemsForRead(false);
9038 return;
9039 }
9040 m_host.TaskInventory.LockItemsForRead(false);
8963 9041
8964 ScenePresence presence = World.GetScenePresence(agentID); 9042 ScenePresence presence = World.GetScenePresence(agentID);
8965 9043
@@ -9009,12 +9087,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9009 9087
9010 // we need the permission first, to know which avatar we want to clear the camera for 9088 // we need the permission first, to know which avatar we want to clear the camera for
9011 UUID agentID; 9089 UUID agentID;
9012 lock (m_host.TaskInventory) 9090 m_host.TaskInventory.LockItemsForRead(true);
9091 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9092 if (agentID == UUID.Zero)
9093 {
9094 m_host.TaskInventory.LockItemsForRead(false);
9095 return;
9096 }
9097 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9013 { 9098 {
9014 agentID = m_host.TaskInventory[invItemID].PermsGranter; 9099 m_host.TaskInventory.LockItemsForRead(false);
9015 if (agentID == UUID.Zero) return; 9100 return;
9016 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9017 } 9101 }
9102 m_host.TaskInventory.LockItemsForRead(false);
9018 9103
9019 ScenePresence presence = World.GetScenePresence(agentID); 9104 ScenePresence presence = World.GetScenePresence(agentID);
9020 9105
@@ -9471,15 +9556,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9471 9556
9472 internal UUID ScriptByName(string name) 9557 internal UUID ScriptByName(string name)
9473 { 9558 {
9474 lock (m_host.TaskInventory) 9559 m_host.TaskInventory.LockItemsForRead(true);
9560
9561 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9475 { 9562 {
9476 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 9563 if (item.Type == 10 && item.Name == name)
9477 { 9564 {
9478 if (item.Type == 10 && item.Name == name) 9565 m_host.TaskInventory.LockItemsForRead(false);
9479 return item.ItemID; 9566 return item.ItemID;
9480 } 9567 }
9481 } 9568 }
9482 9569
9570 m_host.TaskInventory.LockItemsForRead(false);
9571
9483 return UUID.Zero; 9572 return UUID.Zero;
9484 } 9573 }
9485 9574
@@ -9520,6 +9609,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9520 { 9609 {
9521 m_host.AddScriptLPS(1); 9610 m_host.AddScriptLPS(1);
9522 9611
9612 //Clone is thread safe
9523 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 9613 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9524 9614
9525 UUID assetID = UUID.Zero; 9615 UUID assetID = UUID.Zero;
@@ -9582,6 +9672,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9582 { 9672 {
9583 m_host.AddScriptLPS(1); 9673 m_host.AddScriptLPS(1);
9584 9674
9675 //Clone is thread safe
9585 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 9676 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
9586 9677
9587 UUID assetID = UUID.Zero; 9678 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 9c7604b..bd09534 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/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ef990a1
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,21 @@
1using System.Collections;
2using OpenSim.Region.ScriptEngine.Interfaces;
3
4using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
5using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
6using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
7using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
8using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
9using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
10using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
11
12namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
13{
14 public interface ICM_Api
15 {
16 // Windlight Functions
17 LSL_List cmGetWindlightScene(LSL_List rules);
18 int cmSetWindlightScene(LSL_List rules);
19 int cmSetWindlightSceneTargeted(LSL_List rules, key target);
20 }
21}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 580c354..d943b59 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -80,7 +80,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
80 // Avatar Info Commands 80 // Avatar Info Commands
81 string osGetAgentIP(string agent); 81 string osGetAgentIP(string agent);
82 LSL_List osGetAgents(); 82 LSL_List osGetAgents();
83 83
84 // Teleport commands 84 // Teleport commands
85 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 85 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
86 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 86 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs
new file mode 100644
index 0000000..7b67fa3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
30using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
31using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
32
33namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
34{
35 public partial class ScriptBaseClass
36 {
37 // Constants for cmWindlight*
38 public const int WL_WATER_COLOR = 0;
39 public const int WL_WATER_FOG_DENSITY_EXPONENT = 1;
40 public const int WL_UNDERWATER_FOG_MODIFIER = 2;
41 public const int WL_REFLECTION_WAVELET_SCALE = 3;
42 public const int WL_FRESNEL_SCALE = 4;
43 public const int WL_FRESNEL_OFFSET = 5;
44 public const int WL_REFRACT_SCALE_ABOVE = 6;
45 public const int WL_REFRACT_SCALE_BELOW = 7;
46 public const int WL_BLUR_MULTIPLIER = 8;
47 public const int WL_BIG_WAVE_DIRECTION = 9;
48 public const int WL_LITTLE_WAVE_DIRECTION = 10;
49 public const int WL_NORMAL_MAP_TEXTURE = 11;
50 public const int WL_HORIZON = 12;
51 public const int WL_HAZE_HORIZON = 13;
52 public const int WL_BLUE_DENSITY = 14;
53 public const int WL_HAZE_DENSITY = 15;
54 public const int WL_DENSITY_MULTIPLIER = 16;
55 public const int WL_DISTANCE_MULTIPLIER = 17;
56 public const int WL_MAX_ALTITUDE = 18;
57 public const int WL_SUN_MOON_COLOR = 19;
58 public const int WL_AMBIENT = 20;
59 public const int WL_EAST_ANGLE = 21;
60 public const int WL_SUN_GLOW_FOCUS = 22;
61 public const int WL_SUN_GLOW_SIZE = 23;
62 public const int WL_SCENE_GAMMA = 24;
63 public const int WL_STAR_BRIGHTNESS = 25;
64 public const int WL_CLOUD_COLOR = 26;
65 public const int WL_CLOUD_XY_DENSITY = 27;
66 public const int WL_CLOUD_COVERAGE = 28;
67 public const int WL_CLOUD_SCALE = 29;
68 public const int WL_CLOUD_DETAIL_XY_DENSITY = 30;
69 public const int WL_CLOUD_SCROLL_X = 31;
70 public const int WL_CLOUD_SCROLL_Y = 32;
71 public const int WL_CLOUD_SCROLL_Y_LOCK = 33;
72 public const int WL_CLOUD_SCROLL_X_LOCK = 34;
73 public const int WL_DRAW_CLASSIC_CLOUDS = 35;
74
75 }
76}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..5bc3a88
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public LSL_List cmGetWindlightScene(LSL_List rules)
62 {
63 return m_CM_Functions.cmGetWindlightScene(rules);
64 }
65
66 public int cmSetWindlightScene(LSL_List rules)
67 {
68 return m_CM_Functions.cmSetWindlightScene(rules);
69 }
70
71 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
72 {
73 return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target);
74 }
75 }
76}
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/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
index 98bbc68..23138ef 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
@@ -17,6 +17,8 @@
17 <excludeFiles /> 17 <excludeFiles />
18 </DeploymentInformation> 18 </DeploymentInformation>
19 <Contents> 19 <Contents>
20 <File name="./CM_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
21 <File name="./CM_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
20 <File name="./Executor.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 22 <File name="./Executor.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
21 <File name="./LSL_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 23 <File name="./LSL_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
22 <File name="./LSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 24 <File name="./LSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
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 25a4cd6..2a9a2db 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;
@@ -100,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
100 private Dictionary<UUID, IScriptInstance> m_Scripts = 101 private Dictionary<UUID, IScriptInstance> m_Scripts =
101 new Dictionary<UUID, IScriptInstance>(); 102 new Dictionary<UUID, IScriptInstance>();
102 103
104 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
105
103 // Maps the asset ID to the assembly 106 // Maps the asset ID to the assembly
104 107
105 private Dictionary<UUID, string> m_Assemblies = 108 private Dictionary<UUID, string> m_Assemblies =
@@ -121,6 +124,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
121 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); 124 private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue();
122 IWorkItemResult m_CurrentCompile = null; 125 IWorkItemResult m_CurrentCompile = null;
123 126
127 private void lockScriptsForRead(bool locked)
128 {
129 if (locked)
130 {
131 if (m_scriptsLock.RecursiveReadCount > 0)
132 {
133 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
134 m_scriptsLock.ExitReadLock();
135 }
136 if (m_scriptsLock.RecursiveWriteCount > 0)
137 {
138 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
139 m_scriptsLock.ExitWriteLock();
140 }
141
142 while (!m_scriptsLock.TryEnterReadLock(60000))
143 {
144 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
145 if (m_scriptsLock.IsWriteLockHeld)
146 {
147 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
148 }
149 }
150 }
151 else
152 {
153 if (m_scriptsLock.RecursiveReadCount > 0)
154 {
155 m_scriptsLock.ExitReadLock();
156 }
157 }
158 }
159 private void lockScriptsForWrite(bool locked)
160 {
161 if (locked)
162 {
163 if (m_scriptsLock.RecursiveReadCount > 0)
164 {
165 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
166 m_scriptsLock.ExitReadLock();
167 }
168 if (m_scriptsLock.RecursiveWriteCount > 0)
169 {
170 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
171 m_scriptsLock.ExitWriteLock();
172 }
173
174 while (!m_scriptsLock.TryEnterWriteLock(60000))
175 {
176 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
177 if (m_scriptsLock.IsWriteLockHeld)
178 {
179 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
180 }
181 }
182 }
183 else
184 {
185 if (m_scriptsLock.RecursiveWriteCount > 0)
186 {
187 m_scriptsLock.ExitWriteLock();
188 }
189 }
190 }
191
124 public string ScriptEngineName 192 public string ScriptEngineName
125 { 193 {
126 get { return "XEngine"; } 194 get { return "XEngine"; }
@@ -260,43 +328,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
260 328
261 public void RemoveRegion(Scene scene) 329 public void RemoveRegion(Scene scene)
262 { 330 {
263 lock (m_Scripts) 331 lockScriptsForRead(true);
332 foreach (IScriptInstance instance in m_Scripts.Values)
264 { 333 {
265 foreach (IScriptInstance instance in m_Scripts.Values) 334 // Force a final state save
335 //
336 if (m_Assemblies.ContainsKey(instance.AssetID))
266 { 337 {
267 // Force a final state save 338 string assembly = m_Assemblies[instance.AssetID];
268 // 339 instance.SaveState(assembly);
269 if (m_Assemblies.ContainsKey(instance.AssetID)) 340 }
270 {
271 string assembly = m_Assemblies[instance.AssetID];
272 instance.SaveState(assembly);
273 }
274 341
275 // Clear the event queue and abort the instance thread 342 // Clear the event queue and abort the instance thread
276 // 343 //
277 instance.ClearQueue(); 344 instance.ClearQueue();
278 instance.Stop(0); 345 instance.Stop(0);
279 346
280 // Release events, timer, etc 347 // Release events, timer, etc
281 // 348 //
282 instance.DestroyScriptInstance(); 349 instance.DestroyScriptInstance();
283 350
284 // Unload scripts and app domains 351 // Unload scripts and app domains
285 // Must be done explicitly because they have infinite 352 // Must be done explicitly because they have infinite
286 // lifetime 353 // lifetime
287 // 354 //
288 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 355 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
289 if (m_DomainScripts[instance.AppDomain].Count == 0) 356 if (m_DomainScripts[instance.AppDomain].Count == 0)
290 { 357 {
291 m_DomainScripts.Remove(instance.AppDomain); 358 m_DomainScripts.Remove(instance.AppDomain);
292 UnloadAppDomain(instance.AppDomain); 359 UnloadAppDomain(instance.AppDomain);
293 }
294 } 360 }
295 m_Scripts.Clear();
296 m_PrimObjects.Clear();
297 m_Assemblies.Clear();
298 m_DomainScripts.Clear();
299 } 361 }
362 lockScriptsForRead(false);
363 lockScriptsForWrite(true);
364 m_Scripts.Clear();
365 lockScriptsForWrite(false);
366 m_PrimObjects.Clear();
367 m_Assemblies.Clear();
368 m_DomainScripts.Clear();
369
300 lock (m_ScriptEngines) 370 lock (m_ScriptEngines)
301 { 371 {
302 m_ScriptEngines.Remove(this); 372 m_ScriptEngines.Remove(this);
@@ -355,22 +425,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
355 425
356 List<IScriptInstance> instances = new List<IScriptInstance>(); 426 List<IScriptInstance> instances = new List<IScriptInstance>();
357 427
358 lock (m_Scripts) 428 lockScriptsForRead(true);
359 { 429 foreach (IScriptInstance instance in m_Scripts.Values)
360 foreach (IScriptInstance instance in m_Scripts.Values)
361 instances.Add(instance); 430 instances.Add(instance);
362 } 431 lockScriptsForRead(false);
363 432
364 foreach (IScriptInstance i in instances) 433 foreach (IScriptInstance i in instances)
365 { 434 {
366 string assembly = String.Empty; 435 string assembly = String.Empty;
367 436
368 lock (m_Scripts) 437
369 {
370 if (!m_Assemblies.ContainsKey(i.AssetID)) 438 if (!m_Assemblies.ContainsKey(i.AssetID))
371 continue; 439 continue;
372 assembly = m_Assemblies[i.AssetID]; 440 assembly = m_Assemblies[i.AssetID];
373 } 441
374 442
375 i.SaveState(assembly); 443 i.SaveState(assembly);
376 } 444 }
@@ -672,172 +740,183 @@ namespace OpenSim.Region.ScriptEngine.XEngine
672 return false; 740 return false;
673 } 741 }
674 742
675 lock (m_Scripts) 743
744
745 ScriptInstance instance = null;
746 // Create the object record
747 lockScriptsForRead(true);
748 if ((!m_Scripts.ContainsKey(itemID)) ||
749 (m_Scripts[itemID].AssetID != assetID))
676 { 750 {
677 ScriptInstance instance = null; 751 lockScriptsForRead(false);
678 // Create the object record
679 752
680 if ((!m_Scripts.ContainsKey(itemID)) || 753 UUID appDomain = assetID;
681 (m_Scripts[itemID].AssetID != assetID))
682 {
683 UUID appDomain = assetID;
684 754
685 if (part.ParentGroup.IsAttachment) 755 if (part.ParentGroup.IsAttachment)
686 appDomain = part.ParentGroup.RootPart.UUID; 756 appDomain = part.ParentGroup.RootPart.UUID;
687 757
688 if (!m_AppDomains.ContainsKey(appDomain)) 758 if (!m_AppDomains.ContainsKey(appDomain))
759 {
760 try
689 { 761 {
690 try 762 AppDomainSetup appSetup = new AppDomainSetup();
691 { 763 // appSetup.ApplicationBase = Path.Combine(
692 AppDomainSetup appSetup = new AppDomainSetup(); 764 // "ScriptEngines",
693// appSetup.ApplicationBase = Path.Combine( 765 // m_Scene.RegionInfo.RegionID.ToString());
694// "ScriptEngines", 766
695// m_Scene.RegionInfo.RegionID.ToString()); 767 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
696 768 Evidence evidence = new Evidence(baseEvidence);
697 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 769
698 Evidence evidence = new Evidence(baseEvidence); 770 AppDomain sandbox;
699 771 if (m_AppDomainLoading)
700 AppDomain sandbox; 772 sandbox = AppDomain.CreateDomain(
701 if (m_AppDomainLoading) 773 m_Scene.RegionInfo.RegionID.ToString(),
702 sandbox = AppDomain.CreateDomain( 774 evidence, appSetup);
703 m_Scene.RegionInfo.RegionID.ToString(), 775 else
704 evidence, appSetup); 776 sandbox = AppDomain.CurrentDomain;
705 else 777
706 sandbox = AppDomain.CurrentDomain; 778 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
707 779 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
708 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 780 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
709 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 781 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
710 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 782 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
711 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 783 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
712 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 784 //sandbox.SetAppDomainPolicy(sandboxPolicy);
713 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 785
714 //sandbox.SetAppDomainPolicy(sandboxPolicy); 786 m_AppDomains[appDomain] = sandbox;
715 787
716 m_AppDomains[appDomain] = sandbox; 788 m_AppDomains[appDomain].AssemblyResolve +=
717 789 new ResolveEventHandler(
718 m_AppDomains[appDomain].AssemblyResolve += 790 AssemblyResolver.OnAssemblyResolve);
719 new ResolveEventHandler( 791 m_DomainScripts[appDomain] = new List<UUID>();
720 AssemblyResolver.OnAssemblyResolve);
721 m_DomainScripts[appDomain] = new List<UUID>();
722 }
723 catch (Exception e)
724 {
725 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
726 m_ScriptErrorMessage += "Exception creating app domain:\n";
727 m_ScriptFailCount++;
728 lock (m_AddingAssemblies)
729 {
730 m_AddingAssemblies[assembly]--;
731 }
732 return false;
733 }
734 } 792 }
735 m_DomainScripts[appDomain].Add(itemID); 793 catch (Exception e)
736
737 instance = new ScriptInstance(this, part,
738 itemID, assetID, assembly,
739 m_AppDomains[appDomain],
740 part.ParentGroup.RootPart.Name,
741 item.Name, startParam, postOnRez,
742 stateSource, m_MaxScriptQueue);
743
744 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
745 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
746
747 if (presence != null)
748 { 794 {
749 ShowScriptSaveResponse(item.OwnerID, 795 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
750 assetID, "Compile successful", true); 796 m_ScriptErrorMessage += "Exception creating app domain:\n";
797 m_ScriptFailCount++;
798 lock (m_AddingAssemblies)
799 {
800 m_AddingAssemblies[assembly]--;
801 }
802 return false;
751 } 803 }
804 }
805 m_DomainScripts[appDomain].Add(itemID);
752 806
753 instance.AppDomain = appDomain; 807 instance = new ScriptInstance(this, part,
754 instance.LineMap = linemap; 808 itemID, assetID, assembly,
809 m_AppDomains[appDomain],
810 part.ParentGroup.RootPart.Name,
811 item.Name, startParam, postOnRez,
812 stateSource, m_MaxScriptQueue);
755 813
756 m_Scripts[itemID] = instance; 814 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}",
757 } 815 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString());
758 816
759 lock (m_PrimObjects) 817 if (presence != null)
760 { 818 {
761 if (!m_PrimObjects.ContainsKey(localID)) 819 ShowScriptSaveResponse(item.OwnerID,
762 m_PrimObjects[localID] = new List<UUID>(); 820 assetID, "Compile successful", true);
821 }
763 822
764 if (!m_PrimObjects[localID].Contains(itemID)) 823 instance.AppDomain = appDomain;
765 m_PrimObjects[localID].Add(itemID); 824 instance.LineMap = linemap;
825 lockScriptsForWrite(true);
826 m_Scripts[itemID] = instance;
827 lockScriptsForWrite(false);
828 }
829 else
830 {
831 lockScriptsForRead(false);
832 }
833 lock (m_PrimObjects)
834 {
835 if (!m_PrimObjects.ContainsKey(localID))
836 m_PrimObjects[localID] = new List<UUID>();
766 837
767 } 838 if (!m_PrimObjects[localID].Contains(itemID))
839 m_PrimObjects[localID].Add(itemID);
768 840
769 if (!m_Assemblies.ContainsKey(assetID)) 841 }
770 m_Assemblies[assetID] = assembly;
771 842
772 lock (m_AddingAssemblies) 843 if (!m_Assemblies.ContainsKey(assetID))
773 { 844 m_Assemblies[assetID] = assembly;
774 m_AddingAssemblies[assembly]--;
775 }
776 845
777 if (instance!=null) 846 lock (m_AddingAssemblies)
778 instance.Init(); 847 {
848 m_AddingAssemblies[assembly]--;
779 } 849 }
850
851 if (instance!=null)
852 instance.Init();
853
780 return true; 854 return true;
781 } 855 }
782 856
783 public void OnRemoveScript(uint localID, UUID itemID) 857 public void OnRemoveScript(uint localID, UUID itemID)
784 { 858 {
785 lock (m_Scripts) 859 lockScriptsForRead(true);
860 // Do we even have it?
861 if (!m_Scripts.ContainsKey(itemID))
786 { 862 {
787 // Do we even have it? 863 lockScriptsForRead(false);
788 if (!m_Scripts.ContainsKey(itemID)) 864 return;
789 return; 865 }
790 866
791 IScriptInstance instance=m_Scripts[itemID];
792 m_Scripts.Remove(itemID);
793 867
794 instance.ClearQueue(); 868 IScriptInstance instance=m_Scripts[itemID];
795 instance.Stop(0); 869 lockScriptsForRead(false);
870 lockScriptsForWrite(true);
871 m_Scripts.Remove(itemID);
872 lockScriptsForWrite(false);
873 instance.ClearQueue();
874 instance.Stop(0);
796 875
797 SceneObjectPart part = 876 SceneObjectPart part =
798 m_Scene.GetSceneObjectPart(localID); 877 m_Scene.GetSceneObjectPart(localID);
799 878
800 if (part != null) 879 if (part != null)
801 part.RemoveScriptEvents(itemID); 880 part.RemoveScriptEvents(itemID);
802 881
803// bool objectRemoved = false; 882// bool objectRemoved = false;
804 883
805 lock (m_PrimObjects) 884 lock (m_PrimObjects)
885 {
886 // Remove the script from it's prim
887 if (m_PrimObjects.ContainsKey(localID))
806 { 888 {
807 // Remove the script from it's prim 889 // Remove inventory item record
808 if (m_PrimObjects.ContainsKey(localID)) 890 if (m_PrimObjects[localID].Contains(itemID))
809 { 891 m_PrimObjects[localID].Remove(itemID);
810 // Remove inventory item record
811 if (m_PrimObjects[localID].Contains(itemID))
812 m_PrimObjects[localID].Remove(itemID);
813 892
814 // If there are no more scripts, remove prim 893 // If there are no more scripts, remove prim
815 if (m_PrimObjects[localID].Count == 0) 894 if (m_PrimObjects[localID].Count == 0)
816 { 895 {
817 m_PrimObjects.Remove(localID); 896 m_PrimObjects.Remove(localID);
818// objectRemoved = true; 897// objectRemoved = true;
819 }
820 } 898 }
821 } 899 }
900 }
822 901
823 instance.RemoveState(); 902 instance.RemoveState();
824 instance.DestroyScriptInstance(); 903 instance.DestroyScriptInstance();
825 904
826 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 905 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
827 if (m_DomainScripts[instance.AppDomain].Count == 0) 906 if (m_DomainScripts[instance.AppDomain].Count == 0)
828 { 907 {
829 m_DomainScripts.Remove(instance.AppDomain); 908 m_DomainScripts.Remove(instance.AppDomain);
830 UnloadAppDomain(instance.AppDomain); 909 UnloadAppDomain(instance.AppDomain);
831 } 910 }
832 911
833 instance = null; 912 instance = null;
834 913
835 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 914 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
836 if (handlerObjectRemoved != null) 915 if (handlerObjectRemoved != null)
837 handlerObjectRemoved(part.UUID); 916 handlerObjectRemoved(part.UUID);
838 917
839 CleanAssemblies(); 918 CleanAssemblies();
840 } 919
841 920
842 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 921 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
843 if (handlerScriptRemoved != null) 922 if (handlerScriptRemoved != null)
@@ -1090,12 +1169,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1090 private IScriptInstance GetInstance(UUID itemID) 1169 private IScriptInstance GetInstance(UUID itemID)
1091 { 1170 {
1092 IScriptInstance instance; 1171 IScriptInstance instance;
1093 lock (m_Scripts) 1172 lockScriptsForRead(true);
1173 if (!m_Scripts.ContainsKey(itemID))
1094 { 1174 {
1095 if (!m_Scripts.ContainsKey(itemID)) 1175 lockScriptsForRead(false);
1096 return null; 1176 return null;
1097 instance = m_Scripts[itemID];
1098 } 1177 }
1178 instance = m_Scripts[itemID];
1179 lockScriptsForRead(false);
1099 return instance; 1180 return instance;
1100 } 1181 }
1101 1182
@@ -1119,6 +1200,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1119 return false; 1200 return false;
1120 } 1201 }
1121 1202
1203 [DebuggerNonUserCode]
1122 public void ApiResetScript(UUID itemID) 1204 public void ApiResetScript(UUID itemID)
1123 { 1205 {
1124 IScriptInstance instance = GetInstance(itemID); 1206 IScriptInstance instance = GetInstance(itemID);
@@ -1170,6 +1252,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1170 return UUID.Zero; 1252 return UUID.Zero;
1171 } 1253 }
1172 1254
1255 [DebuggerNonUserCode]
1173 public void SetState(UUID itemID, string newState) 1256 public void SetState(UUID itemID, string newState)
1174 { 1257 {
1175 IScriptInstance instance = GetInstance(itemID); 1258 IScriptInstance instance = GetInstance(itemID);
@@ -1197,11 +1280,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1197 { 1280 {
1198 List<IScriptInstance> instances = new List<IScriptInstance>(); 1281 List<IScriptInstance> instances = new List<IScriptInstance>();
1199 1282
1200 lock (m_Scripts) 1283 lockScriptsForRead(true);
1201 { 1284 foreach (IScriptInstance instance in m_Scripts.Values)
1202 foreach (IScriptInstance instance in m_Scripts.Values)
1203 instances.Add(instance); 1285 instances.Add(instance);
1204 } 1286 lockScriptsForRead(false);
1205 1287
1206 foreach (IScriptInstance i in instances) 1288 foreach (IScriptInstance i in instances)
1207 { 1289 {