aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2013-03-18 23:31:27 +0000
committerMelanie2013-03-18 23:31:27 +0000
commit5e1f651e21ba81d8be9693d7e8a47d49daa9fce5 (patch)
tree4856d3aa25fcd942a26af39e1510f58fef3c934d /OpenSim/Region
parentMerge commit 'ccd6f443e1092cb410f565e921f7cf4dd8cd2dac' into newmultiattach (diff)
parentImprove rejection of any attempt to reattach an object that is already attached. (diff)
downloadopensim-SC_OLD-5e1f651e21ba81d8be9693d7e8a47d49daa9fce5.zip
opensim-SC_OLD-5e1f651e21ba81d8be9693d7e8a47d49daa9fce5.tar.gz
opensim-SC_OLD-5e1f651e21ba81d8be9693d7e8a47d49daa9fce5.tar.bz2
opensim-SC_OLD-5e1f651e21ba81d8be9693d7e8a47d49daa9fce5.tar.xz
Merge branch 'master' into newmultiattach
Conflicts: OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs1
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs51
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs124
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs263
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs32
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs139
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs83
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs124
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs5
-rw-r--r--OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs38
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs77
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs103
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs157
-rw-r--r--OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs41
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs39
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs36
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs39
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs50
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs9
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs29
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs33
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs12
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs100
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs6
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs331
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs1
39 files changed, 1466 insertions, 580 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 4075edb..11dd052 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -159,6 +159,7 @@ namespace OpenSim
159 159
160 MainConsole.Instance = m_console; 160 MainConsole.Instance = m_console;
161 161
162 LogEnvironmentInformation();
162 RegisterCommonAppenders(Config.Configs["Startup"]); 163 RegisterCommonAppenders(Config.Configs["Startup"]);
163 RegisterConsoleCommands(); 164 RegisterConsoleCommands();
164 165
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 137bd81..c555915 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -134,10 +134,6 @@ namespace OpenSim
134 /// <param name="configSource"></param> 134 /// <param name="configSource"></param>
135 public OpenSimBase(IConfigSource configSource) : base() 135 public OpenSimBase(IConfigSource configSource) : base()
136 { 136 {
137 // FIXME: This should be done down in ServerBase but we need to sort out and refactor the log4net
138 // XmlConfigurator calls first accross servers.
139 m_log.InfoFormat("[SERVER BASE]: Starting in {0}", m_startupDirectory);
140
141 LoadConfigSettings(configSource); 137 LoadConfigSettings(configSource);
142 } 138 }
143 139
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index ed8ec16..141af8a 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -49,8 +49,10 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
49 private TestScene m_scene; 49 private TestScene m_scene;
50 50
51 [SetUp] 51 [SetUp]
52 public void SetUp() 52 public override void SetUp()
53 { 53 {
54 base.SetUp();
55
54 uint port = 9999; 56 uint port = 9999;
55 uint sslPort = 9998; 57 uint sslPort = 9998;
56 58
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 6742d99..7ea538c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4581,7 +4581,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4581 rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock(); 4581 rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock();
4582 rinfopack.AgentData.AgentID = AgentId; 4582 rinfopack.AgentData.AgentID = AgentId;
4583 rinfopack.AgentData.SessionID = SessionId; 4583 rinfopack.AgentData.SessionID = SessionId;
4584 4584 rinfopack.RegionInfo3 = new RegionInfoPacket.RegionInfo3Block[0];
4585 4585
4586 OutPacket(rinfopack, ThrottleOutPacketType.Task); 4586 OutPacket(rinfopack, ThrottleOutPacketType.Task);
4587 } 4587 }
@@ -7069,7 +7069,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7069 7069
7070 if (handlerUpdatePrimFlags != null) 7070 if (handlerUpdatePrimFlags != null)
7071 { 7071 {
7072 byte[] data = Pack.ToBytes(); 7072// byte[] data = Pack.ToBytes();
7073 // 46,47,48 are special positions within the packet 7073 // 46,47,48 are special positions within the packet
7074 // This may change so perhaps we need a better way 7074 // This may change so perhaps we need a better way
7075 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7075 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index a7628d2..72516cd 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -278,25 +278,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
278 m_shouldCollectStats = false; 278 m_shouldCollectStats = false;
279 if (config != null) 279 if (config != null)
280 { 280 {
281 if (config.Contains("enabled") && config.GetBoolean("enabled")) 281 m_shouldCollectStats = config.GetBoolean("Enabled", false);
282 { 282 binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("packet_headers_period_seconds", 300));
283 if (config.Contains("collect_packet_headers")) 283 binStatsDir = config.GetString("stats_dir", ".");
284 m_shouldCollectStats = config.GetBoolean("collect_packet_headers"); 284 m_aggregatedBWStats = config.GetBoolean("aggregatedBWStats", false);
285 if (config.Contains("packet_headers_period_seconds")) 285 }
286 { 286 #endregion BinaryStats
287 binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("region_stats_period_seconds"));
288 }
289 if (config.Contains("stats_dir"))
290 {
291 binStatsDir = config.GetString("stats_dir");
292 }
293 }
294 else
295 {
296 m_shouldCollectStats = false;
297 }
298 }
299 #endregion BinaryStats
300 287
301 m_throttle = new TokenBucket(null, sceneThrottleBps); 288 m_throttle = new TokenBucket(null, sceneThrottleBps);
302 ThrottleRates = new ThrottleRates(configSource); 289 ThrottleRates = new ThrottleRates(configSource);
@@ -1266,8 +1253,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1266 static object binStatsLogLock = new object(); 1253 static object binStatsLogLock = new object();
1267 static string binStatsDir = ""; 1254 static string binStatsDir = "";
1268 1255
1256 //for Aggregated In/Out BW logging
1257 static bool m_aggregatedBWStats = false;
1258 static long m_aggregatedBytesIn = 0;
1259 static long m_aggregatedByestOut = 0;
1260 static object aggBWStatsLock = new object();
1261
1262 public static long AggregatedLLUDPBytesIn
1263 {
1264 get { return m_aggregatedBytesIn; }
1265 }
1266 public static long AggregatedLLUDPBytesOut
1267 {
1268 get {return m_aggregatedByestOut;}
1269 }
1270
1269 public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size) 1271 public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size)
1270 { 1272 {
1273 if (m_aggregatedBWStats)
1274 {
1275 lock (aggBWStatsLock)
1276 {
1277 if (incoming)
1278 m_aggregatedBytesIn += size;
1279 else
1280 m_aggregatedByestOut += size;
1281 }
1282 }
1283
1271 if (!m_shouldCollectStats) return; 1284 if (!m_shouldCollectStats) return;
1272 1285
1273 // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size 1286 // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index ab7e932..2dea14d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -289,21 +289,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
289 if (!Enabled) 289 if (!Enabled)
290 return false; 290 return false;
291 291
292 if (AttachObjectInternal(sp, group, attachmentPt, silent, temp, append)) 292 return AttachObjectInternal(sp, group, attachmentPt, silent, temp, append);
293 {
294 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
295 return true;
296 }
297
298 return false;
299 } 293 }
300
301 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append)
302 {
303// m_log.DebugFormat(
304// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
305// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
306 294
295 /// <summary>
296 /// Internal method which actually does all the work for attaching an object.
297 /// </summary>
298 /// <returns>The object attached.</returns>
299 /// <param name='sp'></param>
300 /// <param name='group'>The object to attach.</param>
301 /// <param name='attachmentPt'></param>
302 /// <param name='silent'></param>
303 /// <param name='temp'></param>
304 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param>
305 private bool AttachObjectInternal(
306 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts)
307 {
307 if (group.GetSittingAvatarsCount() != 0) 308 if (group.GetSittingAvatarsCount() != 0)
308 { 309 {
309// m_log.WarnFormat( 310// m_log.WarnFormat(
@@ -314,6 +315,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
314 } 315 }
315 316
316 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 317 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
318
317 if (attachments.Contains(group)) 319 if (attachments.Contains(group))
318 { 320 {
319// m_log.WarnFormat( 321// m_log.WarnFormat(
@@ -374,6 +376,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
374 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); 376 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
375 377
376 AttachToAgent(sp, group, attachmentPt, attachPos, silent); 378 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
379
380 if (resumeScripts)
381 {
382 // Fire after attach, so we don't get messy perms dialogs
383 // 4 == AttachedRez
384 group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
385 group.ResumeScripts();
386 }
387
388 // Do this last so that event listeners have access to all the effects of the attachment
389 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
377 } 390 }
378 391
379 return true; 392 return true;
@@ -400,8 +413,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
400 return null; 413 return null;
401 414
402// m_log.DebugFormat( 415// m_log.DebugFormat(
403// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", 416// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}",
404// (AttachmentPoint)AttachmentPt, itemID, sp.Name); 417// (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name);
405 418
406 bool append = (AttachmentPt & 0x80) != 0; 419 bool append = (AttachmentPt & 0x80) != 0;
407 AttachmentPt &= 0x7f; 420 AttachmentPt &= 0x7f;
@@ -533,6 +546,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
533 return; 546 return;
534 } 547 }
535 548
549// m_log.DebugFormat(
550// "[ATTACHMENTS MODULE]: Detaching object {0} {1} for {2} in {3}",
551// so.Name, so.LocalId, sp.Name, m_scene.Name);
552
536 // Scripts MUST be snapshotted before the object is 553 // Scripts MUST be snapshotted before the object is
537 // removed from the scene because doing otherwise will 554 // removed from the scene because doing otherwise will
538 // clobber the run flag 555 // clobber the run flag
@@ -854,61 +871,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
854 return null; 871 return null;
855 } 872 }
856 873
857 // Remove any previous attachments
858 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
859 string previousAttachmentScriptedState = null;
860
861 // At the moment we can only deal with a single attachment
862 if (attachments.Count != 0)
863 DetachSingleAttachmentToInv(sp, attachments[0]);
864
865 lock (sp.AttachmentsSyncLock)
866 {
867// m_log.DebugFormat( 874// m_log.DebugFormat(
868// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", 875// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}",
869// objatt.Name, sp.Name, attachmentPt, m_scene.Name); 876// objatt.Name, sp.Name, attachmentPt, m_scene.Name);
870 877
871 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. 878 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
872 objatt.HasGroupChanged = false; 879 objatt.HasGroupChanged = false;
873 bool tainted = false; 880 bool tainted = false;
874 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) 881 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
875 tainted = true; 882 tainted = true;
876 883
877 // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal 884 // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
878 // course of events. If not, then it's probably not worth trying to recover the situation 885 // course of events. If not, then it's probably not worth trying to recover the situation
879 // since this is more likely to trigger further exceptions and confuse later debugging. If 886 // since this is more likely to trigger further exceptions and confuse later debugging. If
880 // exceptions can be thrown in expected error conditions (not NREs) then make this consistent 887 // exceptions can be thrown in expected error conditions (not NREs) then make this consistent
881 // since other normal error conditions will simply return false instead. 888 // since other normal error conditions will simply return false instead.
882 // This will throw if the attachment fails 889 // This will throw if the attachment fails
883 try 890 try
884 { 891 {
885 AttachObjectInternal(sp, objatt, attachmentPt, false, false, append); 892 AttachObjectInternal(sp, objatt, attachmentPt, false, false, append);
886 } 893 }
887 catch (Exception e) 894 catch (Exception e)
888 { 895 {
889 m_log.ErrorFormat( 896 m_log.ErrorFormat(
890 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", 897 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
891 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); 898 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
892
893 // Make sure the object doesn't stick around and bail
894 sp.RemoveAttachment(objatt);
895 m_scene.DeleteSceneObject(objatt, false);
896 return null;
897 }
898
899 if (tainted)
900 objatt.HasGroupChanged = true;
901 899
902 // Fire after attach, so we don't get messy perms dialogs 900 // Make sure the object doesn't stick around and bail
903 // 4 == AttachedRez 901 sp.RemoveAttachment(objatt);
904 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); 902 m_scene.DeleteSceneObject(objatt, false);
905 objatt.ResumeScripts(); 903 return null;
904 }
906 905
907 // Do this last so that event listeners have access to all the effects of the attachment 906 if (tainted)
908 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); 907 objatt.HasGroupChanged = true;
909 908
910 return objatt; 909 return objatt;
911 }
912 } 910 }
913 911
914 /// <summary> 912 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index f48bb6f..0c1df6a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -228,6 +228,120 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
228 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); 228 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
229 } 229 }
230 230
231 [Test]
232 public void TestWearAttachmentFromGround()
233 {
234 TestHelpers.InMethod();
235// TestHelpers.EnableLogging();
236
237 Scene scene = CreateTestScene();
238 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
239 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
240
241 SceneObjectGroup so2 = SceneHelpers.AddSceneObject(scene, "att2", sp.UUID);
242
243 {
244 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID);
245
246 m_numberOfAttachEventsFired = 0;
247 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false);
248
249 // Check status on scene presence
250 Assert.That(sp.HasAttachments(), Is.True);
251 List<SceneObjectGroup> attachments = sp.GetAttachments();
252 Assert.That(attachments.Count, Is.EqualTo(1));
253 SceneObjectGroup attSo = attachments[0];
254 Assert.That(attSo.Name, Is.EqualTo(so.Name));
255 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
256 Assert.That(attSo.IsAttachment);
257 Assert.That(attSo.UsesPhysics, Is.False);
258 Assert.That(attSo.IsTemporary, Is.False);
259
260 // Check item status
261 Assert.That(
262 sp.Appearance.GetAttachpoint(attSo.FromItemID),
263 Is.EqualTo((int)AttachmentPoint.LeftHand));
264
265 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
266 Assert.That(attachmentItem, Is.Not.Null);
267 Assert.That(attachmentItem.Name, Is.EqualTo(so.Name));
268
269 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
270 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
271
272 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2));
273
274 // Check events
275 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
276 }
277
278 // Test wearing a different attachment from the ground.
279 {
280 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false);
281
282 // Check status on scene presence
283 Assert.That(sp.HasAttachments(), Is.True);
284 List<SceneObjectGroup> attachments = sp.GetAttachments();
285 Assert.That(attachments.Count, Is.EqualTo(1));
286 SceneObjectGroup attSo = attachments[0];
287 Assert.That(attSo.Name, Is.EqualTo(so2.Name));
288 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
289 Assert.That(attSo.IsAttachment);
290 Assert.That(attSo.UsesPhysics, Is.False);
291 Assert.That(attSo.IsTemporary, Is.False);
292
293 // Check item status
294 Assert.That(
295 sp.Appearance.GetAttachpoint(attSo.FromItemID),
296 Is.EqualTo((int)AttachmentPoint.LeftHand));
297
298 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
299 Assert.That(attachmentItem, Is.Not.Null);
300 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
301
302 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
303 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
304
305 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
306
307 // Check events
308 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
309 }
310
311 // Test rewearing an already worn attachment from ground. Nothing should happen.
312 {
313 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false);
314
315 // Check status on scene presence
316 Assert.That(sp.HasAttachments(), Is.True);
317 List<SceneObjectGroup> attachments = sp.GetAttachments();
318 Assert.That(attachments.Count, Is.EqualTo(1));
319 SceneObjectGroup attSo = attachments[0];
320 Assert.That(attSo.Name, Is.EqualTo(so2.Name));
321 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
322 Assert.That(attSo.IsAttachment);
323 Assert.That(attSo.UsesPhysics, Is.False);
324 Assert.That(attSo.IsTemporary, Is.False);
325
326 // Check item status
327 Assert.That(
328 sp.Appearance.GetAttachpoint(attSo.FromItemID),
329 Is.EqualTo((int)AttachmentPoint.LeftHand));
330
331 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
332 Assert.That(attachmentItem, Is.Not.Null);
333 Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
334
335 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
336 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
337
338 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
339
340 // Check events
341 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
342 }
343 }
344
231 /// <summary> 345 /// <summary>
232 /// Test that we do not attempt to attach an in-world object that someone else is sitting on. 346 /// Test that we do not attempt to attach an in-world object that someone else is sitting on.
233 /// </summary> 347 /// </summary>
@@ -275,29 +389,140 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
275 389
276 InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); 390 InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
277 391
278 m_numberOfAttachEventsFired = 0; 392 {
279 scene.AttachmentsModule.RezSingleAttachmentFromInventory( 393 scene.AttachmentsModule.RezSingleAttachmentFromInventory(
280 sp, attItem.ID, (uint)AttachmentPoint.Chest); 394 sp, attItem.ID, (uint)AttachmentPoint.Chest);
281 395
282 // Check scene presence status 396 // Check scene presence status
283 Assert.That(sp.HasAttachments(), Is.True); 397 Assert.That(sp.HasAttachments(), Is.True);
284 List<SceneObjectGroup> attachments = sp.GetAttachments(); 398 List<SceneObjectGroup> attachments = sp.GetAttachments();
285 Assert.That(attachments.Count, Is.EqualTo(1)); 399 Assert.That(attachments.Count, Is.EqualTo(1));
286 SceneObjectGroup attSo = attachments[0]; 400 SceneObjectGroup attSo = attachments[0];
287 Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); 401 Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
288 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); 402 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
289 Assert.That(attSo.IsAttachment); 403 Assert.That(attSo.IsAttachment);
290 Assert.That(attSo.UsesPhysics, Is.False); 404 Assert.That(attSo.UsesPhysics, Is.False);
291 Assert.That(attSo.IsTemporary, Is.False); 405 Assert.That(attSo.IsTemporary, Is.False);
406
407 // Check appearance status
408 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
409 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
410 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
411
412 // Check events
413 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
414 }
415
416 // Test attaching an already attached attachment
417 {
418 scene.AttachmentsModule.RezSingleAttachmentFromInventory(
419 sp, attItem.ID, (uint)AttachmentPoint.Chest);
292 420
293 // Check appearance status 421 // Check scene presence status
294 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); 422 Assert.That(sp.HasAttachments(), Is.True);
295 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); 423 List<SceneObjectGroup> attachments = sp.GetAttachments();
424 Assert.That(attachments.Count, Is.EqualTo(1));
425 SceneObjectGroup attSo = attachments[0];
426 Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
427 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
428 Assert.That(attSo.IsAttachment);
429 Assert.That(attSo.UsesPhysics, Is.False);
430 Assert.That(attSo.IsTemporary, Is.False);
431
432 // Check appearance status
433 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
434 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
435 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
436
437 // Check events
438 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
439 }
440 }
296 441
297 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 442 /// <summary>
443 /// Test wearing an attachment from inventory, as opposed to explicit choosing the rez point
444 /// </summary>
445 [Test]
446 public void TestWearAttachmentFromInventory()
447 {
448 TestHelpers.InMethod();
449// TestHelpers.EnableLogging();
298 450
299 // Check events 451 Scene scene = CreateTestScene();
300 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); 452 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
453 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
454
455 InventoryItemBase attItem1 = CreateAttachmentItem(scene, ua1.PrincipalID, "att1", 0x10, 0x20);
456 InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21);
457
458 {
459 m_numberOfAttachEventsFired = 0;
460 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default);
461
462 // default attachment point is currently the left hand.
463 Assert.That(sp.HasAttachments(), Is.True);
464 List<SceneObjectGroup> attachments = sp.GetAttachments();
465 Assert.That(attachments.Count, Is.EqualTo(1));
466 SceneObjectGroup attSo = attachments[0];
467 Assert.That(attSo.Name, Is.EqualTo(attItem1.Name));
468 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
469 Assert.That(attSo.IsAttachment);
470
471 // Check appearance status
472 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
473 Assert.That(sp.Appearance.GetAttachpoint(attItem1.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
474 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
475
476 // Check events
477 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
478 }
479
480 // Test wearing a second attachment at the same position
481 // Until multiple attachments at one point is implemented, this will remove the first attachment
482 // This test relies on both attachments having the same default attachment point (in this case LeftHand
483 // since none other has been set).
484 {
485 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default);
486
487 // default attachment point is currently the left hand.
488 Assert.That(sp.HasAttachments(), Is.True);
489 List<SceneObjectGroup> attachments = sp.GetAttachments();
490 Assert.That(attachments.Count, Is.EqualTo(1));
491 SceneObjectGroup attSo = attachments[0];
492 Assert.That(attSo.Name, Is.EqualTo(attItem2.Name));
493 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
494 Assert.That(attSo.IsAttachment);
495
496 // Check appearance status
497 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
498 Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
499 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
500
501 // Check events
502 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
503 }
504
505 // Test wearing an already attached attachment
506 {
507 scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default);
508
509 // default attachment point is currently the left hand.
510 Assert.That(sp.HasAttachments(), Is.True);
511 List<SceneObjectGroup> attachments = sp.GetAttachments();
512 Assert.That(attachments.Count, Is.EqualTo(1));
513 SceneObjectGroup attSo = attachments[0];
514 Assert.That(attSo.Name, Is.EqualTo(attItem2.Name));
515 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
516 Assert.That(attSo.IsAttachment);
517
518 // Check appearance status
519 Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
520 Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
521 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
522
523 // Check events
524 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
525 }
301 } 526 }
302 527
303 /// <summary> 528 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
index 37131b9..1f1568f 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
@@ -39,7 +39,7 @@ using OpenSim.Region.Framework;
39using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41 41
42namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule 42namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
43{ 43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")] 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
45 public class DAExampleModule : INonSharedRegionModule 45 public class DAExampleModule : INonSharedRegionModule
@@ -48,6 +48,8 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule
48 48
49 private static readonly bool ENABLED = false; // enable for testing 49 private static readonly bool ENABLED = false; // enable for testing
50 50
51 public const string DANamespace = "DAExample Module";
52
51 protected Scene m_scene; 53 protected Scene m_scene;
52 protected IDialogModule m_dialogMod; 54 protected IDialogModule m_dialogMod;
53 55
@@ -85,19 +87,29 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule
85 { 87 {
86 OSDMap attrs = null; 88 OSDMap attrs = null;
87 SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId); 89 SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId);
88 if (!sop.DynAttrs.TryGetValue(Name, out attrs)) 90
91 if (sop == null)
92 return true;
93
94 if (!sop.DynAttrs.TryGetValue(DANamespace, out attrs))
89 attrs = new OSDMap(); 95 attrs = new OSDMap();
90 96
91 OSDInteger newValue; 97 OSDInteger newValue;
92
93 if (!attrs.ContainsKey("moves"))
94 newValue = new OSDInteger(1);
95 else
96 newValue = new OSDInteger(((OSDInteger)attrs["moves"]).AsInteger() + 1);
97
98 attrs["moves"] = newValue;
99 98
100 sop.DynAttrs[Name] = attrs; 99 // We have to lock on the entire dynamic attributes map to avoid race conditions with serialization code.
100 lock (sop.DynAttrs)
101 {
102 if (!attrs.ContainsKey("moves"))
103 newValue = new OSDInteger(1);
104 else
105 newValue = new OSDInteger(attrs["moves"].AsInteger() + 1);
106
107 attrs["moves"] = newValue;
108
109 sop.DynAttrs[DANamespace] = attrs;
110 }
111
112 sop.ParentGroup.HasGroupChanged = true;
101 113
102 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); 114 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue));
103 115
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
new file mode 100644
index 0000000..650aa35
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
@@ -0,0 +1,139 @@
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.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.Packets;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework;
39using OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42
43namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
44{
45 /// <summary>
46 /// Example module for experimenting with and demonstrating dynamic object ideas.
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DOExampleModule")]
49 public class DOExampleModule : INonSharedRegionModule
50 {
51 public class MyObject
52 {
53 public int Moves { get; set; }
54
55 public MyObject(int moves)
56 {
57 Moves = moves;
58 }
59 }
60
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62
63 private static readonly bool ENABLED = false; // enable for testing
64
65 private Scene m_scene;
66 private IDialogModule m_dialogMod;
67
68 public string Name { get { return "DOExample Module"; } }
69 public Type ReplaceableInterface { get { return null; } }
70
71 public void Initialise(IConfigSource source) {}
72
73 public void AddRegion(Scene scene)
74 {
75 if (ENABLED)
76 {
77 m_scene = scene;
78 m_scene.EventManager.OnObjectAddedToScene += OnObjectAddedToScene;
79 m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove;
80 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
81 }
82 }
83
84 public void RemoveRegion(Scene scene)
85 {
86 if (ENABLED)
87 {
88 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
89 }
90 }
91
92 public void RegionLoaded(Scene scene) {}
93
94 public void Close()
95 {
96 RemoveRegion(m_scene);
97 }
98
99 private void OnObjectAddedToScene(SceneObjectGroup so)
100 {
101 SceneObjectPart rootPart = so.RootPart;
102
103 OSDMap attrs;
104
105 int movesSoFar = 0;
106
107// Console.WriteLine("Here for {0}", so.Name);
108
109 if (rootPart.DynAttrs.TryGetValue(DAExampleModule.DANamespace, out attrs))
110 {
111 movesSoFar = attrs["moves"].AsInteger();
112
113 m_log.DebugFormat(
114 "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name);
115 }
116
117 rootPart.DynObjs.Add(Name, new MyObject(movesSoFar));
118 }
119
120 private bool OnSceneGroupMove(UUID groupId, Vector3 delta)
121 {
122 SceneObjectGroup so = m_scene.GetSceneObjectGroup(groupId);
123
124 if (so == null)
125 return true;
126
127 object rawObj = so.RootPart.DynObjs.Get(Name);
128
129 if (rawObj != null)
130 {
131 MyObject myObj = (MyObject)rawObj;
132
133 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", so.Name, so.UUID, ++myObj.Moves));
134 }
135
136 return true;
137 }
138 }
139} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 07c3666..9b1b69a 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -66,6 +66,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
66 /// </summary> 66 /// </summary>
67 public bool WaitForAgentArrivedAtDestination { get; set; } 67 public bool WaitForAgentArrivedAtDestination { get; set; }
68 68
69 /// <summary>
70 /// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests.
71 /// </summary>
72 /// <remarks>
73 /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a
74 /// situation where avatars can be come 'stuck' due to a failed teleport cancellation. Unfortunately, the
75 /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport
76 /// cancellation consistently suceed.
77 /// </remarks>
78 public bool DisableInterRegionTeleportCancellation { get; set; }
79
69 protected bool m_Enabled = false; 80 protected bool m_Enabled = false;
70 81
71 public Scene Scene { get; private set; } 82 public Scene Scene { get; private set; }
@@ -116,6 +127,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
116 IConfig transferConfig = source.Configs["EntityTransfer"]; 127 IConfig transferConfig = source.Configs["EntityTransfer"];
117 if (transferConfig != null) 128 if (transferConfig != null)
118 { 129 {
130 DisableInterRegionTeleportCancellation
131 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
132
119 WaitForAgentArrivedAtDestination 133 WaitForAgentArrivedAtDestination
120 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); 134 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault);
121 135
@@ -150,6 +164,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
150 { 164 {
151 client.OnTeleportHomeRequest += TeleportHome; 165 client.OnTeleportHomeRequest += TeleportHome;
152 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 166 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
167
168 if (!DisableInterRegionTeleportCancellation)
169 client.OnTeleportCancel += OnClientCancelTeleport;
153 } 170 }
154 171
155 public virtual void Close() {} 172 public virtual void Close() {}
@@ -168,6 +185,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
168 185
169 #region Agent Teleports 186 #region Agent Teleports
170 187
188 private void OnClientCancelTeleport(IClientAPI client)
189 {
190 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
191
192 m_log.DebugFormat(
193 "[ENTITY TRANSFER MODULE]: Received teleport cancel request from {0} in {1}", client.Name, Scene.Name);
194 }
195
171 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) 196 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags)
172 { 197 {
173 if (sp.Scene.Permissions.IsGridGod(sp.UUID)) 198 if (sp.Scene.Permissions.IsGridGod(sp.UUID))
@@ -519,6 +544,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
519 if (sp.ParentID != (uint)0) 544 if (sp.ParentID != (uint)0)
520 sp.StandUp(); 545 sp.StandUp();
521 546
547 if (DisableInterRegionTeleportCancellation)
548 teleportFlags |= (uint)TeleportFlags.DisableCancel;
549
522 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to 550 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
523 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). 551 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
524 sp.ControllingClient.SendTeleportStart(teleportFlags); 552 sp.ControllingClient.SendTeleportStart(teleportFlags);
@@ -567,6 +595,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
567 return; 595 return;
568 } 596 }
569 597
598 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
599 {
600 m_log.DebugFormat(
601 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
602 sp.Name, finalDestination.RegionName, sp.Scene.Name);
603
604 return;
605 }
606
570 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 607 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
571 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 608 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
572 609
@@ -631,7 +668,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
631 return; 668 return;
632 } 669 }
633 670
634 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); 671 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
672 {
673 m_log.DebugFormat(
674 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
675 sp.Name, finalDestination.RegionName, sp.Scene.Name);
676
677 CleanupAbortedInterRegionTeleport(sp, finalDestination);
678
679 return;
680 }
635 681
636 m_log.DebugFormat( 682 m_log.DebugFormat(
637 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", 683 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
@@ -714,14 +760,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
714// } 760// }
715 } 761 }
716 762
717 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) 763 /// <summary>
764 /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation.
765 /// </summary>
766 /// <remarks>
767 /// All operations here must be idempotent so that we can call this method at any point in the teleport process
768 /// up until we send the TeleportFinish event quene event to the viewer.
769 /// <remarks>
770 /// <param name='sp'> </param>
771 /// <param name='finalDestination'></param>
772 protected virtual void CleanupAbortedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
718 { 773 {
719 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 774 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
720 775
721 // Client never contacted destination. Let's restore everything back
722 sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
723
724 // Fail. Reset it back
725 sp.IsChildAgent = false; 776 sp.IsChildAgent = false;
726 ReInstantiateScripts(sp); 777 ReInstantiateScripts(sp);
727 778
@@ -729,7 +780,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
729 780
730 // Finally, kill the agent we just created at the destination. 781 // Finally, kill the agent we just created at the destination.
731 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); 782 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
783 }
732 784
785 /// <summary>
786 /// Signal that the inter-region teleport failed and perform cleanup.
787 /// </summary>
788 /// <param name='sp'></param>
789 /// <param name='finalDestination'></param>
790 /// <param name='logout'></param>
791 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
792 {
793 CleanupAbortedInterRegionTeleport(sp, finalDestination);
794
795 sp.ControllingClient.SendTeleportFailed(
796 string.Format("Problems connecting to destination {0}", finalDestination.RegionName));
733 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 797 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
734 } 798 }
735 799
@@ -1206,6 +1270,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1206 // region doesn't take it 1270 // region doesn't take it
1207 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1271 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1208 1272
1273 m_log.WarnFormat(
1274 "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.",
1275 neighbourRegion.RegionName, agent.Name);
1276
1209 ReInstantiateScripts(agent); 1277 ReInstantiateScripts(agent);
1210 agent.AddToPhysicalScene(isFlying); 1278 agent.AddToPhysicalScene(isFlying);
1211 1279
@@ -1225,6 +1293,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1225 neighbourRegion.RegionHandle); 1293 neighbourRegion.RegionHandle);
1226 return agent; 1294 return agent;
1227 } 1295 }
1296
1228 // No turning back 1297 // No turning back
1229 agent.IsChildAgent = true; 1298 agent.IsChildAgent = true;
1230 1299
@@ -2092,7 +2161,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2092 2161
2093 public bool IsInTransit(UUID id) 2162 public bool IsInTransit(UUID id)
2094 { 2163 {
2095 return m_entityTransferStateMachine.IsInTransit(id); 2164 return m_entityTransferStateMachine.GetAgentTransferState(id) != null;
2096 } 2165 }
2097 2166
2098 protected void ReInstantiateScripts(ScenePresence sp) 2167 protected void ReInstantiateScripts(ScenePresence sp)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index d0cab49..24d81d9 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -51,8 +51,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
51 /// This is a state machine. 51 /// This is a state machine.
52 /// 52 ///
53 /// [Entry] => Preparing 53 /// [Entry] => Preparing
54 /// Preparing => { Transferring || CleaningUp || [Exit] } 54 /// Preparing => { Transferring || Cancelling || CleaningUp || [Exit] }
55 /// Transferring => { ReceivedAtDestination || CleaningUp } 55 /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp }
56 /// Cancelling => CleaningUp
56 /// ReceivedAtDestination => CleaningUp 57 /// ReceivedAtDestination => CleaningUp
57 /// CleaningUp => [Exit] 58 /// CleaningUp => [Exit]
58 /// 59 ///
@@ -64,7 +65,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
64 Preparing, // The agent is being prepared for transfer 65 Preparing, // The agent is being prepared for transfer
65 Transferring, // The agent is in the process of being transferred to a destination 66 Transferring, // The agent is in the process of being transferred to a destination
66 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received 67 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
67 CleaningUp // The agent is being changed to child/removed after a transfer 68 CleaningUp, // The agent is being changed to child/removed after a transfer
69 Cancelling // The user has cancelled the teleport but we have yet to act upon this.
68 } 70 }
69 71
70 /// <summary> 72 /// <summary>
@@ -115,42 +117,110 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
115 /// <param name='newState'></param> 117 /// <param name='newState'></param>
116 /// <returns></returns> 118 /// <returns></returns>
117 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> 119 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
118 internal void UpdateInTransit(UUID id, AgentTransferState newState) 120 internal bool UpdateInTransit(UUID id, AgentTransferState newState)
119 { 121 {
122 bool transitionOkay = false;
123
124 // We don't want to throw an exception on cancel since this can come it at any time.
125 bool failIfNotOkay = true;
126
127 // Should be a failure message if failure is not okay.
128 string failureMessage = null;
129
130 AgentTransferState? oldState = null;
131
120 lock (m_agentsInTransit) 132 lock (m_agentsInTransit)
121 { 133 {
122 // Illegal to try and update an agent that's not actually in transit. 134 // Illegal to try and update an agent that's not actually in transit.
123 if (!m_agentsInTransit.ContainsKey(id)) 135 if (!m_agentsInTransit.ContainsKey(id))
124 throw new Exception( 136 {
125 string.Format( 137 if (newState != AgentTransferState.Cancelling)
126 "Agent with ID {0} is not registered as in transit in {1}", 138 failureMessage = string.Format(
127 id, m_mod.Scene.RegionInfo.RegionName)); 139 "Agent with ID {0} is not registered as in transit in {1}",
128 140 id, m_mod.Scene.RegionInfo.RegionName);
129 AgentTransferState oldState = m_agentsInTransit[id]; 141 else
142 failIfNotOkay = false;
143 }
144 else
145 {
146 oldState = m_agentsInTransit[id];
130 147
131 bool transitionOkay = false; 148 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
149 {
150 transitionOkay = true;
151 }
152 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
153 {
154 transitionOkay = true;
155 }
156 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
157 {
158 transitionOkay = true;
159 }
160 else
161 {
162 if (newState == AgentTransferState.Cancelling
163 && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring))
164 {
165 transitionOkay = true;
166 }
167 else
168 {
169 failIfNotOkay = false;
170 }
171 }
132 172
133 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) 173 if (!transitionOkay)
134 transitionOkay = true; 174 failureMessage
135 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) 175 = string.Format(
136 transitionOkay = true; 176 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
137 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) 177 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName);
138 transitionOkay = true; 178 }
139 179
140 if (transitionOkay) 180 if (transitionOkay)
181 {
141 m_agentsInTransit[id] = newState; 182 m_agentsInTransit[id] = newState;
142 else 183
143 throw new Exception( 184// m_log.DebugFormat(
144 string.Format( 185// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}",
145 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", 186// id, oldState, newState, m_mod.Scene.Name);
146 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName)); 187 }
188 else if (failIfNotOkay)
189 {
190 throw new Exception(failureMessage);
191 }
192// else
193// {
194// if (oldState != null)
195// m_log.DebugFormat(
196// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}",
197// id, oldState, newState, m_mod.Scene.Name);
198// else
199// m_log.DebugFormat(
200// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit",
201// id, newState, m_mod.Scene.Name);
202// }
147 } 203 }
204
205 return transitionOkay;
148 } 206 }
149 207
150 internal bool IsInTransit(UUID id) 208 /// <summary>
209 /// Gets the current agent transfer state.
210 /// </summary>
211 /// <returns>Null if the agent is not in transit</returns>
212 /// <param name='id'>
213 /// Identifier.
214 /// </param>
215 internal AgentTransferState? GetAgentTransferState(UUID id)
151 { 216 {
152 lock (m_agentsInTransit) 217 lock (m_agentsInTransit)
153 return m_agentsInTransit.ContainsKey(id); 218 {
219 if (!m_agentsInTransit.ContainsKey(id))
220 return null;
221 else
222 return m_agentsInTransit[id];
223 }
154 } 224 }
155 225
156 /// <summary> 226 /// <summary>
@@ -203,14 +273,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
203 273
204 lock (m_agentsInTransit) 274 lock (m_agentsInTransit)
205 { 275 {
206 if (!IsInTransit(id)) 276 AgentTransferState? currentState = GetAgentTransferState(id);
277
278 if (currentState == null)
207 throw new Exception( 279 throw new Exception(
208 string.Format( 280 string.Format(
209 "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit", 281 "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit",
210 id, m_mod.Scene.RegionInfo.RegionName)); 282 id, m_mod.Scene.RegionInfo.RegionName));
211 283
212 AgentTransferState currentState = m_agentsInTransit[id];
213
214 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) 284 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination)
215 throw new Exception( 285 throw new Exception(
216 string.Format( 286 string.Format(
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index 4c9ee06..64feec1 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -414,8 +414,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
414 } 414 }
415 private void RegisterStatsManagerRegionStatistics() 415 private void RegisterStatsManagerRegionStatistics()
416 { 416 {
417 string regionName = m_scene.RegionInfo.RegionName;
418
419 MakeStat("RootAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetRootAgentCount(); }); 417 MakeStat("RootAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetRootAgentCount(); });
420 MakeStat("ChildAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetChildAgentCount(); }); 418 MakeStat("ChildAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetChildAgentCount(); });
421 MakeStat("TotalPrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetTotalObjectsCount(); }); 419 MakeStat("TotalPrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetTotalObjectsCount(); });
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index f04fabe..4cecd85 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -516,6 +516,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
516 foreach (string line in GetLines(data, dataDelim)) 516 foreach (string line in GetLines(data, dataDelim))
517 { 517 {
518 string nextLine = line.Trim(); 518 string nextLine = line.Trim();
519
520// m_log.DebugFormat("[VECTOR RENDER MODULE]: Processing line '{0}'", nextLine);
521
519 //replace with switch, or even better, do some proper parsing 522 //replace with switch, or even better, do some proper parsing
520 if (nextLine.StartsWith("MoveTo")) 523 if (nextLine.StartsWith("MoveTo"))
521 { 524 {
@@ -829,6 +832,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
829 float y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture); 832 float y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture);
830 PointF point = new PointF(x, y); 833 PointF point = new PointF(x, y);
831 points[i / 2] = point; 834 points[i / 2] = point;
835
836// m_log.DebugFormat("[VECTOR RENDER MODULE]: Got point {0}", points[i / 2]);
832 } 837 }
833 } 838 }
834 } 839 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 3c18074..a413546 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -219,12 +219,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
219 { 219 {
220// m_log.DebugFormat( 220// m_log.DebugFormat(
221// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", 221// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
222// s.RegionInfo.RegionName, destination.RegionHandle); 222// destination.RegionName, destination.RegionID);
223 223
224 return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); 224 return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData);
225 } 225 }
226 226
227// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); 227// m_log.DebugFormat(
228// "[LOCAL COMMS]: Did not find region {0} {1} for ChildAgentUpdate",
229// destination.RegionName, destination.RegionID);
230
228 return false; 231 return false;
229 } 232 }
230 233
@@ -239,7 +242,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
239 // note that we really don't need the GridRegion for this call 242 // note that we really don't need the GridRegion for this call
240 foreach (Scene s in m_scenes.Values) 243 foreach (Scene s in m_scenes.Values)
241 { 244 {
242 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); 245// m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
243 s.IncomingChildAgentDataUpdate(cAgentData); 246 s.IncomingChildAgentDataUpdate(cAgentData);
244 } 247 }
245 248
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index 7fc358d..73c592d 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -95,6 +95,11 @@ namespace OpenSim.Region.CoreModules.World.Land
95 return null; 95 return null;
96 } 96 }
97 97
98 public ILandObject GetLandObject(Vector3 position)
99 {
100 return GetLandObject(position.X, position.Y);
101 }
102
98 public ILandObject GetLandObject(int x, int y) 103 public ILandObject GetLandObject(int x, int y)
99 { 104 {
100 if (m_landManagementModule != null) 105 if (m_landManagementModule != null)
diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
index 345f01b..b67312e 100644
--- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
@@ -41,6 +41,16 @@ namespace OpenSim.Region.Framework.Interfaces
41 Value = 3 41 Value = 3
42 } 42 }
43 43
44 public enum JsonStoreValueType
45 {
46 Undefined = 0,
47 Boolean = 1,
48 Integer = 2,
49 Float = 3,
50 String = 4,
51 UUID = 5
52 }
53
44 public delegate void TakeValueCallback(string s); 54 public delegate void TakeValueCallback(string s);
45 55
46 public interface IJsonStoreModule 56 public interface IJsonStoreModule
@@ -49,7 +59,9 @@ namespace OpenSim.Region.Framework.Interfaces
49 bool CreateStore(string value, ref UUID result); 59 bool CreateStore(string value, ref UUID result);
50 bool DestroyStore(UUID storeID); 60 bool DestroyStore(UUID storeID);
51 61
52 JsonStoreNodeType GetPathType(UUID storeID, string path); 62 JsonStoreNodeType GetNodeType(UUID storeID, string path);
63 JsonStoreValueType GetValueType(UUID storeID, string path);
64
53 bool TestStore(UUID storeID); 65 bool TestStore(UUID storeID);
54 66
55 bool SetValue(UUID storeID, string path, string value, bool useJson); 67 bool SetValue(UUID storeID, string path, string value, bool useJson);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index cce8b21..a8b63fe 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -129,6 +129,27 @@ namespace OpenSim.Region.Framework.Scenes
129 /// Dynamic attributes can be created and deleted as required. 129 /// Dynamic attributes can be created and deleted as required.
130 /// </summary> 130 /// </summary>
131 public DAMap DynAttrs { get; set; } 131 public DAMap DynAttrs { get; set; }
132
133 private DOMap m_dynObjs;
134
135 /// <summary>
136 /// Dynamic objects that can be created and deleted as required.
137 /// </summary>
138 public DOMap DynObjs
139 {
140 get
141 {
142 if (m_dynObjs == null)
143 m_dynObjs = new DOMap();
144
145 return m_dynObjs;
146 }
147
148 set
149 {
150 m_dynObjs = value;
151 }
152 }
132 153
133 /// <value> 154 /// <value>
134 /// Is this a root part? 155 /// Is this a root part?
@@ -4503,8 +4524,25 @@ namespace OpenSim.Region.Framework.Scenes
4503 4524
4504 Changed changeFlags = 0; 4525 Changed changeFlags = 0;
4505 4526
4527 Primitive.TextureEntryFace fallbackNewFace = newTex.DefaultTexture;
4528 Primitive.TextureEntryFace fallbackOldFace = oldTex.DefaultTexture;
4529
4530 // On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all
4531 // other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point.
4532 if (fallbackNewFace == null)
4533 {
4534 fallbackNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
4535 newTex.DefaultTexture = fallbackNewFace;
4536 }
4537 if (fallbackOldFace == null)
4538 {
4539 fallbackOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0);
4540 oldTex.DefaultTexture = fallbackOldFace;
4541 }
4542
4506 for (int i = 0 ; i < GetNumberOfSides(); i++) 4543 for (int i = 0 ; i < GetNumberOfSides(); i++)
4507 { 4544 {
4545
4508 Primitive.TextureEntryFace newFace = newTex.DefaultTexture; 4546 Primitive.TextureEntryFace newFace = newTex.DefaultTexture;
4509 Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; 4547 Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture;
4510 4548
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 39a885c..82bb759 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -559,16 +559,28 @@ namespace OpenSim.Region.Framework.Scenes
559 559
560 private Quaternion m_bodyRot = Quaternion.Identity; 560 private Quaternion m_bodyRot = Quaternion.Identity;
561 561
562 /// <summary>
563 /// The rotation of the avatar.
564 /// </summary>
565 /// <remarks>
566 /// If the avatar is not sitting, this is with respect to the world
567 /// If the avatar is sitting, this is a with respect to the part that it's sitting upon (a local rotation).
568 /// If you always want the world rotation, use GetWorldRotation()
569 /// </remarks>
562 public Quaternion Rotation 570 public Quaternion Rotation
563 { 571 {
564 get { return m_bodyRot; } 572 get
573 {
574 return m_bodyRot;
575 }
576
565 set 577 set
566 { 578 {
567 m_bodyRot = value; 579 m_bodyRot = value;
580
568 if (PhysicsActor != null) 581 if (PhysicsActor != null)
569 {
570 PhysicsActor.Orientation = m_bodyRot; 582 PhysicsActor.Orientation = m_bodyRot;
571 } 583
572// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 584// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
573 } 585 }
574 } 586 }
@@ -608,6 +620,26 @@ namespace OpenSim.Region.Framework.Scenes
608 set { m_health = value; } 620 set { m_health = value; }
609 } 621 }
610 622
623 /// <summary>
624 /// Gets the world rotation of this presence.
625 /// </summary>
626 /// <remarks>
627 /// Unlike Rotation, this returns the world rotation no matter whether the avatar is sitting on a prim or not.
628 /// </remarks>
629 /// <returns></returns>
630 public Quaternion GetWorldRotation()
631 {
632 if (IsSatOnObject)
633 {
634 SceneObjectPart sitPart = ParentPart;
635
636 if (sitPart != null)
637 return sitPart.GetWorldRotation() * Rotation;
638 }
639
640 return Rotation;
641 }
642
611 public void AdjustKnownSeeds() 643 public void AdjustKnownSeeds()
612 { 644 {
613 Dictionary<ulong, string> seeds; 645 Dictionary<ulong, string> seeds;
@@ -709,8 +741,6 @@ namespace OpenSim.Region.Framework.Scenes
709 741
710 #endregion 742 #endregion
711 743
712
713
714 #region Constructor(s) 744 #region Constructor(s)
715 745
716 public ScenePresence( 746 public ScenePresence(
@@ -1613,32 +1643,28 @@ namespace OpenSim.Region.Framework.Scenes
1613 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || 1643 bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
1614 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 1644 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
1615 1645
1616
1617 //m_log.Debug("[CONTROL]: " +flags); 1646 //m_log.Debug("[CONTROL]: " +flags);
1618 // Applies a satisfying roll effect to the avatar when flying. 1647 // Applies a satisfying roll effect to the avatar when flying.
1619 if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)) 1648 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0 && (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
1620 { 1649 {
1621 1650 ApplyFlyingRoll(
1622 ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0)); 1651 FLY_ROLL_RADIANS_PER_UPDATE,
1623 1652 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
1624 1653 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
1625 } 1654 }
1626 else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) && 1655 else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
1627 ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)) 1656 (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
1628 { 1657 {
1629 ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0)); 1658 ApplyFlyingRoll(
1630 1659 -FLY_ROLL_RADIANS_PER_UPDATE,
1631 1660 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
1661 (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
1632 } 1662 }
1633 else 1663 else
1634 { 1664 {
1635 if (m_AngularVelocity.Z != 0) 1665 if (m_AngularVelocity.Z != 0)
1636 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE); 1666 m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
1637 1667 }
1638 }
1639
1640
1641
1642 1668
1643 if (Flying && IsColliding && controlland) 1669 if (Flying && IsColliding && controlland)
1644 { 1670 {
@@ -2400,7 +2426,8 @@ namespace OpenSim.Region.Framework.Scenes
2400 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2426 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2401 public void AddNewMovement(Vector3 vec) 2427 public void AddNewMovement(Vector3 vec)
2402 { 2428 {
2403// m_log.DebugFormat("[SCENE PRESENCE]: Adding new movement {0} for {1}", vec, Name); 2429// m_log.DebugFormat(
2430// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1} for {2}", vec, Rotation, Name);
2404 2431
2405 Vector3 direc = vec * Rotation; 2432 Vector3 direc = vec * Rotation;
2406 direc.Normalize(); 2433 direc.Normalize();
@@ -2420,6 +2447,8 @@ namespace OpenSim.Region.Framework.Scenes
2420 2447
2421 direc *= 0.03f * 128f * SpeedModifier; 2448 direc *= 0.03f * 128f * SpeedModifier;
2422 2449
2450// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name);
2451
2423 if (PhysicsActor != null) 2452 if (PhysicsActor != null)
2424 { 2453 {
2425 if (Flying) 2454 if (Flying)
@@ -2453,6 +2482,8 @@ namespace OpenSim.Region.Framework.Scenes
2453 } 2482 }
2454 } 2483 }
2455 2484
2485// m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name);
2486
2456 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2487 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2457 m_forceToApply = direc; 2488 m_forceToApply = direc;
2458 } 2489 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
index 96973de..4883ae7 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs
@@ -110,8 +110,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
110 110
111 Vector3 firstSize = new Vector3(2, 3, 4); 111 Vector3 firstSize = new Vector3(2, 3, 4);
112 Vector3 secondSize = new Vector3(5, 6, 7); 112 Vector3 secondSize = new Vector3(5, 6, 7);
113 Vector3 thirdSize = new Vector3(8, 9, 10); 113// Vector3 thirdSize = new Vector3(8, 9, 10);
114 Vector3 fourthSize = new Vector3(11, 12, 13); 114// Vector3 fourthSize = new Vector3(11, 12, 13);
115 115
116 Scene scene = new SceneHelpers().SetupScene(); 116 Scene scene = new SceneHelpers().SetupScene();
117 scene.MaxUndoCount = 20; 117 scene.MaxUndoCount = 20;
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index 5faf131..bbfbbfc 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -289,108 +289,5 @@ namespace OpenSim.Region.Framework.Scenes.Tests
289// 289//
290// Assert.That(presence, Is.Null, "presence is not null"); 290// Assert.That(presence, Is.Null, "presence is not null");
291// } 291// }
292
293 // I'm commenting this test because it does not represent
294 // crossings. The Thread.Sleep's in here are not meaningful mocks,
295 // and they sometimes fail in panda.
296 // We need to talk in order to develop a test
297 // that really tests region crossings. There are 3 async components,
298 // but things are synchronous among them. So there should be
299 // 3 threads in here.
300 //[Test]
301// public void T021_TestCrossToNewRegion()
302// {
303// TestHelpers.InMethod();
304//
305// scene.RegisterRegionWithGrid();
306// scene2.RegisterRegionWithGrid();
307//
308// // Adding child agent to region 1001
309// string reason;
310// scene2.NewUserConnection(acd1,0, out reason);
311// scene2.AddNewClient(testclient, PresenceType.User);
312//
313// ScenePresence presence = scene.GetScenePresence(agent1);
314// presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true);
315//
316// ScenePresence presence2 = scene2.GetScenePresence(agent1);
317//
318// // Adding neighbour region caps info to presence2
319//
320// string cap = presence.ControllingClient.RequestClientInfo().CapsPath;
321// presence2.AddNeighbourRegion(region1, cap);
322//
323// Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region.");
324// Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region.");
325//
326// // Cross to x+1
327// presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100);
328// presence.Update();
329//
330// EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing");
331//
332// // Mimicking communication between client and server, by waiting OK from client
333// // sent by TestClient.CrossRegion call. Originally, this is network comm.
334// if (!wh.WaitOne(5000,false))
335// {
336// presence.Update();
337// if (!wh.WaitOne(8000,false))
338// throw new ArgumentException("1 - Timeout waiting for signal/variable.");
339// }
340//
341// // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which
342// // would normally be fired after receiving the reply packet from comm. done on the last line.
343// testclient.CompleteMovement();
344//
345// // Crossings are asynchronous
346// int timer = 10;
347//
348// // Make sure cross hasn't already finished
349// if (!presence.IsInTransit && !presence.IsChildAgent)
350// {
351// // If not and not in transit yet, give it some more time
352// Thread.Sleep(5000);
353// }
354//
355// // Enough time, should at least be in transit by now.
356// while (presence.IsInTransit && timer > 0)
357// {
358// Thread.Sleep(1000);
359// timer-=1;
360// }
361//
362// Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1.");
363// Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected.");
364// Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent.");
365//
366// // Cross Back
367// presence2.AbsolutePosition = new Vector3(-10, 3, 100);
368// presence2.Update();
369//
370// if (!wh.WaitOne(5000,false))
371// {
372// presence2.Update();
373// if (!wh.WaitOne(8000,false))
374// throw new ArgumentException("2 - Timeout waiting for signal/variable.");
375// }
376// testclient.CompleteMovement();
377//
378// if (!presence2.IsInTransit && !presence2.IsChildAgent)
379// {
380// // If not and not in transit yet, give it some more time
381// Thread.Sleep(5000);
382// }
383//
384// // Enough time, should at least be in transit by now.
385// while (presence2.IsInTransit && timer > 0)
386// {
387// Thread.Sleep(1000);
388// timer-=1;
389// }
390//
391// Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2.");
392// Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected.");
393// Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again.");
394// }
395 } 292 }
396} \ No newline at end of file 293} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
new file mode 100644
index 0000000..81a2fcc
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
@@ -0,0 +1,157 @@
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.Collections.Generic;
30using System.Reflection;
31using Nini.Config;
32using NUnit.Framework;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.CoreModules.Framework;
39using OpenSim.Region.CoreModules.Framework.EntityTransfer;
40using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
41using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock;
43
44namespace OpenSim.Region.Framework.Scenes.Tests
45{
46 [TestFixture]
47 public class ScenePresenceCrossingTests : OpenSimTestCase
48 {
49 [TestFixtureSetUp]
50 public void FixtureInit()
51 {
52 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
53 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
54 }
55
56 [TestFixtureTearDown]
57 public void TearDown()
58 {
59 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
60 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
61 // tests really shouldn't).
62 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
63 }
64
65 [Test]
66 public void TestCrossOnSameSimulator()
67 {
68 TestHelpers.InMethod();
69// TestHelpers.EnableLogging();
70
71 UUID userId = TestHelpers.ParseTail(0x1);
72
73// TestEventQueueGetModule eqmA = new TestEventQueueGetModule();
74 EntityTransferModule etmA = new EntityTransferModule();
75 EntityTransferModule etmB = new EntityTransferModule();
76 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
77
78 IConfigSource config = new IniConfigSource();
79 IConfig modulesConfig = config.AddConfig("Modules");
80 modulesConfig.Set("EntityTransferModule", etmA.Name);
81 modulesConfig.Set("SimulationServices", lscm.Name);
82// IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
83
84 // In order to run a single threaded regression test we do not want the entity transfer module waiting
85 // for a callback from the destination scene before removing its avatar data.
86// entityTransferConfig.Set("wait_for_callback", false);
87
88 SceneHelpers sh = new SceneHelpers();
89 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
90 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999);
91
92 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
93 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
94// SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, eqmA);
95 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
96
97 ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
98 originalSp.AbsolutePosition = new Vector3(128, 32, 10);
99
100// originalSp.Flying = true;
101
102// Console.WriteLine("First pos {0}", originalSp.AbsolutePosition);
103
104// eqmA.ClearEvents();
105
106 AgentUpdateArgs moveArgs = new AgentUpdateArgs();
107 //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero);
108 moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2)));
109 moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
110
111 originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs);
112
113 sceneA.Update(1);
114
115// Console.WriteLine("Second pos {0}", originalSp.AbsolutePosition);
116
117 // FIXME: This is a sufficient number of updates to for the presence to reach the northern border.
118 // But really we want to do this in a more robust way.
119 for (int i = 0; i < 100; i++)
120 {
121 sceneA.Update(1);
122// Console.WriteLine("Pos {0}", originalSp.AbsolutePosition);
123 }
124
125 // Need to sort processing of EnableSimulator message on adding scene presences before we can test eqm
126 // messages
127// Dictionary<UUID, List<TestEventQueueGetModule.Event>> eqmEvents = eqmA.Events;
128//
129// Assert.That(eqmEvents.Count, Is.EqualTo(1));
130// Assert.That(eqmEvents.ContainsKey(originalSp.UUID), Is.True);
131//
132// List<TestEventQueueGetModule.Event> spEqmEvents = eqmEvents[originalSp.UUID];
133//
134// Assert.That(spEqmEvents.Count, Is.EqualTo(1));
135// Assert.That(spEqmEvents[0].Name, Is.EqualTo("CrossRegion"));
136
137 // sceneA should now only have a child agent
138 ScenePresence spAfterCrossSceneA = sceneA.GetScenePresence(originalSp.UUID);
139 Assert.That(spAfterCrossSceneA.IsChildAgent, Is.True);
140
141 ScenePresence spAfterCrossSceneB = sceneB.GetScenePresence(originalSp.UUID);
142
143 // Agent remains a child until the client triggers complete movement
144 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.True);
145
146 TestClient sceneBTc = ((TestClient)spAfterCrossSceneB.ControllingClient);
147
148 int agentMovementCompleteReceived = 0;
149 sceneBTc.OnReceivedMoveAgentIntoRegion += (ri, pos, look) => agentMovementCompleteReceived++;
150
151 sceneBTc.CompleteMovement();
152
153 Assert.That(agentMovementCompleteReceived, Is.EqualTo(1));
154 Assert.That(spAfterCrossSceneB.IsChildAgent, Is.False);
155 }
156 }
157} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
index a3d2436..6e74ce0 100644
--- a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
+++ b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
@@ -140,9 +140,12 @@ public class ServerStats : ISharedRegionModule
140 } 140 }
141 #endregion ISharedRegionModule 141 #endregion ISharedRegionModule
142 142
143 private void MakeStat(string pName, string pUnit, string pContainer, Action<Stat> act) 143 private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action<Stat> act)
144 { 144 {
145 Stat stat = new Stat(pName, pName, "", pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info); 145 string desc = pDesc;
146 if (desc == null)
147 desc = pName;
148 Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info);
146 StatsManager.RegisterStat(stat); 149 StatsManager.RegisterStat(stat);
147 RegisteredStats.Add(pName, stat); 150 RegisteredStats.Add(pName, stat);
148 } 151 }
@@ -166,16 +169,16 @@ public class ServerStats : ISharedRegionModule
166 StatsManager.RegisterStat(tempStat); 169 StatsManager.RegisterStat(tempStat);
167 RegisteredStats.Add(tempName, tempStat); 170 RegisteredStats.Add(tempName, tempStat);
168 171
169 MakeStat("TotalProcessorTime", "sec", ContainerProcessor, 172 MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor,
170 (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; }); 173 (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; });
171 174
172 MakeStat("UserProcessorTime", "sec", ContainerProcessor, 175 MakeStat("UserProcessorTime", null, "sec", ContainerProcessor,
173 (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; }); 176 (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
174 177
175 MakeStat("PrivilegedProcessorTime", "sec", ContainerProcessor, 178 MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor,
176 (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; }); 179 (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; });
177 180
178 MakeStat("Threads", "threads", ContainerProcessor, 181 MakeStat("Threads", null, "threads", ContainerProcessor,
179 (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; }); 182 (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
180 } 183 }
181 catch (Exception e) 184 catch (Exception e)
@@ -196,8 +199,10 @@ public class ServerStats : ISharedRegionModule
196 string nicInterfaceType = nic.NetworkInterfaceType.ToString(); 199 string nicInterfaceType = nic.NetworkInterfaceType.ToString();
197 if (!okInterfaceTypes.Contains(nicInterfaceType)) 200 if (!okInterfaceTypes.Contains(nicInterfaceType))
198 { 201 {
199 m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'. To include, add to [Monitoring]NetworkInterfaceTypes='Ethernet,Loopback'", 202 m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.",
200 LogHeader, nic.Name, nicInterfaceType); 203 LogHeader, nic.Name, nicInterfaceType);
204 m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}",
205 LogHeader, NetworkInterfaceTypes);
201 continue; 206 continue;
202 } 207 }
203 208
@@ -206,14 +211,15 @@ public class ServerStats : ISharedRegionModule
206 IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics(); 211 IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics();
207 if (nicStats != null) 212 if (nicStats != null)
208 { 213 {
209 MakeStat("BytesRcvd/" + nic.Name, "KB", ContainerNetwork, 214 MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork,
210 (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); }); 215 (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); });
211 MakeStat("BytesSent/" + nic.Name, "KB", ContainerNetwork, 216 MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork,
212 (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); }); 217 (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); });
213 MakeStat("TotalBytes/" + nic.Name, "KB", ContainerNetwork, 218 MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork,
214 (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); }); 219 (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); });
215 } 220 }
216 } 221 }
222 // TODO: add IPv6 (it may actually happen someday)
217 } 223 }
218 } 224 }
219 catch (Exception e) 225 catch (Exception e)
@@ -221,13 +227,13 @@ public class ServerStats : ISharedRegionModule
221 m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e); 227 m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e);
222 } 228 }
223 229
224 MakeStat("ProcessMemory", "MB", ContainerMemory, 230 MakeStat("ProcessMemory", null, "MB", ContainerMemory,
225 (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; }); 231 (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; });
226 MakeStat("ObjectMemory", "MB", ContainerMemory, 232 MakeStat("ObjectMemory", null, "MB", ContainerMemory,
227 (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; }); 233 (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; });
228 MakeStat("LastMemoryChurn", "MB/sec", ContainerMemory, 234 MakeStat("LastMemoryChurn", null, "MB/sec", ContainerMemory,
229 (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); }); 235 (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); });
230 MakeStat("AverageMemoryChurn", "MB/sec", ContainerMemory, 236 MakeStat("AverageMemoryChurn", null, "MB/sec", ContainerMemory,
231 (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); }); 237 (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); });
232 } 238 }
233 239
@@ -263,6 +269,8 @@ public class ServerStats : ISharedRegionModule
263 } 269 }
264 } 270 }
265 271
272 // Lookup the nic that goes with this stat and set the value by using a fetch action.
273 // Not sure about closure with delegates inside delegates.
266 private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat); 274 private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat);
267 private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor) 275 private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor)
268 { 276 {
@@ -275,7 +283,10 @@ public class ServerStats : ISharedRegionModule
275 { 283 {
276 IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics(); 284 IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics();
277 if (intrStats != null) 285 if (intrStats != null)
278 stat.Value = Math.Round(getter(intrStats) / factor, 3); 286 {
287 double newVal = Math.Round(getter(intrStats) / factor, 3);
288 stat.Value = newVal;
289 }
279 break; 290 break;
280 } 291 }
281 } 292 }
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
index 40adba1..e498c6a 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
@@ -145,7 +145,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
145 /// 145 ///
146 /// </summary> 146 /// </summary>
147 // ----------------------------------------------------------------- 147 // -----------------------------------------------------------------
148 public JsonStoreNodeType PathType(string expr) 148 public JsonStoreNodeType GetNodeType(string expr)
149 { 149 {
150 Stack<string> path; 150 Stack<string> path;
151 if (! ParsePathExpression(expr,out path)) 151 if (! ParsePathExpression(expr,out path))
@@ -173,6 +173,43 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
173 /// 173 ///
174 /// </summary> 174 /// </summary>
175 // ----------------------------------------------------------------- 175 // -----------------------------------------------------------------
176 public JsonStoreValueType GetValueType(string expr)
177 {
178 Stack<string> path;
179 if (! ParsePathExpression(expr,out path))
180 return JsonStoreValueType.Undefined;
181
182 OSD result = ProcessPathExpression(ValueStore,path);
183
184 if (result == null)
185 return JsonStoreValueType.Undefined;
186
187 if (result is OSDMap)
188 return JsonStoreValueType.Undefined;
189
190 if (result is OSDArray)
191 return JsonStoreValueType.Undefined;
192
193 if (result is OSDBoolean)
194 return JsonStoreValueType.Boolean;
195
196 if (result is OSDInteger)
197 return JsonStoreValueType.Integer;
198
199 if (result is OSDReal)
200 return JsonStoreValueType.Float;
201
202 if (result is OSDString)
203 return JsonStoreValueType.String;
204
205 return JsonStoreValueType.Undefined;
206 }
207
208 // -----------------------------------------------------------------
209 /// <summary>
210 ///
211 /// </summary>
212 // -----------------------------------------------------------------
176 public int ArrayLength(string expr) 213 public int ArrayLength(string expr)
177 { 214 {
178 Stack<string> path; 215 Stack<string> path;
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index e78a2f4..5fbfcc5 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -270,7 +270,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
270 /// 270 ///
271 /// </summary> 271 /// </summary>
272 // ----------------------------------------------------------------- 272 // -----------------------------------------------------------------
273 public JsonStoreNodeType GetPathType(UUID storeID, string path) 273 public JsonStoreNodeType GetNodeType(UUID storeID, string path)
274 { 274 {
275 if (! m_enabled) return JsonStoreNodeType.Undefined; 275 if (! m_enabled) return JsonStoreNodeType.Undefined;
276 276
@@ -287,7 +287,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
287 try 287 try
288 { 288 {
289 lock (map) 289 lock (map)
290 return map.PathType(path); 290 return map.GetNodeType(path);
291 } 291 }
292 catch (Exception e) 292 catch (Exception e)
293 { 293 {
@@ -302,6 +302,38 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
302 /// 302 ///
303 /// </summary> 303 /// </summary>
304 // ----------------------------------------------------------------- 304 // -----------------------------------------------------------------
305 public JsonStoreValueType GetValueType(UUID storeID, string path)
306 {
307 if (! m_enabled) return JsonStoreValueType.Undefined;
308
309 JsonStore map = null;
310 lock (m_JsonValueStore)
311 {
312 if (! m_JsonValueStore.TryGetValue(storeID,out map))
313 {
314 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
315 return JsonStoreValueType.Undefined;
316 }
317 }
318
319 try
320 {
321 lock (map)
322 return map.GetValueType(path);
323 }
324 catch (Exception e)
325 {
326 m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
327 }
328
329 return JsonStoreValueType.Undefined;
330 }
331
332 // -----------------------------------------------------------------
333 /// <summary>
334 ///
335 /// </summary>
336 // -----------------------------------------------------------------
305 public bool SetValue(UUID storeID, string path, string value, bool useJson) 337 public bool SetValue(UUID storeID, string path, string value, bool useJson)
306 { 338 {
307 if (! m_enabled) return false; 339 if (! m_enabled) return false;
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index e13eb56..4a754a9 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -192,16 +192,32 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
192#region ScriptConstantsInterface 192#region ScriptConstantsInterface
193 193
194 [ScriptConstant] 194 [ScriptConstant]
195 public static readonly int JSON_TYPE_UNDEF = (int)JsonStoreNodeType.Undefined; 195 public static readonly int JSON_NODETYPE_UNDEF = (int)JsonStoreNodeType.Undefined;
196 196
197 [ScriptConstant] 197 [ScriptConstant]
198 public static readonly int JSON_TYPE_OBJECT = (int)JsonStoreNodeType.Object; 198 public static readonly int JSON_NODETYPE_OBJECT = (int)JsonStoreNodeType.Object;
199 199
200 [ScriptConstant] 200 [ScriptConstant]
201 public static readonly int JSON_TYPE_ARRAY = (int)JsonStoreNodeType.Array; 201 public static readonly int JSON_NODETYPE_ARRAY = (int)JsonStoreNodeType.Array;
202 202
203 [ScriptConstant] 203 [ScriptConstant]
204 public static readonly int JSON_TYPE_VALUE = (int)JsonStoreNodeType.Value; 204 public static readonly int JSON_NODETYPE_VALUE = (int)JsonStoreNodeType.Value;
205
206 [ScriptConstant]
207 public static readonly int JSON_VALUETYPE_UNDEF = (int)JsonStoreValueType.Undefined;
208
209 [ScriptConstant]
210 public static readonly int JSON_VALUETYPE_BOOLEAN = (int)JsonStoreValueType.Boolean;
211
212 [ScriptConstant]
213 public static readonly int JSON_VALUETYPE_INTEGER = (int)JsonStoreValueType.Integer;
214
215 [ScriptConstant]
216 public static readonly int JSON_VALUETYPE_FLOAT = (int)JsonStoreValueType.Float;
217
218 [ScriptConstant]
219 public static readonly int JSON_VALUETYPE_STRING = (int)JsonStoreValueType.String;
220
205 221
206#endregion 222#endregion
207 223
@@ -310,9 +326,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
310 /// </summary> 326 /// </summary>
311 // ----------------------------------------------------------------- 327 // -----------------------------------------------------------------
312 [ScriptInvocation] 328 [ScriptInvocation]
313 public int JsonGetPathType(UUID hostID, UUID scriptID, UUID storeID, string path) 329 public int JsonGetNodeType(UUID hostID, UUID scriptID, UUID storeID, string path)
330 {
331 return (int)m_store.GetNodeType(storeID,path);
332 }
333
334 // -----------------------------------------------------------------
335 /// <summary>
336 ///
337 /// </summary>
338 // -----------------------------------------------------------------
339 [ScriptInvocation]
340 public int JsonGetValueType(UUID hostID, UUID scriptID, UUID storeID, string path)
314 { 341 {
315 return (int)m_store.GetPathType(storeID,path); 342 return (int)m_store.GetValueType(storeID,path);
316 } 343 }
317 344
318 // ----------------------------------------------------------------- 345 // -----------------------------------------------------------------
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
index b64dbd4..bfa9937 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs
@@ -158,8 +158,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
158 158
159 Assert.That(dsrv, Is.EqualTo(1)); 159 Assert.That(dsrv, Is.EqualTo(1));
160 160
161 int tprv = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); 161 int tprv = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
162 Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); 162 Assert.That(tprv, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
163 } 163 }
164 164
165 [Test] 165 [Test]
@@ -277,8 +277,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
277 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); 277 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
278 Assert.That(returnValue, Is.EqualTo(1)); 278 Assert.That(returnValue, Is.EqualTo(1));
279 279
280 int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); 280 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
281 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); 281 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
282 282
283 string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello"); 283 string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello");
284 Assert.That(returnValue2, Is.EqualTo("")); 284 Assert.That(returnValue2, Is.EqualTo(""));
@@ -291,8 +291,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
291 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello"); 291 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
292 Assert.That(returnValue, Is.EqualTo(1)); 292 Assert.That(returnValue, Is.EqualTo(1));
293 293
294 int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); 294 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
295 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); 295 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
296 296
297 string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello"); 297 string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello");
298 Assert.That(returnValue2, Is.EqualTo("")); 298 Assert.That(returnValue2, Is.EqualTo(""));
@@ -306,11 +306,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
306 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]"); 306 int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]");
307 Assert.That(returnValue, Is.EqualTo(1)); 307 Assert.That(returnValue, Is.EqualTo(1));
308 308
309 int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello[0]"); 309 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[0]");
310 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); 310 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
311 311
312 result = (int)InvokeOp("JsonGetPathType", storeId, "Hello[1]"); 312 result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello[1]");
313 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); 313 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
314 314
315 string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]"); 315 string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]");
316 Assert.That(stringReturnValue, Is.EqualTo("value2")); 316 Assert.That(stringReturnValue, Is.EqualTo("value2"));
@@ -433,7 +433,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
433 } 433 }
434 434
435 [Test] 435 [Test]
436 public void TestJsonGetPathType() 436 public void TestJsonGetNodeType()
437 { 437 {
438 TestHelpers.InMethod(); 438 TestHelpers.InMethod();
439// TestHelpers.EnableLogging(); 439// TestHelpers.EnableLogging();
@@ -441,41 +441,41 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
441 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); 441 UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }");
442 442
443 { 443 {
444 int result = (int)InvokeOp("JsonGetPathType", storeId, "."); 444 int result = (int)InvokeOp("JsonGetNodeType", storeId, ".");
445 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT)); 445 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT));
446 } 446 }
447 447
448 { 448 {
449 int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello"); 449 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello");
450 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT)); 450 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_OBJECT));
451 } 451 }
452 452
453 { 453 {
454 int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World"); 454 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World");
455 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_ARRAY)); 455 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_ARRAY));
456 } 456 }
457 457
458 { 458 {
459 int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[0]"); 459 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[0]");
460 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); 460 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
461 } 461 }
462 462
463 { 463 {
464 int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[1]"); 464 int result = (int)InvokeOp("JsonGetNodeType", storeId, "Hello.World[1]");
465 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE)); 465 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_VALUE));
466 } 466 }
467 467
468 // Test for non-existant path 468 // Test for non-existant path
469 { 469 {
470 int result = (int)InvokeOp("JsonGetPathType", storeId, "foo"); 470 int result = (int)InvokeOp("JsonGetNodeType", storeId, "foo");
471 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); 471 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
472 } 472 }
473 473
474 // Test for non-existant store 474 // Test for non-existant store
475 { 475 {
476 UUID fakeStoreId = TestHelpers.ParseTail(0x500); 476 UUID fakeStoreId = TestHelpers.ParseTail(0x500);
477 int result = (int)InvokeOp("JsonGetPathType", fakeStoreId, "."); 477 int result = (int)InvokeOp("JsonGetNodeType", fakeStoreId, ".");
478 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF)); 478 Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_NODETYPE_UNDEF));
479 } 479 }
480 } 480 }
481 481
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
index c4b9117..0816b7b 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
@@ -102,6 +102,8 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
102 102
103 public override float Simulate(float timeStep) 103 public override float Simulate(float timeStep)
104 { 104 {
105// Console.WriteLine("Simulating");
106
105 float fps = 0; 107 float fps = 0;
106 for (int i = 0; i < _actors.Count; ++i) 108 for (int i = 0; i < _actors.Count; ++i)
107 { 109 {
@@ -109,8 +111,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
109 Vector3 actorPosition = actor.Position; 111 Vector3 actorPosition = actor.Position;
110 Vector3 actorVelocity = actor.Velocity; 112 Vector3 actorVelocity = actor.Velocity;
111 113
112 actorPosition.X += actor.Velocity.X*timeStep; 114// Console.WriteLine(
113 actorPosition.Y += actor.Velocity.Y*timeStep; 115// "Processing actor {0}, starting pos {1}, starting vel {2}", i, actorPosition, actorVelocity);
116
117 actorPosition.X += actor.Velocity.X * timeStep;
118 actorPosition.Y += actor.Velocity.Y * timeStep;
114 119
115 if (actor.Position.Y < 0) 120 if (actor.Position.Y < 0)
116 { 121 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index f442ca2..e208d3a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -205,7 +205,7 @@ public sealed class BSCharacter : BSPhysObject
205 // errors can creap in and the avatar will slowly float off in some direction. 205 // errors can creap in and the avatar will slowly float off in some direction.
206 // So, the problem is that, when an avatar is standing, we cannot tell creaping error 206 // So, the problem is that, when an avatar is standing, we cannot tell creaping error
207 // from real pushing. 207 // from real pushing.
208 // The code below keeps setting the velocity to zero hoping the world will keep pushing. 208 // The code below uses whether the collider is static or moving to decide whether to zero motion.
209 209
210 _velocityMotor.Step(timeStep); 210 _velocityMotor.Step(timeStep);
211 211
@@ -244,6 +244,7 @@ public sealed class BSCharacter : BSPhysObject
244 } 244 }
245 else 245 else
246 { 246 {
247 // Supposed to be moving.
247 OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue; 248 OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
248 249
249 if (Friction != BSParam.AvatarFriction) 250 if (Friction != BSParam.AvatarFriction)
@@ -276,8 +277,8 @@ public sealed class BSCharacter : BSPhysObject
276 }); 277 });
277 } 278 }
278 279
279 // Decide of the character is colliding with a low object and compute a force to pop the 280 // Decide if the character is colliding with a low object and compute a force to pop the
280 // avatar up so it has a chance of walking up and over the low object. 281 // avatar up so it can walk up and over the low objects.
281 private OMV.Vector3 WalkUpStairs() 282 private OMV.Vector3 WalkUpStairs()
282 { 283 {
283 OMV.Vector3 ret = OMV.Vector3.Zero; 284 OMV.Vector3 ret = OMV.Vector3.Zero;
@@ -476,17 +477,19 @@ public sealed class BSCharacter : BSPhysObject
476 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition)) 477 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
477 { 478 {
478 // The character is out of the known/simulated area. 479 // The character is out of the known/simulated area.
479 // Upper levels of code will handle the transition to other areas so, for 480 // Force the avatar position to be within known. ScenePresence will use the position
480 // the time, we just ignore the position. 481 // plus the velocity to decide if the avatar is moving out of the region.
481 return ret; 482 RawPosition = PhysicsScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition);
483 DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition);
484 return true;
482 } 485 }
483 486
484 // If below the ground, move the avatar up 487 // If below the ground, move the avatar up
485 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); 488 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
486 if (Position.Z < terrainHeight) 489 if (Position.Z < terrainHeight)
487 { 490 {
488 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 491 DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight);
489 _position.Z = terrainHeight + 2.0f; 492 _position.Z = terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters;
490 ret = true; 493 ret = true;
491 } 494 }
492 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) 495 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
@@ -806,14 +809,7 @@ public sealed class BSCharacter : BSPhysObject
806 private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 809 private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
807 if (force.IsFinite()) 810 if (force.IsFinite())
808 { 811 {
809 float magnitude = force.Length(); 812 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
810 if (magnitude > BSParam.MaxAddForceMagnitude)
811 {
812 // Force has a limit
813 force = force / magnitude * BSParam.MaxAddForceMagnitude;
814 }
815
816 OMV.Vector3 addForce = force;
817 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); 813 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
818 814
819 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() 815 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
@@ -902,6 +898,7 @@ public sealed class BSCharacter : BSPhysObject
902 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 898 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
903 if (PositionSanityCheck(true)) 899 if (PositionSanityCheck(true))
904 { 900 {
901 DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position);
905 entprop.Position = _position; 902 entprop.Position = _position;
906 } 903 }
907 904
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 235cefc..38596fa 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -143,7 +143,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
143 { 143 {
144 enableAngularVerticalAttraction = true; 144 enableAngularVerticalAttraction = true;
145 enableAngularDeflection = false; 145 enableAngularDeflection = false;
146 enableAngularBanking = false; 146 enableAngularBanking = true;
147 if (BSParam.VehicleDebuggingEnabled) 147 if (BSParam.VehicleDebuggingEnabled)
148 { 148 {
149 enableAngularVerticalAttraction = true; 149 enableAngularVerticalAttraction = true;
@@ -1280,11 +1280,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1280 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement 1280 // That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
1281 // TODO: This is here because this is where ODE put it but documentation says it 1281 // TODO: This is here because this is where ODE put it but documentation says it
1282 // is a linear effect. Where should this check go? 1282 // is a linear effect. Where should this check go?
1283 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 1283 //if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
1284 { 1284 // {
1285 angularMotorContributionV.X = 0f; 1285 // angularMotorContributionV.X = 0f;
1286 angularMotorContributionV.Y = 0f; 1286 // angularMotorContributionV.Y = 0f;
1287 } 1287 // }
1288 1288
1289 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation; 1289 VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
1290 VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContributionV); 1290 VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", Prim.LocalID, angularMotorContributionV);
@@ -1335,7 +1335,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1335 Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG 1335 Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
1336 vertContributionV /= m_verticalAttractionTimescale; 1336 vertContributionV /= m_verticalAttractionTimescale;
1337 1337
1338 VehicleRotationalVelocity += vertContributionV * VehicleOrientation; 1338 VehicleRotationalVelocity += vertContributionV;
1339 1339
1340 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", 1340 VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
1341 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, 1341 Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
@@ -1437,24 +1437,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin
1437 // As the vehicle rolls to the right or left, the Y value will increase from 1437 // As the vehicle rolls to the right or left, the Y value will increase from
1438 // zero (straight up) to 1 or -1 (full tilt right or left) 1438 // zero (straight up) to 1 or -1 (full tilt right or left)
1439 Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation; 1439 Vector3 rollComponents = Vector3.UnitZ * VehicleOrientation;
1440
1441 // Figure out the yaw value for this much roll.
1442 // Squared because that seems to give a good value
1443 float yawAngle = (float)Math.Asin(rollComponents.Y * rollComponents.Y) * m_bankingEfficiency;
1444 1440
1441 // Figure out the yaw value for this much roll.
1442 float yawAngle = m_angularMotorDirection.X * m_bankingEfficiency;
1445 // actual error = static turn error + dynamic turn error 1443 // actual error = static turn error + dynamic turn error
1446 float mixedYawAngle = yawAngle * (1f - m_bankingMix) + yawAngle * m_bankingMix * VehicleForwardSpeed; 1444 float mixedYawAngle =(yawAngle * (1f - m_bankingMix)) + ((yawAngle * m_bankingMix) * VehicleForwardSpeed);
1447 1445
1448 // TODO: the banking effect should not go to infinity but what to limit it to? 1446 // TODO: the banking effect should not go to infinity but what to limit it to?
1449 mixedYawAngle = ClampInRange(-20f, mixedYawAngle, 20f); 1447 // And what should happen when this is being added to a user defined yaw that is already PI*4?
1448 mixedYawAngle = ClampInRange(-12, mixedYawAngle, 12);
1450 1449
1451 // Build the force vector to change rotation from what it is to what it should be 1450 // Build the force vector to change rotation from what it is to what it should be
1452 bankingContributionV.Z = -mixedYawAngle; 1451 bankingContributionV.Z = -mixedYawAngle;
1453 1452
1454 // Don't do it all at once. 1453 // Don't do it all at once. Fudge because 1 second is too fast with most user defined roll as PI*4.
1455 bankingContributionV /= m_bankingTimescale; 1454 bankingContributionV /= m_bankingTimescale * BSParam.VehicleAngularBankingTimescaleFudge;
1456 1455
1457 VehicleRotationalVelocity += bankingContributionV * VehicleOrientation; 1456 //VehicleRotationalVelocity += bankingContributionV * VehicleOrientation;
1457 VehicleRotationalVelocity += bankingContributionV;
1458
1458 1459
1459 VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}", 1460 VDetailLog("{0}, MoveAngular,Banking,rollComp={1},speed={2},rollComp={3},yAng={4},mYAng={5},ret={6}",
1460 Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV); 1461 Prim.LocalID, rollComponents, VehicleForwardSpeed, rollComponents, yawAngle, mixedYawAngle, bankingContributionV);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index fa58109..77bdacb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -107,6 +107,7 @@ public static class BSParam
107 public static float AvatarCapsuleDepth { get; private set; } 107 public static float AvatarCapsuleDepth { get; private set; }
108 public static float AvatarCapsuleHeight { get; private set; } 108 public static float AvatarCapsuleHeight { get; private set; }
109 public static float AvatarContactProcessingThreshold { get; private set; } 109 public static float AvatarContactProcessingThreshold { get; private set; }
110 public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
110 public static float AvatarStepHeight { get; private set; } 111 public static float AvatarStepHeight { get; private set; }
111 public static float AvatarStepApproachFactor { get; private set; } 112 public static float AvatarStepApproachFactor { get; private set; }
112 public static float AvatarStepForceFactor { get; private set; } 113 public static float AvatarStepForceFactor { get; private set; }
@@ -122,6 +123,7 @@ public static class BSParam
122 public static Vector3 VehicleLinearFactor { get; private set; } 123 public static Vector3 VehicleLinearFactor { get; private set; }
123 public static Vector3 VehicleAngularFactor { get; private set; } 124 public static Vector3 VehicleAngularFactor { get; private set; }
124 public static float VehicleGroundGravityFudge { get; private set; } 125 public static float VehicleGroundGravityFudge { get; private set; }
126 public static float VehicleAngularBankingTimescaleFudge { get; private set; }
125 public static bool VehicleDebuggingEnabled { get; private set; } 127 public static bool VehicleDebuggingEnabled { get; private set; }
126 128
127 // Linkset implementation parameters 129 // Linkset implementation parameters
@@ -497,6 +499,10 @@ public static class BSParam
497 0.1f, 499 0.1f,
498 (s) => { return AvatarContactProcessingThreshold; }, 500 (s) => { return AvatarContactProcessingThreshold; },
499 (s,v) => { AvatarContactProcessingThreshold = v; } ), 501 (s,v) => { AvatarContactProcessingThreshold = v; } ),
502 new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
503 1.0f,
504 (s) => { return AvatarBelowGroundUpCorrectionMeters; },
505 (s,v) => { AvatarBelowGroundUpCorrectionMeters = v; } ),
500 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction", 506 new ParameterDefn<float>("AvatarStepHeight", "Height of a step obstacle to consider step correction",
501 0.3f, 507 0.3f,
502 (s) => { return AvatarStepHeight; }, 508 (s) => { return AvatarStepHeight; },
@@ -538,10 +544,14 @@ public static class BSParam
538 0.0f, 544 0.0f,
539 (s) => { return VehicleRestitution; }, 545 (s) => { return VehicleRestitution; },
540 (s,v) => { VehicleRestitution = v; } ), 546 (s,v) => { VehicleRestitution = v; } ),
541 new ParameterDefn<float>("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)", 547 new ParameterDefn<float>("VehicleGroundGravityFudge", "Factor to multiply gravity if a ground vehicle is probably on the ground (0.0 - 1.0)",
542 0.2f, 548 0.2f,
543 (s) => { return VehicleGroundGravityFudge; }, 549 (s) => { return VehicleGroundGravityFudge; },
544 (s,v) => { VehicleGroundGravityFudge = v; } ), 550 (s,v) => { VehicleGroundGravityFudge = v; } ),
551 new ParameterDefn<float>("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.",
552 60.0f,
553 (s) => { return VehicleAngularBankingTimescaleFudge; },
554 (s,v) => { VehicleAngularBankingTimescaleFudge = v; } ),
545 new ParameterDefn<bool>("VehicleDebuggingEnable", "Turn on/off vehicle debugging", 555 new ParameterDefn<bool>("VehicleDebuggingEnable", "Turn on/off vehicle debugging",
546 false, 556 false,
547 (s) => { return VehicleDebuggingEnabled; }, 557 (s) => { return VehicleDebuggingEnabled; },
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
index 2e9db39..e8040d8 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -337,6 +337,54 @@ public sealed class BSTerrainManager : IDisposable
337 return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ); 337 return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ);
338 } 338 }
339 339
340 // Return a new position that is over known terrain if the position is outside our terrain.
341 public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos)
342 {
343 Vector3 ret = pPos;
344
345 // Can't do this function if we don't know about any terrain.
346 if (m_terrains.Count == 0)
347 return ret;
348
349 int loopPrevention = 5;
350 Vector3 terrainBaseXYZ;
351 BSTerrainPhys physTerrain;
352 while (!GetTerrainPhysicalAtXYZ(ret, out physTerrain, out terrainBaseXYZ))
353 {
354 // The passed position is not within a known terrain area.
355
356 // First, base addresses are never negative so correct for that possible problem.
357 if (ret.X < 0f || ret.Y < 0f)
358 {
359 if (ret.X < 0f)
360 ret.X = 0f;
361 if (ret.Y < 0f)
362 ret.Y = 0f;
363 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,zeroingNegXorY,oldPos={1},newPos={2}",
364 BSScene.DetailLogZero, pPos, ret);
365 }
366 else
367 {
368 // Must be off the top of a region. Find an adjacent region to move into.
369 Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ);
370
371 ret.X = Math.Min(ret.X, adjacentTerrainBase.X + DefaultRegionSize.X);
372 ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + DefaultRegionSize.Y);
373 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}",
374 BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret);
375 }
376 if (loopPrevention-- < 0f)
377 {
378 // The 'while' is a little dangerous so this prevents looping forever if the
379 // mapping of the terrains ever gets messed up (like nothing at <0,0>) or
380 // the list of terrains is in transition.
381 DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,suppressingFindAdjacentRegionLoop", BSScene.DetailLogZero);
382 break;
383 }
384 }
385 return ret;
386 }
387
340 // Given an X and Y, find the height of the terrain. 388 // Given an X and Y, find the height of the terrain.
341 // Since we could be handling multiple terrains for a mega-region, 389 // Since we could be handling multiple terrains for a mega-region,
342 // the base of the region is calcuated assuming all regions are 390 // the base of the region is calcuated assuming all regions are
@@ -400,18 +448,60 @@ public sealed class BSTerrainManager : IDisposable
400 // the descriptor class and the 'base' fo the addresses therein. 448 // the descriptor class and the 'base' fo the addresses therein.
401 private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase) 449 private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase)
402 { 450 {
403 int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X; 451 bool ret = false;
404 int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; 452
405 Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); 453 Vector3 terrainBaseXYZ = Vector3.Zero;
454 if (pos.X < 0f || pos.Y < 0f)
455 {
456 // We don't handle negative addresses so just make up a base that will not be found.
457 terrainBaseXYZ = new Vector3(-DefaultRegionSize.X, -DefaultRegionSize.Y, 0f);
458 }
459 else
460 {
461 int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
462 int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
463 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
464 }
406 465
407 BSTerrainPhys physTerrain = null; 466 BSTerrainPhys physTerrain = null;
408 lock (m_terrains) 467 lock (m_terrains)
409 { 468 {
410 m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain); 469 ret = m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain);
411 } 470 }
412 outTerrainBase = terrainBaseXYZ; 471 outTerrainBase = terrainBaseXYZ;
413 outPhysTerrain = physTerrain; 472 outPhysTerrain = physTerrain;
414 return (physTerrain != null); 473 return ret;
474 }
475
476 // Given a terrain base, return a terrain base for a terrain that is closer to <0,0> than
477 // this one. Usually used to return an out of bounds object to a known place.
478 private Vector3 FindAdjacentTerrainBase(Vector3 pTerrainBase)
479 {
480 Vector3 ret = pTerrainBase;
481 ret.Z = 0f;
482 lock (m_terrains)
483 {
484 // Once down to the <0,0> region, we have to be done.
485 while (ret.X > 0f && ret.Y > 0f)
486 {
487 if (ret.X > 0f)
488 {
489 ret.X = Math.Max(0f, ret.X - DefaultRegionSize.X);
490 DetailLog("{0},BSTerrainManager.FindAdjacentTerrainBase,reducingX,terrainBase={1}", BSScene.DetailLogZero, ret);
491 if (m_terrains.ContainsKey(ret))
492 break;
493 }
494 if (ret.Y > 0f)
495 {
496 ret.Y = Math.Max(0f, ret.Y - DefaultRegionSize.Y);
497 DetailLog("{0},BSTerrainManager.FindAdjacentTerrainBase,reducingY,terrainBase={1}", BSScene.DetailLogZero, ret);
498 if (m_terrains.ContainsKey(ret))
499 break;
500 }
501 }
502 }
503
504 return ret;
415 } 505 }
416 506
417 // Although no one seems to check this, I do support combining. 507 // Although no one seems to check this, I do support combining.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
index d7e800d..57a5ff2 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
@@ -215,7 +215,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
215 215
216 float magX = (float)sizeX / extentX; 216 float magX = (float)sizeX / extentX;
217 float magY = (float)sizeY / extentY; 217 float magY = (float)sizeY / extentY;
218 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", 218 if (physicsScene != null)
219 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}",
219 BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); 220 BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY);
220 float minHeight = float.MaxValue; 221 float minHeight = float.MaxValue;
221 // Note that sizeX+1 vertices are created since there is land between this and the next region. 222 // Note that sizeX+1 vertices are created since there is land between this and the next region.
@@ -257,7 +258,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
257 } 258 }
258 catch (Exception e) 259 catch (Exception e)
259 { 260 {
260 physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}", 261 if (physicsScene != null)
262 physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. For={1}/{2}, e={3}",
261 LogHeader, physicsScene.RegionName, extentBase, e); 263 LogHeader, physicsScene.RegionName, extentBase, e);
262 } 264 }
263 265
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
index a133e51..b4abc1d 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
@@ -68,6 +68,11 @@ public class RegionCombinerLargeLandChannel : ILandChannel
68 RootRegionLandChannel.Clear(setupDefaultParcel); 68 RootRegionLandChannel.Clear(setupDefaultParcel);
69 } 69 }
70 70
71 public ILandObject GetLandObject(Vector3 position)
72 {
73 return GetLandObject(position.X, position.Y);
74 }
75
71 public ILandObject GetLandObject(int x, int y) 76 public ILandObject GetLandObject(int x, int y)
72 { 77 {
73 //m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y); 78 //m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index cf6f13e..e1f0071 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -283,6 +283,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
283 } 283 }
284 } 284 }
285 285
286 /// <summary>
287 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
288 /// </summary>
289 /// <remarks>
290 /// If there are any ScenePresence's in the linkset (i.e. because they are sat upon one of the prims), then
291 /// these are counted as extra entities that correspond to linknums beyond the number of prims in the linkset.
292 /// The ScenePresences receive linknums in the order in which they sat.
293 /// </remarks>
294 /// <returns>
295 /// The link entity. null if not found.
296 /// </returns>
297 /// <param name='linknum'>
298 /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4).
299 /// If ScriptBaseClass.LINK_THIS then the entity containing the script is returned.
300 /// If the linkset has one entity and a linknum of zero is given, then the single entity is returned. If any
301 /// positive integer is given in this case then null is returned.
302 /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number
303 /// of entities, then the entity which corresponds to that linknum is returned.
304 /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then
305 /// null is returned.
306 /// </param>
307 public ISceneEntity GetLinkEntity(int linknum)
308 {
309 if (linknum < 0)
310 {
311 if (linknum == ScriptBaseClass.LINK_THIS)
312 return m_host;
313 else
314 return null;
315 }
316
317 int actualPrimCount = m_host.ParentGroup.PrimCount;
318 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
319 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
320
321 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
322 // prim that has any avatars sat upon it (in which case the root prim is link 1).
323 if (linknum == 0)
324 {
325 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
326 return m_host;
327
328 return null;
329 }
330 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
331 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
332 else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1)
333 {
334 if (sittingAvatarIds.Count > 0)
335 return m_host.ParentGroup.RootPart;
336 else
337 return null;
338 }
339 else if (linknum <= adjustedPrimCount)
340 {
341 if (linknum <= actualPrimCount)
342 {
343 return m_host.ParentGroup.GetLinkNumPart(linknum);
344 }
345 else
346 {
347 ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
348 if (sp != null)
349 return sp;
350 else
351 return null;
352 }
353 }
354 else
355 {
356 return null;
357 }
358 }
359
286 public List<SceneObjectPart> GetLinkParts(int linkType) 360 public List<SceneObjectPart> GetLinkParts(int linkType)
287 { 361 {
288 return GetLinkParts(m_host, linkType); 362 return GetLinkParts(m_host, linkType);
@@ -2174,23 +2248,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2174 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 2248 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2175 q = avatar.CameraRotation; // Mouselook 2249 q = avatar.CameraRotation; // Mouselook
2176 else 2250 else
2177 q = avatar.Rotation; // Currently infrequently updated so may be inaccurate 2251 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
2178 } 2252 }
2179 else 2253 else
2180 q = part.ParentGroup.GroupRotation; // Likely never get here but just in case 2254 q = part.ParentGroup.GroupRotation; // Likely never get here but just in case
2181 } 2255 }
2182 else 2256 else
2183 q = part.ParentGroup.GroupRotation; // just the group rotation 2257 q = part.ParentGroup.GroupRotation; // just the group rotation
2184 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2258
2259 return new LSL_Rotation(q);
2185 } 2260 }
2186 q = part.GetWorldRotation(); 2261
2187 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2262 return new LSL_Rotation(part.GetWorldRotation());
2188 } 2263 }
2189 2264
2190 public LSL_Rotation llGetLocalRot() 2265 public LSL_Rotation llGetLocalRot()
2191 { 2266 {
2192 m_host.AddScriptLPS(1); 2267 m_host.AddScriptLPS(1);
2193 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2268
2269 return new LSL_Rotation(m_host.RotationOffset);
2194 } 2270 }
2195 2271
2196 public void llSetForce(LSL_Vector force, int local) 2272 public void llSetForce(LSL_Vector force, int local)
@@ -2285,8 +2361,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2285 public LSL_Vector llGetTorque() 2361 public LSL_Vector llGetTorque()
2286 { 2362 {
2287 m_host.AddScriptLPS(1); 2363 m_host.AddScriptLPS(1);
2288 Vector3 torque = m_host.ParentGroup.GetTorque(); 2364
2289 return new LSL_Vector(torque.X,torque.Y,torque.Z); 2365 return new LSL_Vector(m_host.ParentGroup.GetTorque());
2290 } 2366 }
2291 2367
2292 public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local) 2368 public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local)
@@ -2312,19 +2388,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2312 vel = m_host.Velocity; 2388 vel = m_host.Velocity;
2313 } 2389 }
2314 2390
2315 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2391 return new LSL_Vector(vel);
2316 } 2392 }
2317 2393
2318 public LSL_Vector llGetAccel() 2394 public LSL_Vector llGetAccel()
2319 { 2395 {
2320 m_host.AddScriptLPS(1); 2396 m_host.AddScriptLPS(1);
2321 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2397
2398 return new LSL_Vector(m_host.Acceleration);
2322 } 2399 }
2323 2400
2324 public LSL_Vector llGetOmega() 2401 public LSL_Vector llGetOmega()
2325 { 2402 {
2326 m_host.AddScriptLPS(1); 2403 m_host.AddScriptLPS(1);
2327 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2404
2405 return new LSL_Vector(m_host.AngularVelocity);
2328 } 2406 }
2329 2407
2330 public LSL_Float llGetTimeOfDay() 2408 public LSL_Float llGetTimeOfDay()
@@ -3101,13 +3179,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3101 msg.ParentEstateID = 0; //ParentEstateID; 3179 msg.ParentEstateID = 0; //ParentEstateID;
3102 msg.Position = new Vector3(m_host.AbsolutePosition); 3180 msg.Position = new Vector3(m_host.AbsolutePosition);
3103 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3181 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3182
3183 Vector3 pos = m_host.AbsolutePosition;
3104 msg.binaryBucket 3184 msg.binaryBucket
3105 = Util.StringToBytes256( 3185 = Util.StringToBytes256(
3106 "{0}/{1}/{2}/{3}", 3186 "{0}/{1}/{2}/{3}",
3107 World.RegionInfo.RegionName, 3187 World.RegionInfo.RegionName,
3108 (int)Math.Floor(m_host.AbsolutePosition.X), 3188 (int)Math.Floor(pos.X),
3109 (int)Math.Floor(m_host.AbsolutePosition.Y), 3189 (int)Math.Floor(pos.Y),
3110 (int)Math.Floor(m_host.AbsolutePosition.Z)); 3190 (int)Math.Floor(pos.Z));
3111 3191
3112 if (m_TransferModule != null) 3192 if (m_TransferModule != null)
3113 { 3193 {
@@ -3691,47 +3771,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3691 { 3771 {
3692 m_host.AddScriptLPS(1); 3772 m_host.AddScriptLPS(1);
3693 3773
3694 if (linknum < 0) 3774 ISceneEntity entity = GetLinkEntity(linknum);
3695 {
3696 if (linknum == ScriptBaseClass.LINK_THIS)
3697 return m_host.UUID.ToString();
3698 else
3699 return ScriptBaseClass.NULL_KEY;
3700 }
3701
3702 int actualPrimCount = m_host.ParentGroup.PrimCount;
3703 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
3704 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3705
3706 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3707 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3708 if (linknum == 0)
3709 {
3710 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3711 return m_host.UUID.ToString();
3712 3775
3713 return ScriptBaseClass.NULL_KEY; 3776 if (entity != null)
3714 } 3777 return entity.UUID.ToString();
3715 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3716 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3717 else if (linknum == 1 && actualPrimCount == 1)
3718 {
3719 if (sittingAvatarIds.Count > 0)
3720 return m_host.ParentGroup.RootPart.UUID.ToString();
3721 else
3722 return ScriptBaseClass.NULL_KEY;
3723 }
3724 else if (linknum <= adjustedPrimCount)
3725 {
3726 if (linknum <= actualPrimCount)
3727 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3728 else
3729 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3730 }
3731 else 3778 else
3732 {
3733 return ScriptBaseClass.NULL_KEY; 3779 return ScriptBaseClass.NULL_KEY;
3734 }
3735 } 3780 }
3736 3781
3737 /// <summary> 3782 /// <summary>
@@ -3777,55 +3822,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3777 { 3822 {
3778 m_host.AddScriptLPS(1); 3823 m_host.AddScriptLPS(1);
3779 3824
3780 if (linknum < 0) 3825 ISceneEntity entity = GetLinkEntity(linknum);
3781 {
3782 if (linknum == ScriptBaseClass.LINK_THIS)
3783 return m_host.Name;
3784 else
3785 return ScriptBaseClass.NULL_KEY;
3786 }
3787 3826
3788 int actualPrimCount = m_host.ParentGroup.PrimCount; 3827 if (entity != null)
3789 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); 3828 return entity.Name;
3790 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3791
3792 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3793 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3794 if (linknum == 0)
3795 {
3796 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3797 return m_host.Name;
3798
3799 return ScriptBaseClass.NULL_KEY;
3800 }
3801 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3802 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3803 else if (linknum == 1 && actualPrimCount == 1)
3804 {
3805 if (sittingAvatarIds.Count > 0)
3806 return m_host.ParentGroup.RootPart.Name;
3807 else
3808 return ScriptBaseClass.NULL_KEY;
3809 }
3810 else if (linknum <= adjustedPrimCount)
3811 {
3812 if (linknum <= actualPrimCount)
3813 {
3814 return m_host.ParentGroup.GetLinkNumPart(linknum).Name;
3815 }
3816 else
3817 {
3818 ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
3819 if (sp != null)
3820 return sp.Name;
3821 else
3822 return ScriptBaseClass.NULL_KEY;
3823 }
3824 }
3825 else 3829 else
3826 {
3827 return ScriptBaseClass.NULL_KEY; 3830 return ScriptBaseClass.NULL_KEY;
3828 }
3829 } 3831 }
3830 3832
3831 public LSL_Integer llGetInventoryNumber(int type) 3833 public LSL_Integer llGetInventoryNumber(int type)
@@ -4170,13 +4172,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4170 if (presence != null) 4172 if (presence != null)
4171 { 4173 {
4172 // agent must be over the owners land 4174 // agent must be over the owners land
4173 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4175 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4174 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4175 { 4176 {
4176 World.TeleportClientHome(agentId, presence.ControllingClient); 4177 World.TeleportClientHome(agentId, presence.ControllingClient);
4177 } 4178 }
4178 } 4179 }
4179 } 4180 }
4181
4180 ScriptSleep(5000); 4182 ScriptSleep(5000);
4181 } 4183 }
4182 4184
@@ -4197,8 +4199,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4197 destination = World.RegionInfo.RegionName; 4199 destination = World.RegionInfo.RegionName;
4198 4200
4199 // agent must be over the owners land 4201 // agent must be over the owners land
4200 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4202 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4201 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4202 { 4203 {
4203 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4204 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4204 } 4205 }
@@ -4229,8 +4230,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4229 if (presence.GodLevel >= 200) return; 4230 if (presence.GodLevel >= 200) return;
4230 4231
4231 // agent must be over the owners land 4232 // agent must be over the owners land
4232 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4233 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4233 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4234 { 4234 {
4235 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4235 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4236 } 4236 }
@@ -4434,7 +4434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4434 { 4434 {
4435 if (pushrestricted) 4435 if (pushrestricted)
4436 { 4436 {
4437 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4437 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4438 4438
4439 // We didn't find the parcel but region is push restricted so assume it is NOT ok 4439 // We didn't find the parcel but region is push restricted so assume it is NOT ok
4440 if (targetlandObj == null) 4440 if (targetlandObj == null)
@@ -4449,7 +4449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4449 } 4449 }
4450 else 4450 else
4451 { 4451 {
4452 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4452 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4453 if (targetlandObj == null) 4453 if (targetlandObj == null)
4454 { 4454 {
4455 // We didn't find the parcel but region isn't push restricted so assume it's ok 4455 // We didn't find the parcel but region isn't push restricted so assume it's ok
@@ -4871,8 +4871,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4871 public LSL_Vector llGetCenterOfMass() 4871 public LSL_Vector llGetCenterOfMass()
4872 { 4872 {
4873 m_host.AddScriptLPS(1); 4873 m_host.AddScriptLPS(1);
4874 Vector3 center = m_host.GetCenterOfMass(); 4874
4875 return new LSL_Vector(center.X,center.Y,center.Z); 4875 return new LSL_Vector(m_host.GetCenterOfMass());
4876 } 4876 }
4877 4877
4878 public LSL_List llListSort(LSL_List src, int stride, int ascending) 4878 public LSL_List llListSort(LSL_List src, int stride, int ascending)
@@ -5703,12 +5703,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5703 } 5703 }
5704 5704
5705 ILandObject land; 5705 ILandObject land;
5706 Vector3 pos;
5707 UUID id = UUID.Zero; 5706 UUID id = UUID.Zero;
5707
5708 if (parcel || parcelOwned) 5708 if (parcel || parcelOwned)
5709 { 5709 {
5710 pos = m_host.ParentGroup.RootPart.GetWorldPosition(); 5710 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition());
5711 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
5712 if (land == null) 5711 if (land == null)
5713 { 5712 {
5714 id = UUID.Zero; 5713 id = UUID.Zero;
@@ -5734,8 +5733,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5734 { 5733 {
5735 if (!regionWide) 5734 if (!regionWide)
5736 { 5735 {
5737 pos = ssp.AbsolutePosition; 5736 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition);
5738 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
5739 if (land != null) 5737 if (land != null)
5740 { 5738 {
5741 if (parcelOwned && land.LandData.OwnerID == id || 5739 if (parcelOwned && land.LandData.OwnerID == id ||
@@ -5860,7 +5858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5860 if (presence != null) 5858 if (presence != null)
5861 { 5859 {
5862 // agent must be over the owners land 5860 // agent must be over the owners land
5863 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); 5861 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition);
5864 if (land == null) 5862 if (land == null)
5865 return; 5863 return;
5866 5864
@@ -5882,19 +5880,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5882 ScenePresence presence = World.GetScenePresence(key); 5880 ScenePresence presence = World.GetScenePresence(key);
5883 if (presence != null) // object is an avatar 5881 if (presence != null) // object is an avatar
5884 { 5882 {
5885 if (m_host.OwnerID 5883 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
5886 == World.LandChannel.GetLandObject(
5887 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
5888 return 1; 5884 return 1;
5889 } 5885 }
5890 else // object is not an avatar 5886 else // object is not an avatar
5891 { 5887 {
5892 SceneObjectPart obj = World.GetSceneObjectPart(key); 5888 SceneObjectPart obj = World.GetSceneObjectPart(key);
5889
5893 if (obj != null) 5890 if (obj != null)
5894 if (m_host.OwnerID 5891 {
5895 == World.LandChannel.GetLandObject( 5892 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID)
5896 obj.AbsolutePosition.X, obj.AbsolutePosition.Y).LandData.OwnerID)
5897 return 1; 5893 return 1;
5894 }
5898 } 5895 }
5899 } 5896 }
5900 5897
@@ -5972,8 +5969,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5972 // if the land is group owned and the object is group owned by the same group 5969 // if the land is group owned and the object is group owned by the same group
5973 // or 5970 // or
5974 // if the object is owned by a person with estate access. 5971 // if the object is owned by a person with estate access.
5975 5972 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition);
5976 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y);
5977 if (parcel != null) 5973 if (parcel != null)
5978 { 5974 {
5979 if (m_host.OwnerID == parcel.LandData.OwnerID || 5975 if (m_host.OwnerID == parcel.LandData.OwnerID ||
@@ -5985,14 +5981,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5985 } 5981 }
5986 } 5982 }
5987 } 5983 }
5988
5989 } 5984 }
5990
5991 } 5985 }
5992 5986
5993 public LSL_Vector llGroundSlope(LSL_Vector offset) 5987 public LSL_Vector llGroundSlope(LSL_Vector offset)
5994 { 5988 {
5995 m_host.AddScriptLPS(1); 5989 m_host.AddScriptLPS(1);
5990
5996 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 5991 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
5997 LSL_Vector vsn = llGroundNormal(offset); 5992 LSL_Vector vsn = llGroundNormal(offset);
5998 5993
@@ -6003,7 +5998,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6003 vsl.Normalize(); 5998 vsl.Normalize();
6004 //Normalization might be overkill here 5999 //Normalization might be overkill here
6005 6000
6006 return new LSL_Vector(vsl.X, vsl.Y, vsl.Z); 6001 vsn.x = vsl.X;
6002 vsn.y = vsl.Y;
6003 vsn.z = vsl.Z;
6004
6005 return vsn;
6007 } 6006 }
6008 6007
6009 public LSL_Vector llGroundNormal(LSL_Vector offset) 6008 public LSL_Vector llGroundNormal(LSL_Vector offset)
@@ -6053,7 +6052,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6053 //I believe the crossproduct of two normalized vectors is a normalized vector so 6052 //I believe the crossproduct of two normalized vectors is a normalized vector so
6054 //this normalization may be overkill 6053 //this normalization may be overkill
6055 6054
6056 return new LSL_Vector(vsn.X, vsn.Y, vsn.Z); 6055 return new LSL_Vector(vsn);
6057 } 6056 }
6058 6057
6059 public LSL_Vector llGroundContour(LSL_Vector offset) 6058 public LSL_Vector llGroundContour(LSL_Vector offset)
@@ -6069,7 +6068,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6069 return m_host.ParentGroup.AttachmentPoint; 6068 return m_host.ParentGroup.AttachmentPoint;
6070 } 6069 }
6071 6070
6072 public LSL_Integer llGetFreeMemory() 6071 public virtual LSL_Integer llGetFreeMemory()
6073 { 6072 {
6074 m_host.AddScriptLPS(1); 6073 m_host.AddScriptLPS(1);
6075 // Make scripts designed for LSO happy 6074 // Make scripts designed for LSO happy
@@ -6553,7 +6552,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6553 { 6552 {
6554 m_host.AddScriptLPS(1); 6553 m_host.AddScriptLPS(1);
6555 UUID key; 6554 UUID key;
6556 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 6555 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
6556
6557 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 6557 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
6558 { 6558 {
6559 int expires = 0; 6559 int expires = 0;
@@ -7782,7 +7782,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7782 { 7782 {
7783 m_host.AddScriptLPS(1); 7783 m_host.AddScriptLPS(1);
7784 7784
7785 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 7785 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7786 7786
7787 if (land.LandData.OwnerID != m_host.OwnerID) 7787 if (land.LandData.OwnerID != m_host.OwnerID)
7788 return; 7788 return;
@@ -7796,7 +7796,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7796 { 7796 {
7797 m_host.AddScriptLPS(1); 7797 m_host.AddScriptLPS(1);
7798 7798
7799 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 7799 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7800 7800
7801 if (land.LandData.OwnerID != m_host.OwnerID) 7801 if (land.LandData.OwnerID != m_host.OwnerID)
7802 return String.Empty; 7802 return String.Empty;
@@ -7807,8 +7807,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7807 public LSL_Vector llGetRootPosition() 7807 public LSL_Vector llGetRootPosition()
7808 { 7808 {
7809 m_host.AddScriptLPS(1); 7809 m_host.AddScriptLPS(1);
7810 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition.X, m_host.ParentGroup.AbsolutePosition.Y, 7810
7811 m_host.ParentGroup.AbsolutePosition.Z); 7811 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
7812 } 7812 }
7813 7813
7814 /// <summary> 7814 /// <summary>
@@ -7831,13 +7831,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7831 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 7831 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
7832 q = avatar.CameraRotation; // Mouselook 7832 q = avatar.CameraRotation; // Mouselook
7833 else 7833 else
7834 q = avatar.Rotation; // Currently infrequently updated so may be inaccurate 7834 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
7835 else 7835 else
7836 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case 7836 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case
7837 } 7837 }
7838 else 7838 else
7839 q = m_host.ParentGroup.GroupRotation; // just the group rotation 7839 q = m_host.ParentGroup.GroupRotation; // just the group rotation
7840 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 7840
7841 return new LSL_Rotation(q);
7841 } 7842 }
7842 7843
7843 public LSL_String llGetObjectDesc() 7844 public LSL_String llGetObjectDesc()
@@ -7944,7 +7945,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7944 7945
7945 public LSL_Vector llGetGeometricCenter() 7946 public LSL_Vector llGetGeometricCenter()
7946 { 7947 {
7947 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 7948 return new LSL_Vector(m_host.GetGeometricCenter());
7948 } 7949 }
7949 7950
7950 public LSL_List llGetPrimitiveParams(LSL_List rules) 7951 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -8031,23 +8032,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8031 break; 8032 break;
8032 8033
8033 case (int)ScriptBaseClass.PRIM_POSITION: 8034 case (int)ScriptBaseClass.PRIM_POSITION:
8034 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8035 LSL_Vector v = new LSL_Vector(part.AbsolutePosition);
8035 part.AbsolutePosition.Y, 8036
8036 part.AbsolutePosition.Z);
8037 // For some reason, the part.AbsolutePosition.* values do not change if the 8037 // For some reason, the part.AbsolutePosition.* values do not change if the
8038 // linkset is rotated; they always reflect the child prim's world position 8038 // linkset is rotated; they always reflect the child prim's world position
8039 // as though the linkset is unrotated. This is incompatible behavior with SL's 8039 // as though the linkset is unrotated. This is incompatible behavior with SL's
8040 // implementation, so will break scripts imported from there (not to mention it 8040 // implementation, so will break scripts imported from there (not to mention it
8041 // makes it more difficult to determine a child prim's actual inworld position). 8041 // makes it more difficult to determine a child prim's actual inworld position).
8042 if (part.ParentID != 0) 8042 if (!part.IsRoot)
8043 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition(); 8043 {
8044 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8045 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8046 }
8047
8044 res.Add(v); 8048 res.Add(v);
8045 break; 8049 break;
8046 8050
8047 case (int)ScriptBaseClass.PRIM_SIZE: 8051 case (int)ScriptBaseClass.PRIM_SIZE:
8048 res.Add(new LSL_Vector(part.Scale.X, 8052 res.Add(new LSL_Vector(part.Scale));
8049 part.Scale.Y,
8050 part.Scale.Z));
8051 break; 8053 break;
8052 8054
8053 case (int)ScriptBaseClass.PRIM_ROTATION: 8055 case (int)ScriptBaseClass.PRIM_ROTATION:
@@ -8361,8 +8363,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8361 case (int)ScriptBaseClass.PRIM_DESC: 8363 case (int)ScriptBaseClass.PRIM_DESC:
8362 res.Add(new LSL_String(part.Description)); 8364 res.Add(new LSL_String(part.Description));
8363 break; 8365 break;
8364 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8366 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8365 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 8367 res.Add(new LSL_Rotation(part.RotationOffset));
8366 break; 8368 break;
8367 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 8369 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8368 res.Add(new LSL_Vector(GetPartLocalPos(part))); 8370 res.Add(new LSL_Vector(GetPartLocalPos(part)));
@@ -9571,7 +9573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9571 9573
9572 // according to the docs, this command only works if script owner and land owner are the same 9574 // according to the docs, this command only works if script owner and land owner are the same
9573 // lets add estate owners and gods, too, and use the generic permission check. 9575 // lets add estate owners and gods, too, and use the generic permission check.
9574 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 9576 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
9575 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 9577 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return;
9576 9578
9577 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 9579 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
@@ -9890,21 +9892,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9890 m_host.AddScriptLPS(1); 9892 m_host.AddScriptLPS(1);
9891 9893
9892 if (m_item.PermsGranter == UUID.Zero) 9894 if (m_item.PermsGranter == UUID.Zero)
9893 return new LSL_Vector(); 9895 return Vector3.Zero;
9894 9896
9895 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9897 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9896 { 9898 {
9897 ShoutError("No permissions to track the camera"); 9899 ShoutError("No permissions to track the camera");
9898 return new LSL_Vector(); 9900 return Vector3.Zero;
9899 } 9901 }
9900 9902
9901 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9903 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9902 if (presence != null) 9904 if (presence != null)
9903 { 9905 {
9904 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 9906 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
9905 return pos; 9907 return pos;
9906 } 9908 }
9907 return new LSL_Vector(); 9909
9910 return Vector3.Zero;
9908 } 9911 }
9909 9912
9910 public LSL_Rotation llGetCameraRot() 9913 public LSL_Rotation llGetCameraRot()
@@ -9912,21 +9915,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9912 m_host.AddScriptLPS(1); 9915 m_host.AddScriptLPS(1);
9913 9916
9914 if (m_item.PermsGranter == UUID.Zero) 9917 if (m_item.PermsGranter == UUID.Zero)
9915 return new LSL_Rotation(); 9918 return Quaternion.Identity;
9916 9919
9917 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9920 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9918 { 9921 {
9919 ShoutError("No permissions to track the camera"); 9922 ShoutError("No permissions to track the camera");
9920 return new LSL_Rotation(); 9923 return Quaternion.Identity;
9921 } 9924 }
9922 9925
9923 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9926 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9924 if (presence != null) 9927 if (presence != null)
9925 { 9928 {
9926 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 9929 return new LSL_Rotation(presence.CameraRotation);
9927 } 9930 }
9928 9931
9929 return new LSL_Rotation(); 9932 return Quaternion.Identity;
9930 } 9933 }
9931 9934
9932 /// <summary> 9935 /// <summary>
@@ -9995,7 +9998,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9995 { 9998 {
9996 m_host.AddScriptLPS(1); 9999 m_host.AddScriptLPS(1);
9997 UUID key; 10000 UUID key;
9998 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10001 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
9999 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10002 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10000 { 10003 {
10001 int expires = 0; 10004 int expires = 0;
@@ -10036,7 +10039,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10036 { 10039 {
10037 m_host.AddScriptLPS(1); 10040 m_host.AddScriptLPS(1);
10038 UUID key; 10041 UUID key;
10039 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10042 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10040 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 10043 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
10041 { 10044 {
10042 if (UUID.TryParse(avatar, out key)) 10045 if (UUID.TryParse(avatar, out key))
@@ -10063,7 +10066,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10063 { 10066 {
10064 m_host.AddScriptLPS(1); 10067 m_host.AddScriptLPS(1);
10065 UUID key; 10068 UUID key;
10066 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10069 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10067 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10070 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10068 { 10071 {
10069 if (UUID.TryParse(avatar, out key)) 10072 if (UUID.TryParse(avatar, out key))
@@ -10325,7 +10328,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10325 public void llResetLandBanList() 10328 public void llResetLandBanList()
10326 { 10329 {
10327 m_host.AddScriptLPS(1); 10330 m_host.AddScriptLPS(1);
10328 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 10331 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
10329 if (land.OwnerID == m_host.OwnerID) 10332 if (land.OwnerID == m_host.OwnerID)
10330 { 10333 {
10331 foreach (LandAccessEntry entry in land.ParcelAccessList) 10334 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -10342,7 +10345,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10342 public void llResetLandPassList() 10345 public void llResetLandPassList()
10343 { 10346 {
10344 m_host.AddScriptLPS(1); 10347 m_host.AddScriptLPS(1);
10345 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 10348 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
10346 if (land.OwnerID == m_host.OwnerID) 10349 if (land.OwnerID == m_host.OwnerID)
10347 { 10350 {
10348 foreach (LandAccessEntry entry in land.ParcelAccessList) 10351 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -10518,7 +10521,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10518 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 10521 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z));
10519 break; 10522 break;
10520 case ScriptBaseClass.OBJECT_ROT: 10523 case ScriptBaseClass.OBJECT_ROT:
10521 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 10524 ret.Add(new LSL_Rotation(av.GetWorldRotation()));
10522 break; 10525 break;
10523 case ScriptBaseClass.OBJECT_VELOCITY: 10526 case ScriptBaseClass.OBJECT_VELOCITY:
10524 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 10527 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z));
@@ -10920,7 +10923,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10920 10923
10921 LSL_List result = new LSL_List(); 10924 LSL_List result = new LSL_List();
10922 10925
10923 if (obj != null && obj.OwnerID != m_host.OwnerID) 10926 if (obj != null && obj.OwnerID == m_host.OwnerID)
10924 { 10927 {
10925 LSL_List remaining = GetPrimParams(obj, rules, ref result); 10928 LSL_List remaining = GetPrimParams(obj, rules, ref result);
10926 10929
@@ -11021,7 +11024,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11021 World.ForEachScenePresence(delegate(ScenePresence sp) 11024 World.ForEachScenePresence(delegate(ScenePresence sp)
11022 { 11025 {
11023 Vector3 ac = sp.AbsolutePosition - rayStart; 11026 Vector3 ac = sp.AbsolutePosition - rayStart;
11024 Vector3 bc = sp.AbsolutePosition - rayEnd; 11027// Vector3 bc = sp.AbsolutePosition - rayEnd;
11025 11028
11026 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 11029 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11027 11030
@@ -11111,7 +11114,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11111 radius = Math.Abs(maxZ); 11114 radius = Math.Abs(maxZ);
11112 radius = radius*1.413f; 11115 radius = radius*1.413f;
11113 Vector3 ac = group.AbsolutePosition - rayStart; 11116 Vector3 ac = group.AbsolutePosition - rayStart;
11114 Vector3 bc = group.AbsolutePosition - rayEnd; 11117// Vector3 bc = group.AbsolutePosition - rayEnd;
11115 11118
11116 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 11119 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11117 11120
@@ -11455,7 +11458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11455 list.Add(new LSL_Integer(linkNum)); 11458 list.Add(new LSL_Integer(linkNum));
11456 11459
11457 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11460 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11458 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); 11461 list.Add(new LSL_Vector(result.Normal));
11459 11462
11460 values++; 11463 values++;
11461 if (values >= count) 11464 if (values >= count)
@@ -11557,7 +11560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11557 return 16384; 11560 return 16384;
11558 } 11561 }
11559 11562
11560 public LSL_Integer llGetUsedMemory() 11563 public virtual LSL_Integer llGetUsedMemory()
11561 { 11564 {
11562 m_host.AddScriptLPS(1); 11565 m_host.AddScriptLPS(1);
11563 // The value returned for LSO scripts in SL 11566 // The value returned for LSO scripts in SL
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index d0922aa..21bae27 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -266,6 +266,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
266 { 266 {
267 llist[i] = new LSL_Float((float)result[i]); 267 llist[i] = new LSL_Float((float)result[i]);
268 } 268 }
269 else if (result[i] is double)
270 {
271 llist[i] = new LSL_Float((double)result[i]);
272 }
269 else if (result[i] is UUID) 273 else if (result[i] is UUID)
270 { 274 {
271 llist[i] = new LSL_Key(result[i].ToString()); 275 llist[i] = new LSL_Key(result[i].ToString());
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 48c6b50..bf1b45b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -363,7 +363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
363 //OSSL only may be used if object is in the same group as the parcel 363 //OSSL only may be used if object is in the same group as the parcel
364 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER")) 364 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER"))
365 { 365 {
366 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 366 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
367 367
368 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero) 368 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero)
369 { 369 {
@@ -374,7 +374,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
374 //Only Parcelowners may use the function 374 //Only Parcelowners may use the function
375 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_OWNER")) 375 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_OWNER"))
376 { 376 {
377 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 377 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
378 378
379 if (land.LandData.OwnerID == ownerID) 379 if (land.LandData.OwnerID == ownerID)
380 { 380 {
@@ -1502,8 +1502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1502 1502
1503 m_host.AddScriptLPS(1); 1503 m_host.AddScriptLPS(1);
1504 1504
1505 ILandObject land 1505 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1506 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1507 1506
1508 if (land.LandData.OwnerID != m_host.OwnerID) 1507 if (land.LandData.OwnerID != m_host.OwnerID)
1509 return; 1508 return;
@@ -1519,8 +1518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1518
1520 m_host.AddScriptLPS(1); 1519 m_host.AddScriptLPS(1);
1521 1520
1522 ILandObject land 1521 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1523 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1524 1522
1525 if (land.LandData.OwnerID != m_host.OwnerID) 1523 if (land.LandData.OwnerID != m_host.OwnerID)
1526 { 1524 {
@@ -2515,13 +2513,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2515 ScenePresence sp = World.GetScenePresence(npcId); 2513 ScenePresence sp = World.GetScenePresence(npcId);
2516 2514
2517 if (sp != null) 2515 if (sp != null)
2518 { 2516 return new LSL_Vector(sp.AbsolutePosition);
2519 Vector3 pos = sp.AbsolutePosition;
2520 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2521 }
2522 } 2517 }
2523 2518
2524 return new LSL_Vector(0, 0, 0); 2519 return Vector3.Zero;
2525 } 2520 }
2526 2521
2527 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos) 2522 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
@@ -2578,21 +2573,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2578 { 2573 {
2579 UUID npcId; 2574 UUID npcId;
2580 if (!UUID.TryParse(npc.m_string, out npcId)) 2575 if (!UUID.TryParse(npc.m_string, out npcId))
2581 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2576 return new LSL_Rotation(Quaternion.Identity);
2582 2577
2583 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID)) 2578 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2584 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2579 return new LSL_Rotation(Quaternion.Identity);
2585 2580
2586 ScenePresence sp = World.GetScenePresence(npcId); 2581 ScenePresence sp = World.GetScenePresence(npcId);
2587 2582
2588 if (sp != null) 2583 if (sp != null)
2589 { 2584 return new LSL_Rotation(sp.GetWorldRotation());
2590 Quaternion rot = sp.Rotation;
2591 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2592 }
2593 } 2585 }
2594 2586
2595 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2587 return Quaternion.Identity;
2596 } 2588 }
2597 2589
2598 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) 2590 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
@@ -3022,20 +3014,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 3014
3023 UUID avatarId = new UUID(avatar); 3015 UUID avatarId = new UUID(avatar);
3024 ScenePresence presence = World.GetScenePresence(avatarId); 3016 ScenePresence presence = World.GetScenePresence(avatarId);
3025 Vector3 pos = m_host.GetWorldPosition(); 3017
3026 bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.X, (float)pos.Y, (float)pos.Z)); 3018 if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition()))
3027 if (result)
3028 { 3019 {
3029 if (presence != null) 3020 float health = presence.Health;
3030 { 3021 health += (float)healing;
3031 float health = presence.Health; 3022
3032 health += (float)healing; 3023 if (health >= 100)
3033 if (health >= 100) 3024 health = 100;
3034 { 3025
3035 health = 100; 3026 presence.setHealthWithUpdate(health);
3036 }
3037 presence.setHealthWithUpdate(health);
3038 }
3039 } 3027 }
3040 } 3028 }
3041 3029
@@ -3112,8 +3100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 if (avatar != null && avatar.UUID != m_host.OwnerID) 3100 if (avatar != null && avatar.UUID != m_host.OwnerID)
3113 { 3101 {
3114 result.Add(new LSL_String(avatar.UUID.ToString())); 3102 result.Add(new LSL_String(avatar.UUID.ToString()));
3115 OpenMetaverse.Vector3 ap = avatar.AbsolutePosition; 3103 result.Add(new LSL_Vector(avatar.AbsolutePosition));
3116 result.Add(new LSL_Vector(ap.X, ap.Y, ap.Z));
3117 result.Add(new LSL_String(avatar.Name)); 3104 result.Add(new LSL_String(avatar.Name));
3118 } 3105 }
3119 }); 3106 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index dd45406..88ab515 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -353,7 +353,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.Rotation * q; 356 q = avatar.GetWorldRotation() * q;
357 } 357 }
358 358
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -480,7 +480,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 480 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 481 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.Rotation * q; 483 q = avatar.GetWorldRotation() * q;
484 } 484 }
485 485
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 9d20c9e..b71afe3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -662,13 +662,18 @@ namespace SecondLife
662 { 662 {
663 string severity = CompErr.IsWarning ? "Warning" : "Error"; 663 string severity = CompErr.IsWarning ? "Warning" : "Error";
664 664
665 KeyValuePair<int, int> lslPos; 665 KeyValuePair<int, int> errorPos;
666 666
667 // Show 5 errors max, but check entire list for errors 667 // Show 5 errors max, but check entire list for errors
668 668
669 if (severity == "Error") 669 if (severity == "Error")
670 { 670 {
671 lslPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]); 671 // C# scripts will not have a linemap since theres no line translation involved.
672 if (!m_lineMaps.ContainsKey(assembly))
673 errorPos = new KeyValuePair<int, int>(CompErr.Line, CompErr.Column);
674 else
675 errorPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]);
676
672 string text = CompErr.ErrorText; 677 string text = CompErr.ErrorText;
673 678
674 // Use LSL type names 679 // Use LSL type names
@@ -678,7 +683,7 @@ namespace SecondLife
678 // The Second Life viewer's script editor begins 683 // The Second Life viewer's script editor begins
679 // countingn lines and columns at 0, so we subtract 1. 684 // countingn lines and columns at 0, so we subtract 1.
680 errtext += String.Format("({0},{1}): {4} {2}: {3}\n", 685 errtext += String.Format("({0},{1}): {4} {2}: {3}\n",
681 lslPos.Key - 1, lslPos.Value - 1, 686 errorPos.Key - 1, errorPos.Value - 1,
682 CompErr.ErrorNumber, text, severity); 687 CompErr.ErrorNumber, text, severity);
683 hadErrors = true; 688 hadErrors = true;
684 } 689 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs
index b0baa1c..ab44e38 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs
@@ -209,7 +209,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
209 += (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse); 209 += (itemId, evp) => m_lslApi.llHTTPResponse(evp.Params[0].ToString(), 200, testResponse);
210 210
211// Console.WriteLine("Trying {0}", returnedUri); 211// Console.WriteLine("Trying {0}", returnedUri);
212 HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(returnedUri);
213 212
214 AssertHttpResponse(returnedUri, testResponse); 213 AssertHttpResponse(returnedUri, testResponse);
215 214