AttachmentsModuleTests.cs 48 KB

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