aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorKitto Flora2010-02-03 14:32:29 -0500
committerKitto Flora2010-02-03 14:32:29 -0500
commitfc1ac2593510965789e09136693649f7395897cb (patch)
treeecabcee704d9833c01f0ccab90306ba61d944854 /OpenSim
parentAngMotor update 1 (diff)
parentMerge branch 'master' into careminster (diff)
downloadopensim-SC_OLD-fc1ac2593510965789e09136693649f7395897cb.zip
opensim-SC_OLD-fc1ac2593510965789e09136693649f7395897cb.tar.gz
opensim-SC_OLD-fc1ac2593510965789e09136693649f7395897cb.tar.bz2
opensim-SC_OLD-fc1ac2593510965789e09136693649f7395897cb.tar.xz
Merge branch 'master' of ssh://3dhosting.de/var/git/careminster
Diffstat (limited to '')
-rw-r--r--OpenSim/ConsoleClient/ConsoleClient.cs4
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs211
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs13
-rw-r--r--OpenSim/Region/Framework/Interfaces/IWorldComm.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs40
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs80
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs203
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs26
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs150
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs7
16 files changed, 535 insertions, 303 deletions
diff --git a/OpenSim/ConsoleClient/ConsoleClient.cs b/OpenSim/ConsoleClient/ConsoleClient.cs
index d195d25..8c616e0 100644
--- a/OpenSim/ConsoleClient/ConsoleClient.cs
+++ b/OpenSim/ConsoleClient/ConsoleClient.cs
@@ -82,9 +82,11 @@ namespace OpenSim.ConsoleClient
82 82
83 private static void SendCommand(string module, string[] cmd) 83 private static void SendCommand(string module, string[] cmd)
84 { 84 {
85 string sendCmd = cmd[0]; 85 string sendCmd = "";
86 if (cmd.Length > 1) 86 if (cmd.Length > 1)
87 { 87 {
88 sendCmd = cmd[0];
89
88 Array.Copy(cmd, 1, cmd, 0, cmd.Length-1); 90 Array.Copy(cmd, 1, cmd, 0, cmd.Length-1);
89 Array.Resize(ref cmd, cmd.Length-1); 91 Array.Resize(ref cmd, cmd.Length-1);
90 sendCmd += "\"" + String.Join("\" \"", cmd) + "\""; 92 sendCmd += "\"" + String.Join("\" \"", cmd) + "\"";
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index adcf6bd..9216e0b 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -762,7 +762,7 @@ namespace Flotsam.RegionModules.AssetCache
762 case "expire": 762 case "expire":
763 763
764 764
765 if (cmdparams.Length >= 3) 765 if (cmdparams.Length < 3)
766 { 766 {
767 m_log.InfoFormat("[FLOTSAM ASSET CACHE] Invalid parameters for Expire, please specify a valid date & time", cmd); 767 m_log.InfoFormat("[FLOTSAM ASSET CACHE] Invalid parameters for Expire, please specify a valid date & time", cmd);
768 break; 768 break;
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 1200105..c3e57f0 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -42,6 +42,7 @@ using OpenSim.Region.CoreModules.World.Terrain;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Tests.Common; 44using OpenSim.Tests.Common;
45using OpenSim.Tests.Common.Mock;
45using OpenSim.Tests.Common.Setup; 46using OpenSim.Tests.Common.Setup;
46 47
47namespace OpenSim.Region.CoreModules.World.Archiver.Tests 48namespace OpenSim.Region.CoreModules.World.Archiver.Tests
@@ -51,6 +52,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
51 { 52 {
52 private Guid m_lastRequestId; 53 private Guid m_lastRequestId;
53 private string m_lastErrorMessage; 54 private string m_lastErrorMessage;
55
56 protected TestScene m_scene;
57 protected ArchiverModule m_archiverModule;
58
59 [SetUp]
60 public void SetUp()
61 {
62 m_archiverModule = new ArchiverModule();
63 SerialiserModule serialiserModule = new SerialiserModule();
64 TerrainModule terrainModule = new TerrainModule();
65
66 m_scene = SceneSetupHelpers.SetupScene("scene1");
67 SceneSetupHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule);
68 }
54 69
55 private void LoadCompleted(Guid requestId, string errorMessage) 70 private void LoadCompleted(Guid requestId, string errorMessage)
56 { 71 {
@@ -75,6 +90,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
75 } 90 }
76 } 91 }
77 92
93 protected SceneObjectPart CreateSceneObjectPart1()
94 {
95 string partName = "My Little Pony";
96 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
97 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
98 Vector3 groupPosition = new Vector3(10, 20, 30);
99 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
100 Vector3 offsetPosition = new Vector3(5, 10, 15);
101
102 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
103 }
104
105 protected SceneObjectPart CreateSceneObjectPart2()
106 {
107 string partName = "Action Man";
108 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
109 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
110 Vector3 groupPosition = new Vector3(90, 80, 70);
111 Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
112 Vector3 offsetPosition = new Vector3(20, 25, 30);
113
114 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
115 }
116
78 /// <summary> 117 /// <summary>
79 /// Test saving a V0.2 OpenSim Region Archive. 118 /// Test saving a V0.2 OpenSim Region Archive.
80 /// </summary> 119 /// </summary>
@@ -84,59 +123,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
84 TestHelper.InMethod(); 123 TestHelper.InMethod();
85 //log4net.Config.XmlConfigurator.Configure(); 124 //log4net.Config.XmlConfigurator.Configure();
86 125
87 ArchiverModule archiverModule = new ArchiverModule(); 126 SceneObjectPart part1 = CreateSceneObjectPart1();
88 SerialiserModule serialiserModule = new SerialiserModule(); 127 m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
89 TerrainModule terrainModule = new TerrainModule();
90
91 Scene scene = SceneSetupHelpers.SetupScene("asset");
92 SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
93
94 SceneObjectPart part1;
95
96 // Create and add prim 1
97 {
98 string partName = "My Little Pony";
99 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
100 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
101 Vector3 groupPosition = new Vector3(10, 20, 30);
102 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
103 Vector3 offsetPosition = new Vector3(5, 10, 15);
104
105 part1
106 = new SceneObjectPart(
107 ownerId, shape, groupPosition, rotationOffset, offsetPosition);
108 part1.Name = partName;
109
110 scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
111 }
112
113 SceneObjectPart part2;
114 128
115 // Create and add prim 2 129 SceneObjectPart part2 = CreateSceneObjectPart2();
116 { 130 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
117 string partName = "Action Man";
118 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
119 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
120 Vector3 groupPosition = new Vector3(90, 80, 70);
121 Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
122 Vector3 offsetPosition = new Vector3(20, 25, 30);
123
124 part2
125 = new SceneObjectPart(
126 ownerId, shape, groupPosition, rotationOffset, offsetPosition);
127 part2.Name = partName;
128
129 scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
130 }
131 131
132 MemoryStream archiveWriteStream = new MemoryStream(); 132 MemoryStream archiveWriteStream = new MemoryStream();
133 scene.EventManager.OnOarFileSaved += SaveCompleted; 133 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
134 134
135 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080"); 135 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
136 136
137 lock (this) 137 lock (this)
138 { 138 {
139 archiverModule.ArchiveRegion(archiveWriteStream, requestId); 139 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId);
140 //AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer; 140 //AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
141 //while (assetServer.HasWaitingRequests()) 141 //while (assetServer.HasWaitingRequests())
142 // assetServer.ProcessNextRequest(); 142 // assetServer.ProcessNextRequest();
@@ -218,25 +218,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
218 218
219 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile()); 219 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
220 220
221 string part1Name = "object1"; 221 SceneObjectPart part1 = CreateSceneObjectPart1();
222 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
223 Vector3 groupPosition = new Vector3(90, 80, 70);
224 Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
225 Vector3 offsetPosition = new Vector3(20, 25, 30);
226
227 SerialiserModule serialiserModule = new SerialiserModule();
228 ArchiverModule archiverModule = new ArchiverModule();
229
230 Scene scene = SceneSetupHelpers.SetupScene();
231 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
232
233 SceneObjectPart part1
234 = new SceneObjectPart(
235 UUID.Zero, shape, groupPosition, rotationOffset, offsetPosition);
236 part1.Name = part1Name;
237 SceneObjectGroup object1 = new SceneObjectGroup(part1); 222 SceneObjectGroup object1 = new SceneObjectGroup(part1);
238 223
239 // Let's put some inventory items into our object 224 // Let's put some inventory items into our object
225 string soundItemName = "sound-item1";
240 UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); 226 UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
241 Type type = GetType(); 227 Type type = GetType();
242 Assembly assembly = type.Assembly; 228 Assembly assembly = type.Assembly;
@@ -269,17 +255,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
269 asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav"; 255 asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
270 */ 256 */
271 257
272 TaskInventoryItem item1 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid }; 258 TaskInventoryItem item1
259 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
273 part1.Inventory.AddInventoryItem(item1, true); 260 part1.Inventory.AddInventoryItem(item1, true);
274 } 261 }
275 } 262 }
276 263
277 scene.AddNewSceneObject(object1, false); 264 m_scene.AddNewSceneObject(object1, false);
278 265
279 string object1FileName = string.Format( 266 string object1FileName = string.Format(
280 "{0}_{1:000}-{2:000}-{3:000}__{4}.xml", 267 "{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
281 part1Name, 268 part1.Name,
282 Math.Round(groupPosition.X), Math.Round(groupPosition.Y), Math.Round(groupPosition.Z), 269 Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
283 part1.UUID); 270 part1.UUID);
284 tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1)); 271 tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1));
285 272
@@ -289,30 +276,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
289 276
290 lock (this) 277 lock (this)
291 { 278 {
292 scene.EventManager.OnOarFileLoaded += LoadCompleted; 279 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
293 archiverModule.DearchiveRegion(archiveReadStream); 280 m_archiverModule.DearchiveRegion(archiveReadStream);
294 } 281 }
295 282
296 Assert.That(m_lastErrorMessage, Is.Null); 283 Assert.That(m_lastErrorMessage, Is.Null);
297 284
298 SceneObjectPart object1PartLoaded = scene.GetSceneObjectPart(part1Name); 285 SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
299 286
300 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); 287 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
301 Assert.That(object1PartLoaded.Name, Is.EqualTo(part1Name), "object1 names not identical"); 288 Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical");
302 Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(groupPosition), "object1 group position not equal"); 289 Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
303 Assert.That( 290 Assert.That(
304 object1PartLoaded.RotationOffset, Is.EqualTo(rotationOffset), "object1 rotation offset not equal"); 291 object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
305 Assert.That( 292 Assert.That(
306 object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal"); 293 object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
307 294
308 // Need to implement a method to get the task inventory item by name (since the uuid will have changed on load) 295 TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
309 /*
310 TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItem(soundItemUuid);
311 Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); 296 Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
312 AssetBase loadedSoundAsset = scene.AssetService.Get(loadedSoundItem.AssetID.ToString()); 297 AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
313 Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null"); 298 Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
314 Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); 299 Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
315 */
316 300
317 // Temporary 301 // Temporary
318 Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); 302 Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod());
@@ -325,12 +309,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
325 public void TestLoadOarV0_2RegionSettings() 309 public void TestLoadOarV0_2RegionSettings()
326 { 310 {
327 TestHelper.InMethod(); 311 TestHelper.InMethod();
328 //log4net.Config.XmlConfigurator.Configure(); 312 //log4net.Config.XmlConfigurator.Configure();
329
330 SerialiserModule serialiserModule = new SerialiserModule();
331 ArchiverModule archiverModule = new ArchiverModule();
332 Scene scene = SceneSetupHelpers.SetupScene();
333 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
334 313
335 MemoryStream archiveWriteStream = new MemoryStream(); 314 MemoryStream archiveWriteStream = new MemoryStream();
336 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); 315 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
@@ -377,12 +356,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
377 356
378 lock (this) 357 lock (this)
379 { 358 {
380 scene.EventManager.OnOarFileLoaded += LoadCompleted; 359 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
381 archiverModule.DearchiveRegion(archiveReadStream); 360 m_archiverModule.DearchiveRegion(archiveReadStream);
382 } 361 }
383 362
384 Assert.That(m_lastErrorMessage, Is.Null); 363 Assert.That(m_lastErrorMessage, Is.Null);
385 RegionSettings loadedRs = scene.RegionInfo.RegionSettings; 364 RegionSettings loadedRs = m_scene.RegionInfo.RegionSettings;
386 365
387 Assert.That(loadedRs.AgentLimit, Is.EqualTo(17)); 366 Assert.That(loadedRs.AgentLimit, Is.EqualTo(17));
388 Assert.That(loadedRs.AllowDamage, Is.True); 367 Assert.That(loadedRs.AllowDamage, Is.True);
@@ -426,11 +405,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
426 405
427 MemoryStream archiveWriteStream = new MemoryStream(); 406 MemoryStream archiveWriteStream = new MemoryStream();
428 407
429 string part2Name = "objectMerge"; 408// string part2Name = "objectMerge";
430 PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder(); 409// PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
431 Vector3 part2GroupPosition = new Vector3(90, 80, 70); 410// Vector3 part2GroupPosition = new Vector3(90, 80, 70);
432 Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90); 411// Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
433 Vector3 part2OffsetPosition = new Vector3(20, 25, 30); 412// Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
413
414 SceneObjectPart part2 = CreateSceneObjectPart2();
434 415
435 // Create an oar file that we can use for the merge 416 // Create an oar file that we can use for the merge
436 { 417 {
@@ -439,63 +420,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
439 TerrainModule terrainModule = new TerrainModule(); 420 TerrainModule terrainModule = new TerrainModule();
440 421
441 Scene scene = SceneSetupHelpers.SetupScene(); 422 Scene scene = SceneSetupHelpers.SetupScene();
442 SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); 423 SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
443 424
444 SceneObjectPart part2 425 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
445 = new SceneObjectPart(
446 UUID.Zero, part2Shape, part2GroupPosition, part2RotationOffset, part2OffsetPosition);
447 part2.Name = part2Name;
448 SceneObjectGroup object2 = new SceneObjectGroup(part2);
449
450 scene.AddNewSceneObject(object2, false);
451 426
452 // Write out this scene 427 // Write out this scene
453 scene.EventManager.OnOarFileSaved += SaveCompleted; 428 scene.EventManager.OnOarFileSaved += SaveCompleted;
454 429
455 lock (this) 430 lock (this)
456 { 431 {
457 archiverModule.ArchiveRegion(archiveWriteStream); 432 m_archiverModule.ArchiveRegion(archiveWriteStream);
458 Monitor.Wait(this, 60000); 433 Monitor.Wait(this, 60000);
459 } 434 }
460 } 435 }
461 436
462 { 437 {
463 ArchiverModule archiverModule = new ArchiverModule(); 438 SceneObjectPart part1 = CreateSceneObjectPart1();
464 SerialiserModule serialiserModule = new SerialiserModule(); 439 m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
465 TerrainModule terrainModule = new TerrainModule();
466
467 Scene scene = SceneSetupHelpers.SetupScene();
468 SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
469
470 string part1Name = "objectExisting";
471 PrimitiveBaseShape part1Shape = PrimitiveBaseShape.CreateCylinder();
472 Vector3 part1GroupPosition = new Vector3(80, 70, 60);
473 Quaternion part1RotationOffset = new Quaternion(50, 60, 70, 80);
474 Vector3 part1OffsetPosition = new Vector3(15, 20, 25);
475
476 SceneObjectPart part1
477 = new SceneObjectPart(
478 UUID.Zero, part1Shape, part1GroupPosition, part1RotationOffset, part1OffsetPosition);
479 part1.Name = part1Name;
480 SceneObjectGroup object1 = new SceneObjectGroup(part1);
481
482 scene.AddNewSceneObject(object1, false);
483 440
484 // Merge in the archive we created earlier 441 // Merge in the archive we created earlier
485 byte[] archive = archiveWriteStream.ToArray(); 442 byte[] archive = archiveWriteStream.ToArray();
486 MemoryStream archiveReadStream = new MemoryStream(archive); 443 MemoryStream archiveReadStream = new MemoryStream(archive);
487 444
488 archiverModule.DearchiveRegion(archiveReadStream, true, Guid.Empty); 445 m_archiverModule.DearchiveRegion(archiveReadStream, true, Guid.Empty);
489 446
490 SceneObjectPart object1Existing = scene.GetSceneObjectPart(part1Name); 447 SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name);
491 Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge"); 448 Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
492 Assert.That(object1Existing.Name, Is.EqualTo(part1Name), "object1 names not identical after merge"); 449 Assert.That(object1Existing.Name, Is.EqualTo(part1.Name), "object1 names not identical after merge");
493 Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1GroupPosition), "object1 group position not equal after merge"); 450 Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal after merge");
494 451
495 SceneObjectPart object2PartMerged = scene.GetSceneObjectPart(part2Name); 452 SceneObjectPart object2PartMerged = m_scene.GetSceneObjectPart(part2.Name);
496 Assert.That(object2PartMerged, Is.Not.Null, "object2 was not present after merge"); 453 Assert.That(object2PartMerged, Is.Not.Null, "object2 was not present after merge");
497 Assert.That(object2PartMerged.Name, Is.EqualTo(part2Name), "object2 names not identical after merge"); 454 Assert.That(object2PartMerged.Name, Is.EqualTo(part2.Name), "object2 names not identical after merge");
498 Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2GroupPosition), "object2 group position not equal after merge"); 455 Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge");
499 } 456 }
500 } 457 }
501 } 458 }
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index eeb5102..fa9bf19 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -71,7 +71,8 @@ namespace OpenSim.Region.Framework.Interfaces
71 /// <summary> 71 /// <summary>
72 /// Start all the scripts contained in this entity's inventory 72 /// Start all the scripts contained in this entity's inventory
73 /// </summary> 73 /// </summary>
74 void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource); 74 void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
75
75 ArrayList GetScriptErrors(UUID itemID); 76 ArrayList GetScriptErrors(UUID itemID);
76 77
77 /// <summary> 78 /// <summary>
@@ -143,6 +144,16 @@ namespace OpenSim.Region.Framework.Interfaces
143 TaskInventoryItem GetInventoryItem(UUID itemId); 144 TaskInventoryItem GetInventoryItem(UUID itemId);
144 145
145 /// <summary> 146 /// <summary>
147 /// Get inventory items by name.
148 /// </summary>
149 /// <param name="name"></param>
150 /// <returns>
151 /// A list of inventory items with that name.
152 /// If no inventory item has that name then an empty list is returned.
153 /// </returns>
154 IList<TaskInventoryItem> GetInventoryItems(string name);
155
156 /// <summary>
146 /// Update an existing inventory item. 157 /// Update an existing inventory item.
147 /// </summary> 158 /// </summary>
148 /// <param name="item">The updated item. An item with the same id must already exist 159 /// <param name="item">The updated item. An item with the same id must already exist
diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
index 74526c4..948b9dc 100644
--- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
+++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
@@ -49,10 +49,49 @@ namespace OpenSim.Region.Framework.Interfaces
49 49
50 public interface IWorldComm 50 public interface IWorldComm
51 { 51 {
52 /// <summary>
53 /// Create a listen event callback with the specified filters.
54 /// The parameters localID,itemID are needed to uniquely identify
55 /// the script during 'peek' time. Parameter hostID is needed to
56 /// determine the position of the script.
57 /// </summary>
58 /// <param name="localID">localID of the script engine</param>
59 /// <param name="itemID">UUID of the script engine</param>
60 /// <param name="hostID">UUID of the SceneObjectPart</param>
61 /// <param name="channel">channel to listen on</param>
62 /// <param name="name">name to filter on</param>
63 /// <param name="id">key to filter on (user given, could be totally faked)</param>
64 /// <param name="msg">msg to filter on</param>
65 /// <returns>number of the scripts handle</returns>
52 int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg); 66 int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg);
67
68 /// <summary>
69 /// This method scans over the objects which registered an interest in listen callbacks.
70 /// For everyone it finds, it checks if it fits the given filter. If it does, then
71 /// enqueue the message for delivery to the objects listen event handler.
72 /// The enqueued ListenerInfo no longer has filter values, but the actually trigged values.
73 /// Objects that do an llSay have their messages delivered here and for nearby avatars,
74 /// the OnChatFromClient event is used.
75 /// </summary>
76 /// <param name="type">type of delvery (whisper,say,shout or regionwide)</param>
77 /// <param name="channel">channel to sent on</param>
78 /// <param name="name">name of sender (object or avatar)</param>
79 /// <param name="id">key of sender (object or avatar)</param>
80 /// <param name="msg">msg to sent</param>
53 void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg); 81 void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg);
82
83 /// <summary>
84 /// Are there any listen events ready to be dispatched?
85 /// </summary>
86 /// <returns>boolean indication</returns>
54 bool HasMessages(); 87 bool HasMessages();
88
89 /// <summary>
90 /// Pop the first availlable listen event from the queue
91 /// </summary>
92 /// <returns>ListenerInfo with filter filled in</returns>
55 IWorldCommListenerInfo GetNextMessage(); 93 IWorldCommListenerInfo GetNextMessage();
94
56 void ListenControl(UUID itemID, int handle, int active); 95 void ListenControl(UUID itemID, int handle, int active);
57 void ListenRemove(UUID itemID, int handle); 96 void ListenRemove(UUID itemID, int handle);
58 void DeleteListener(UUID itemID); 97 void DeleteListener(UUID itemID);
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 8f0b866..fe40f52 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -92,8 +92,7 @@ namespace OpenSim.Region.Framework.Scenes
92 public delegate void OnShutdownDelegate(); 92 public delegate void OnShutdownDelegate();
93 93
94 public event OnShutdownDelegate OnShutdown; 94 public event OnShutdownDelegate OnShutdown;
95 95
96 public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
97 public delegate void ObjectDeGrabDelegate(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs); 96 public delegate void ObjectDeGrabDelegate(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
98 public delegate void ScriptResetDelegate(uint localID, UUID itemID); 97 public delegate void ScriptResetDelegate(uint localID, UUID itemID);
99 98
@@ -103,62 +102,57 @@ namespace OpenSim.Region.Framework.Scenes
103 102
104 public event OnSetRootAgentSceneDelegate OnSetRootAgentScene; 103 public event OnSetRootAgentSceneDelegate OnSetRootAgentScene;
105 104
105 /// <summary>
106 /// Called when an object is touched/grabbed.
107 /// </summary>
108 /// The originalID is the local ID of the part that was actually touched. The localID itself is always that of
109 /// the root part.
110 public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
106 public event ObjectGrabDelegate OnObjectGrab; 111 public event ObjectGrabDelegate OnObjectGrab;
112
113 public event ObjectGrabDelegate OnObjectGrabbing;
107 public event ObjectDeGrabDelegate OnObjectDeGrab; 114 public event ObjectDeGrabDelegate OnObjectDeGrab;
108 public event ScriptResetDelegate OnScriptReset; 115 public event ScriptResetDelegate OnScriptReset;
109 116
110 public event OnPermissionErrorDelegate OnPermissionError; 117 public event OnPermissionErrorDelegate OnPermissionError;
111 118
112 public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource); 119 public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource);
113
114 public event NewRezScript OnRezScript; 120 public event NewRezScript OnRezScript;
115 121
116 public delegate void RemoveScript(uint localID, UUID itemID); 122 public delegate void RemoveScript(uint localID, UUID itemID);
117
118 public event RemoveScript OnRemoveScript; 123 public event RemoveScript OnRemoveScript;
119 124
120 public delegate void StartScript(uint localID, UUID itemID); 125 public delegate void StartScript(uint localID, UUID itemID);
121
122 public event StartScript OnStartScript; 126 public event StartScript OnStartScript;
123 127
124 public delegate void StopScript(uint localID, UUID itemID); 128 public delegate void StopScript(uint localID, UUID itemID);
125
126 public event StopScript OnStopScript; 129 public event StopScript OnStopScript;
127 130
128 public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta); 131 public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta);
129
130 public event SceneGroupMoved OnSceneGroupMove; 132 public event SceneGroupMoved OnSceneGroupMove;
131 133
132 public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID); 134 public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID);
133
134 public event SceneGroupGrabed OnSceneGroupGrab; 135 public event SceneGroupGrabed OnSceneGroupGrab;
135 136
136 public delegate bool SceneGroupSpinStarted(UUID groupID); 137 public delegate bool SceneGroupSpinStarted(UUID groupID);
137
138 public event SceneGroupSpinStarted OnSceneGroupSpinStart; 138 public event SceneGroupSpinStarted OnSceneGroupSpinStart;
139 139
140 public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation); 140 public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation);
141
142 public event SceneGroupSpun OnSceneGroupSpin; 141 public event SceneGroupSpun OnSceneGroupSpin;
143 142
144 public delegate void LandObjectAdded(ILandObject newParcel); 143 public delegate void LandObjectAdded(ILandObject newParcel);
145
146 public event LandObjectAdded OnLandObjectAdded; 144 public event LandObjectAdded OnLandObjectAdded;
147 145
148 public delegate void LandObjectRemoved(UUID globalID); 146 public delegate void LandObjectRemoved(UUID globalID);
149
150 public event LandObjectRemoved OnLandObjectRemoved; 147 public event LandObjectRemoved OnLandObjectRemoved;
151 148
152 public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID); 149 public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID);
153
154 public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; 150 public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
155 151
156 public delegate void SignificantClientMovement(IClientAPI remote_client); 152 public delegate void SignificantClientMovement(IClientAPI remote_client);
157
158 public event SignificantClientMovement OnSignificantClientMovement; 153 public event SignificantClientMovement OnSignificantClientMovement;
159 154
160 public delegate void IncomingInstantMessage(GridInstantMessage message); 155 public delegate void IncomingInstantMessage(GridInstantMessage message);
161
162 public event IncomingInstantMessage OnIncomingInstantMessage; 156 public event IncomingInstantMessage OnIncomingInstantMessage;
163 157
164 public event IncomingInstantMessage OnUnhandledInstantMessage; 158 public event IncomingInstantMessage OnUnhandledInstantMessage;
@@ -316,9 +310,10 @@ namespace OpenSim.Region.Framework.Scenes
316 public event EmptyScriptCompileQueue OnEmptyScriptCompileQueue; 310 public event EmptyScriptCompileQueue OnEmptyScriptCompileQueue;
317 311
318 /// <summary> 312 /// <summary>
319 /// Called whenever an object is attached, or detached 313 /// Called whenever an object is attached, or detached from an in-world presence.
320 /// from an in-world presence.
321 /// </summary> 314 /// </summary>
315 /// If the object is being attached, then the avatarID will be present. If the object is being detached then
316 /// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical).
322 public delegate void Attach(uint localID, UUID itemID, UUID avatarID); 317 public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
323 public event Attach OnAttach; 318 public event Attach OnAttach;
324 319
@@ -412,6 +407,7 @@ namespace OpenSim.Region.Framework.Scenes
412 private OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = null; //OnParcelPrimCountAdd; 407 private OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = null; //OnParcelPrimCountAdd;
413 private OnShutdownDelegate handlerShutdown = null; //OnShutdown; 408 private OnShutdownDelegate handlerShutdown = null; //OnShutdown;
414 private ObjectGrabDelegate handlerObjectGrab = null; //OnObjectGrab; 409 private ObjectGrabDelegate handlerObjectGrab = null; //OnObjectGrab;
410 private ObjectGrabDelegate handlerObjectGrabbing = null; //OnObjectGrabbing;
415 private ObjectDeGrabDelegate handlerObjectDeGrab = null; //OnObjectDeGrab; 411 private ObjectDeGrabDelegate handlerObjectDeGrab = null; //OnObjectDeGrab;
416 private ScriptResetDelegate handlerScriptReset = null; // OnScriptReset 412 private ScriptResetDelegate handlerScriptReset = null; // OnScriptReset
417 private NewRezScript handlerRezScript = null; //OnRezScript; 413 private NewRezScript handlerRezScript = null; //OnRezScript;
@@ -626,6 +622,15 @@ namespace OpenSim.Region.Framework.Scenes
626 } 622 }
627 } 623 }
628 624
625 public void TriggerObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
626 {
627 handlerObjectGrabbing = OnObjectGrabbing;
628 if (handlerObjectGrabbing != null)
629 {
630 handlerObjectGrabbing(localID, originalID, offsetPos, remoteClient, surfaceArgs);
631 }
632 }
633
629 public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) 634 public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
630 { 635 {
631 handlerObjectDeGrab = OnObjectDeGrab; 636 handlerObjectDeGrab = OnObjectDeGrab;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index a18bf76..7b852a2 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -2385,9 +2385,19 @@ namespace OpenSim.Region.Framework.Scenes
2385 } 2385 }
2386 } 2386 }
2387 2387
2388 public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent) 2388 /// <summary>
2389 /// Attach an object.
2390 /// </summary>
2391 /// <param name="controllingClient"></param>
2392 /// <param name="localID"></param>
2393 /// <param name="attachPoint"></param>
2394 /// <param name="rot"></param>
2395 /// <param name="pos"></param>
2396 /// <param name="silent"></param>
2397 /// <returns>true if the object was successfully attached, false otherwise</returns>
2398 public bool AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
2389 { 2399 {
2390 m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent); 2400 return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
2391 } 2401 }
2392 2402
2393 public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 2403 public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 47fbeb4..ac04dc7 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -292,6 +292,46 @@ namespace OpenSim.Region.Framework.Scenes
292 } 292 }
293 } 293 }
294 294
295 public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
296 {
297 List<EntityBase> EntityList = GetEntities();
298
299 SurfaceTouchEventArgs surfaceArg = null;
300 if (surfaceArgs != null && surfaceArgs.Count > 0)
301 surfaceArg = surfaceArgs[0];
302
303 foreach (EntityBase ent in EntityList)
304 {
305 if (ent is SceneObjectGroup)
306 {
307 SceneObjectGroup obj = ent as SceneObjectGroup;
308 if (obj != null)
309 {
310 // Is this prim part of the group
311 if (obj.HasChildPrim(objectID))
312 {
313 SceneObjectPart part = obj.GetChildPart(objectID);
314
315 // If the touched prim handles touches, deliver it
316 // If not, deliver to root prim
317 if ((part.ScriptEvents & scriptEvents.touch) != 0)
318 EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
319 // Deliver to the root prim if the touched prim doesn't handle touches
320 // or if we're meant to pass on touches anyway. Don't send to root prim
321 // if prim touched is the root prim as we just did it
322 if (((part.ScriptEvents & scriptEvents.touch) == 0) ||
323 (part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
324 {
325 EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
326 }
327
328 return;
329 }
330 }
331 }
332 }
333 }
334
295 public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) 335 public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
296 { 336 {
297 List<EntityBase> EntityList = GetEntities(); 337 List<EntityBase> EntityList = GetEntities();
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 23db482..d2f33b0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2702,6 +2702,7 @@ namespace OpenSim.Region.Framework.Scenes
2702 client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily; 2702 client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
2703 client.OnObjectPermissions += HandleObjectPermissionsUpdate; 2703 client.OnObjectPermissions += HandleObjectPermissionsUpdate;
2704 client.OnGrabObject += ProcessObjectGrab; 2704 client.OnGrabObject += ProcessObjectGrab;
2705 client.OnGrabUpdate += ProcessObjectGrabUpdate;
2705 client.OnDeGrabObject += ProcessObjectDeGrab; 2706 client.OnDeGrabObject += ProcessObjectDeGrab;
2706 client.OnUndo += m_sceneGraph.HandleUndo; 2707 client.OnUndo += m_sceneGraph.HandleUndo;
2707 client.OnObjectDescription += m_sceneGraph.PrimDescription; 2708 client.OnObjectDescription += m_sceneGraph.PrimDescription;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 34a92fe..2c66719 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -502,46 +502,62 @@ namespace OpenSim.Region.Framework.Scenes
502 if (part == null) 502 if (part == null)
503 return; 503 return;
504 504
505 if (!m_parentScene.Permissions.CanTakeObject( 505 if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
506 part.UUID, remoteClient.AgentId))
507 return; 506 return;
508 507
509 // Calls attach with a Zero position 508 // Calls attach with a Zero position
510 AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); 509 if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false))
511 m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
512
513 // Save avatar attachment information
514 ScenePresence presence;
515 if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
516 { 510 {
517 m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt); 511 m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
518 m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 512
513 // Save avatar attachment information
514 ScenePresence presence;
515 if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
516 {
517 m_log.Info(
518 "[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
519 + ", AttachmentPoint: " + AttachmentPt);
520
521 m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
522 }
519 } 523 }
520 } 524 }
521 525
522 public SceneObjectGroup RezSingleAttachment( 526 /// <summary>
523 IClientAPI remoteClient, UUID itemID, uint AttachmentPt) 527 /// Rez an attachment
528 /// </summary>
529 /// <param name="remoteClient"></param>
530 /// <param name="itemID"></param>
531 /// <param name="AttachmentPt"></param>
532 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
533 public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
524 { 534 {
525 SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient, 535 SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient,
526 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, 536 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
527 false, false, remoteClient.AgentId, true); 537 false, false, remoteClient.AgentId, true);
528 538
529
530 if (objatt != null) 539 if (objatt != null)
531 { 540 {
532 bool tainted = false; 541 bool tainted = false;
533 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) 542 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
534 tainted = true; 543 tainted = true;
535 544
536 AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); 545 if (AttachObject(
537 objatt.ScheduleGroupForFullUpdate(); 546 remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false))
538 if (tainted) 547 {
539 objatt.HasGroupChanged = true; 548 objatt.ScheduleGroupForFullUpdate();
540 549 if (tainted)
541 // Fire after attach, so we don't get messy perms dialogs 550 objatt.HasGroupChanged = true;
542 // 3 == AttachedRez 551
543 objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); 552 // Fire after attach, so we don't get messy perms dialogs
553 // 3 == AttachedRez
554 objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3);
555
556 // Do this last so that event listeners have access to all the effects of the attachment
557 m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
558 }
544 } 559 }
560
545 return objatt; 561 return objatt;
546 } 562 }
547 563
@@ -590,7 +606,17 @@ namespace OpenSim.Region.Framework.Scenes
590 } 606 }
591 } 607 }
592 608
593 protected internal void AttachObject( 609 /// <summary>
610 /// Attach a scene object to an avatar.
611 /// </summary>
612 /// <param name="remoteClient"></param>
613 /// <param name="objectLocalID"></param>
614 /// <param name="AttachmentPt"></param>
615 /// <param name="rot"></param>
616 /// <param name="attachPos"></param>
617 /// <param name="silent"></param>
618 /// <returns>true if the attachment was successful, false otherwise</returns>
619 protected internal bool AttachObject(
594 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) 620 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
595 { 621 {
596 SceneObjectGroup group = GetGroupByPrim(objectLocalID); 622 SceneObjectGroup group = GetGroupByPrim(objectLocalID);
@@ -619,10 +645,8 @@ namespace OpenSim.Region.Framework.Scenes
619 // Stick it on left hand with Zero Offset from the attachment point. 645 // Stick it on left hand with Zero Offset from the attachment point.
620 AttachmentPt = (uint)AttachmentPoint.LeftHand; 646 AttachmentPt = (uint)AttachmentPoint.LeftHand;
621 attachPos = Vector3.Zero; 647 attachPos = Vector3.Zero;
622
623 } 648 }
624 649
625
626 group.SetAttachmentPoint((byte)AttachmentPt); 650 group.SetAttachmentPoint((byte)AttachmentPt);
627 group.AbsolutePosition = attachPos; 651 group.AbsolutePosition = attachPos;
628 652
@@ -645,15 +669,21 @@ namespace OpenSim.Region.Framework.Scenes
645 // it get cleaned up 669 // it get cleaned up
646 // 670 //
647 group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); 671 group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
648 group.HasGroupChanged = false; 672 group.HasGroupChanged = false;
649 } 673 }
650 else 674 else
651 { 675 {
652 remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false); 676 remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false);
677 return false;
653 } 678 }
654 } 679 }
655 else 680 else
681 {
656 m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID); 682 m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID);
683 return false;
684 }
685
686 return true;
657 } 687 }
658 688
659 protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) 689 protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 768ceb5..9cb1398 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -301,6 +301,9 @@ namespace OpenSim.Region.Framework.Scenes
301 set { m_rootPart.GroupID = value; } 301 set { m_rootPart.GroupID = value; }
302 } 302 }
303 303
304 /// <value>
305 /// The parts of this scene object group. You must lock this property before using it.
306 /// </value>
304 public Dictionary<UUID, SceneObjectPart> Children 307 public Dictionary<UUID, SceneObjectPart> Children
305 { 308 {
306 get { return m_parts; } 309 get { return m_parts; }
@@ -2239,7 +2242,7 @@ namespace OpenSim.Region.Framework.Scenes
2239 } 2242 }
2240 2243
2241 /// <summary> 2244 /// <summary>
2242 /// Get a child part with a given UUID 2245 /// Get a part with a given UUID
2243 /// </summary> 2246 /// </summary>
2244 /// <param name="primID"></param> 2247 /// <param name="primID"></param>
2245 /// <returns>null if a child part with the primID was not found</returns> 2248 /// <returns>null if a child part with the primID was not found</returns>
@@ -2254,7 +2257,7 @@ namespace OpenSim.Region.Framework.Scenes
2254 } 2257 }
2255 2258
2256 /// <summary> 2259 /// <summary>
2257 /// Get a child part with a given local ID 2260 /// Get a part with a given local ID
2258 /// </summary> 2261 /// </summary>
2259 /// <param name="localID"></param> 2262 /// <param name="localID"></param>
2260 /// <returns>null if a child part with the local ID was not found</returns> 2263 /// <returns>null if a child part with the local ID was not found</returns>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index da7ec44..fe1e218 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -90,10 +90,27 @@ namespace OpenSim.Region.Framework.Scenes
90 SCALE = 0x40 90 SCALE = 0x40
91 } 91 }
92 92
93 public enum PrimType : int
94 {
95 BOX = 0,
96 CYLINDER = 1,
97 PRISM = 2,
98 SPHERE = 3,
99 TORUS = 4,
100 TUBE = 5,
101 RING = 6,
102 SCULPT = 7
103 }
104
93 #endregion Enumerations 105 #endregion Enumerations
94 106
95 public class SceneObjectPart : IScriptHost 107 public class SceneObjectPart : IScriptHost
96 { 108 {
109 /// <value>
110 /// Denote all sides of the prim
111 /// </value>
112 public const int ALL_SIDES = -1;
113
97 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 114 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
98 115
99 // use only one serializer to give the runtime a chance to optimize it (it won't do that if you 116 // use only one serializer to give the runtime a chance to optimize it (it won't do that if you
@@ -741,6 +758,9 @@ namespace OpenSim.Region.Framework.Scenes
741 } 758 }
742 } 759 }
743 760
761 /// <value>
762 /// Text color.
763 /// </value>
744 public Color Color 764 public Color Color
745 { 765 {
746 get { return m_color; } 766 get { return m_color; }
@@ -1910,7 +1930,7 @@ namespace OpenSim.Region.Framework.Scenes
1910 foreach (uint localId in startedColliders) 1930 foreach (uint localId in startedColliders)
1911 { 1931 {
1912 if (localId == 0) 1932 if (localId == 0)
1913 return; 1933 continue;
1914 // always running this check because if the user deletes the object it would return a null reference. 1934 // always running this check because if the user deletes the object it would return a null reference.
1915 if (m_parentGroup == null) 1935 if (m_parentGroup == null)
1916 return; 1936 return;
@@ -2046,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes
2046 { 2066 {
2047 // always running this check because if the user deletes the object it would return a null reference. 2067 // always running this check because if the user deletes the object it would return a null reference.
2048 if (localId == 0) 2068 if (localId == 0)
2049 return; 2069 continue;
2050 2070
2051 if (m_parentGroup == null) 2071 if (m_parentGroup == null)
2052 return; 2072 return;
@@ -2178,7 +2198,7 @@ namespace OpenSim.Region.Framework.Scenes
2178 foreach (uint localId in endedColliders) 2198 foreach (uint localId in endedColliders)
2179 { 2199 {
2180 if (localId == 0) 2200 if (localId == 0)
2181 return; 2201 continue;
2182 2202
2183 // always running this check because if the user deletes the object it would return a null reference. 2203 // always running this check because if the user deletes the object it would return a null reference.
2184 if (m_parentGroup == null) 2204 if (m_parentGroup == null)
@@ -2981,6 +3001,178 @@ namespace OpenSim.Region.Framework.Scenes
2981 PhysActor.VehicleFlagsRemove(flags); 3001 PhysActor.VehicleFlagsRemove(flags);
2982 } 3002 }
2983 } 3003 }
3004
3005 /// <summary>
3006 /// Set the color of prim faces
3007 /// </summary>
3008 /// <param name="color"></param>
3009 /// <param name="face"></param>
3010 public void SetFaceColor(Vector3 color, int face)
3011 {
3012 Primitive.TextureEntry tex = Shape.Textures;
3013 Color4 texcolor;
3014 if (face >= 0 && face < GetNumberOfSides())
3015 {
3016 texcolor = tex.CreateFace((uint)face).RGBA;
3017 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
3018 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
3019 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
3020 tex.FaceTextures[face].RGBA = texcolor;
3021 UpdateTexture(tex);
3022 return;
3023 }
3024 else if (face == ALL_SIDES)
3025 {
3026 for (uint i = 0; i < GetNumberOfSides(); i++)
3027 {
3028 if (tex.FaceTextures[i] != null)
3029 {
3030 texcolor = tex.FaceTextures[i].RGBA;
3031 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
3032 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
3033 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
3034 tex.FaceTextures[i].RGBA = texcolor;
3035 }
3036 texcolor = tex.DefaultTexture.RGBA;
3037 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
3038 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
3039 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
3040 tex.DefaultTexture.RGBA = texcolor;
3041 }
3042 UpdateTexture(tex);
3043 return;
3044 }
3045 }
3046
3047 /// <summary>
3048 /// Get the number of sides that this part has.
3049 /// </summary>
3050 /// <returns></returns>
3051 public int GetNumberOfSides()
3052 {
3053 int ret = 0;
3054 bool hasCut;
3055 bool hasHollow;
3056 bool hasDimple;
3057 bool hasProfileCut;
3058
3059 PrimType primType = GetPrimType();
3060 HasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
3061
3062 switch (primType)
3063 {
3064 case PrimType.BOX:
3065 ret = 6;
3066 if (hasCut) ret += 2;
3067 if (hasHollow) ret += 1;
3068 break;
3069 case PrimType.CYLINDER:
3070 ret = 3;
3071 if (hasCut) ret += 2;
3072 if (hasHollow) ret += 1;
3073 break;
3074 case PrimType.PRISM:
3075 ret = 5;
3076 if (hasCut) ret += 2;
3077 if (hasHollow) ret += 1;
3078 break;
3079 case PrimType.SPHERE:
3080 ret = 1;
3081 if (hasCut) ret += 2;
3082 if (hasDimple) ret += 2;
3083 if (hasHollow) ret += 1;
3084 break;
3085 case PrimType.TORUS:
3086 ret = 1;
3087 if (hasCut) ret += 2;
3088 if (hasProfileCut) ret += 2;
3089 if (hasHollow) ret += 1;
3090 break;
3091 case PrimType.TUBE:
3092 ret = 4;
3093 if (hasCut) ret += 2;
3094 if (hasProfileCut) ret += 2;
3095 if (hasHollow) ret += 1;
3096 break;
3097 case PrimType.RING:
3098 ret = 3;
3099 if (hasCut) ret += 2;
3100 if (hasProfileCut) ret += 2;
3101 if (hasHollow) ret += 1;
3102 break;
3103 case PrimType.SCULPT:
3104 ret = 1;
3105 break;
3106 }
3107 return ret;
3108 }
3109
3110 /// <summary>
3111 /// Tell us what type this prim is
3112 /// </summary>
3113 /// <param name="primShape"></param>
3114 /// <returns></returns>
3115 public PrimType GetPrimType()
3116 {
3117 if (Shape.SculptEntry)
3118 return PrimType.SCULPT;
3119 if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
3120 {
3121 if (Shape.PathCurve == (byte)Extrusion.Straight)
3122 return PrimType.BOX;
3123 else if (Shape.PathCurve == (byte)Extrusion.Curve1)
3124 return PrimType.TUBE;
3125 }
3126 else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
3127 {
3128 if (Shape.PathCurve == (byte)Extrusion.Straight)
3129 return PrimType.CYLINDER;
3130 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
3131 else if (Shape.PathCurve == (byte)Extrusion.Curve1)
3132 return PrimType.TORUS;
3133 }
3134 else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
3135 {
3136 if (Shape.PathCurve == (byte)Extrusion.Curve1 || Shape.PathCurve == (byte)Extrusion.Curve2)
3137 return PrimType.SPHERE;
3138 }
3139 else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
3140 {
3141 if (Shape.PathCurve == (byte)Extrusion.Straight)
3142 return PrimType.PRISM;
3143 else if (Shape.PathCurve == (byte)Extrusion.Curve1)
3144 return PrimType.RING;
3145 }
3146
3147 return PrimType.BOX;
3148 }
3149
3150 /// <summary>
3151 /// Tell us if this object has cut, hollow, dimple, and other factors affecting the number of faces
3152 /// </summary>
3153 /// <param name="primType"></param>
3154 /// <param name="shape"></param>
3155 /// <param name="hasCut"></param>
3156 /// <param name="hasHollow"></param>
3157 /// <param name="hasDimple"></param>
3158 /// <param name="hasProfileCut"></param>
3159 protected static void HasCutHollowDimpleProfileCut(PrimType primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
3160 out bool hasDimple, out bool hasProfileCut)
3161 {
3162 if (primType == PrimType.BOX
3163 ||
3164 primType == PrimType.CYLINDER
3165 ||
3166 primType == PrimType.PRISM)
3167
3168 hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
3169 else
3170 hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
3171
3172 hasHollow = shape.ProfileHollow > 0;
3173 hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
3174 hasProfileCut = hasDimple; // is it the same thing?
3175 }
2984 3176
2985 public void SetGroup(UUID groupID, IClientAPI client) 3177 public void SetGroup(UUID groupID, IClientAPI client)
2986 { 3178 {
@@ -3013,6 +3205,11 @@ namespace OpenSim.Region.Framework.Scenes
3013 } 3205 }
3014 } 3206 }
3015 3207
3208 /// <summary>
3209 /// Set the events that this part will pass on to listeners.
3210 /// </summary>
3211 /// <param name="scriptid"></param>
3212 /// <param name="events"></param>
3016 public void SetScriptEvents(UUID scriptid, int events) 3213 public void SetScriptEvents(UUID scriptid, int events)
3017 { 3214 {
3018 // scriptEvents oldparts; 3215 // scriptEvents oldparts;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 9661775..3317dd3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -585,8 +585,32 @@ namespace OpenSim.Region.Framework.Scenes
585 m_items.TryGetValue(itemId, out item); 585 m_items.TryGetValue(itemId, out item);
586 m_items.LockItemsForRead(false); 586 m_items.LockItemsForRead(false);
587 return item; 587 return item;
588 } 588 }
589
590 /// <summary>
591 /// Get inventory items by name.
592 /// </summary>
593 /// <param name="name"></param>
594 /// <returns>
595 /// A list of inventory items with that name.
596 /// If no inventory item has that name then an empty list is returned.
597 /// </returns>
598 public IList<TaskInventoryItem> GetInventoryItems(string name)
599 {
600 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
601
602 lock (m_items)
603 {
604 foreach (TaskInventoryItem item in m_items.Values)
605 {
606 if (item.Name == name)
607 items.Add(item);
608 }
609 }
589 610
611 return items;
612 }
613
590 /// <summary> 614 /// <summary>
591 /// Update an existing inventory item. 615 /// Update an existing inventory item.
592 /// </summary> 616 /// </summary>
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
index 4521f8e..f2adcb7 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
@@ -116,7 +116,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
116 116
117 static string ConvertMRMKeywords(string script) 117 static string ConvertMRMKeywords(string script)
118 { 118 {
119 script = script.Replace("microthreaded void ", "IEnumerable"); 119 script = script.Replace("microthreaded void", "IEnumerable");
120 script = script.Replace("relax;", "yield return null;"); 120 script = script.Replace("relax;", "yield return null;");
121 121
122 return script; 122 return script;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 33218aa..e4ccce8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -54,8 +54,8 @@ using OpenSim.Region.ScriptEngine.Interfaces;
54using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; 54using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
55using OpenSim.Services.Interfaces; 55using OpenSim.Services.Interfaces;
56 56
57using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
57using GridRegion = OpenSim.Services.Interfaces.GridRegion; 58using GridRegion = OpenSim.Services.Interfaces.GridRegion;
58
59using AssetLandmark = OpenSim.Framework.AssetLandmark; 59using AssetLandmark = OpenSim.Framework.AssetLandmark;
60 60
61using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 61using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
@@ -1442,6 +1442,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1442 part.UpdateTexture(tex); 1442 part.UpdateTexture(tex);
1443 return; 1443 return;
1444 } 1444 }
1445
1446 if (face == ScriptBaseClass.ALL_SIDES)
1447 face = SceneObjectPart.ALL_SIDES;
1448
1449 m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
1445 } 1450 }
1446 1451
1447 public void SetTexGen(SceneObjectPart part, int face,int style) 1452 public void SetTexGen(SceneObjectPart part, int face,int style)
@@ -1599,7 +1604,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1599 { 1604 {
1600 int i; 1605 int i;
1601 double sum = 0.0; 1606 double sum = 0.0;
1602 for (i = 0 ; i < GetNumberOfSides(part) ; i++) 1607 for (i = 0 ; i < GetNumberOfSides(part); i++)
1603 sum += (double)tex.GetFace((uint)i).RGBA.A; 1608 sum += (double)tex.GetFace((uint)i).RGBA.A;
1604 return sum; 1609 return sum;
1605 } 1610 }
@@ -1749,7 +1754,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1749 { 1754 {
1750 int i; 1755 int i;
1751 1756
1752 for (i = 0 ; i < GetNumberOfSides(part) ; i++) 1757 for (i = 0 ; i < GetNumberOfSides(part); i++)
1753 { 1758 {
1754 texcolor = tex.GetFace((uint)i).RGBA; 1759 texcolor = tex.GetFace((uint)i).RGBA;
1755 rgb.x += texcolor.R; 1760 rgb.x += texcolor.R;
@@ -3568,7 +3573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3568 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3573 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3569 3574
3570 foreach (SceneObjectPart part in parts) 3575 foreach (SceneObjectPart part in parts)
3571 SetColor(part, color, face); 3576 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3572 } 3577 }
3573 3578
3574 public void llCreateLink(string target, int parent) 3579 public void llCreateLink(string target, int parent)
@@ -4423,63 +4428,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4423 return result; 4428 return result;
4424 } 4429 }
4425 4430
4426 // this function to understand which shape it is (taken from meshmerizer)
4427 // quite useful can be used by meshmerizer to have a centralized point of understanding the shape
4428 // except that it refers to scripting constants
4429 public int getScriptPrimType(PrimitiveBaseShape primShape)
4430 {
4431 if (primShape.SculptEntry)
4432 return ScriptBaseClass.PRIM_TYPE_SCULPT;
4433 if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
4434 {
4435 if (primShape.PathCurve == (byte)Extrusion.Straight)
4436 return ScriptBaseClass.PRIM_TYPE_BOX;
4437 else if (primShape.PathCurve == (byte)Extrusion.Curve1)
4438 return ScriptBaseClass.PRIM_TYPE_TUBE;
4439 }
4440 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
4441 {
4442 if (primShape.PathCurve == (byte)Extrusion.Straight)
4443 return ScriptBaseClass.PRIM_TYPE_CYLINDER;
4444 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
4445 else if (primShape.PathCurve == (byte)Extrusion.Curve1)
4446 return ScriptBaseClass.PRIM_TYPE_TORUS;
4447 }
4448 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
4449 {
4450 if (primShape.PathCurve == (byte)Extrusion.Curve1 || primShape.PathCurve == (byte)Extrusion.Curve2)
4451 return ScriptBaseClass.PRIM_TYPE_SPHERE;
4452 }
4453 else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
4454 {
4455 if (primShape.PathCurve == (byte)Extrusion.Straight)
4456 return ScriptBaseClass.PRIM_TYPE_PRISM;
4457 else if (primShape.PathCurve == (byte)Extrusion.Curve1)
4458 return ScriptBaseClass.PRIM_TYPE_RING;
4459 }
4460 return ScriptBaseClass.PRIM_TYPE_BOX;
4461 }
4462
4463 // Helper functions to understand if object has cut, hollow, dimple, and other affecting number of faces
4464 protected void hasCutHollowDimpleProfileCut(int primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
4465 out bool hasDimple, out bool hasProfileCut)
4466 {
4467 if (primType == ScriptBaseClass.PRIM_TYPE_BOX
4468 ||
4469 primType == ScriptBaseClass.PRIM_TYPE_CYLINDER
4470 ||
4471 primType == ScriptBaseClass.PRIM_TYPE_PRISM)
4472
4473 hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
4474 else
4475 hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
4476
4477 hasHollow = shape.ProfileHollow > 0;
4478 hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
4479 hasProfileCut = hasDimple; // is it the same thing?
4480
4481 }
4482
4483 public LSL_Integer llGetNumberOfSides() 4431 public LSL_Integer llGetNumberOfSides()
4484 { 4432 {
4485 m_host.AddScriptLPS(1); 4433 m_host.AddScriptLPS(1);
@@ -4489,63 +4437,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4489 4437
4490 protected int GetNumberOfSides(SceneObjectPart part) 4438 protected int GetNumberOfSides(SceneObjectPart part)
4491 { 4439 {
4492 int ret = 0; 4440 int sides = part.GetNumberOfSides();
4493 bool hasCut;
4494 bool hasHollow;
4495 bool hasDimple;
4496 bool hasProfileCut;
4497
4498 int primType = getScriptPrimType(part.Shape);
4499 hasCutHollowDimpleProfileCut(primType, part.Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
4500 4441
4501 switch (primType) 4442 if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0)
4502 { 4443 {
4503 case ScriptBaseClass.PRIM_TYPE_BOX: 4444 // Make up for a bug where LSL shows 4 sides rather than 2
4504 ret = 6; 4445 sides += 2;
4505 if (hasCut) ret += 2;
4506 if (hasHollow) ret += 1;
4507 break;
4508 case ScriptBaseClass.PRIM_TYPE_CYLINDER:
4509 ret = 3;
4510 if (hasCut) ret += 2;
4511 if (hasHollow) ret += 1;
4512 break;
4513 case ScriptBaseClass.PRIM_TYPE_PRISM:
4514 ret = 5;
4515 if (hasCut) ret += 2;
4516 if (hasHollow) ret += 1;
4517 break;
4518 case ScriptBaseClass.PRIM_TYPE_SPHERE:
4519 ret = 1;
4520 if (hasCut) ret += 2;
4521 if (hasDimple) ret += 2;
4522 if (hasHollow) ret += 3; // Emulate lsl on secondlife (according to documentation it should have added only +1)
4523 break;
4524 case ScriptBaseClass.PRIM_TYPE_TORUS:
4525 ret = 1;
4526 if (hasCut) ret += 2;
4527 if (hasProfileCut) ret += 2;
4528 if (hasHollow) ret += 1;
4529 break;
4530 case ScriptBaseClass.PRIM_TYPE_TUBE:
4531 ret = 4;
4532 if (hasCut) ret += 2;
4533 if (hasProfileCut) ret += 2;
4534 if (hasHollow) ret += 1;
4535 break;
4536 case ScriptBaseClass.PRIM_TYPE_RING:
4537 ret = 3;
4538 if (hasCut) ret += 2;
4539 if (hasProfileCut) ret += 2;
4540 if (hasHollow) ret += 1;
4541 break;
4542 case ScriptBaseClass.PRIM_TYPE_SCULPT:
4543 ret = 1;
4544 break;
4545 } 4446 }
4546 return ret;
4547 }
4548 4447
4448 return sides;
4449 }
4450
4549 4451
4550 /* The new / changed functions were tested with the following LSL script: 4452 /* The new / changed functions were tested with the following LSL script:
4551 4453
@@ -4570,8 +4472,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4570 } 4472 }
4571 */ 4473 */
4572 4474
4573
4574
4575 // Xantor 29/apr/2008 4475 // Xantor 29/apr/2008
4576 // Returns rotation described by rotating angle radians about axis. 4476 // Returns rotation described by rotating angle radians about axis.
4577 // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2)) 4477 // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2))
@@ -7203,10 +7103,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7203 LSL_Vector color=rules.GetVector3Item(idx++); 7103 LSL_Vector color=rules.GetVector3Item(idx++);
7204 double alpha=(double)rules.GetLSLFloatItem(idx++); 7104 double alpha=(double)rules.GetLSLFloatItem(idx++);
7205 7105
7206 SetColor(part, color, face); 7106 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
7207 SetAlpha(part, alpha, face); 7107 SetAlpha(part, alpha, face);
7208 7108
7209 break; 7109 break;
7110
7210 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 7111 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7211 if (remain < 7) 7112 if (remain < 7)
7212 return; 7113 return;
@@ -7222,6 +7123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7222 SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force); 7123 SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force);
7223 7124
7224 break; 7125 break;
7126
7225 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 7127 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7226 if (remain < 5) 7128 if (remain < 5)
7227 return; 7129 return;
@@ -7234,6 +7136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7234 SetPointLight(part, light, lightcolor, intensity, radius, falloff); 7136 SetPointLight(part, light, lightcolor, intensity, radius, falloff);
7235 7137
7236 break; 7138 break;
7139
7237 case (int)ScriptBaseClass.PRIM_GLOW: 7140 case (int)ScriptBaseClass.PRIM_GLOW:
7238 if (remain < 2) 7141 if (remain < 2)
7239 return; 7142 return;
@@ -7243,6 +7146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7243 SetGlow(part, face, glow); 7146 SetGlow(part, face, glow);
7244 7147
7245 break; 7148 break;
7149
7246 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 7150 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7247 if (remain < 3) 7151 if (remain < 3)
7248 return; 7152 return;
@@ -7253,6 +7157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7253 SetShiny(part, face, shiny, bump); 7157 SetShiny(part, face, shiny, bump);
7254 7158
7255 break; 7159 break;
7160
7256 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 7161 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7257 if (remain < 2) 7162 if (remain < 2)
7258 return; 7163 return;
@@ -7260,6 +7165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7260 bool st = rules.GetLSLIntegerItem(idx++); 7165 bool st = rules.GetLSLIntegerItem(idx++);
7261 SetFullBright(part, face , st); 7166 SetFullBright(part, face , st);
7262 break; 7167 break;
7168
7263 case (int)ScriptBaseClass.PRIM_MATERIAL: 7169 case (int)ScriptBaseClass.PRIM_MATERIAL:
7264 if (remain < 1) 7170 if (remain < 1)
7265 return; 7171 return;
@@ -7269,6 +7175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7269 7175
7270 part.Material = Convert.ToByte(mat); 7176 part.Material = Convert.ToByte(mat);
7271 break; 7177 break;
7178
7272 case (int)ScriptBaseClass.PRIM_PHANTOM: 7179 case (int)ScriptBaseClass.PRIM_PHANTOM:
7273 if (remain < 1) 7180 if (remain < 1)
7274 return; 7181 return;
@@ -7283,6 +7190,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7283 7190
7284 part.ScriptSetPhantomStatus(phantom); 7191 part.ScriptSetPhantomStatus(phantom);
7285 break; 7192 break;
7193
7286 case (int)ScriptBaseClass.PRIM_PHYSICS: 7194 case (int)ScriptBaseClass.PRIM_PHYSICS:
7287 if (remain < 1) 7195 if (remain < 1)
7288 return; 7196 return;
@@ -7296,6 +7204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7296 7204
7297 part.ScriptSetPhysicsStatus(physics); 7205 part.ScriptSetPhysicsStatus(physics);
7298 break; 7206 break;
7207
7299 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 7208 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7300 if (remain < 1) 7209 if (remain < 1)
7301 return; 7210 return;
@@ -7563,7 +7472,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7563 7472
7564 public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) 7473 public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules)
7565 { 7474 {
7566
7567 LSL_List res = new LSL_List(); 7475 LSL_List res = new LSL_List();
7568 int idx=0; 7476 int idx=0;
7569 while (idx < rules.Length) 7477 while (idx < rules.Length)
@@ -7625,7 +7533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7625 case (int)ScriptBaseClass.PRIM_TYPE: 7533 case (int)ScriptBaseClass.PRIM_TYPE:
7626 // implementing box 7534 // implementing box
7627 PrimitiveBaseShape Shape = part.Shape; 7535 PrimitiveBaseShape Shape = part.Shape;
7628 int primType = getScriptPrimType(part.Shape); 7536 int primType = (int)part.GetPrimType();
7629 res.Add(new LSL_Integer(primType)); 7537 res.Add(new LSL_Integer(primType));
7630 double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX 7538 double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX
7631 double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY. 7539 double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY.
@@ -7705,7 +7613,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7705 Primitive.TextureEntry tex = part.Shape.Textures; 7613 Primitive.TextureEntry tex = part.Shape.Textures;
7706 if (face == ScriptBaseClass.ALL_SIDES) 7614 if (face == ScriptBaseClass.ALL_SIDES)
7707 { 7615 {
7708 for (face = 0 ; face < GetNumberOfSides(part) ; face++) 7616 for (face = 0 ; face < GetNumberOfSides(part); face++)
7709 { 7617 {
7710 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 7618 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7711 7619
@@ -7747,7 +7655,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7747 Color4 texcolor; 7655 Color4 texcolor;
7748 if (face == ScriptBaseClass.ALL_SIDES) 7656 if (face == ScriptBaseClass.ALL_SIDES)
7749 { 7657 {
7750 for (face = 0 ; face < GetNumberOfSides(part) ; face++) 7658 for (face = 0 ; face < GetNumberOfSides(part); face++)
7751 { 7659 {
7752 texcolor = tex.GetFace((uint)face).RGBA; 7660 texcolor = tex.GetFace((uint)face).RGBA;
7753 res.Add(new LSL_Vector(texcolor.R, 7661 res.Add(new LSL_Vector(texcolor.R,
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 16309ef..09b79d0 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -55,6 +55,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
55 m_log.Info("[XEngine] Hooking up to server events"); 55 m_log.Info("[XEngine] Hooking up to server events");
56 myScriptEngine.World.EventManager.OnAttach += attach; 56 myScriptEngine.World.EventManager.OnAttach += attach;
57 myScriptEngine.World.EventManager.OnObjectGrab += touch_start; 57 myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
58 myScriptEngine.World.EventManager.OnObjectGrabbing += touch;
58 myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end; 59 myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end;
59 myScriptEngine.World.EventManager.OnScriptChangedEvent += changed; 60 myScriptEngine.World.EventManager.OnScriptChangedEvent += changed;
60 myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target; 61 myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target;
@@ -148,7 +149,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
148 } 149 }
149 150
150 public void touch(uint localID, uint originalID, Vector3 offsetPos, 151 public void touch(uint localID, uint originalID, Vector3 offsetPos,
151 IClientAPI remoteClient) 152 IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
152 { 153 {
153 // Add to queue for all scripts in ObjectID object 154 // Add to queue for all scripts in ObjectID object
154 DetectParams[] det = new DetectParams[1]; 155 DetectParams[] det = new DetectParams[1];
@@ -172,6 +173,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
172 SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); 173 SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID);
173 det[0].LinkNum = originalPart.LinkNum; 174 det[0].LinkNum = originalPart.LinkNum;
174 } 175 }
176 if (surfaceArgs != null)
177 {
178 det[0].SurfaceTouchArgs = surfaceArgs;
179 }
175 180
176 myScriptEngine.PostObjectEvent(localID, new EventParams( 181 myScriptEngine.PostObjectEvent(localID, new EventParams(
177 "touch", new Object[] { new LSL_Types.LSLInteger(1) }, 182 "touch", new Object[] { new LSL_Types.LSLInteger(1) },