AttachmentsModuleTests.cs 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  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. using System;
  28. using System.Collections.Generic;
  29. using System.Reflection;
  30. using System.Text;
  31. using System.Threading;
  32. using System.Timers;
  33. using System.Xml;
  34. using Timer=System.Timers.Timer;
  35. using Nini.Config;
  36. using NUnit.Framework;
  37. using OpenMetaverse;
  38. using OpenSim.Framework;
  39. using OpenSim.Framework.Communications;
  40. using OpenSim.Framework.Servers;
  41. using OpenSim.Framework.Servers.HttpServer;
  42. using OpenSim.Region.CoreModules.Avatar.Attachments;
  43. using OpenSim.Region.CoreModules.Framework;
  44. using OpenSim.Region.CoreModules.Framework.EntityTransfer;
  45. using OpenSim.Region.CoreModules.Framework.InventoryAccess;
  46. using OpenSim.Region.CoreModules.Scripting.WorldComm;
  47. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
  48. using OpenSim.Region.CoreModules.World.Serialiser;
  49. using OpenSim.Region.Framework.Scenes;
  50. using OpenSim.Region.Framework.Interfaces;
  51. using OpenSim.Region.ScriptEngine.Interfaces;
  52. using OpenSim.Region.ScriptEngine.XEngine;
  53. using OpenSim.Services.Interfaces;
  54. using OpenSim.Tests.Common;
  55. using OpenSim.Tests.Common.Mock;
  56. namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
  57. {
  58. /// <summary>
  59. /// Attachment tests
  60. /// </summary>
  61. [TestFixture]
  62. public class AttachmentsModuleTests : OpenSimTestCase
  63. {
  64. private AutoResetEvent m_chatEvent = new AutoResetEvent(false);
  65. // private OSChatMessage m_osChatMessageReceived;
  66. // Used to test whether the operations have fired the attach event. Must be reset after each test.
  67. private int m_numberOfAttachEventsFired;
  68. [TestFixtureSetUp]
  69. public void FixtureInit()
  70. {
  71. // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
  72. Util.FireAndForgetMethod = FireAndForgetMethod.None;
  73. }
  74. [TestFixtureTearDown]
  75. public void TearDown()
  76. {
  77. // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
  78. // threads. Possibly, later tests should be rewritten not to worry about such things.
  79. Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
  80. }
  81. private void OnChatFromWorld(object sender, OSChatMessage oscm)
  82. {
  83. // Console.WriteLine("Got chat [{0}]", oscm.Message);
  84. // m_osChatMessageReceived = oscm;
  85. m_chatEvent.Set();
  86. }
  87. private Scene CreateTestScene()
  88. {
  89. IConfigSource config = new IniConfigSource();
  90. List<object> modules = new List<object>();
  91. AddCommonConfig(config, modules);
  92. Scene scene
  93. = new SceneHelpers().SetupScene(
  94. "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
  95. SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
  96. scene.EventManager.OnAttach += (localID, itemID, avatarID) => m_numberOfAttachEventsFired++;
  97. return scene;
  98. }
  99. private Scene CreateScriptingEnabledTestScene()
  100. {
  101. IConfigSource config = new IniConfigSource();
  102. List<object> modules = new List<object>();
  103. AddCommonConfig(config, modules);
  104. AddScriptingConfig(config, modules);
  105. Scene scene
  106. = new SceneHelpers().SetupScene(
  107. "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
  108. SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
  109. scene.StartScripts();
  110. return scene;
  111. }
  112. private void AddCommonConfig(IConfigSource config, List<object> modules)
  113. {
  114. config.AddConfig("Modules");
  115. config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
  116. AttachmentsModule attMod = new AttachmentsModule();
  117. attMod.DebugLevel = 1;
  118. modules.Add(attMod);
  119. modules.Add(new BasicInventoryAccessModule());
  120. }
  121. private void AddScriptingConfig(IConfigSource config, List<object> modules)
  122. {
  123. IConfig startupConfig = config.AddConfig("Startup");
  124. startupConfig.Set("DefaultScriptEngine", "XEngine");
  125. IConfig xEngineConfig = config.AddConfig("XEngine");
  126. xEngineConfig.Set("Enabled", "true");
  127. xEngineConfig.Set("StartDelay", "0");
  128. // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call
  129. // to AssemblyResolver.OnAssemblyResolve fails.
  130. xEngineConfig.Set("AppDomainLoading", "false");
  131. modules.Add(new XEngine());
  132. // Necessary to stop serialization complaining
  133. // FIXME: Stop this being necessary if at all possible
  134. // modules.Add(new WorldCommModule());
  135. }
  136. /// <summary>
  137. /// Creates an attachment item in the given user's inventory. Does not attach.
  138. /// </summary>
  139. /// <remarks>
  140. /// A user with the given ID and an inventory must already exist.
  141. /// </remarks>
  142. /// <returns>
  143. /// The attachment item.
  144. /// </returns>
  145. /// <param name='scene'></param>
  146. /// <param name='userId'></param>
  147. /// <param name='attName'></param>
  148. /// <param name='rawItemId'></param>
  149. /// <param name='rawAssetId'></param>
  150. private InventoryItemBase CreateAttachmentItem(
  151. Scene scene, UUID userId, string attName, int rawItemId, int rawAssetId)
  152. {
  153. return UserInventoryHelpers.CreateInventoryItem(
  154. scene,
  155. attName,
  156. TestHelpers.ParseTail(rawItemId),
  157. TestHelpers.ParseTail(rawAssetId),
  158. userId,
  159. InventoryType.Object);
  160. }
  161. [Test]
  162. public void TestAddAttachmentFromGround()
  163. {
  164. TestHelpers.InMethod();
  165. // TestHelpers.EnableLogging();
  166. m_numberOfAttachEventsFired = 0;
  167. Scene scene = CreateTestScene();
  168. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  169. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  170. string attName = "att";
  171. SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
  172. m_numberOfAttachEventsFired = 0;
  173. scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false);
  174. // Check status on scene presence
  175. Assert.That(sp.HasAttachments(), Is.True);
  176. List<SceneObjectGroup> attachments = sp.GetAttachments();
  177. Assert.That(attachments.Count, Is.EqualTo(1));
  178. SceneObjectGroup attSo = attachments[0];
  179. Assert.That(attSo.Name, Is.EqualTo(attName));
  180. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
  181. Assert.That(attSo.IsAttachment);
  182. Assert.That(attSo.UsesPhysics, Is.False);
  183. Assert.That(attSo.IsTemporary, Is.False);
  184. // Check item status
  185. Assert.That(
  186. sp.Appearance.GetAttachpoint(attSo.FromItemID),
  187. Is.EqualTo((int)AttachmentPoint.Chest));
  188. InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
  189. Assert.That(attachmentItem, Is.Not.Null);
  190. Assert.That(attachmentItem.Name, Is.EqualTo(attName));
  191. InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
  192. Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
  193. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  194. // Check events
  195. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  196. }
  197. [Test]
  198. public void TestWearAttachmentFromGround()
  199. {
  200. TestHelpers.InMethod();
  201. // TestHelpers.EnableLogging();
  202. Scene scene = CreateTestScene();
  203. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  204. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  205. SceneObjectGroup so2 = SceneHelpers.AddSceneObject(scene, "att2", sp.UUID);
  206. {
  207. SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID);
  208. m_numberOfAttachEventsFired = 0;
  209. scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false);
  210. // Check status on scene presence
  211. Assert.That(sp.HasAttachments(), Is.True);
  212. List<SceneObjectGroup> attachments = sp.GetAttachments();
  213. Assert.That(attachments.Count, Is.EqualTo(1));
  214. SceneObjectGroup attSo = attachments[0];
  215. Assert.That(attSo.Name, Is.EqualTo(so.Name));
  216. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
  217. Assert.That(attSo.IsAttachment);
  218. Assert.That(attSo.UsesPhysics, Is.False);
  219. Assert.That(attSo.IsTemporary, Is.False);
  220. // Check item status
  221. Assert.That(
  222. sp.Appearance.GetAttachpoint(attSo.FromItemID),
  223. Is.EqualTo((int)AttachmentPoint.LeftHand));
  224. InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
  225. Assert.That(attachmentItem, Is.Not.Null);
  226. Assert.That(attachmentItem.Name, Is.EqualTo(so.Name));
  227. InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
  228. Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
  229. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2));
  230. // Check events
  231. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  232. }
  233. // Test wearing a different attachment from the ground.
  234. {
  235. scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false);
  236. // Check status on scene presence
  237. Assert.That(sp.HasAttachments(), Is.True);
  238. List<SceneObjectGroup> attachments = sp.GetAttachments();
  239. Assert.That(attachments.Count, Is.EqualTo(1));
  240. SceneObjectGroup attSo = attachments[0];
  241. Assert.That(attSo.Name, Is.EqualTo(so2.Name));
  242. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
  243. Assert.That(attSo.IsAttachment);
  244. Assert.That(attSo.UsesPhysics, Is.False);
  245. Assert.That(attSo.IsTemporary, Is.False);
  246. // Check item status
  247. Assert.That(
  248. sp.Appearance.GetAttachpoint(attSo.FromItemID),
  249. Is.EqualTo((int)AttachmentPoint.LeftHand));
  250. InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
  251. Assert.That(attachmentItem, Is.Not.Null);
  252. Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
  253. InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
  254. Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
  255. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  256. // Check events
  257. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
  258. }
  259. // Test rewearing an already worn attachment from ground. Nothing should happen.
  260. {
  261. scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false);
  262. // Check status on scene presence
  263. Assert.That(sp.HasAttachments(), Is.True);
  264. List<SceneObjectGroup> attachments = sp.GetAttachments();
  265. Assert.That(attachments.Count, Is.EqualTo(1));
  266. SceneObjectGroup attSo = attachments[0];
  267. Assert.That(attSo.Name, Is.EqualTo(so2.Name));
  268. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
  269. Assert.That(attSo.IsAttachment);
  270. Assert.That(attSo.UsesPhysics, Is.False);
  271. Assert.That(attSo.IsTemporary, Is.False);
  272. // Check item status
  273. Assert.That(
  274. sp.Appearance.GetAttachpoint(attSo.FromItemID),
  275. Is.EqualTo((int)AttachmentPoint.LeftHand));
  276. InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
  277. Assert.That(attachmentItem, Is.Not.Null);
  278. Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name));
  279. InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
  280. Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
  281. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  282. // Check events
  283. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
  284. }
  285. }
  286. /// <summary>
  287. /// Test that we do not attempt to attach an in-world object that someone else is sitting on.
  288. /// </summary>
  289. [Test]
  290. public void TestAddSatOnAttachmentFromGround()
  291. {
  292. TestHelpers.InMethod();
  293. // TestHelpers.EnableLogging();
  294. m_numberOfAttachEventsFired = 0;
  295. Scene scene = CreateTestScene();
  296. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  297. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  298. string attName = "att";
  299. SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
  300. UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(scene, 0x2);
  301. ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, ua2);
  302. // Put avatar within 10m of the prim so that sit doesn't fail.
  303. sp2.AbsolutePosition = new Vector3(0, 0, 0);
  304. sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
  305. scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false);
  306. Assert.That(sp.HasAttachments(), Is.False);
  307. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  308. // Check events
  309. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  310. }
  311. [Test]
  312. public void TestRezAttachmentFromInventory()
  313. {
  314. TestHelpers.InMethod();
  315. // log4net.Config.XmlConfigurator.Configure();
  316. Scene scene = CreateTestScene();
  317. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  318. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
  319. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  320. {
  321. scene.AttachmentsModule.RezSingleAttachmentFromInventory(
  322. sp, attItem.ID, (uint)AttachmentPoint.Chest);
  323. // Check scene presence status
  324. Assert.That(sp.HasAttachments(), Is.True);
  325. List<SceneObjectGroup> attachments = sp.GetAttachments();
  326. Assert.That(attachments.Count, Is.EqualTo(1));
  327. SceneObjectGroup attSo = attachments[0];
  328. Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
  329. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
  330. Assert.That(attSo.IsAttachment);
  331. Assert.That(attSo.UsesPhysics, Is.False);
  332. Assert.That(attSo.IsTemporary, Is.False);
  333. // Check appearance status
  334. Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
  335. Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  336. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  337. // Check events
  338. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  339. }
  340. // Test attaching an already attached attachment
  341. {
  342. scene.AttachmentsModule.RezSingleAttachmentFromInventory(
  343. sp, attItem.ID, (uint)AttachmentPoint.Chest);
  344. // Check scene presence status
  345. Assert.That(sp.HasAttachments(), Is.True);
  346. List<SceneObjectGroup> attachments = sp.GetAttachments();
  347. Assert.That(attachments.Count, Is.EqualTo(1));
  348. SceneObjectGroup attSo = attachments[0];
  349. Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
  350. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
  351. Assert.That(attSo.IsAttachment);
  352. Assert.That(attSo.UsesPhysics, Is.False);
  353. Assert.That(attSo.IsTemporary, Is.False);
  354. // Check appearance status
  355. Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
  356. Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  357. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  358. // Check events
  359. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  360. }
  361. }
  362. /// <summary>
  363. /// Test wearing an attachment from inventory, as opposed to explicit choosing the rez point
  364. /// </summary>
  365. [Test]
  366. public void TestWearAttachmentFromInventory()
  367. {
  368. TestHelpers.InMethod();
  369. // TestHelpers.EnableLogging();
  370. Scene scene = CreateTestScene();
  371. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  372. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
  373. InventoryItemBase attItem1 = CreateAttachmentItem(scene, ua1.PrincipalID, "att1", 0x10, 0x20);
  374. InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21);
  375. {
  376. m_numberOfAttachEventsFired = 0;
  377. scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default);
  378. // default attachment point is currently the left hand.
  379. Assert.That(sp.HasAttachments(), Is.True);
  380. List<SceneObjectGroup> attachments = sp.GetAttachments();
  381. Assert.That(attachments.Count, Is.EqualTo(1));
  382. SceneObjectGroup attSo = attachments[0];
  383. Assert.That(attSo.Name, Is.EqualTo(attItem1.Name));
  384. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
  385. Assert.That(attSo.IsAttachment);
  386. // Check appearance status
  387. Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
  388. Assert.That(sp.Appearance.GetAttachpoint(attItem1.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
  389. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  390. // Check events
  391. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  392. }
  393. // Test wearing a second attachment at the same position
  394. // Until multiple attachments at one point is implemented, this will remove the first attachment
  395. // This test relies on both attachments having the same default attachment point (in this case LeftHand
  396. // since none other has been set).
  397. {
  398. scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default);
  399. // default attachment point is currently the left hand.
  400. Assert.That(sp.HasAttachments(), Is.True);
  401. List<SceneObjectGroup> attachments = sp.GetAttachments();
  402. Assert.That(attachments.Count, Is.EqualTo(1));
  403. SceneObjectGroup attSo = attachments[0];
  404. Assert.That(attSo.Name, Is.EqualTo(attItem2.Name));
  405. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
  406. Assert.That(attSo.IsAttachment);
  407. // Check appearance status
  408. Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
  409. Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
  410. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  411. // Check events
  412. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
  413. }
  414. // Test wearing an already attached attachment
  415. {
  416. scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default);
  417. // default attachment point is currently the left hand.
  418. Assert.That(sp.HasAttachments(), Is.True);
  419. List<SceneObjectGroup> attachments = sp.GetAttachments();
  420. Assert.That(attachments.Count, Is.EqualTo(1));
  421. SceneObjectGroup attSo = attachments[0];
  422. Assert.That(attSo.Name, Is.EqualTo(attItem2.Name));
  423. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand));
  424. Assert.That(attSo.IsAttachment);
  425. // Check appearance status
  426. Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
  427. Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand));
  428. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  429. // Check events
  430. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3));
  431. }
  432. }
  433. /// <summary>
  434. /// Test specific conditions associated with rezzing a scripted attachment from inventory.
  435. /// </summary>
  436. [Test]
  437. public void TestRezScriptedAttachmentFromInventory()
  438. {
  439. TestHelpers.InMethod();
  440. Scene scene = CreateScriptingEnabledTestScene();
  441. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  442. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  443. SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
  444. TaskInventoryItem scriptItem
  445. = TaskInventoryHelpers.AddScript(
  446. scene,
  447. so.RootPart,
  448. "scriptItem",
  449. "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
  450. InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
  451. // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
  452. // In the future, we need to be able to do this programatically more predicably.
  453. scene.EventManager.OnChatFromWorld += OnChatFromWorld;
  454. scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
  455. m_chatEvent.WaitOne(60000);
  456. // TODO: Need to have a test that checks the script is actually started but this involves a lot more
  457. // plumbing of the script engine and either pausing for events or more infrastructure to turn off various
  458. // script engine delays/asychronicity that isn't helpful in an automated regression testing context.
  459. SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name);
  460. Assert.That(attSo.ContainsScripts(), Is.True);
  461. TaskInventoryItem reRezzedScriptItem = attSo.RootPart.Inventory.GetInventoryItem(scriptItem.Name);
  462. IScriptModule xengine = scene.RequestModuleInterface<IScriptModule>();
  463. Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
  464. }
  465. [Test]
  466. public void TestDetachAttachmentToGround()
  467. {
  468. TestHelpers.InMethod();
  469. // log4net.Config.XmlConfigurator.Configure();
  470. Scene scene = CreateTestScene();
  471. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  472. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
  473. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  474. ISceneEntity so
  475. = scene.AttachmentsModule.RezSingleAttachmentFromInventory(
  476. sp, attItem.ID, (uint)AttachmentPoint.Chest);
  477. m_numberOfAttachEventsFired = 0;
  478. scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId);
  479. // Check scene presence status
  480. Assert.That(sp.HasAttachments(), Is.False);
  481. List<SceneObjectGroup> attachments = sp.GetAttachments();
  482. Assert.That(attachments.Count, Is.EqualTo(0));
  483. // Check appearance status
  484. Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(0));
  485. // Check item status
  486. Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null);
  487. // Check object in scene
  488. Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
  489. // Check events
  490. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  491. }
  492. [Test]
  493. public void TestDetachAttachmentToInventory()
  494. {
  495. TestHelpers.InMethod();
  496. Scene scene = CreateTestScene();
  497. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  498. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
  499. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  500. SceneObjectGroup so
  501. = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(
  502. sp, attItem.ID, (uint)AttachmentPoint.Chest);
  503. m_numberOfAttachEventsFired = 0;
  504. scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so);
  505. // Check status on scene presence
  506. Assert.That(sp.HasAttachments(), Is.False);
  507. List<SceneObjectGroup> attachments = sp.GetAttachments();
  508. Assert.That(attachments.Count, Is.EqualTo(0));
  509. // Check item status
  510. Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0));
  511. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0));
  512. // Check events
  513. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  514. }
  515. /// <summary>
  516. /// Test specific conditions associated with detaching a scripted attachment from inventory.
  517. /// </summary>
  518. [Test]
  519. public void TestDetachScriptedAttachmentToInventory()
  520. {
  521. TestHelpers.InMethod();
  522. // TestHelpers.EnableLogging();
  523. Scene scene = CreateScriptingEnabledTestScene();
  524. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  525. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  526. SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
  527. TaskInventoryItem scriptTaskItem
  528. = TaskInventoryHelpers.AddScript(
  529. scene,
  530. so.RootPart,
  531. "scriptItem",
  532. "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
  533. InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
  534. // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
  535. // In the future, we need to be able to do this programatically more predicably.
  536. scene.EventManager.OnChatFromWorld += OnChatFromWorld;
  537. SceneObjectGroup rezzedSo
  538. = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
  539. // Wait for chat to signal rezzed script has been started.
  540. m_chatEvent.WaitOne(60000);
  541. scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo);
  542. InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem);
  543. AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString());
  544. // TODO: It would probably be better here to check script state via the saving and retrieval of state
  545. // information at a higher level, rather than having to inspect the serialization.
  546. XmlDocument soXml = new XmlDocument();
  547. soXml.LoadXml(Encoding.UTF8.GetString(asset.Data));
  548. XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState");
  549. Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
  550. // Re-rez the attachment to check script running state
  551. SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
  552. // Wait for chat to signal rezzed script has been started.
  553. m_chatEvent.WaitOne(60000);
  554. TaskInventoryItem reRezzedScriptItem = reRezzedSo.RootPart.Inventory.GetInventoryItem(scriptTaskItem.Name);
  555. IScriptModule xengine = scene.RequestModuleInterface<IScriptModule>();
  556. Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
  557. // Console.WriteLine(soXml.OuterXml);
  558. }
  559. /// <summary>
  560. /// Test that attachments don't hang about in the scene when the agent is closed
  561. /// </summary>
  562. [Test]
  563. public void TestRemoveAttachmentsOnAvatarExit()
  564. {
  565. TestHelpers.InMethod();
  566. // log4net.Config.XmlConfigurator.Configure();
  567. Scene scene = CreateTestScene();
  568. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  569. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  570. AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
  571. acd.Appearance = new AvatarAppearance();
  572. acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
  573. ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
  574. SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
  575. m_numberOfAttachEventsFired = 0;
  576. scene.CloseAgent(presence.UUID, false);
  577. // Check that we can't retrieve this attachment from the scene.
  578. Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
  579. // Check events
  580. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  581. }
  582. [Test]
  583. public void TestRezAttachmentsOnAvatarEntrance()
  584. {
  585. TestHelpers.InMethod();
  586. // TestHelpers.EnableLogging();
  587. Scene scene = CreateTestScene();
  588. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  589. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  590. AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
  591. acd.Appearance = new AvatarAppearance();
  592. acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
  593. m_numberOfAttachEventsFired = 0;
  594. ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
  595. Assert.That(presence.HasAttachments(), Is.True);
  596. List<SceneObjectGroup> attachments = presence.GetAttachments();
  597. Assert.That(attachments.Count, Is.EqualTo(1));
  598. SceneObjectGroup attSo = attachments[0];
  599. Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
  600. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
  601. Assert.That(attSo.IsAttachment);
  602. Assert.That(attSo.UsesPhysics, Is.False);
  603. Assert.That(attSo.IsTemporary, Is.False);
  604. // Check appearance status
  605. List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
  606. Assert.That(retreivedAttachments.Count, Is.EqualTo(1));
  607. Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
  608. Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID));
  609. Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
  610. Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  611. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  612. // Check events. We expect OnAttach to fire on login.
  613. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  614. }
  615. [Test]
  616. public void TestUpdateAttachmentPosition()
  617. {
  618. TestHelpers.InMethod();
  619. Scene scene = CreateTestScene();
  620. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  621. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  622. AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
  623. acd.Appearance = new AvatarAppearance();
  624. acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
  625. ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd);
  626. SceneObjectGroup attSo = sp.GetAttachments()[0];
  627. Vector3 newPosition = new Vector3(1, 2, 4);
  628. m_numberOfAttachEventsFired = 0;
  629. scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient);
  630. Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition));
  631. Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition));
  632. // Check events
  633. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  634. }
  635. [Test]
  636. public void TestSameSimulatorNeighbouringRegionsTeleportV1()
  637. {
  638. TestHelpers.InMethod();
  639. // TestHelpers.EnableLogging();
  640. BaseHttpServer httpServer = new BaseHttpServer(99999);
  641. MainServer.AddHttpServer(httpServer);
  642. MainServer.Instance = httpServer;
  643. AttachmentsModule attModA = new AttachmentsModule();
  644. AttachmentsModule attModB = new AttachmentsModule();
  645. EntityTransferModule etmA = new EntityTransferModule();
  646. EntityTransferModule etmB = new EntityTransferModule();
  647. LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
  648. IConfigSource config = new IniConfigSource();
  649. IConfig modulesConfig = config.AddConfig("Modules");
  650. modulesConfig.Set("EntityTransferModule", etmA.Name);
  651. modulesConfig.Set("SimulationServices", lscm.Name);
  652. IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
  653. // In order to run a single threaded regression test we do not want the entity transfer module waiting
  654. // for a callback from the destination scene before removing its avatar data.
  655. entityTransferConfig.Set("wait_for_callback", false);
  656. modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule");
  657. SceneHelpers sh = new SceneHelpers();
  658. TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
  659. TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
  660. SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
  661. SceneHelpers.SetupSceneModules(
  662. sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule());
  663. SceneHelpers.SetupSceneModules(
  664. sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
  665. // FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
  666. lscm.ServiceVersion = "SIMULATION/0.1";
  667. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
  668. AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
  669. TestClient tc = new TestClient(acd, sceneA);
  670. List<TestClient> destinationTestClients = new List<TestClient>();
  671. EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
  672. ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
  673. beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
  674. InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
  675. sceneA.AttachmentsModule.RezSingleAttachmentFromInventory(
  676. beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest);
  677. Vector3 teleportPosition = new Vector3(10, 11, 12);
  678. Vector3 teleportLookAt = new Vector3(20, 21, 22);
  679. m_numberOfAttachEventsFired = 0;
  680. sceneA.RequestTeleportLocation(
  681. beforeTeleportSp.ControllingClient,
  682. sceneB.RegionInfo.RegionHandle,
  683. teleportPosition,
  684. teleportLookAt,
  685. (uint)TeleportFlags.ViaLocation);
  686. destinationTestClients[0].CompleteMovement();
  687. // Check attachments have made it into sceneB
  688. ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID);
  689. // This is appearance data, as opposed to actually rezzed attachments
  690. List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments();
  691. Assert.That(sceneBAttachments.Count, Is.EqualTo(1));
  692. Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
  693. Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID));
  694. Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
  695. Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  696. // This is the actual attachment
  697. List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments();
  698. Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1));
  699. SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
  700. Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
  701. Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
  702. Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
  703. // Check attachments have been removed from sceneA
  704. ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID);
  705. // Since this is appearance data, it is still present on the child avatar!
  706. List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments();
  707. Assert.That(sceneAAttachments.Count, Is.EqualTo(1));
  708. Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  709. // This is the actual attachment, which should no longer exist
  710. List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments();
  711. Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
  712. Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
  713. // Check events
  714. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  715. }
  716. [Test]
  717. public void TestSameSimulatorNeighbouringRegionsTeleportV2()
  718. {
  719. TestHelpers.InMethod();
  720. // TestHelpers.EnableLogging();
  721. BaseHttpServer httpServer = new BaseHttpServer(99999);
  722. MainServer.AddHttpServer(httpServer);
  723. MainServer.Instance = httpServer;
  724. AttachmentsModule attModA = new AttachmentsModule();
  725. AttachmentsModule attModB = new AttachmentsModule();
  726. EntityTransferModule etmA = new EntityTransferModule();
  727. EntityTransferModule etmB = new EntityTransferModule();
  728. LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
  729. IConfigSource config = new IniConfigSource();
  730. IConfig modulesConfig = config.AddConfig("Modules");
  731. modulesConfig.Set("EntityTransferModule", etmA.Name);
  732. modulesConfig.Set("SimulationServices", lscm.Name);
  733. modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule");
  734. SceneHelpers sh = new SceneHelpers();
  735. TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
  736. TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
  737. SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
  738. SceneHelpers.SetupSceneModules(
  739. sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule());
  740. SceneHelpers.SetupSceneModules(
  741. sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
  742. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
  743. AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
  744. TestClient tc = new TestClient(acd, sceneA);
  745. List<TestClient> destinationTestClients = new List<TestClient>();
  746. EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients);
  747. ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
  748. beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
  749. Assert.That(destinationTestClients.Count, Is.EqualTo(1));
  750. Assert.That(destinationTestClients[0], Is.Not.Null);
  751. InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
  752. sceneA.AttachmentsModule.RezSingleAttachmentFromInventory(
  753. beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest);
  754. Vector3 teleportPosition = new Vector3(10, 11, 12);
  755. Vector3 teleportLookAt = new Vector3(20, 21, 22);
  756. // Here, we need to make clientA's receipt of SendRegionTeleport trigger clientB's CompleteMovement(). This
  757. // is to operate the teleport V2 mechanism where the EntityTransferModule will first request the client to
  758. // CompleteMovement to the region and then call UpdateAgent to the destination region to confirm the receipt
  759. // Both these operations will occur on different threads and will wait for each other.
  760. // We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1
  761. // test protocol, where we are trying to avoid unpredictable async operations in regression tests.
  762. tc.OnTestClientSendRegionTeleport
  763. += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL)
  764. => ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null);
  765. m_numberOfAttachEventsFired = 0;
  766. sceneA.RequestTeleportLocation(
  767. beforeTeleportSp.ControllingClient,
  768. sceneB.RegionInfo.RegionHandle,
  769. teleportPosition,
  770. teleportLookAt,
  771. (uint)TeleportFlags.ViaLocation);
  772. // Check attachments have made it into sceneB
  773. ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID);
  774. // This is appearance data, as opposed to actually rezzed attachments
  775. List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments();
  776. Assert.That(sceneBAttachments.Count, Is.EqualTo(1));
  777. Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
  778. Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID));
  779. Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
  780. Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  781. // This is the actual attachment
  782. List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments();
  783. Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1));
  784. SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
  785. Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
  786. Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
  787. Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
  788. // Check attachments have been removed from sceneA
  789. ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID);
  790. // Since this is appearance data, it is still present on the child avatar!
  791. List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments();
  792. Assert.That(sceneAAttachments.Count, Is.EqualTo(1));
  793. Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  794. // This is the actual attachment, which should no longer exist
  795. List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments();
  796. Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
  797. Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
  798. // Check events
  799. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  800. }
  801. }
  802. }