aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs122
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs2
-rw-r--r--OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs2
-rw-r--r--OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs13
-rw-r--r--OpenSim/Data/MySQL/MySQLLegacyRegionData.cs192
-rw-r--r--OpenSim/Data/MySQL/Resources/032_RegionStore.sql70
-rw-r--r--OpenSim/Data/Null/NullDataStore.cs11
-rw-r--r--OpenSim/Data/SQLite/SQLiteRegionData.cs13
-rw-r--r--OpenSim/Framework/IClientAPI.cs2
-rw-r--r--OpenSim/Framework/RegionInfo.cs298
-rw-r--r--OpenSim/Framework/Servers/VersionInfo.cs3
-rw-r--r--OpenSim/Framework/TaskInventoryDictionary.cs117
-rw-r--r--OpenSim/Framework/Util.cs26
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs93
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs27
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs107
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs53
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs27
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs21
-rw-r--r--OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs245
-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.cs12
-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.cs98
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs380
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs471
-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.cs93
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSCharacter.cs21
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSPrim.cs20
-rw-r--r--OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs44
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs430
-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.cs20
-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.cs71
-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
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs2
-rw-r--r--bin/OpenSim.ini.example12
63 files changed, 4078 insertions, 1261 deletions
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index adf7967..b22003c 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -123,6 +123,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
123 availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod; 123 availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod;
124 availableMethods["admin_shutdown"] = XmlRpcShutdownMethod; 124 availableMethods["admin_shutdown"] = XmlRpcShutdownMethod;
125 availableMethods["admin_broadcast"] = XmlRpcAlertMethod; 125 availableMethods["admin_broadcast"] = XmlRpcAlertMethod;
126 availableMethods["admin_dialog"] = XmlRpcDialogMethod;
126 availableMethods["admin_restart"] = XmlRpcRestartMethod; 127 availableMethods["admin_restart"] = XmlRpcRestartMethod;
127 availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; 128 availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod;
128 // User management 129 // User management
@@ -212,9 +213,59 @@ namespace OpenSim.ApplicationPlugins.RemoteController
212 if (!m_app.SceneManager.TryGetScene(regionID, out rebootedScene)) 213 if (!m_app.SceneManager.TryGetScene(regionID, out rebootedScene))
213 throw new Exception("region not found"); 214 throw new Exception("region not found");
214 215
216 int timeout = 30000;
217 string message;
218
219 if (requestData.ContainsKey("restart")
220 && ((string)requestData["restart"] == "delayed")
221 && requestData.ContainsKey("milliseconds"))
222 {
223 timeout = Int32.Parse(requestData["milliseconds"].ToString());
224
225 if (timeout < 15000)
226 {
227 //It must be at least 15 seconds or we'll cancel the reboot request
228 timeout = 15000;
229 }
230
231 message
232 = "Region is restarting in " + ((int)(timeout / 1000)).ToString()
233 + " second(s). Please save what you are doing and log out.";
234 }
235 else
236 {
237 message = "Region is restarting in 30 second(s). Please save what you are doing and log out.";
238 }
239
240 if (requestData.ContainsKey("noticetype")
241 && ((string)requestData["noticetype"] == "dialog"))
242 {
243 m_app.SceneManager.ForEachScene(
244 delegate(Scene scene)
245 {
246 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
247 if (dialogModule != null)
248 dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
249 });
250 }
251 else
252 {
253 if (!requestData.ContainsKey("noticetype")
254 || ((string)requestData["noticetype"] != "none"))
255 {
256 m_app.SceneManager.ForEachScene(
257 delegate(Scene scene)
258 {
259 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
260 if (dialogModule != null)
261 dialogModule.SendGeneralAlert(message);
262 });
263 }
264 }
265
215 responseData["rebooting"] = true; 266 responseData["rebooting"] = true;
216 response.Value = responseData; 267 response.Value = responseData;
217 rebootedScene.Restart(30); 268 rebootedScene.Restart(timeout / 1000,false);
218 } 269 }
219 catch (Exception e) 270 catch (Exception e)
220 { 271 {
@@ -277,6 +328,53 @@ namespace OpenSim.ApplicationPlugins.RemoteController
277 m_log.Info("[RADMIN]: Alert request complete"); 328 m_log.Info("[RADMIN]: Alert request complete");
278 return response; 329 return response;
279 } 330 }
331 public XmlRpcResponse XmlRpcDialogMethod(XmlRpcRequest request, IPEndPoint remoteClient)
332 {
333 XmlRpcResponse response = new XmlRpcResponse();
334 Hashtable responseData = new Hashtable();
335
336 m_log.Info("[RADMIN]: Dialog request started");
337
338 try
339 {
340 Hashtable requestData = (Hashtable)request.Params[0];
341
342 checkStringParameters(request, new string[] { "password", "from", "message" });
343
344 if (m_requiredPassword != String.Empty &&
345 (!requestData.Contains("password") || (string)requestData["password"] != m_requiredPassword))
346 throw new Exception("wrong password");
347
348 string message = (string)requestData["message"];
349 string fromuuid = (string)requestData["from"];
350 m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
351
352 responseData["accepted"] = true;
353 responseData["success"] = true;
354 response.Value = responseData;
355
356 m_app.SceneManager.ForEachScene(
357 delegate(Scene scene)
358 {
359 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
360 if (dialogModule != null)
361 dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
362 });
363 }
364 catch (Exception e)
365 {
366 m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message);
367 m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString());
368
369 responseData["accepted"] = false;
370 responseData["success"] = false;
371 responseData["error"] = e.Message;
372 response.Value = responseData;
373 }
374
375 m_log.Info("[RADMIN]: Alert request complete");
376 return response;
377 }
280 378
281 public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient) 379 public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient)
282 { 380 {
@@ -384,13 +482,33 @@ namespace OpenSim.ApplicationPlugins.RemoteController
384 message = "Region is going down now."; 482 message = "Region is going down now.";
385 } 483 }
386 484
387 m_app.SceneManager.ForEachScene( 485 if (requestData.ContainsKey("noticetype")
486 && ((string) requestData["noticetype"] == "dialog"))
487 {
488 m_app.SceneManager.ForEachScene(
388 delegate(Scene scene) 489 delegate(Scene scene)
389 { 490 {
390 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>(); 491 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
391 if (dialogModule != null) 492 if (dialogModule != null)
493 dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
494 });
495 }
496 else
497 {
498 if (!requestData.ContainsKey("noticetype")
499 || ((string)requestData["noticetype"] != "none"))
500 {
501 m_app.SceneManager.ForEachScene(
502 delegate(Scene scene)
503 {
504 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
505 if (dialogModule != null)
392 dialogModule.SendGeneralAlert(message); 506 dialogModule.SendGeneralAlert(message);
393 }); 507 });
508 }
509 }
510
511
394 512
395 // Perform shutdown 513 // Perform shutdown
396 System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing 514 System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index 0cae3dd..9f9d151 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -902,7 +902,7 @@ namespace OpenSim.Client.MXP.ClientStack
902 // Need to translate to MXP somehow 902 // Need to translate to MXP somehow
903 } 903 }
904 904
905 public void SendGenericMessage(string method, List<string> message) 905 public void SendGenericMessage(string method, List<byte[]> message)
906 { 906 {
907 // Need to translate to MXP somehow 907 // Need to translate to MXP somehow
908 } 908 }
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index fb87c15..533475f 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -483,7 +483,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
483 throw new System.NotImplementedException(); 483 throw new System.NotImplementedException();
484 } 484 }
485 485
486 public void SendGenericMessage(string method, List<string> message) 486 public void SendGenericMessage(string method, List<byte[]> message)
487 { 487 {
488 throw new System.NotImplementedException(); 488 throw new System.NotImplementedException();
489 } 489 }
diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
index 6371307..0b430c7 100644
--- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs
@@ -671,7 +671,16 @@ VALUES
671 cmd.ExecuteNonQuery(); 671 cmd.ExecuteNonQuery();
672 } 672 }
673 } 673 }
674 674 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
675 {
676 //This connector doesn't support the windlight module yet
677 //Return default LL windlight settings
678 return new RegionMeta7WindlightData();
679 }
680 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
681 {
682 //This connector doesn't support the windlight module yet
683 }
675 /// <summary> 684 /// <summary>
676 /// Loads the settings of a region. 685 /// Loads the settings of a region.
677 /// </summary> 686 /// </summary>
@@ -696,7 +705,7 @@ VALUES
696 } 705 }
697 } 706 }
698 707
699 //If comes here then there is now region setting for that region 708 //If we reach this point then there are new region settings for that region
700 regionSettings = new RegionSettings(); 709 regionSettings = new RegionSettings();
701 regionSettings.RegionUUID = regionUUID; 710 regionSettings.RegionUUID = regionUUID;
702 regionSettings.OnSave += StoreRegionSettings; 711 regionSettings.OnSave += StoreRegionSettings;
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
index 9a4a4bb..e57e929 100644
--- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
@@ -693,6 +693,97 @@ namespace OpenSim.Data.MySQL
693 } 693 }
694 } 694 }
695 695
696 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
697 {
698 RegionMeta7WindlightData nWP = new RegionMeta7WindlightData();
699 nWP.OnSave += StoreRegionWindlightSettings;
700 lock (m_Connection)
701 {
702
703 string command = "select * from `regionwindlight` where region_id = ?regionID";
704
705 MySqlCommand cmd = new MySqlCommand(command);
706
707 cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
708
709 IDataReader result = ExecuteReader(cmd);
710 if (!result.Read())
711 {
712 //No result, so store our default windlight profile and return it
713 nWP.regionID = regionUUID;
714 StoreRegionWindlightSettings(nWP);
715 return nWP;
716 }
717 else
718 {
719 UUID.TryParse(result["region_id"].ToString(), out nWP.regionID);
720 nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
721 nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
722 nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
723 nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
724 nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
725 nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
726 nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
727 nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
728 nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
729 nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
730 nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
731 nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
732 nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
733 nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
734 nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
735 nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
736 nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
737 UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
738 nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
739 nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
740 nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
741 nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
742 nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
743 nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
744 nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
745 nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
746 nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
747 nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
748 nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
749 nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
750 nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
751 nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
752 nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
753 nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
754 nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
755 nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
756 nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
757 nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
758 nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
759 nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
760 nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
761 nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
762 nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
763 nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
764 nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
765 nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
766 nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
767 nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
768 nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
769 nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
770 nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
771 nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
772 nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
773 nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
774 nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
775 nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
776 nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
777 nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
778 nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
779 nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
780 nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
781 nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
782 }
783 }
784 return nWP;
785 }
786
696 public RegionSettings LoadRegionSettings(UUID regionUUID) 787 public RegionSettings LoadRegionSettings(UUID regionUUID)
697 { 788 {
698 RegionSettings rs = null; 789 RegionSettings rs = null;
@@ -726,6 +817,107 @@ namespace OpenSim.Data.MySQL
726 return rs; 817 return rs;
727 } 818 }
728 819
820 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
821 {
822 lock (m_Connection)
823 {
824 using (MySqlCommand cmd = m_Connection.CreateCommand())
825 {
826 cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
827 cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
828 cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
829 cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
830 cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
831 cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
832 cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
833 cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
834 cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
835 cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
836 cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
837 cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
838 cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
839 cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
840 cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
841 cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
842 cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
843 cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
844 cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
845 cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
846 cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
847 cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
848 cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
849 cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
850 cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
851
852 cmd.Parameters.AddWithValue("region_id", wl.regionID);
853 cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
854 cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
855 cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
856 cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
857 cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
858 cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
859 cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
860 cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
861 cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
862 cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
863 cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
864 cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
865 cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
866 cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
867 cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
868 cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
869 cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
870 cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
871 cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
872 cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
873 cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
874 cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
875 cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
876 cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
877 cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
878 cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
879 cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
880 cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
881 cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
882 cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
883 cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
884 cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
885 cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
886 cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
887 cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
888 cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
889 cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
890 cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
891 cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
892 cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
893 cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
894 cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
895 cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
896 cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
897 cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
898 cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
899 cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
900 cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
901 cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
902 cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
903 cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
904 cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
905 cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
906 cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
907 cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
908 cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
909 cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
910 cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
911 cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
912 cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
913 cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
914 cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
915
916 ExecuteNonQuery(cmd);
917 }
918 }
919 }
920
729 public void StoreRegionSettings(RegionSettings rs) 921 public void StoreRegionSettings(RegionSettings rs)
730 { 922 {
731 lock (m_Connection) 923 lock (m_Connection)
diff --git a/OpenSim/Data/MySQL/Resources/032_RegionStore.sql b/OpenSim/Data/MySQL/Resources/032_RegionStore.sql
new file mode 100644
index 0000000..0545ee1
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/032_RegionStore.sql
@@ -0,0 +1,70 @@
1BEGIN;
2
3CREATE TABLE `regionwindlight` (
4 `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
5 `water_color_r` float(9,6) unsigned NOT NULL DEFAULT '4.000000',
6 `water_color_g` float(9,6) unsigned NOT NULL DEFAULT '38.000000',
7 `water_color_b` float(9,6) unsigned NOT NULL DEFAULT '64.000000',
8 `water_fog_density_exponent` float(3,1) unsigned NOT NULL DEFAULT '4.0',
9 `underwater_fog_modifier` float(3,2) unsigned NOT NULL DEFAULT '0.25',
10 `reflection_wavelet_scale_1` float(3,1) unsigned NOT NULL DEFAULT '2.0',
11 `reflection_wavelet_scale_2` float(3,1) unsigned NOT NULL DEFAULT '2.0',
12 `reflection_wavelet_scale_3` float(3,1) unsigned NOT NULL DEFAULT '2.0',
13 `fresnel_scale` float(3,2) unsigned NOT NULL DEFAULT '0.40',
14 `fresnel_offset` float(3,2) unsigned NOT NULL DEFAULT '0.50',
15 `refract_scale_above` float(3,2) unsigned NOT NULL DEFAULT '0.03',
16 `refract_scale_below` float(3,2) unsigned NOT NULL DEFAULT '0.20',
17 `blur_multiplier` float(4,3) unsigned NOT NULL DEFAULT '0.040',
18 `big_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.05',
19 `big_wave_direction_y` float(3,2) NOT NULL DEFAULT '-0.42',
20 `little_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.11',
21 `little_wave_direction_y` float(3,2) NOT NULL DEFAULT '-1.16',
22 `normal_map_texture` varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4',
23 `horizon_r` float(3,2) unsigned NOT NULL DEFAULT '0.26',
24 `horizon_g` float(3,2) unsigned NOT NULL DEFAULT '0.24',
25 `horizon_b` float(3,2) unsigned NOT NULL DEFAULT '0.33',
26 `horizon_i` float(3,2) unsigned NOT NULL DEFAULT '0.33',
27 `haze_horizon` float(3,2) unsigned NOT NULL DEFAULT '0.19',
28 `blue_density_r` float(3,2) unsigned NOT NULL DEFAULT '0.10',
29 `blue_density_g` float(3,2) unsigned NOT NULL DEFAULT '0.93',
30 `blue_density_b` float(3,2) unsigned NOT NULL DEFAULT '0.02',
31 `blue_density_i` float(3,2) unsigned NOT NULL DEFAULT '0.93',
32 `haze_density` float(3,2) unsigned NOT NULL DEFAULT '0.70',
33 `density_multiplier` float(3,2) unsigned NOT NULL DEFAULT '0.18',
34 `distance_multiplier` float(4,1) unsigned NOT NULL DEFAULT '0.8',
35 `max_altitude` int(4) unsigned NOT NULL DEFAULT '1605',
36 `sun_moon_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.24',
37 `sun_moon_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.26',
38 `sun_moon_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.30',
39 `sun_moon_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.30',
40 `sun_moon_position` float(4,3) unsigned NOT NULL DEFAULT '0.335',
41 `ambient_r` float(3,2) unsigned NOT NULL DEFAULT '0.35',
42 `ambient_g` float(3,2) unsigned NOT NULL DEFAULT '0.35',
43 `ambient_b` float(3,2) unsigned NOT NULL DEFAULT '0.35',
44 `ambient_i` float(3,2) unsigned NOT NULL DEFAULT '0.35',
45 `east_angle` float(3,2) unsigned NOT NULL DEFAULT '0.00',
46 `sun_glow_focus` float(3,2) unsigned NOT NULL DEFAULT '0.10',
47 `sun_glow_size` float(3,2) unsigned NOT NULL DEFAULT '1.75',
48 `scene_gamma` float(4,2) unsigned NOT NULL DEFAULT '1.00',
49 `star_brightness` float(3,2) unsigned NOT NULL DEFAULT '0.00',
50 `cloud_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.41',
51 `cloud_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.41',
52 `cloud_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.41',
53 `cloud_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.41',
54 `cloud_x` float(3,2) unsigned NOT NULL DEFAULT '1.00',
55 `cloud_y` float(3,2) unsigned NOT NULL DEFAULT '0.53',
56 `cloud_density` float(3,2) unsigned NOT NULL DEFAULT '1.00',
57 `cloud_coverage` float(3,2) unsigned NOT NULL DEFAULT '0.27',
58 `cloud_scale` float(3,2) unsigned NOT NULL DEFAULT '0.42',
59 `cloud_detail_x` float(3,2) unsigned NOT NULL DEFAULT '1.00',
60 `cloud_detail_y` float(3,2) unsigned NOT NULL DEFAULT '0.53',
61 `cloud_detail_density` float(3,2) unsigned NOT NULL DEFAULT '0.12',
62 `cloud_scroll_x` float(3,2) unsigned NOT NULL DEFAULT '0.20',
63 `cloud_scroll_x_lock` tinyint(1) unsigned NOT NULL DEFAULT '0',
64 `cloud_scroll_y` float(3,2) unsigned NOT NULL DEFAULT '0.01',
65 `cloud_scroll_y_lock` tinyint(1) unsigned NOT NULL DEFAULT '0',
66 `draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '0',
67 PRIMARY KEY (`region_id`)
68);
69
70COMMIT; \ No newline at end of file
diff --git a/OpenSim/Data/Null/NullDataStore.cs b/OpenSim/Data/Null/NullDataStore.cs
index 427fa0a..4b6d0f3 100644
--- a/OpenSim/Data/Null/NullDataStore.cs
+++ b/OpenSim/Data/Null/NullDataStore.cs
@@ -50,7 +50,16 @@ namespace OpenSim.Data.Null
50 public void StoreRegionSettings(RegionSettings rs) 50 public void StoreRegionSettings(RegionSettings rs)
51 { 51 {
52 } 52 }
53 53 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
54 {
55 //This connector doesn't support the windlight module yet
56 //Return default LL windlight settings
57 return new RegionMeta7WindlightData();
58 }
59 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
60 {
61 //This connector doesn't support the windlight module yet
62 }
54 public RegionSettings LoadRegionSettings(UUID regionUUID) 63 public RegionSettings LoadRegionSettings(UUID regionUUID)
55 { 64 {
56 return null; 65 return null;
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index b68de1a..83fd775 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -272,7 +272,16 @@ namespace OpenSim.Data.SQLite
272 Commit(); 272 Commit();
273 } 273 }
274 } 274 }
275 275 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
276 {
277 //This connector doesn't support the windlight module yet
278 //Return default LL windlight settings
279 return new RegionMeta7WindlightData();
280 }
281 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
282 {
283 //This connector doesn't support the windlight module yet
284 }
276 public RegionSettings LoadRegionSettings(UUID regionUUID) 285 public RegionSettings LoadRegionSettings(UUID regionUUID)
277 { 286 {
278 lock (ds) 287 lock (ds)
@@ -320,7 +329,7 @@ namespace OpenSim.Data.SQLite
320 { 329 {
321 foreach (SceneObjectPart prim in obj.Children.Values) 330 foreach (SceneObjectPart prim in obj.Children.Values)
322 { 331 {
323 m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); 332// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
324 addPrim(prim, obj.UUID, regionUUID); 333 addPrim(prim, obj.UUID, regionUUID);
325 } 334 }
326 } 335 }
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 04ba9c6..cb136e2 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -1077,7 +1077,7 @@ namespace OpenSim.Framework
1077 1077
1078 void SendInstantMessage(GridInstantMessage im); 1078 void SendInstantMessage(GridInstantMessage im);
1079 1079
1080 void SendGenericMessage(string method, List<string> message); 1080 void SendGenericMessage(string method, List<byte[]> message);
1081 1081
1082 void SendLayerData(float[] map); 1082 void SendLayerData(float[] map);
1083 void SendLayerData(int px, int py, float[] map); 1083 void SendLayerData(int px, int py, float[] map);
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 88b62e0..9e00528 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -36,8 +36,290 @@ using OpenMetaverse;
36using OpenMetaverse.StructuredData; 36using OpenMetaverse.StructuredData;
37using OpenSim.Framework.Console; 37using OpenSim.Framework.Console;
38 38
39
39namespace OpenSim.Framework 40namespace OpenSim.Framework
40{ 41{
42 public class RegionMeta7WindlightData
43 {
44 public UUID regionID = UUID.Zero;
45 public Vector3 waterColor = new Vector3(4.0f,38.0f,64.0f);
46 public float waterFogDensityExponent = 4.0f;
47 public float underwaterFogModifier = 0.25f;
48 public Vector3 reflectionWaveletScale = new Vector3(2.0f,2.0f,2.0f);
49 public float fresnelScale = 0.40f;
50 public float fresnelOffset = 0.50f;
51 public float refractScaleAbove = 0.03f;
52 public float refractScaleBelow = 0.20f;
53 public float blurMultiplier = 0.040f;
54 public Vector2 bigWaveDirection = new Vector2(1.05f,-0.42f);
55 public Vector2 littleWaveDirection = new Vector2(1.11f,-1.16f);
56 public UUID normalMapTexture = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4");
57 public Vector4 horizon = new Vector4(0.26f, 0.24f, 0.34f, 0.33f);
58 public float hazeHorizon = 0.19f;
59 public Vector4 blueDensity = new Vector4(0.10f, 0.93f, 0.02f, 0.93f);
60 public float hazeDensity = 0.70f;
61 public float densityMultiplier = 0.18f;
62 public float distanceMultiplier = 0.8f;
63 public UInt16 maxAltitude = 1605;
64 public Vector4 sunMoonColor = new Vector4(0.24f, 0.26f, 0.30f, 0.30f);
65 public float sunMoonPosition = 0.335f;
66 public Vector4 ambient = new Vector4(0.35f,0.35f,0.35f,0.35f);
67 public float eastAngle = 0.0f;
68 public float sunGlowFocus = 0.10f;
69 public float sunGlowSize = 0.10f;
70 public float sceneGamma = 1.0f;
71 public float starBrightness = 0.0f;
72 public Vector4 cloudColor = new Vector4(0.41f, 0.41f, 0.41f, 0.41f);
73 public Vector3 cloudXYDensity = new Vector3(1.00f, 0.53f, 1.00f);
74 public float cloudCoverage = 0.27f;
75 public float cloudScale = 0.42f;
76 public Vector3 cloudDetailXYDensity = new Vector3(1.00f, 0.53f, 0.12f);
77 public float cloudScrollX = 0.20f;
78 public bool cloudScrollXLock = false;
79 public float cloudScrollY = 0.01f;
80 public bool cloudScrollYLock = false;
81 public bool drawClassicClouds = false;
82
83 public delegate void SaveDelegate(RegionMeta7WindlightData wl);
84 public event SaveDelegate OnSave;
85 public void Save()
86 {
87 if (OnSave != null)
88 OnSave(this);
89 }
90 }
91
92 [Serializable]
93 public class SimpleRegionInfo
94 {
95 // private static readonly log4net.ILog m_log
96 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
97
98 /// <summary>
99 /// The port by which http communication occurs with the region (most noticeably, CAPS communication)
100 /// </summary>
101 public uint HttpPort
102 {
103 get { return m_httpPort; }
104 set { m_httpPort = value; }
105 }
106 protected uint m_httpPort;
107
108 /// <summary>
109 /// A well-formed URI for the host region server (namely "http://" + ExternalHostName)
110 /// </summary>
111 public string ServerURI
112 {
113 get { return m_serverURI; }
114 set { m_serverURI = value; }
115 }
116 protected string m_serverURI;
117
118 public string RegionName
119 {
120 get { return m_regionName; }
121 set { m_regionName = value; }
122 }
123 protected string m_regionName = String.Empty;
124
125 protected bool Allow_Alternate_Ports;
126 public bool m_allow_alternate_ports;
127 protected string m_externalHostName;
128
129 protected IPEndPoint m_internalEndPoint;
130 protected uint? m_regionLocX;
131 protected uint? m_regionLocY;
132 protected uint m_remotingPort;
133 public UUID RegionID = UUID.Zero;
134 public string RemotingAddress;
135 public UUID ScopeID = UUID.Zero;
136
137 public SimpleRegionInfo()
138 {
139 }
140
141 public SimpleRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri)
142 {
143 m_regionLocX = regionLocX;
144 m_regionLocY = regionLocY;
145
146 m_internalEndPoint = internalEndPoint;
147 m_externalHostName = externalUri;
148 }
149
150 public SimpleRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port)
151 {
152 m_regionLocX = regionLocX;
153 m_regionLocY = regionLocY;
154
155 m_externalHostName = externalUri;
156
157 m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port);
158 }
159
160 public SimpleRegionInfo(RegionInfo ConvertFrom)
161 {
162 m_regionName = ConvertFrom.RegionName;
163 m_regionLocX = ConvertFrom.RegionLocX;
164 m_regionLocY = ConvertFrom.RegionLocY;
165 m_internalEndPoint = ConvertFrom.InternalEndPoint;
166 m_externalHostName = ConvertFrom.ExternalHostName;
167 m_remotingPort = ConvertFrom.RemotingPort;
168 m_httpPort = ConvertFrom.HttpPort;
169 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
170 RemotingAddress = ConvertFrom.RemotingAddress;
171 RegionID = UUID.Zero;
172 ServerURI = ConvertFrom.ServerURI;
173 }
174
175 public uint RemotingPort
176 {
177 get { return m_remotingPort; }
178 set { m_remotingPort = value; }
179 }
180
181 /// <value>
182 /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw.
183 ///
184 /// XXX Isn't this really doing too much to be a simple getter, rather than an explict method?
185 /// </value>
186 public IPEndPoint ExternalEndPoint
187 {
188 get
189 {
190 // Old one defaults to IPv6
191 //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port);
192
193 IPAddress ia = null;
194 // If it is already an IP, don't resolve it - just return directly
195 if (IPAddress.TryParse(m_externalHostName, out ia))
196 return new IPEndPoint(ia, m_internalEndPoint.Port);
197
198 // Reset for next check
199 ia = null;
200 try
201 {
202 foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName))
203 {
204 if (ia == null)
205 ia = Adr;
206
207 if (Adr.AddressFamily == AddressFamily.InterNetwork)
208 {
209 ia = Adr;
210 break;
211 }
212 }
213 }
214 catch (SocketException e)
215 {
216 throw new Exception(
217 "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" +
218 e + "' attached to this exception", e);
219 }
220
221 return new IPEndPoint(ia, m_internalEndPoint.Port);
222 }
223
224 set { m_externalHostName = value.ToString(); }
225 }
226
227 public string ExternalHostName
228 {
229 get { return m_externalHostName; }
230 set { m_externalHostName = value; }
231 }
232
233 public IPEndPoint InternalEndPoint
234 {
235 get { return m_internalEndPoint; }
236 set { m_internalEndPoint = value; }
237 }
238
239 public uint RegionLocX
240 {
241 get { return m_regionLocX.Value; }
242 set { m_regionLocX = value; }
243 }
244
245 public uint RegionLocY
246 {
247 get { return m_regionLocY.Value; }
248 set { m_regionLocY = value; }
249 }
250
251 public ulong RegionHandle
252 {
253 get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); }
254 }
255
256 public int getInternalEndPointPort()
257 {
258 return m_internalEndPoint.Port;
259 }
260
261 public Dictionary<string, object> ToKeyValuePairs()
262 {
263 Dictionary<string, object> kvp = new Dictionary<string, object>();
264 kvp["uuid"] = RegionID.ToString();
265 kvp["locX"] = RegionLocX.ToString();
266 kvp["locY"] = RegionLocY.ToString();
267 kvp["external_ip_address"] = ExternalEndPoint.Address.ToString();
268 kvp["external_port"] = ExternalEndPoint.Port.ToString();
269 kvp["external_host_name"] = ExternalHostName;
270 kvp["http_port"] = HttpPort.ToString();
271 kvp["internal_ip_address"] = InternalEndPoint.Address.ToString();
272 kvp["internal_port"] = InternalEndPoint.Port.ToString();
273 kvp["alternate_ports"] = m_allow_alternate_ports.ToString();
274 kvp["server_uri"] = ServerURI;
275
276 return kvp;
277 }
278
279 public SimpleRegionInfo(Dictionary<string, object> kvp)
280 {
281 if ((kvp["external_ip_address"] != null) && (kvp["external_port"] != null))
282 {
283 int port = 0;
284 Int32.TryParse((string)kvp["external_port"], out port);
285 IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["external_ip_address"]), port);
286 ExternalEndPoint = ep;
287 }
288 else
289 ExternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
290
291 if (kvp["external_host_name"] != null)
292 ExternalHostName = (string)kvp["external_host_name"];
293
294 if (kvp["http_port"] != null)
295 {
296 UInt32 port = 0;
297 UInt32.TryParse((string)kvp["http_port"], out port);
298 HttpPort = port;
299 }
300
301 if ((kvp["internal_ip_address"] != null) && (kvp["internal_port"] != null))
302 {
303 int port = 0;
304 Int32.TryParse((string)kvp["internal_port"], out port);
305 IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["internal_ip_address"]), port);
306 InternalEndPoint = ep;
307 }
308 else
309 InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
310
311 if (kvp["alternate_ports"] != null)
312 {
313 bool alts = false;
314 Boolean.TryParse((string)kvp["alternate_ports"], out alts);
315 m_allow_alternate_ports = alts;
316 }
317
318 if (kvp["server_uri"] != null)
319 ServerURI = (string)kvp["server_uri"];
320 }
321 }
322
41 public class RegionInfo 323 public class RegionInfo
42 { 324 {
43 // private static readonly log4net.ILog m_log 325 // private static readonly log4net.ILog m_log
@@ -73,6 +355,7 @@ namespace OpenSim.Framework
73 private bool m_clampPrimSize = false; 355 private bool m_clampPrimSize = false;
74 private int m_objectCapacity = 0; 356 private int m_objectCapacity = 0;
75 private string m_regionType = String.Empty; 357 private string m_regionType = String.Empty;
358 private RegionMeta7WindlightData m_windlight = new RegionMeta7WindlightData();
76 protected uint m_httpPort; 359 protected uint m_httpPort;
77 protected string m_serverURI; 360 protected string m_serverURI;
78 protected string m_regionName = String.Empty; 361 protected string m_regionName = String.Empty;
@@ -211,6 +494,21 @@ namespace OpenSim.Framework
211 set { m_regionSettings = value; } 494 set { m_regionSettings = value; }
212 } 495 }
213 496
497 public RegionMeta7WindlightData WindlightSettings
498 {
499 get
500 {
501 if (m_windlight == null)
502 {
503 m_windlight = new RegionMeta7WindlightData();
504 }
505
506 return m_windlight;
507 }
508
509 set { m_windlight = value; }
510 }
511
214 public int NonphysPrimMax 512 public int NonphysPrimMax
215 { 513 {
216 get { return m_nonphysPrimMax; } 514 get { return m_nonphysPrimMax; }
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs
index ec94b2d..d348c90 100644
--- a/OpenSim/Framework/Servers/VersionInfo.cs
+++ b/OpenSim/Framework/Servers/VersionInfo.cs
@@ -29,9 +29,8 @@ namespace OpenSim
29{ 29{
30 public class VersionInfo 30 public class VersionInfo
31 { 31 {
32 private const string VERSION_NUMBER = "0.6.9"; 32 private const string VERSION_NUMBER = "0.6.9CM";
33 private const Flavour VERSION_FLAVOUR = Flavour.Dev; 33 private const Flavour VERSION_FLAVOUR = Flavour.Dev;
34
35 public enum Flavour 34 public enum Flavour
36 { 35 {
37 Unknown, 36 Unknown,
diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs
index 25ae6b0..4b9a509 100644
--- a/OpenSim/Framework/TaskInventoryDictionary.cs
+++ b/OpenSim/Framework/TaskInventoryDictionary.cs
@@ -27,9 +27,12 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Threading;
31using System.Reflection;
30using System.Xml; 32using System.Xml;
31using System.Xml.Schema; 33using System.Xml.Schema;
32using System.Xml.Serialization; 34using System.Xml.Serialization;
35using log4net;
33using OpenMetaverse; 36using OpenMetaverse;
34 37
35namespace OpenSim.Framework 38namespace OpenSim.Framework
@@ -45,6 +48,111 @@ namespace OpenSim.Framework
45 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 49
47 private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem)); 50 private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem));
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private Thread LockedByThread;
54 /// <value>
55 /// An advanced lock for inventory data
56 /// </value>
57 private System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
58
59 /// <summary>
60 /// Are we readlocked by the calling thread?
61 /// </summary>
62 public bool IsReadLockedByMe()
63 {
64 if (m_itemLock.RecursiveReadCount > 0)
65 {
66 return true;
67 }
68 else
69 {
70 return false;
71 }
72 }
73
74 /// <summary>
75 /// Lock our inventory list for reading (many can read, one can write)
76 /// </summary>
77 public void LockItemsForRead(bool locked)
78 {
79 if (locked)
80 {
81 if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
82 {
83 if (!LockedByThread.IsAlive)
84 {
85 //Locked by dead thread, reset.
86 m_itemLock = new System.Threading.ReaderWriterLockSlim();
87 }
88 }
89
90 if (m_itemLock.RecursiveReadCount > 0)
91 {
92 m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
93 m_itemLock.ExitReadLock();
94 }
95 if (m_itemLock.RecursiveWriteCount > 0)
96 {
97 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
98 m_itemLock.ExitWriteLock();
99 }
100
101 while (!m_itemLock.TryEnterReadLock(60000))
102 {
103 m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
104 if (m_itemLock.IsWriteLockHeld)
105 {
106 m_itemLock = new System.Threading.ReaderWriterLockSlim();
107 }
108 }
109 }
110 else
111 {
112 if (m_itemLock.RecursiveReadCount>0)
113 {
114 m_itemLock.ExitReadLock();
115 }
116 }
117 }
118
119 /// <summary>
120 /// Lock our inventory list for writing (many can read, one can write)
121 /// </summary>
122 public void LockItemsForWrite(bool locked)
123 {
124 if (locked)
125 {
126 //Enter a write lock, wait indefinately for one to open.
127 if (m_itemLock.RecursiveReadCount > 0)
128 {
129 m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
130 m_itemLock.ExitReadLock();
131 }
132 if (m_itemLock.RecursiveWriteCount > 0)
133 {
134 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
135 m_itemLock.ExitWriteLock();
136 }
137 while (!m_itemLock.TryEnterWriteLock(60000))
138 {
139 m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
140 if (m_itemLock.IsWriteLockHeld)
141 {
142 m_itemLock = new System.Threading.ReaderWriterLockSlim();
143 }
144 }
145
146 LockedByThread = Thread.CurrentThread;
147 }
148 else
149 {
150 if (m_itemLock.RecursiveWriteCount > 0)
151 {
152 m_itemLock.ExitWriteLock();
153 }
154 }
155 }
48 156
49 #region ICloneable Members 157 #region ICloneable Members
50 158
@@ -52,13 +160,12 @@ namespace OpenSim.Framework
52 { 160 {
53 TaskInventoryDictionary clone = new TaskInventoryDictionary(); 161 TaskInventoryDictionary clone = new TaskInventoryDictionary();
54 162
55 lock (this) 163 m_itemLock.EnterReadLock();
164 foreach (UUID uuid in Keys)
56 { 165 {
57 foreach (UUID uuid in Keys) 166 clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
58 {
59 clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
60 }
61 } 167 }
168 m_itemLock.ExitReadLock();
62 169
63 return clone; 170 return clone;
64 } 171 }
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 7215086..58a0d77 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -990,19 +990,19 @@ namespace OpenSim.Framework
990 { 990 {
991 string os = String.Empty; 991 string os = String.Empty;
992 992
993 if (Environment.OSVersion.Platform != PlatformID.Unix) 993// if (Environment.OSVersion.Platform != PlatformID.Unix)
994 { 994// {
995 os = Environment.OSVersion.ToString(); 995// os = Environment.OSVersion.ToString();
996 } 996// }
997 else 997// else
998 { 998// {
999 os = ReadEtcIssue(); 999// os = ReadEtcIssue();
1000 } 1000// }
1001 1001//
1002 if (os.Length > 45) 1002// if (os.Length > 45)
1003 { 1003// {
1004 os = os.Substring(0, 45); 1004// os = os.Substring(0, 45);
1005 } 1005// }
1006 1006
1007 return os; 1007 return os;
1008 } 1008 }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 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/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 3c4fa72..4d9f58f 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -402,6 +402,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
402 #region Queue or Send 402 #region Queue or Send
403 403
404 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); 404 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
405 outgoingPacket.Type = type;
405 406
406 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) 407 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket))
407 SendPacketFinal(outgoingPacket); 408 SendPacketFinal(outgoingPacket);
@@ -513,6 +514,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
513 byte flags = buffer.Data[0]; 514 byte flags = buffer.Data[0];
514 bool isResend = (flags & Helpers.MSG_RESENT) != 0; 515 bool isResend = (flags & Helpers.MSG_RESENT) != 0;
515 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; 516 bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
517 bool sendSynchronous = false;
516 LLUDPClient udpClient = outgoingPacket.Client; 518 LLUDPClient udpClient = outgoingPacket.Client;
517 519
518 if (!udpClient.IsConnected) 520 if (!udpClient.IsConnected)
@@ -568,9 +570,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
568 if (isReliable) 570 if (isReliable)
569 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength); 571 Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength);
570 572
571 // Put the UDP payload on the wire 573 //Some packet types need to be sent synchonously.
572 AsyncBeginSend(buffer); 574 //Sorry, i know it's not optimal, but until the LL client
575 //manages packets correctly and re-orders them as required, this is necessary.
573 576
577
578 // Put the UDP payload on the wire
579 if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate)
580 {
581 SyncBeginPrioritySend(buffer, 2); // highest priority
582 }
583 else if (outgoingPacket.Type == PacketType.ObjectUpdate
584 || outgoingPacket.Type == PacketType.LayerData)
585 {
586 SyncBeginPrioritySend(buffer, 1); // medium priority
587 }
588 else
589 {
590 SyncBeginPrioritySend(buffer, 0); // normal priority
591 }
592
593 //AsyncBeginSend(buffer);
594
574 // Keep track of when this packet was sent out (right now) 595 // Keep track of when this packet was sent out (right now)
575 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; 596 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
576 } 597 }
@@ -851,7 +872,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
851 872
852 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); 873 Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
853 874
854 AsyncBeginSend(buffer); 875 SyncBeginPrioritySend(buffer, 1); //Setting this to a medium priority should help minimise resends
855 } 876 }
856 877
857 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) 878 private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index d2779ba..de2cd24 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
@@ -29,6 +29,7 @@ using System;
29using System.Net; 29using System.Net;
30using System.Net.Sockets; 30using System.Net.Sockets;
31using System.Threading; 31using System.Threading;
32using System.Collections.Generic;
32using log4net; 33using log4net;
33 34
34namespace OpenMetaverse 35namespace OpenMetaverse
@@ -52,12 +53,30 @@ namespace OpenMetaverse
52 /// <summary>Local IP address to bind to in server mode</summary> 53 /// <summary>Local IP address to bind to in server mode</summary>
53 protected IPAddress m_localBindAddress; 54 protected IPAddress m_localBindAddress;
54 55
56 /// <summary>
57 /// Standard queue for our outgoing SyncBeginPrioritySend
58 /// </summary>
59 private List<UDPPacketBuffer> m_standardQueue = new List<UDPPacketBuffer>();
60
61 /// <summary>
62 /// Medium priority queue for our outgoing SyncBeginPrioritySend
63 /// </summary>
64 private List<UDPPacketBuffer> m_mediumPriorityQueue = new List<UDPPacketBuffer>();
65
66 /// <summary>
67 /// Prioritised queue for our outgoing SyncBeginPrioritySend
68 /// </summary>
69 private List<UDPPacketBuffer> m_priorityQueue = new List<UDPPacketBuffer>();
70
55 /// <summary>UDP socket, used in either client or server mode</summary> 71 /// <summary>UDP socket, used in either client or server mode</summary>
56 private Socket m_udpSocket; 72 private Socket m_udpSocket;
57 73
58 /// <summary>Flag to process packets asynchronously or synchronously</summary> 74 /// <summary>Flag to process packets asynchronously or synchronously</summary>
59 private bool m_asyncPacketHandling; 75 private bool m_asyncPacketHandling;
60 76
77 /// <summary>Are we currently sending data asynchronously?</summary>
78 private volatile bool m_sendingData = false;
79
61 /// <summary>The all important shutdown flag</summary> 80 /// <summary>The all important shutdown flag</summary>
62 private volatile bool m_shutdownFlag = true; 81 private volatile bool m_shutdownFlag = true;
63 82
@@ -246,7 +265,51 @@ namespace OpenMetaverse
246 } 265 }
247 } 266 }
248 267
249 public void AsyncBeginSend(UDPPacketBuffer buf) 268 public void SyncBeginPrioritySend(UDPPacketBuffer buf, int Priority)
269 {
270 if (!m_shutdownFlag)
271 {
272 if (!m_sendingData)
273 {
274 m_sendingData = true;
275 try
276 {
277 AsyncBeginSend(buf);
278 }
279 catch (SocketException) { }
280 catch (ObjectDisposedException) { }
281 }
282 else
283 {
284 if (Priority == 2)
285 {
286 lock (m_priorityQueue)
287 {
288 m_priorityQueue.Add(buf);
289 }
290 }
291 else
292 {
293 if (Priority != 0)
294 {
295 lock (m_mediumPriorityQueue)
296 {
297 m_mediumPriorityQueue.Add(buf);
298 }
299 }
300 else
301 {
302 lock (m_standardQueue)
303 {
304 m_standardQueue.Add(buf);
305 }
306 }
307 }
308 }
309 }
310 }
311
312 private void AsyncBeginSend(UDPPacketBuffer buf)
250 { 313 {
251 if (!m_shutdownFlag) 314 if (!m_shutdownFlag)
252 { 315 {
@@ -270,8 +333,48 @@ namespace OpenMetaverse
270 { 333 {
271 try 334 try
272 { 335 {
273// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
274 m_udpSocket.EndSendTo(result); 336 m_udpSocket.EndSendTo(result);
337
338 if (m_sendingData)
339 {
340 lock (m_priorityQueue)
341 {
342 if (m_priorityQueue.Count > 0)
343 {
344 UDPPacketBuffer buf = m_priorityQueue[0];
345 m_priorityQueue.RemoveAt(0);
346 AsyncBeginSend(buf);
347 }
348 else
349 {
350 lock (m_mediumPriorityQueue)
351 {
352 if (m_mediumPriorityQueue.Count > 0)
353 {
354 UDPPacketBuffer buf = m_mediumPriorityQueue[0];
355 m_mediumPriorityQueue.RemoveAt(0);
356 AsyncBeginSend(buf);
357 }
358 else
359 {
360 lock (m_standardQueue)
361 {
362 if (m_standardQueue.Count > 0)
363 {
364 UDPPacketBuffer buf = m_standardQueue[0];
365 m_standardQueue.RemoveAt(0);
366 AsyncBeginSend(buf);
367 }
368 else
369 {
370 m_sendingData = false;
371 }
372 }
373 }
374 }
375 }
376 }
377 }
275 } 378 }
276 catch (SocketException) { } 379 catch (SocketException) { }
277 catch (ObjectDisposedException) { } 380 catch (ObjectDisposedException) { }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
index 1a1a1cb..7dc42d3 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using OpenSim.Framework; 29using OpenSim.Framework;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenMetaverse.Packets;
31 32
32namespace OpenSim.Region.ClientStack.LindenUDP 33namespace OpenSim.Region.ClientStack.LindenUDP
33{ 34{
@@ -52,7 +53,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
52 public int TickCount; 53 public int TickCount;
53 /// <summary>Category this packet belongs to</summary> 54 /// <summary>Category this packet belongs to</summary>
54 public ThrottleOutPacketType Category; 55 public ThrottleOutPacketType Category;
55 56 /// <summary>The type of packet so its delivery method can be determined</summary>
57 public PacketType Type;
56 /// <summary> 58 /// <summary>
57 /// Default constructor 59 /// Default constructor
58 /// </summary> 60 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 6dacbba..e3e8718 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
49 private int m_shoutdistance = 100; 49 private int m_shoutdistance = 100;
50 private int m_whisperdistance = 10; 50 private int m_whisperdistance = 10;
51 private List<Scene> m_scenes = new List<Scene>(); 51 private List<Scene> m_scenes = new List<Scene>();
52 52 private string m_adminPrefix = "";
53 internal object m_syncy = new object(); 53 internal object m_syncy = new object();
54 54
55 internal IConfig m_config; 55 internal IConfig m_config;
@@ -76,6 +76,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
76 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 76 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
77 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 77 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
78 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 78 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
79 m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
79 } 80 }
80 81
81 public virtual void AddRegion(Scene scene) 82 public virtual void AddRegion(Scene scene)
@@ -185,6 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
185 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) 186 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
186 { 187 {
187 string fromName = c.From; 188 string fromName = c.From;
189 string fromNamePrefix = "";
188 UUID fromID = UUID.Zero; 190 UUID fromID = UUID.Zero;
189 string message = c.Message; 191 string message = c.Message;
190 IScene scene = c.Scene; 192 IScene scene = c.Scene;
@@ -207,7 +209,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
207 fromPos = avatar.AbsolutePosition; 209 fromPos = avatar.AbsolutePosition;
208 fromName = avatar.Name; 210 fromName = avatar.Name;
209 fromID = c.Sender.AgentId; 211 fromID = c.Sender.AgentId;
210 212 if (avatar.GodLevel > 200)
213 {
214 fromNamePrefix = m_adminPrefix;
215 }
211 break; 216 break;
212 217
213 case ChatSourceType.Object: 218 case ChatSourceType.Object:
@@ -227,7 +232,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
227 s.ForEachScenePresence( 232 s.ForEachScenePresence(
228 delegate(ScenePresence presence) 233 delegate(ScenePresence presence)
229 { 234 {
230 TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType); 235 TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix+fromName, c.Type, message, sourceType);
231 } 236 }
232 ); 237 );
233 } 238 }
@@ -266,25 +271,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
266 } 271 }
267 272
268 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 273 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
269 274 if (c.Scene != null)
270 ((Scene)c.Scene).ForEachScenePresence( 275 {
271 delegate(ScenePresence presence) 276 ((Scene)c.Scene).ForEachScenePresence
272 { 277 (
273 // ignore chat from child agents 278 delegate(ScenePresence presence)
274 if (presence.IsChildAgent) return; 279 {
275 280 // ignore chat from child agents
276 IClientAPI client = presence.ControllingClient; 281 if (presence.IsChildAgent) return;
277 282
278 // don't forward SayOwner chat from objects to 283 IClientAPI client = presence.ControllingClient;
279 // non-owner agents 284
280 if ((c.Type == ChatTypeEnum.Owner) && 285 // don't forward SayOwner chat from objects to
281 (null != c.SenderObject) && 286 // non-owner agents
282 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 287 if ((c.Type == ChatTypeEnum.Owner) &&
283 return; 288 (null != c.SenderObject) &&
284 289 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
285 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, 290 return;
286 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 291
287 }); 292 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
293 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
294 }
295 );
296 }
288 } 297 }
289 298
290 299
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 1614b70..7f9e5af 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -164,19 +164,22 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
164 List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>( 164 List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
165 "POST", m_RestURL+"/RetrieveMessages/", client.AgentId); 165 "POST", m_RestURL+"/RetrieveMessages/", client.AgentId);
166 166
167 foreach (GridInstantMessage im in msglist) 167 if (msglist != null)
168 { 168 {
169 // client.SendInstantMessage(im); 169 foreach (GridInstantMessage im in msglist)
170 170 {
171 // Send through scene event manager so all modules get a chance 171 // client.SendInstantMessage(im);
172 // to look at this message before it gets delivered. 172
173 // 173 // Send through scene event manager so all modules get a chance
174 // Needed for proper state management for stored group 174 // to look at this message before it gets delivered.
175 // invitations 175 //
176 // 176 // Needed for proper state management for stored group
177 Scene s = FindScene(client.AgentId); 177 // invitations
178 if (s != null) 178 //
179 s.EventManager.TriggerIncomingInstantMessage(im); 179 Scene s = FindScene(client.AgentId);
180 if (s != null)
181 s.EventManager.TriggerIncomingInstantMessage(im);
182 }
180 } 183 }
181 } 184 }
182 185
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index d9a021f..b60b32b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -389,7 +389,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
389 { 389 {
390 // Check if this is ours to handle 390 // Check if this is ours to handle
391 // 391 //
392 m_log.Info("OnFridInstantMessage"); 392 //m_log.Info("OnFridInstantMessage");
393 if (msg.dialog != (byte) InstantMessageDialog.InventoryOffered) 393 if (msg.dialog != (byte) InstantMessageDialog.InventoryOffered)
394 return; 394 return;
395 395
diff --git a/OpenSim/Region/CoreModules/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..f180b47
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs
@@ -0,0 +1,245 @@
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 }
75
76 InstallCommands();
77
78 m_log.Debug("[WINDLIGHT]: Initialised windlight module");
79 }
80 public void SendProfileToClient(ScenePresence presence)
81 {
82 if (m_enableWindlight)
83 {
84 if (presence.IsChildAgent == false)
85 {
86 IClientAPI client = presence.ControllingClient;
87 RegionMeta7WindlightData wl = m_scene.RegionInfo.WindlightSettings;
88 byte[] mBlock = new Byte[249];
89 int pos = 0;
90
91 wl.waterColor.ToBytes(mBlock, 0); pos += 12;
92 Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4;
93 Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4;
94 wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12;
95 Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4;
96 Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4;
97 Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4;
98 Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4;
99 Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4;
100 wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8;
101 wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8;
102 wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16;
103 wl.horizon.ToBytes(mBlock, pos); pos += 16;
104 Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4;
105 wl.blueDensity.ToBytes(mBlock, pos); pos += 16;
106 Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4;
107 Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4;
108 Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4;
109 wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16;
110 Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4;
111 wl.ambient.ToBytes(mBlock, pos); pos += 16;
112 Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4;
113 Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4;
114 Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4;
115 Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4;
116 Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4;
117 wl.cloudColor.ToBytes(mBlock, pos); pos += 16;
118 wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12;
119 Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4;
120 Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4;
121 wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12;
122 Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4;
123 Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4;
124 Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2;
125 mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++;
126 mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++;
127 mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++;
128 List<byte[]> param = new List<byte[]>();
129 param.Add(mBlock);
130
131 client.SendGenericMessage("Windlight", param);
132 }
133 }
134 else
135 {
136 //We probably don't want to spam chat with this.. probably
137 //m_log.Debug("[WINDLIGHT]: Module disabled");
138 }
139 }
140 private void EventManager_OnMakeRootAgent(ScenePresence presence)
141 {
142 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
143 SendProfileToClient(presence);
144 }
145
146 private void EventManager_OnSaveNewWindlightProfile()
147 {
148 m_scene.ForEachScenePresence(SendProfileToClient);
149 }
150
151 public void PostInitialise()
152 {
153
154 }
155
156 public void Close()
157 {
158 }
159
160 public string Name
161 {
162 get { return "Meta7WindlightModule"; }
163 }
164
165 public bool IsSharedModule
166 {
167 get { return false; }
168 }
169
170 #endregion
171
172 #region events
173
174 #endregion
175
176 #region ICommandableModule Members
177
178 private void InstallCommands()
179 {
180 Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast");
181 Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin");
182 Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Enable the windlight plugin");
183
184 m_commander.RegisterCommand("load", wlload);
185 m_commander.RegisterCommand("enable", wlenable);
186 m_commander.RegisterCommand("disable", wldisable);
187
188 m_scene.RegisterModuleCommander(m_commander);
189 }
190
191 private void HandleLoad(Object[] args)
192 {
193 if (!m_enableWindlight)
194 {
195 m_log.InfoFormat("[WINDLIGHT]: Cannot load windlight profile, module disabled. Use 'windlight enable' first.");
196 }
197 else
198 {
199 m_log.InfoFormat("[WINDLIGHT]: Loading Windlight profile from database");
200 m_scene.LoadWindlightProfile();
201 m_log.InfoFormat("[WINDLIGHT]: Load complete");
202 }
203 }
204
205 private void HandleDisable(Object[] args)
206 {
207 m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled");
208 m_enableWindlight=false;
209 }
210
211 private void HandleEnable(Object[] args)
212 {
213 m_log.InfoFormat("[WINDLIGHT]: Plugin now enabled");
214 m_enableWindlight = true;
215 }
216
217 /// <summary>
218 /// Processes commandline input. Do not call directly.
219 /// </summary>
220 /// <param name="args">Commandline arguments</param>
221 private void EventManager_OnPluginConsole(string[] args)
222 {
223 if (args[0] == "windlight")
224 {
225 if (args.Length == 1)
226 {
227 m_commander.ProcessConsoleCommand("add", new string[0]);
228 return;
229 }
230
231 string[] tmpArgs = new string[args.Length - 2];
232 int i;
233 for (i = 2; i < args.Length; i++)
234 {
235 tmpArgs[i - 2] = args[i];
236 }
237
238 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
239 }
240 }
241 #endregion
242
243 }
244}
245
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..a86e263 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -193,7 +193,9 @@ 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();
196 public event OnMakeRootAgentDelegate OnMakeRootAgent; 197 public event OnMakeRootAgentDelegate OnMakeRootAgent;
198 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
197 199
198 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); 200 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
199 201
@@ -411,6 +413,7 @@ namespace OpenSim.Region.Framework.Scenes
411 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage; 413 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage;
412 private ClientClosed handlerClientClosed = null; //OnClientClosed; 414 private ClientClosed handlerClientClosed = null; //OnClientClosed;
413 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; 415 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
416 private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile;
414 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent; 417 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent;
415 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; 418 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
416 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; 419 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
@@ -772,6 +775,15 @@ namespace OpenSim.Region.Framework.Scenes
772 } 775 }
773 } 776 }
774 777
778 public void TriggerOnSaveNewWindlightProfile()
779 {
780 handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
781 if (handlerSaveNewWindlightProfile != null)
782 {
783 handlerSaveNewWindlightProfile();
784 }
785 }
786
775 public void TriggerOnMakeRootAgent(ScenePresence presence) 787 public void TriggerOnMakeRootAgent(ScenePresence presence)
776 { 788 {
777 handlerMakeRootAgent = OnMakeRootAgent; 789 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 eb284c1..104d22b 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();
@@ -1506,6 +1520,19 @@ namespace OpenSim.Region.Framework.Scenes
1506 { 1520 {
1507 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1521 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1508 } 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();
1535 }
1509 1536
1510 /// <summary> 1537 /// <summary>
1511 /// Loads the World heightmap 1538 /// Loads the World heightmap
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..a23c11e 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
@@ -508,9 +513,16 @@ namespace OpenSim.Region.Framework.Scenes
508 { 513 {
509 // If this is a linkset, we don't want the physics engine mucking up our group position here. 514 // If this is a linkset, we don't want the physics engine mucking up our group position here.
510 PhysicsActor actor = PhysActor; 515 PhysicsActor actor = PhysActor;
511 if (actor != null && _parentID == 0) 516 if (actor != null)
512 { 517 {
513 m_groupPosition = actor.Position; 518 if (_parentID == 0)
519 {
520 m_groupPosition = actor.Position;
521 }
522 else
523 {
524 m_groupPosition = ParentGroup.AbsolutePosition; // KF+Casper Update Child prims too!
525 }
514 } 526 }
515 527
516 if (IsAttachment) 528 if (IsAttachment)
@@ -837,7 +849,8 @@ namespace OpenSim.Region.Framework.Scenes
837 if (IsAttachment) 849 if (IsAttachment)
838 return GroupPosition; 850 return GroupPosition;
839 851
840 return m_offsetPosition + m_groupPosition; } 852// return m_offsetPosition + m_groupPosition; }
853 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
841 } 854 }
842 855
843 public SceneObjectGroup ParentGroup 856 public SceneObjectGroup ParentGroup
@@ -989,6 +1002,13 @@ namespace OpenSim.Region.Framework.Scenes
989 get { return _flags; } 1002 get { return _flags; }
990 set { _flags = value; } 1003 set { _flags = value; }
991 } 1004 }
1005
1006 [XmlIgnore]
1007 public bool IsOccupied // KF If an av is sittingon this prim
1008 {
1009 get { return m_occupied; }
1010 set { m_occupied = value; }
1011 }
992 1012
993 [XmlIgnore] 1013 [XmlIgnore]
994 public UUID SitTargetAvatar 1014 public UUID SitTargetAvatar
@@ -1064,14 +1084,6 @@ namespace OpenSim.Region.Framework.Scenes
1064 } 1084 }
1065 } 1085 }
1066 1086
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) 1087 private void SendObjectPropertiesToClient(UUID AgentID)
1076 { 1088 {
1077 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 1089 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -1739,9 +1751,13 @@ namespace OpenSim.Region.Framework.Scenes
1739 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1751 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1740 1752
1741 Vector3 axPos = OffsetPosition; 1753 Vector3 axPos = OffsetPosition;
1742
1743 axPos *= parentRot; 1754 axPos *= parentRot;
1744 Vector3 translationOffsetPosition = axPos; 1755 Vector3 translationOffsetPosition = axPos;
1756
1757 int tx = (int)GroupPosition.X;
1758 int ty = (int)GroupPosition.Y;
1759 int tz = (int)GroupPosition.Z;
1760
1745 return GroupPosition + translationOffsetPosition; 1761 return GroupPosition + translationOffsetPosition;
1746 } 1762 }
1747 1763
@@ -2109,17 +2125,18 @@ namespace OpenSim.Region.Framework.Scenes
2109 //Trys to fetch sound id from prim's inventory. 2125 //Trys to fetch sound id from prim's inventory.
2110 //Prim's inventory doesn't support non script items yet 2126 //Prim's inventory doesn't support non script items yet
2111 2127
2112 lock (TaskInventory) 2128 TaskInventory.LockItemsForRead(true);
2129
2130 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2113 { 2131 {
2114 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2132 if (item.Value.Name == sound)
2115 { 2133 {
2116 if (item.Value.Name == sound) 2134 soundID = item.Value.ItemID;
2117 { 2135 break;
2118 soundID = item.Value.ItemID;
2119 break;
2120 }
2121 } 2136 }
2122 } 2137 }
2138
2139 TaskInventory.LockItemsForRead(false);
2123 } 2140 }
2124 2141
2125 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); 2142 List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars();
@@ -2185,6 +2202,11 @@ namespace OpenSim.Region.Framework.Scenes
2185 ParentGroup.HasGroupChanged = true; 2202 ParentGroup.HasGroupChanged = true;
2186 ScheduleFullUpdate(); 2203 ScheduleFullUpdate();
2187 } 2204 }
2205
2206 public void RotLookAt(Quaternion target, float strength, float damping)
2207 {
2208 m_parentGroup.rotLookAt(target, strength, damping);
2209 }
2188 2210
2189 /// <summary> 2211 /// <summary>
2190 /// Schedules this prim for a full update 2212 /// Schedules this prim for a full update
@@ -2389,8 +2411,8 @@ namespace OpenSim.Region.Framework.Scenes
2389 { 2411 {
2390 const float ROTATION_TOLERANCE = 0.01f; 2412 const float ROTATION_TOLERANCE = 0.01f;
2391 const float VELOCITY_TOLERANCE = 0.001f; 2413 const float VELOCITY_TOLERANCE = 0.001f;
2392 const float POSITION_TOLERANCE = 0.05f; 2414 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
2393 const int TIME_MS_TOLERANCE = 3000; 2415 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
2394 2416
2395 if (m_updateFlag == 1) 2417 if (m_updateFlag == 1)
2396 { 2418 {
@@ -2404,7 +2426,7 @@ namespace OpenSim.Region.Framework.Scenes
2404 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 2426 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
2405 { 2427 {
2406 AddTerseUpdateToAllAvatars(); 2428 AddTerseUpdateToAllAvatars();
2407 ClearUpdateSchedule(); 2429
2408 2430
2409 // This causes the Scene to 'poll' physical objects every couple of frames 2431 // This causes the Scene to 'poll' physical objects every couple of frames
2410 // bad, so it's been replaced by an event driven method. 2432 // bad, so it's been replaced by an event driven method.
@@ -2422,16 +2444,18 @@ namespace OpenSim.Region.Framework.Scenes
2422 m_lastAngularVelocity = AngularVelocity; 2444 m_lastAngularVelocity = AngularVelocity;
2423 m_lastTerseSent = Environment.TickCount; 2445 m_lastTerseSent = Environment.TickCount;
2424 } 2446 }
2447 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
2448 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
2425 } 2449 }
2426 else 2450 else
2427 { 2451 {
2428 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 2452 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
2429 { 2453 {
2430 AddFullUpdateToAllAvatars(); 2454 AddFullUpdateToAllAvatars();
2431 ClearUpdateSchedule(); 2455 m_updateFlag = 0; //Same here
2432 } 2456 }
2433 } 2457 }
2434 ClearUpdateSchedule(); 2458 m_updateFlag = 0;
2435 } 2459 }
2436 2460
2437 /// <summary> 2461 /// <summary>
@@ -2458,17 +2482,16 @@ namespace OpenSim.Region.Framework.Scenes
2458 if (!UUID.TryParse(sound, out soundID)) 2482 if (!UUID.TryParse(sound, out soundID))
2459 { 2483 {
2460 // search sound file from inventory 2484 // search sound file from inventory
2461 lock (TaskInventory) 2485 TaskInventory.LockItemsForRead(true);
2486 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2462 { 2487 {
2463 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2488 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
2464 { 2489 {
2465 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 2490 soundID = item.Value.ItemID;
2466 { 2491 break;
2467 soundID = item.Value.ItemID;
2468 break;
2469 }
2470 } 2492 }
2471 } 2493 }
2494 TaskInventory.LockItemsForRead(false);
2472 } 2495 }
2473 2496
2474 if (soundID == UUID.Zero) 2497 if (soundID == UUID.Zero)
@@ -2684,6 +2707,13 @@ namespace OpenSim.Region.Framework.Scenes
2684 SetText(text); 2707 SetText(text);
2685 } 2708 }
2686 2709
2710 public void StopLookAt()
2711 {
2712 m_parentGroup.stopLookAt();
2713
2714 m_parentGroup.ScheduleGroupForTerseUpdate();
2715 }
2716
2687 public void StopMoveToTarget() 2717 public void StopMoveToTarget()
2688 { 2718 {
2689 m_parentGroup.stopMoveToTarget(); 2719 m_parentGroup.stopMoveToTarget();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 22eedba..b57d912 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -80,7 +80,9 @@ namespace OpenSim.Region.Framework.Scenes
80 /// </value> 80 /// </value>
81 protected internal TaskInventoryDictionary Items 81 protected internal TaskInventoryDictionary Items
82 { 82 {
83 get { return m_items; } 83 get {
84 return m_items;
85 }
84 set 86 set
85 { 87 {
86 m_items = value; 88 m_items = value;
@@ -116,22 +118,25 @@ namespace OpenSim.Region.Framework.Scenes
116 /// <param name="linkNum">Link number for the part</param> 118 /// <param name="linkNum">Link number for the part</param>
117 public void ResetInventoryIDs() 119 public void ResetInventoryIDs()
118 { 120 {
119 lock (Items) 121 m_items.LockItemsForWrite(true);
122
123 if (0 == Items.Count)
120 { 124 {
121 if (0 == Items.Count) 125 m_items.LockItemsForWrite(false);
122 return; 126 return;
127 }
123 128
124 HasInventoryChanged = true; 129 HasInventoryChanged = true;
125 m_part.ParentGroup.HasGroupChanged = true; 130 m_part.ParentGroup.HasGroupChanged = true;
126 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 131 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
127 Items.Clear(); 132 Items.Clear();
128 133
129 foreach (TaskInventoryItem item in items) 134 foreach (TaskInventoryItem item in items)
130 { 135 {
131 item.ResetIDs(m_part.UUID); 136 item.ResetIDs(m_part.UUID);
132 Items.Add(item.ItemID, item); 137 Items.Add(item.ItemID, item);
133 }
134 } 138 }
139 m_items.LockItemsForWrite(false);
135 } 140 }
136 141
137 /// <summary> 142 /// <summary>
@@ -140,25 +145,25 @@ namespace OpenSim.Region.Framework.Scenes
140 /// <param name="ownerId"></param> 145 /// <param name="ownerId"></param>
141 public void ChangeInventoryOwner(UUID ownerId) 146 public void ChangeInventoryOwner(UUID ownerId)
142 { 147 {
143 lock (Items) 148 m_items.LockItemsForWrite(true);
149 if (0 == Items.Count)
144 { 150 {
145 if (0 == Items.Count) 151 m_items.LockItemsForWrite(false);
146 { 152 return;
147 return; 153 }
148 }
149 154
150 HasInventoryChanged = true; 155 HasInventoryChanged = true;
151 m_part.ParentGroup.HasGroupChanged = true; 156 m_part.ParentGroup.HasGroupChanged = true;
152 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 157 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
153 foreach (TaskInventoryItem item in items) 158 foreach (TaskInventoryItem item in items)
159 {
160 if (ownerId != item.OwnerID)
154 { 161 {
155 if (ownerId != item.OwnerID) 162 item.LastOwnerID = item.OwnerID;
156 { 163 item.OwnerID = ownerId;
157 item.LastOwnerID = item.OwnerID;
158 item.OwnerID = ownerId;
159 }
160 } 164 }
161 } 165 }
166 m_items.LockItemsForWrite(false);
162 } 167 }
163 168
164 /// <summary> 169 /// <summary>
@@ -167,24 +172,24 @@ namespace OpenSim.Region.Framework.Scenes
167 /// <param name="groupID"></param> 172 /// <param name="groupID"></param>
168 public void ChangeInventoryGroup(UUID groupID) 173 public void ChangeInventoryGroup(UUID groupID)
169 { 174 {
170 lock (Items) 175 m_items.LockItemsForWrite(true);
176 if (0 == Items.Count)
171 { 177 {
172 if (0 == Items.Count) 178 m_items.LockItemsForWrite(false);
173 { 179 return;
174 return; 180 }
175 }
176 181
177 HasInventoryChanged = true; 182 HasInventoryChanged = true;
178 m_part.ParentGroup.HasGroupChanged = true; 183 m_part.ParentGroup.HasGroupChanged = true;
179 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 184 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
180 foreach (TaskInventoryItem item in items) 185 foreach (TaskInventoryItem item in items)
186 {
187 if (groupID != item.GroupID)
181 { 188 {
182 if (groupID != item.GroupID) 189 item.GroupID = groupID;
183 {
184 item.GroupID = groupID;
185 }
186 } 190 }
187 } 191 }
192 m_items.LockItemsForWrite(false);
188 } 193 }
189 194
190 /// <summary> 195 /// <summary>
@@ -192,14 +197,14 @@ namespace OpenSim.Region.Framework.Scenes
192 /// </summary> 197 /// </summary>
193 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 198 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
194 { 199 {
195 lock (m_items) 200 Items.LockItemsForRead(true);
201 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
202 Items.LockItemsForRead(false);
203 foreach (TaskInventoryItem item in items)
196 { 204 {
197 foreach (TaskInventoryItem item in Items.Values) 205 if ((int)InventoryType.LSL == item.InvType)
198 { 206 {
199 if ((int)InventoryType.LSL == item.InvType) 207 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
200 {
201 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
202 }
203 } 208 }
204 } 209 }
205 } 210 }
@@ -209,17 +214,20 @@ namespace OpenSim.Region.Framework.Scenes
209 /// </summary> 214 /// </summary>
210 public void RemoveScriptInstances() 215 public void RemoveScriptInstances()
211 { 216 {
212 lock (Items) 217 Items.LockItemsForRead(true);
218 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
219 Items.LockItemsForRead(false);
220
221 foreach (TaskInventoryItem item in items)
213 { 222 {
214 foreach (TaskInventoryItem item in Items.Values) 223 if ((int)InventoryType.LSL == item.InvType)
215 { 224 {
216 if ((int)InventoryType.LSL == item.InvType) 225 RemoveScriptInstance(item.ItemID);
217 { 226 m_part.RemoveScriptEvents(item.ItemID);
218 RemoveScriptInstance(item.ItemID);
219 m_part.RemoveScriptEvents(item.ItemID);
220 }
221 } 227 }
222 } 228 }
229
230
223 } 231 }
224 232
225 /// <summary> 233 /// <summary>
@@ -244,8 +252,10 @@ namespace OpenSim.Region.Framework.Scenes
244 if (stateSource == 1 && // Prim crossing 252 if (stateSource == 1 && // Prim crossing
245 m_part.ParentGroup.Scene.m_trustBinaries) 253 m_part.ParentGroup.Scene.m_trustBinaries)
246 { 254 {
255 m_items.LockItemsForWrite(true);
247 m_items[item.ItemID].PermsMask = 0; 256 m_items[item.ItemID].PermsMask = 0;
248 m_items[item.ItemID].PermsGranter = UUID.Zero; 257 m_items[item.ItemID].PermsGranter = UUID.Zero;
258 m_items.LockItemsForWrite(false);
249 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 259 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
250 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 260 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
251 m_part.ParentGroup.AddActiveScriptCount(1); 261 m_part.ParentGroup.AddActiveScriptCount(1);
@@ -267,8 +277,10 @@ namespace OpenSim.Region.Framework.Scenes
267 { 277 {
268 if (m_part.ParentGroup.m_savedScriptState != null) 278 if (m_part.ParentGroup.m_savedScriptState != null)
269 RestoreSavedScriptState(item.OldItemID, item.ItemID); 279 RestoreSavedScriptState(item.OldItemID, item.ItemID);
280 m_items.LockItemsForWrite(true);
270 m_items[item.ItemID].PermsMask = 0; 281 m_items[item.ItemID].PermsMask = 0;
271 m_items[item.ItemID].PermsGranter = UUID.Zero; 282 m_items[item.ItemID].PermsGranter = UUID.Zero;
283 m_items.LockItemsForWrite(false);
272 string script = Utils.BytesToString(asset.Data); 284 string script = Utils.BytesToString(asset.Data);
273 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 285 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
274 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 286 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
@@ -303,14 +315,17 @@ namespace OpenSim.Region.Framework.Scenes
303 /// </param> 315 /// </param>
304 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 316 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
305 { 317 {
306 lock (m_items) 318 m_items.LockItemsForRead(true);
319 if (m_items.ContainsKey(itemId))
307 { 320 {
308 if (m_items.ContainsKey(itemId)) 321 if (m_items.ContainsKey(itemId))
309 { 322 {
323 m_items.LockItemsForRead(false);
310 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 324 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
311 } 325 }
312 else 326 else
313 { 327 {
328 m_items.LockItemsForRead(false);
314 m_log.ErrorFormat( 329 m_log.ErrorFormat(
315 "[PRIM INVENTORY]: " + 330 "[PRIM INVENTORY]: " +
316 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 331 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
@@ -318,6 +333,15 @@ namespace OpenSim.Region.Framework.Scenes
318 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 333 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
319 } 334 }
320 } 335 }
336 else
337 {
338 m_items.LockItemsForRead(false);
339 m_log.ErrorFormat(
340 "[PRIM INVENTORY]: " +
341 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
342 itemId, m_part.Name, m_part.UUID);
343 }
344
321 } 345 }
322 346
323 /// <summary> 347 /// <summary>
@@ -349,11 +373,16 @@ namespace OpenSim.Region.Framework.Scenes
349 /// <returns></returns> 373 /// <returns></returns>
350 private bool InventoryContainsName(string name) 374 private bool InventoryContainsName(string name)
351 { 375 {
352 foreach (TaskInventoryItem item in Items.Values) 376 m_items.LockItemsForRead(true);
377 foreach (TaskInventoryItem item in m_items.Values)
353 { 378 {
354 if (item.Name == name) 379 if (item.Name == name)
380 {
381 m_items.LockItemsForRead(false);
355 return true; 382 return true;
383 }
356 } 384 }
385 m_items.LockItemsForRead(false);
357 return false; 386 return false;
358 } 387 }
359 388
@@ -395,7 +424,9 @@ namespace OpenSim.Region.Framework.Scenes
395 /// <param name="item"></param> 424 /// <param name="item"></param>
396 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 425 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
397 { 426 {
427 m_items.LockItemsForRead(true);
398 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); 428 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
429 m_items.LockItemsForRead(false);
399 foreach (TaskInventoryItem i in il) 430 foreach (TaskInventoryItem i in il)
400 { 431 {
401 if (i.Name == item.Name) 432 if (i.Name == item.Name)
@@ -432,15 +463,14 @@ namespace OpenSim.Region.Framework.Scenes
432 item.ParentPartID = m_part.UUID; 463 item.ParentPartID = m_part.UUID;
433 item.Name = name; 464 item.Name = name;
434 465
435 lock (m_items) 466 m_items.LockItemsForWrite(true);
436 { 467 m_items.Add(item.ItemID, item);
437 m_items.Add(item.ItemID, item); 468 m_items.LockItemsForWrite(false);
438
439 if (allowedDrop) 469 if (allowedDrop)
440 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 470 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
441 else 471 else
442 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 472 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
443 } 473
444 474
445 m_inventorySerial++; 475 m_inventorySerial++;
446 //m_inventorySerial += 2; 476 //m_inventorySerial += 2;
@@ -457,14 +487,13 @@ namespace OpenSim.Region.Framework.Scenes
457 /// <param name="items"></param> 487 /// <param name="items"></param>
458 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 488 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
459 { 489 {
460 lock (m_items) 490 m_items.LockItemsForWrite(true);
491 foreach (TaskInventoryItem item in items)
461 { 492 {
462 foreach (TaskInventoryItem item in items) 493 m_items.Add(item.ItemID, item);
463 { 494 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
464 m_items.Add(item.ItemID, item);
465 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
466 }
467 } 495 }
496 m_items.LockItemsForWrite(false);
468 497
469 m_inventorySerial++; 498 m_inventorySerial++;
470 } 499 }
@@ -477,8 +506,9 @@ namespace OpenSim.Region.Framework.Scenes
477 public TaskInventoryItem GetInventoryItem(UUID itemId) 506 public TaskInventoryItem GetInventoryItem(UUID itemId)
478 { 507 {
479 TaskInventoryItem item; 508 TaskInventoryItem item;
509 m_items.LockItemsForRead(true);
480 m_items.TryGetValue(itemId, out item); 510 m_items.TryGetValue(itemId, out item);
481 511 m_items.LockItemsForRead(false);
482 return item; 512 return item;
483 } 513 }
484 514
@@ -490,46 +520,46 @@ namespace OpenSim.Region.Framework.Scenes
490 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 520 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
491 public bool UpdateInventoryItem(TaskInventoryItem item) 521 public bool UpdateInventoryItem(TaskInventoryItem item)
492 { 522 {
493 lock (m_items) 523 m_items.LockItemsForWrite(true);
524
525 if (m_items.ContainsKey(item.ItemID))
494 { 526 {
495 if (m_items.ContainsKey(item.ItemID)) 527 item.ParentID = m_part.UUID;
528 item.ParentPartID = m_part.UUID;
529 item.Flags = m_items[item.ItemID].Flags;
530 if (item.AssetID == UUID.Zero)
496 { 531 {
497 item.ParentID = m_part.UUID; 532 item.AssetID = m_items[item.ItemID].AssetID;
498 item.ParentPartID = m_part.UUID; 533 }
499 item.Flags = m_items[item.ItemID].Flags; 534 else if ((InventoryType)item.Type == InventoryType.Notecard)
500 if (item.AssetID == UUID.Zero) 535 {
501 { 536 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
502 item.AssetID = m_items[item.ItemID].AssetID;
503 }
504 else if ((InventoryType)item.Type == InventoryType.Notecard)
505 {
506 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
507 537
508 if (presence != null) 538 if (presence != null)
509 { 539 {
510 presence.ControllingClient.SendAgentAlertMessage( 540 presence.ControllingClient.SendAgentAlertMessage(
511 "Notecard saved", false); 541 "Notecard saved", false);
512 }
513 } 542 }
543 }
514 544
515 m_items[item.ItemID] = item; 545 m_items[item.ItemID] = item;
516 m_inventorySerial++; 546 m_inventorySerial++;
517 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 547 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
518
519 HasInventoryChanged = true;
520 m_part.ParentGroup.HasGroupChanged = true;
521 548
522 return true; 549 HasInventoryChanged = true;
523 } 550 m_part.ParentGroup.HasGroupChanged = true;
524 else 551 m_items.LockItemsForWrite(false);
525 { 552 return true;
526 m_log.ErrorFormat( 553 }
527 "[PRIM INVENTORY]: " + 554 else
528 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 555 {
529 item.ItemID, m_part.Name, m_part.UUID, 556 m_log.ErrorFormat(
530 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 557 "[PRIM INVENTORY]: " +
531 } 558 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
559 item.ItemID, m_part.Name, m_part.UUID,
560 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
532 } 561 }
562 m_items.LockItemsForWrite(false);
533 563
534 return false; 564 return false;
535 } 565 }
@@ -542,52 +572,54 @@ namespace OpenSim.Region.Framework.Scenes
542 /// in this prim's inventory.</returns> 572 /// in this prim's inventory.</returns>
543 public int RemoveInventoryItem(UUID itemID) 573 public int RemoveInventoryItem(UUID itemID)
544 { 574 {
545 lock (m_items) 575 m_items.LockItemsForRead(true);
576
577 if (m_items.ContainsKey(itemID))
546 { 578 {
547 if (m_items.ContainsKey(itemID)) 579 int type = m_items[itemID].InvType;
580 m_items.LockItemsForRead(false);
581 if (type == 10) // Script
548 { 582 {
549 int type = m_items[itemID].InvType; 583 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
550 if (type == 10) // Script 584 }
551 { 585 m_items.LockItemsForWrite(true);
552 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 586 m_items.Remove(itemID);
553 } 587 m_items.LockItemsForWrite(false);
554 m_items.Remove(itemID); 588 m_inventorySerial++;
555 m_inventorySerial++; 589 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
556 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
557
558 HasInventoryChanged = true;
559 m_part.ParentGroup.HasGroupChanged = true;
560 590
561 int scriptcount = 0; 591 HasInventoryChanged = true;
562 lock (m_items) 592 m_part.ParentGroup.HasGroupChanged = true;
563 {
564 foreach (TaskInventoryItem item in m_items.Values)
565 {
566 if (item.Type == 10)
567 {
568 scriptcount++;
569 }
570 }
571 }
572 593
573 if (scriptcount <= 0) 594 int scriptcount = 0;
595 m_items.LockItemsForRead(true);
596 foreach (TaskInventoryItem item in m_items.Values)
597 {
598 if (item.Type == 10)
574 { 599 {
575 m_part.RemFlag(PrimFlags.Scripted); 600 scriptcount++;
576 } 601 }
577
578 m_part.ScheduleFullUpdate();
579
580 return type;
581 } 602 }
582 else 603 m_items.LockItemsForRead(false);
604
605
606 if (scriptcount <= 0)
583 { 607 {
584 m_log.ErrorFormat( 608 m_part.RemFlag(PrimFlags.Scripted);
585 "[PRIM INVENTORY]: " +
586 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
587 itemID, m_part.Name, m_part.UUID,
588 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
589 } 609 }
610
611 m_part.ScheduleFullUpdate();
612
613 return type;
614 }
615 else
616 {
617 m_log.ErrorFormat(
618 "[PRIM INVENTORY]: " +
619 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
620 itemID, m_part.Name, m_part.UUID);
590 } 621 }
622 m_items.LockItemsForWrite(false);
591 623
592 return -1; 624 return -1;
593 } 625 }
@@ -640,52 +672,53 @@ namespace OpenSim.Region.Framework.Scenes
640 // isn't available (such as drag from prim inventory to agent inventory) 672 // isn't available (such as drag from prim inventory to agent inventory)
641 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 673 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
642 674
643 lock (m_items) 675 m_items.LockItemsForRead(true);
676
677 foreach (TaskInventoryItem item in m_items.Values)
644 { 678 {
645 foreach (TaskInventoryItem item in m_items.Values) 679 UUID ownerID = item.OwnerID;
646 { 680 uint everyoneMask = 0;
647 UUID ownerID = item.OwnerID; 681 uint baseMask = item.BasePermissions;
648 uint everyoneMask = 0; 682 uint ownerMask = item.CurrentPermissions;
649 uint baseMask = item.BasePermissions;
650 uint ownerMask = item.CurrentPermissions;
651 683
652 invString.AddItemStart(); 684 invString.AddItemStart();
653 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 685 invString.AddNameValueLine("item_id", item.ItemID.ToString());
654 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 686 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
655 687
656 invString.AddPermissionsStart(); 688 invString.AddPermissionsStart();
657 689
658 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 690 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
659 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 691 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
660 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); 692 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0));
661 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 693 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
662 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 694 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
663 695
664 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 696 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
665 invString.AddNameValueLine("owner_id", ownerID.ToString()); 697 invString.AddNameValueLine("owner_id", ownerID.ToString());
666 698
667 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 699 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
668 700
669 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 701 invString.AddNameValueLine("group_id", item.GroupID.ToString());
670 invString.AddSectionEnd(); 702 invString.AddSectionEnd();
671 703
672 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 704 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
673 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 705 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
674 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 706 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
675 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 707 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
676 708
677 invString.AddSaleStart(); 709 invString.AddSaleStart();
678 invString.AddNameValueLine("sale_type", "not"); 710 invString.AddNameValueLine("sale_type", "not");
679 invString.AddNameValueLine("sale_price", "0"); 711 invString.AddNameValueLine("sale_price", "0");
680 invString.AddSectionEnd(); 712 invString.AddSectionEnd();
681 713
682 invString.AddNameValueLine("name", item.Name + "|"); 714 invString.AddNameValueLine("name", item.Name + "|");
683 invString.AddNameValueLine("desc", item.Description + "|"); 715 invString.AddNameValueLine("desc", item.Description + "|");
684 716
685 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 717 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
686 invString.AddSectionEnd(); 718 invString.AddSectionEnd();
687 }
688 } 719 }
720 int count = m_items.Count;
721 m_items.LockItemsForRead(false);
689 722
690 fileData = Utils.StringToBytes(invString.BuildString); 723 fileData = Utils.StringToBytes(invString.BuildString);
691 724
@@ -706,10 +739,9 @@ namespace OpenSim.Region.Framework.Scenes
706 { 739 {
707 if (HasInventoryChanged) 740 if (HasInventoryChanged)
708 { 741 {
709 lock (Items) 742 Items.LockItemsForRead(true);
710 { 743 datastore.StorePrimInventory(m_part.UUID, Items.Values);
711 datastore.StorePrimInventory(m_part.UUID, Items.Values); 744 Items.LockItemsForRead(false);
712 }
713 745
714 HasInventoryChanged = false; 746 HasInventoryChanged = false;
715 } 747 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2710cff..c67463a 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73// { 73// {
74// m_log.Debug("[ScenePresence] Destructor called"); 74// m_log.Debug("[ScenePresence] Destructor called");
75// } 75// }
76 76
77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 78
79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 79 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
@@ -89,7 +89,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 90 /// issue #1716
91 /// </summary> 91 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 92// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
93 // Value revised by KF 091121 by comparison with SL.
94 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 95
94 public UUID currentParcelUUID = UUID.Zero; 96 public UUID currentParcelUUID = UUID.Zero;
95 97
@@ -113,7 +115,9 @@ namespace OpenSim.Region.Framework.Scenes
113 public Vector3 lastKnownAllowedPosition; 115 public Vector3 lastKnownAllowedPosition;
114 public bool sentMessageAboutRestrictedParcelFlyingDown; 116 public bool sentMessageAboutRestrictedParcelFlyingDown;
115 public Vector4 CollisionPlane = Vector4.UnitW; 117 public Vector4 CollisionPlane = Vector4.UnitW;
116 118
119 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
120 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
117 private Vector3 m_lastPosition; 121 private Vector3 m_lastPosition;
118 private Quaternion m_lastRotation; 122 private Quaternion m_lastRotation;
119 private Vector3 m_lastVelocity; 123 private Vector3 m_lastVelocity;
@@ -145,7 +149,6 @@ namespace OpenSim.Region.Framework.Scenes
145 private int m_perfMonMS; 149 private int m_perfMonMS;
146 150
147 private bool m_setAlwaysRun; 151 private bool m_setAlwaysRun;
148
149 private bool m_forceFly; 152 private bool m_forceFly;
150 private bool m_flyDisabled; 153 private bool m_flyDisabled;
151 154
@@ -169,7 +172,8 @@ namespace OpenSim.Region.Framework.Scenes
169 protected RegionInfo m_regionInfo; 172 protected RegionInfo m_regionInfo;
170 protected ulong crossingFromRegion; 173 protected ulong crossingFromRegion;
171 174
172 private readonly Vector3[] Dir_Vectors = new Vector3[6]; 175 private readonly Vector3[] Dir_Vectors = new Vector3[11];
176 private bool m_isNudging = false;
173 177
174 // Position of agent's camera in world (region cordinates) 178 // Position of agent's camera in world (region cordinates)
175 protected Vector3 m_CameraCenter; 179 protected Vector3 m_CameraCenter;
@@ -194,6 +198,7 @@ namespace OpenSim.Region.Framework.Scenes
194 private bool m_autopilotMoving; 198 private bool m_autopilotMoving;
195 private Vector3 m_autoPilotTarget; 199 private Vector3 m_autoPilotTarget;
196 private bool m_sitAtAutoTarget; 200 private bool m_sitAtAutoTarget;
201 private Vector3 m_initialSitTarget; //KF: First estimate of where to sit
197 202
198 private string m_nextSitAnimation = String.Empty; 203 private string m_nextSitAnimation = String.Empty;
199 204
@@ -204,6 +209,9 @@ namespace OpenSim.Region.Framework.Scenes
204 private bool m_followCamAuto; 209 private bool m_followCamAuto;
205 210
206 private int m_movementUpdateCount; 211 private int m_movementUpdateCount;
212 private int m_lastColCount = -1; //KF: Look for Collision chnages
213 private int m_updateCount = 0; //KF: Update Anims for a while
214 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
207 215
208 private const int NumMovementsBetweenRayCast = 5; 216 private const int NumMovementsBetweenRayCast = 5;
209 217
@@ -233,6 +241,10 @@ namespace OpenSim.Region.Framework.Scenes
233 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, 241 DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
234 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 242 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
235 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 243 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
244 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
245 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
246 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
247 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 248 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
237 } 249 }
238 250
@@ -658,10 +670,7 @@ namespace OpenSim.Region.Framework.Scenes
658 670
659 671
660 AdjustKnownSeeds(); 672 AdjustKnownSeeds();
661
662 // TODO: I think, this won't send anything, as we are still a child here...
663 Animator.TrySetMovementAnimation("STAND"); 673 Animator.TrySetMovementAnimation("STAND");
664
665 // we created a new ScenePresence (a new child agent) in a fresh region. 674 // we created a new ScenePresence (a new child agent) in a fresh region.
666 // Request info about all the (root) agents in this region 675 // 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) 676 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -717,21 +726,47 @@ namespace OpenSim.Region.Framework.Scenes
717 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 726 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
718 Dir_Vectors[4] = Vector3.UnitZ; //UP 727 Dir_Vectors[4] = Vector3.UnitZ; //UP
719 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 728 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
720 Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 729 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
730 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
731 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
732 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
733 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
721 } 734 }
722 735
723 private Vector3[] GetWalkDirectionVectors() 736 private Vector3[] GetWalkDirectionVectors()
724 { 737 {
725 Vector3[] vector = new Vector3[6]; 738 Vector3[] vector = new Vector3[11];
726 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD 739 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 740 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
728 vector[2] = Vector3.UnitY; //LEFT 741 vector[2] = Vector3.UnitY; //LEFT
729 vector[3] = -Vector3.UnitY; //RIGHT 742 vector[3] = -Vector3.UnitY; //RIGHT
730 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 743 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 744 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 745 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
746 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
747 vector[8] = Vector3.UnitY; //LEFT_NUDGE
748 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
749 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
733 return vector; 750 return vector;
734 } 751 }
752
753 private bool[] GetDirectionIsNudge()
754 {
755 bool[] isNudge = new bool[11];
756 isNudge[0] = false; //FORWARD
757 isNudge[1] = false; //BACK
758 isNudge[2] = false; //LEFT
759 isNudge[3] = false; //RIGHT
760 isNudge[4] = false; //UP
761 isNudge[5] = false; //DOWN
762 isNudge[6] = true; //FORWARD_NUDGE
763 isNudge[7] = true; //BACK_NUDGE
764 isNudge[8] = true; //LEFT_NUDGE
765 isNudge[9] = true; //RIGHT_NUDGE
766 isNudge[10] = true; //DOWN_Nudge
767 return isNudge;
768 }
769
735 770
736 #endregion 771 #endregion
737 772
@@ -995,7 +1030,9 @@ namespace OpenSim.Region.Framework.Scenes
995 { 1030 {
996 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1031 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
997 } 1032 }
998 1033
1034 m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim.
1035
999 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1036 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))); 1037 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1001 } 1038 }
@@ -1230,7 +1267,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); 1267 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1231 } 1268 }
1232 } 1269 }
1233
1234 lock (scriptedcontrols) 1270 lock (scriptedcontrols)
1235 { 1271 {
1236 if (scriptedcontrols.Count > 0) 1272 if (scriptedcontrols.Count > 0)
@@ -1245,9 +1281,7 @@ namespace OpenSim.Region.Framework.Scenes
1245 1281
1246 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1282 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1247 { 1283 {
1248 // TODO: This doesn't prevent the user from walking yet. 1284 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"); 1285 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1252 } 1286 }
1253 1287
@@ -1292,6 +1326,11 @@ namespace OpenSim.Region.Framework.Scenes
1292 update_rotation = true; 1326 update_rotation = true;
1293 } 1327 }
1294 1328
1329 //guilty until proven innocent..
1330 bool Nudging = true;
1331 //Basically, if there is at least one non-nudge control then we don't need
1332 //to worry about stopping the avatar
1333
1295 if (m_parentID == 0) 1334 if (m_parentID == 0)
1296 { 1335 {
1297 bool bAllowUpdateMoveToPosition = false; 1336 bool bAllowUpdateMoveToPosition = false;
@@ -1306,6 +1345,12 @@ namespace OpenSim.Region.Framework.Scenes
1306 else 1345 else
1307 dirVectors = Dir_Vectors; 1346 dirVectors = Dir_Vectors;
1308 1347
1348 bool[] isNudge = GetDirectionIsNudge();
1349
1350
1351
1352
1353
1309 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1354 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1310 { 1355 {
1311 if (((uint)flags & (uint)DCF) != 0) 1356 if (((uint)flags & (uint)DCF) != 0)
@@ -1315,6 +1360,10 @@ namespace OpenSim.Region.Framework.Scenes
1315 try 1360 try
1316 { 1361 {
1317 agent_control_v3 += dirVectors[i]; 1362 agent_control_v3 += dirVectors[i];
1363 if (isNudge[i] == false)
1364 {
1365 Nudging = false;
1366 }
1318 } 1367 }
1319 catch (IndexOutOfRangeException) 1368 catch (IndexOutOfRangeException)
1320 { 1369 {
@@ -1376,6 +1425,9 @@ namespace OpenSim.Region.Framework.Scenes
1376 // Ignore z component of vector 1425 // Ignore z component of vector
1377 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1426 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1378 LocalVectorToTarget2D.Normalize(); 1427 LocalVectorToTarget2D.Normalize();
1428
1429 //We're not nudging
1430 Nudging = false;
1379 agent_control_v3 += LocalVectorToTarget2D; 1431 agent_control_v3 += LocalVectorToTarget2D;
1380 1432
1381 // update avatar movement flags. the avatar coordinate system is as follows: 1433 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1464,7 +1516,7 @@ namespace OpenSim.Region.Framework.Scenes
1464 // m_log.DebugFormat( 1516 // m_log.DebugFormat(
1465 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); 1517 // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);
1466 1518
1467 AddNewMovement(agent_control_v3, q); 1519 AddNewMovement(agent_control_v3, q, Nudging);
1468 1520
1469 1521
1470 } 1522 }
@@ -1485,7 +1537,6 @@ namespace OpenSim.Region.Framework.Scenes
1485 m_sitAtAutoTarget = false; 1537 m_sitAtAutoTarget = false;
1486 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; 1538 PrimitiveBaseShape proxy = PrimitiveBaseShape.Default;
1487 //proxy.PCode = (byte)PCode.ParticleSystem; 1539 //proxy.PCode = (byte)PCode.ParticleSystem;
1488
1489 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); 1540 proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy);
1490 proxyObjectGroup.AttachToScene(m_scene); 1541 proxyObjectGroup.AttachToScene(m_scene);
1491 1542
@@ -1527,7 +1578,7 @@ namespace OpenSim.Region.Framework.Scenes
1527 } 1578 }
1528 m_moveToPositionInProgress = true; 1579 m_moveToPositionInProgress = true;
1529 m_moveToPositionTarget = new Vector3(locx, locy, locz); 1580 m_moveToPositionTarget = new Vector3(locx, locy, locz);
1530 } 1581 }
1531 catch (Exception ex) 1582 catch (Exception ex)
1532 { 1583 {
1533 //Why did I get this error? 1584 //Why did I get this error?
@@ -1549,7 +1600,7 @@ namespace OpenSim.Region.Framework.Scenes
1549 Velocity = Vector3.Zero; 1600 Velocity = Vector3.Zero;
1550 SendFullUpdateToAllClients(); 1601 SendFullUpdateToAllClients();
1551 1602
1552 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1603 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1553 } 1604 }
1554 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1605 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1555 m_requestedSitTargetUUID = UUID.Zero; 1606 m_requestedSitTargetUUID = UUID.Zero;
@@ -1587,38 +1638,51 @@ namespace OpenSim.Region.Framework.Scenes
1587 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); 1638 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
1588 if (part != null) 1639 if (part != null)
1589 { 1640 {
1641 part.TaskInventory.LockItemsForRead(true);
1590 TaskInventoryDictionary taskIDict = part.TaskInventory; 1642 TaskInventoryDictionary taskIDict = part.TaskInventory;
1591 if (taskIDict != null) 1643 if (taskIDict != null)
1592 { 1644 {
1593 lock (taskIDict) 1645 foreach (UUID taskID in taskIDict.Keys)
1594 { 1646 {
1595 foreach (UUID taskID in taskIDict.Keys) 1647 UnRegisterControlEventsToScript(LocalId, taskID);
1596 { 1648 taskIDict[taskID].PermsMask &= ~(
1597 UnRegisterControlEventsToScript(LocalId, taskID); 1649 2048 | //PERMISSION_CONTROL_CAMERA
1598 taskIDict[taskID].PermsMask &= ~( 1650 4); // PERMISSION_TAKE_CONTROLS
1599 2048 | //PERMISSION_CONTROL_CAMERA
1600 4); // PERMISSION_TAKE_CONTROLS
1601 }
1602 } 1651 }
1603
1604 } 1652 }
1653 part.TaskInventory.LockItemsForRead(false);
1605 // Reset sit target. 1654 // Reset sit target.
1606 if (part.GetAvatarOnSitTarget() == UUID) 1655 if (part.GetAvatarOnSitTarget() == UUID)
1607 part.SetAvatarOnSitTarget(UUID.Zero); 1656 part.SetAvatarOnSitTarget(UUID.Zero);
1608
1609 m_parentPosition = part.GetWorldPosition(); 1657 m_parentPosition = part.GetWorldPosition();
1610 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1658 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1611 } 1659 }
1660 // part.GetWorldRotation() is the rotation of the object being sat on
1661 // Rotation is the sittiing Av's rotation
1662
1663 Quaternion partRot;
1664 if (part.LinkNum == 1)
1665 { // Root prim of linkset
1666 partRot = part.ParentGroup.RootPart.RotationOffset;
1667 }
1668 else
1669 { // single or child prim
1670 partRot = part.GetWorldRotation();
1671 }
1672 Quaternion partIRot = Quaternion.Inverse(partRot);
1673
1674 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
1675 Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av
1676 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ( m_pos * partRot); // + av sit offset!
1612 1677
1613 if (m_physicsActor == null) 1678 if (m_physicsActor == null)
1614 { 1679 {
1615 AddToPhysicalScene(false); 1680 AddToPhysicalScene(false);
1616 } 1681 }
1617 1682 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
1618 m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
1619 m_parentPosition = Vector3.Zero; 1683 m_parentPosition = Vector3.Zero;
1620 1684 m_parentID = 0;
1621 m_parentID = 0; 1685 part.IsOccupied = false;
1622 SendFullUpdateToAllClients(); 1686 SendFullUpdateToAllClients();
1623 m_requestedSitTargetID = 0; 1687 m_requestedSitTargetID = 0;
1624 if ((m_physicsActor != null) && (m_avHeight > 0)) 1688 if ((m_physicsActor != null) && (m_avHeight > 0))
@@ -1626,7 +1690,6 @@ namespace OpenSim.Region.Framework.Scenes
1626 SetHeight(m_avHeight); 1690 SetHeight(m_avHeight);
1627 } 1691 }
1628 } 1692 }
1629
1630 Animator.TrySetMovementAnimation("STAND"); 1693 Animator.TrySetMovementAnimation("STAND");
1631 } 1694 }
1632 1695
@@ -1657,13 +1720,9 @@ namespace OpenSim.Region.Framework.Scenes
1657 Vector3 avSitOffSet = part.SitTargetPosition; 1720 Vector3 avSitOffSet = part.SitTargetPosition;
1658 Quaternion avSitOrientation = part.SitTargetOrientation; 1721 Quaternion avSitOrientation = part.SitTargetOrientation;
1659 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1722 UUID avOnTargetAlready = part.GetAvatarOnSitTarget();
1660 1723 bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero);
1661 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1724 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1662 bool SitTargetisSet = 1725 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 { 1726 {
1668 //switch the target to this prim 1727 //switch the target to this prim
1669 return part; 1728 return part;
@@ -1677,84 +1736,146 @@ namespace OpenSim.Region.Framework.Scenes
1677 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 1736 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1678 { 1737 {
1679 bool autopilot = true; 1738 bool autopilot = true;
1739 Vector3 autopilotTarget = new Vector3();
1740 Quaternion sitOrientation = Quaternion.Identity;
1680 Vector3 pos = new Vector3(); 1741 Vector3 pos = new Vector3();
1681 Quaternion sitOrientation = pSitOrientation;
1682 Vector3 cameraEyeOffset = Vector3.Zero; 1742 Vector3 cameraEyeOffset = Vector3.Zero;
1683 Vector3 cameraAtOffset = Vector3.Zero; 1743 Vector3 cameraAtOffset = Vector3.Zero;
1684 bool forceMouselook = false; 1744 bool forceMouselook = false;
1685 1745
1686 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1746 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1687 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1747 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1688 if (part != null) 1748 if (part == null) return;
1689 { 1749
1690 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 1750 // 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 1751 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
1692 1752
1693 // Is a sit target available? 1753 // part is the prim to sit on
1694 Vector3 avSitOffSet = part.SitTargetPosition; 1754 // offset is the world-ref vector distance from that prim center to the click-spot
1695 Quaternion avSitOrientation = part.SitTargetOrientation; 1755 // UUID is the UUID of the Avatar doing the clicking
1696 UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); 1756
1697 1757 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
1698 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 1758
1699 bool SitTargetisSet = 1759 // Is a sit target available?
1700 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && 1760 Vector3 avSitOffSet = part.SitTargetPosition;
1701 ( 1761 Quaternion avSitOrientation = part.SitTargetOrientation;
1702 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion 1762
1703 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point 1763 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 1764 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
1705 ) 1765 Quaternion partRot;
1706 )); 1766 if (part.LinkNum == 1)
1707 1767 { // Root prim of linkset
1708 if (SitTargetisSet && SitTargetUnOccupied) 1768 partRot = part.ParentGroup.RootPart.RotationOffset;
1709 { 1769 }
1710 part.SetAvatarOnSitTarget(UUID); 1770 else
1711 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 1771 { // single or child prim
1712 sitOrientation = avSitOrientation; 1772 partRot = part.GetWorldRotation();
1713 autopilot = false; 1773 }
1714 } 1774 Quaternion partIRot = Quaternion.Inverse(partRot);
1715 1775//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
1716 pos = part.AbsolutePosition + offset; 1776 // Sit analysis rewritten by KF 091125
1717 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) 1777 if (SitTargetisSet) // scipted sit
1718 //{ 1778 {
1719 // offset = pos; 1779 if (!part.IsOccupied)
1720 //autopilot = false; 1780 {
1721 //} 1781//Console.WriteLine("Scripted, unoccupied");
1722 if (m_physicsActor != null) 1782 part.SetAvatarOnSitTarget(UUID); // set that Av will be on it
1723 { 1783 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 1784 sitOrientation = avSitOrientation; // Change rotatione to the scripted one
1725 // We can remove the physicsActor until they stand up. 1785 autopilot = false; // Jump direct to scripted llSitPos()
1726 m_sitAvatarHeight = m_physicsActor.Size.Z; 1786 }
1727 1787 else
1728 if (autopilot) 1788 {
1729 { 1789//Console.WriteLine("Scripted, occupied");
1730 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 1790 return;
1731 { 1791 }
1732 autopilot = false; 1792 }
1793 else // Not Scripted
1794 {
1795 if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) )
1796 {
1797 // large prim & offset, ignore if other Avs sitting
1798// offset.Z -= 0.05f;
1799 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
1800 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
1801
1802//Console.WriteLine(" offset ={0}", offset);
1803//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
1804//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
1805
1806 }
1807 else // small offset
1808 {
1809//Console.WriteLine("Small offset");
1810 if (!part.IsOccupied)
1811 {
1812 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
1813 autopilotTarget = part.AbsolutePosition;
1814 }
1815 else return; // occupied small
1816 } // end large/small
1817 } // end Scripted/not
1818 cameraAtOffset = part.GetCameraAtOffset();
1819 cameraEyeOffset = part.GetCameraEyeOffset();
1820 forceMouselook = part.GetForceMouselook();
1821 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
1822 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
1733 1823
1734 RemoveFromPhysicalScene(); 1824 if (m_physicsActor != null)
1735 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 1825 {
1736 } 1826 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1737 } 1827 // We can remove the physicsActor until they stand up.
1738 else 1828 m_sitAvatarHeight = m_physicsActor.Size.Z;
1829 if (autopilot)
1830 { // its not a scripted sit
1831// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
1832 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) )
1739 { 1833 {
1834 autopilot = false; // close enough
1740 RemoveFromPhysicalScene(); 1835 RemoveFromPhysicalScene();
1741 } 1836 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
1837 } // else the autopilot will get us close
1838 }
1839 else
1840 { // its a scripted sit
1841 RemoveFromPhysicalScene();
1742 } 1842 }
1743
1744 cameraAtOffset = part.GetCameraAtOffset();
1745 cameraEyeOffset = part.GetCameraEyeOffset();
1746 forceMouselook = part.GetForceMouselook();
1747 } 1843 }
1844 else return; // physactor is null!
1748 1845
1749 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 1846 Vector3 offsetr; // = offset * partIRot;
1750 m_requestedSitTargetUUID = targetID; 1847 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
1848 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
1849 if (part.LinkNum < 2)
1850 { // Single, or Root prim of linkset, target is ClickOffset * RootRot
1851 offsetr = offset * partIRot;
1852 }
1853 else
1854 { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
1855 offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
1856 (offset * partRot);
1857 }
1858
1859//Console.WriteLine(" ");
1860//Console.WriteLine("link number ={0}", part.LinkNum);
1861//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
1862//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
1863//Console.WriteLine("Click offst ={0}", offset);
1864//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
1865//Console.WriteLine("offsetr ={0}", offsetr);
1866//Console.WriteLine("Camera At ={0}", cameraAtOffset);
1867//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
1868
1869 ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
1870 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
1751 // This calls HandleAgentSit twice, once from here, and the client calls 1871 // This calls HandleAgentSit twice, once from here, and the client calls
1752 // HandleAgentSit itself after it gets to the location 1872 // HandleAgentSit itself after it gets to the location
1753 // It doesn't get to the location until we've moved them there though 1873 // It doesn't get to the location until we've moved them there though
1754 // which happens in HandleAgentSit :P 1874 // which happens in HandleAgentSit :P
1755 m_autopilotMoving = autopilot; 1875 m_autopilotMoving = autopilot;
1756 m_autoPilotTarget = pos; 1876 m_autoPilotTarget = autopilotTarget;
1757 m_sitAtAutoTarget = autopilot; 1877 m_sitAtAutoTarget = autopilot;
1878 m_initialSitTarget = autopilotTarget;
1758 if (!autopilot) 1879 if (!autopilot)
1759 HandleAgentSit(remoteClient, UUID); 1880 HandleAgentSit(remoteClient, UUID);
1760 } 1881 }
@@ -2051,29 +2172,62 @@ namespace OpenSim.Region.Framework.Scenes
2051 { 2172 {
2052 if (part.GetAvatarOnSitTarget() == UUID) 2173 if (part.GetAvatarOnSitTarget() == UUID)
2053 { 2174 {
2175//Console.WriteLine("Scripted Sit");
2176 // Scripted sit
2054 Vector3 sitTargetPos = part.SitTargetPosition; 2177 Vector3 sitTargetPos = part.SitTargetPosition;
2055 Quaternion sitTargetOrient = part.SitTargetOrientation; 2178 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); 2179 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2063 m_pos += SIT_TARGET_ADJUSTMENT; 2180 m_pos += SIT_TARGET_ADJUSTMENT;
2064 m_bodyRot = sitTargetOrient; 2181 m_bodyRot = sitTargetOrient;
2065 //Rotation = sitTargetOrient;
2066 m_parentPosition = part.AbsolutePosition; 2182 m_parentPosition = part.AbsolutePosition;
2067 2183 part.IsOccupied = true;
2068 //SendTerseUpdateToAllClients();
2069 } 2184 }
2070 else 2185 else
2071 { 2186 {
2072 m_pos -= part.AbsolutePosition; 2187 // if m_avUnscriptedSitPos is zero then Av sits above center
2188 // Else Av sits at m_avUnscriptedSitPos
2189
2190 // Non-scripted sit by Kitto Flora 21Nov09
2191 // Calculate angle of line from prim to Av
2192 Quaternion partIRot;
2193 if (part.LinkNum == 1)
2194 { // Root prim of linkset
2195 partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2196 }
2197 else
2198 { // single or child prim
2199 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2200 }
2201 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2202 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2203 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2204 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2205 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2206 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2207 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2208 // Av sits at world euler <0,0, z>, translated by part rotation
2209 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2210
2073 m_parentPosition = part.AbsolutePosition; 2211 m_parentPosition = part.AbsolutePosition;
2074 } 2212 part.IsOccupied = true;
2075 } 2213 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2076 else 2214 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2215 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2216 m_avUnscriptedSitPos; // adds click offset, if any
2217 //Set up raytrace to find top surface of prim
2218 Vector3 size = part.Scale;
2219 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2220 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2221 Vector3 down = new Vector3(0f, 0f, -1f);
2222//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2223 m_scene.PhysicsScene.RaycastWorld(
2224 start, // Vector3 position,
2225 down, // Vector3 direction,
2226 mag, // float length,
2227 SitAltitudeCallback); // retMethod
2228 } // end scripted/not
2229 }
2230 else // no Av
2077 { 2231 {
2078 return; 2232 return;
2079 } 2233 }
@@ -2085,11 +2239,36 @@ namespace OpenSim.Region.Framework.Scenes
2085 2239
2086 Animator.TrySetMovementAnimation(sitAnimation); 2240 Animator.TrySetMovementAnimation(sitAnimation);
2087 SendFullUpdateToAllClients(); 2241 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 } 2242 }
2243
2244 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2245 {
2246 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2247 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2248 if(hitYN)
2249 {
2250 // m_pos = Av offset from prim center to make look like on center
2251 // m_parentPosition = Actual center pos of prim
2252 // collisionPoint = spot on prim where we want to sit
2253 // collisionPoint.Z = global sit surface height
2254 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2255 Quaternion partIRot;
2256 if (part.LinkNum == 1)
2257 { // Root prim of linkset
2258 partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2259 }
2260 else
2261 { // single or child prim
2262 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2263 }
2264 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2265 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2266//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2267 m_pos += offset;
2268// ControllingClient.SendClearFollowCamProperties(part.UUID);
2269
2270 }
2271 } // End SitAltitudeCallback KF.
2093 2272
2094 /// <summary> 2273 /// <summary>
2095 /// Event handler for the 'Always run' setting on the client 2274 /// Event handler for the 'Always run' setting on the client
@@ -2119,7 +2298,7 @@ namespace OpenSim.Region.Framework.Scenes
2119 /// </summary> 2298 /// </summary>
2120 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2299 /// <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. 2300 /// <param name="rotation">The direction in which this avatar should now face.
2122 public void AddNewMovement(Vector3 vec, Quaternion rotation) 2301 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2123 { 2302 {
2124 if (m_isChildAgent) 2303 if (m_isChildAgent)
2125 { 2304 {
@@ -2193,7 +2372,7 @@ namespace OpenSim.Region.Framework.Scenes
2193 2372
2194 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2373 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2195 m_forceToApply = direc; 2374 m_forceToApply = direc;
2196 2375 m_isNudging = Nudging;
2197 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2376 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2198 } 2377 }
2199 2378
@@ -2208,7 +2387,7 @@ namespace OpenSim.Region.Framework.Scenes
2208 const float POSITION_TOLERANCE = 0.05f; 2387 const float POSITION_TOLERANCE = 0.05f;
2209 //const int TIME_MS_TOLERANCE = 3000; 2388 //const int TIME_MS_TOLERANCE = 3000;
2210 2389
2211 SendPrimUpdates(); 2390
2212 2391
2213 if (m_newCoarseLocations) 2392 if (m_newCoarseLocations)
2214 { 2393 {
@@ -2244,6 +2423,9 @@ namespace OpenSim.Region.Framework.Scenes
2244 CheckForBorderCrossing(); 2423 CheckForBorderCrossing();
2245 CheckForSignificantMovement(); // sends update to the modules. 2424 CheckForSignificantMovement(); // sends update to the modules.
2246 } 2425 }
2426
2427 //Sending prim updates AFTER the avatar terse updates are sent
2428 SendPrimUpdates();
2247 } 2429 }
2248 2430
2249 #endregion 2431 #endregion
@@ -3097,14 +3279,25 @@ namespace OpenSim.Region.Framework.Scenes
3097 { 3279 {
3098 if (m_forceToApply.HasValue) 3280 if (m_forceToApply.HasValue)
3099 { 3281 {
3100 Vector3 force = m_forceToApply.Value;
3101 3282
3283 Vector3 force = m_forceToApply.Value;
3102 m_updateflag = true; 3284 m_updateflag = true;
3103// movementvector = force;
3104 Velocity = force; 3285 Velocity = force;
3105 3286
3106 m_forceToApply = null; 3287 m_forceToApply = null;
3107 } 3288 }
3289 else
3290 {
3291 if (m_isNudging)
3292 {
3293 Vector3 force = Vector3.Zero;
3294
3295 m_updateflag = true;
3296 Velocity = force;
3297 m_isNudging = false;
3298 m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND"
3299 }
3300 }
3108 } 3301 }
3109 3302
3110 public override void SetText(string text, Vector3 color, double alpha) 3303 public override void SetText(string text, Vector3 color, double alpha)
@@ -3156,18 +3349,29 @@ namespace OpenSim.Region.Framework.Scenes
3156 { 3349 {
3157 if (e == null) 3350 if (e == null)
3158 return; 3351 return;
3159 3352
3160 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3353 // 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 3354 // as of this comment the interval is set in AddToPhysicalScene
3163 if (Animator!=null) 3355 if (Animator!=null)
3164 Animator.UpdateMovementAnimations(); 3356 {
3357 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3358 { // else its will lock out other animation changes, like ground sit.
3359 Animator.UpdateMovementAnimations();
3360 m_updateCount--;
3361 }
3362 }
3165 3363
3166 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3364 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3167 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3365 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3168 3366
3169 CollisionPlane = Vector4.UnitW; 3367 CollisionPlane = Vector4.UnitW;
3170 3368
3369 if (m_lastColCount != coldata.Count)
3370 {
3371 m_updateCount = UPDATE_COUNT;
3372 m_lastColCount = coldata.Count;
3373 }
3374
3171 if (coldata.Count != 0 && Animator != null) 3375 if (coldata.Count != 0 && Animator != null)
3172 { 3376 {
3173 switch (Animator.CurrentMovementAnimation) 3377 switch (Animator.CurrentMovementAnimation)
@@ -3815,5 +4019,16 @@ namespace OpenSim.Region.Framework.Scenes
3815 m_reprioritization_called = false; 4019 m_reprioritization_called = false;
3816 } 4020 }
3817 } 4021 }
4022
4023 private Vector3 Quat2Euler(Quaternion rot){
4024 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4025 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4026 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4027 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4028 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4029 return(new Vector3(x,y,z));
4030 }
4031
4032
3818 } 4033 }
3819} \ No newline at end of file 4034}
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..c27c420 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;
@@ -2822,6 +2881,12 @@ Console.WriteLine(" JointCreateFixed");
2822 } 2881 }
2823 public override bool PIDActive { set { m_usePID = value; } } 2882 public override bool PIDActive { set { m_usePID = value; } }
2824 public override float PIDTau { set { m_PIDTau = value; } } 2883 public override float PIDTau { set { m_PIDTau = value; } }
2884
2885 // For RotLookAt
2886 public override Quaternion APIDTarget { set { m_APIDTarget = value; } }
2887 public override bool APIDActive { set { m_useAPID = value; } }
2888 public override float APIDStrength { set { m_APIDStrength = value; } }
2889 public override float APIDDamping { set { m_APIDDamping = value; } }
2825 2890
2826 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } 2891 public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
2827 public override bool PIDHoverActive { set { m_useHoverPID = value; } } 2892 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..4cc2f0a
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,430 @@
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 /// <summary>
235 /// Set the current Windlight scene
236 /// </summary>
237 /// <param name="rules"></param>
238 /// <returns>success: true or false</returns>
239 public int cmSetWindlightScene(LSL_List rules)
240 {
241 if (!m_CMFunctionsEnabled)
242 {
243 CMShoutError("Careminster functions are not enabled.");
244 return 0;
245 }
246 int success = 0;
247 m_host.AddScriptLPS(1);
248 if (Meta7WindlightModule.EnableWindlight)
249 {
250 RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings;
251
252 LSL_List values = new LSL_List();
253 int idx = 0;
254 success = 1;
255 while (idx < rules.Length)
256 {
257 uint rule = (uint)rules.GetLSLIntegerItem(idx);
258 LSL_Types.Quaternion iQ;
259 LSL_Types.Vector3 iV;
260 switch (rule)
261 {
262 case (int)ScriptBaseClass.WL_AMBIENT:
263 idx++;
264 iQ = rules.GetQuaternionItem(idx);
265 wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
266 break;
267 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
268 idx++;
269 iV = rules.GetVector3Item(idx);
270 wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y);
271 break;
272 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
273 idx++;
274 iQ = rules.GetQuaternionItem(idx);
275 wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
276 break;
277 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
278 idx++;
279 wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx);
280 break;
281 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
282 idx++;
283 iQ = rules.GetQuaternionItem(idx);
284 wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
285 break;
286 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
287 idx++;
288 wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx);
289 break;
290 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
291 idx++;
292 iV = rules.GetVector3Item(idx);
293 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
294 break;
295 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
296 idx++;
297 wl.cloudScale = (float)rules.GetLSLFloatItem(idx);
298 break;
299 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
300 idx++;
301 wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx);
302 break;
303 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
304 idx++;
305 wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
306 break;
307 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
308 idx++;
309 wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx);
310 break;
311 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
312 idx++;
313 wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
314 break;
315 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
316 idx++;
317 iV = rules.GetVector3Item(idx);
318 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
319 break;
320 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
321 idx++;
322 wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx);
323 break;
324 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
325 idx++;
326 wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx);
327 break;
328 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
329 idx++;
330 wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
331 break;
332 case (int)ScriptBaseClass.WL_EAST_ANGLE:
333 idx++;
334 wl.eastAngle = (float)rules.GetLSLFloatItem(idx);
335 break;
336 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
337 idx++;
338 wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx);
339 break;
340 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
341 idx++;
342 wl.fresnelScale = (float)rules.GetLSLFloatItem(idx);
343 break;
344 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
345 idx++;
346 wl.hazeDensity = (float)rules.GetLSLFloatItem(idx);
347 break;
348 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
349 idx++;
350 wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx);
351 break;
352 case (int)ScriptBaseClass.WL_HORIZON:
353 idx++;
354 iQ = rules.GetQuaternionItem(idx);
355 wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
356 break;
357 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
358 idx++;
359 iV = rules.GetVector3Item(idx);
360 wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y);
361 break;
362 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
363 idx++;
364 wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value;
365 break;
366 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
367 idx++;
368 wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string);
369 break;
370 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
371 idx++;
372 iV = rules.GetVector3Item(idx);
373 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
374 break;
375 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
376 idx++;
377 wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx);
378 break;
379 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
380 idx++;
381 wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx);
382 break;
383 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
384 idx++;
385 wl.sceneGamma = (float)rules.GetLSLFloatItem(idx);
386 break;
387 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
388 idx++;
389 wl.starBrightness = (float)rules.GetLSLFloatItem(idx);
390 break;
391 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
392 idx++;
393 wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx);
394 break;
395 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
396 idx++;
397 wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx);
398 break;
399 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
400 idx++;
401 iQ = rules.GetQuaternionItem(idx);
402 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
403 break;
404 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
405 idx++;
406 wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx);
407 break;
408 case (int)ScriptBaseClass.WL_WATER_COLOR:
409 idx++;
410 iV = rules.GetVector3Item(idx);
411 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
412 break;
413 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
414 idx++;
415 wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx);
416 break;
417 default:
418 success = 0;
419 break;
420 }
421 idx++;
422 }
423 m_host.ParentGroup.Scene.StoreWindlightProfile(wl);
424
425 }
426 return success;
427 }
428
429 }
430}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 9a905f1..e694f15 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..9dd0b73
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,20 @@
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 }
20}
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..e85d41e
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
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}
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 9030a5c..184af19 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 {
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 27025d9..5f172c4 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -491,7 +491,7 @@ namespace OpenSim.Tests.Common.Mock
491 491
492 } 492 }
493 493
494 public void SendGenericMessage(string method, List<string> message) 494 public void SendGenericMessage(string method, List<byte[]> message)
495 { 495 {
496 496
497 } 497 }
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 1cf96b0..af9632e 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -462,6 +462,9 @@
462 462
463 ; Distance in meters that shouts should travel. Default is 100m 463 ; Distance in meters that shouts should travel. Default is 100m
464 shout_distance = 100 464 shout_distance = 100
465
466 ; Append a prefix to the god avatar names appearing in chat whilst in god mode
467 ; admin_prefix = "@"
465 468
466 469
467[Messaging] 470[Messaging]
@@ -830,6 +833,12 @@
830 ; default is 1000 833 ; default is 1000
831 cloud_update_rate = 1000 834 cloud_update_rate = 1000
832 835
836[Meta7Windlight]
837
838 ; This enables the transmission of Windlight scenes to supporting clients, such as the Meta7 viewer.
839 ; It has no ill effect on viewers which do not support server-side windlight settings.
840 ; Currently we only have support for MySQL databases.
841 enable_windlight = false;
833 842
834[Trees] 843[Trees]
835 ; Enable this to allow the tree module to manage your sim trees, including growing, reproducing and dying 844 ; Enable this to allow the tree module to manage your sim trees, including growing, reproducing and dying
@@ -979,6 +988,9 @@
979 988
980 ; Allow the use of os* functions (some are dangerous) 989 ; Allow the use of os* functions (some are dangerous)
981 AllowOSFunctions = false 990 AllowOSFunctions = false
991
992 ; Allow the user of Careminster functions
993 AllowCareminsterFunctions = false
982 994
983 ; Threat level to allow, one of None, VeryLow, Low, Moderate, High, VeryHigh, Severe 995 ; Threat level to allow, one of None, VeryLow, Low, Moderate, High, VeryHigh, Severe
984 OSFunctionThreatLevel = VeryLow 996 OSFunctionThreatLevel = VeryLow