AttachmentsModuleTests.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  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.Region.CoreModules.Avatar.Attachments;
  41. using OpenSim.Region.CoreModules.Framework;
  42. using OpenSim.Region.CoreModules.Framework.EntityTransfer;
  43. using OpenSim.Region.CoreModules.Framework.InventoryAccess;
  44. using OpenSim.Region.CoreModules.Scripting.WorldComm;
  45. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
  46. using OpenSim.Region.CoreModules.World.Serialiser;
  47. using OpenSim.Region.Framework.Scenes;
  48. using OpenSim.Region.Framework.Interfaces;
  49. using OpenSim.Region.ScriptEngine.Interfaces;
  50. using OpenSim.Region.ScriptEngine.XEngine;
  51. using OpenSim.Services.Interfaces;
  52. using OpenSim.Tests.Common;
  53. using OpenSim.Tests.Common.Mock;
  54. namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
  55. {
  56. /// <summary>
  57. /// Attachment tests
  58. /// </summary>
  59. [TestFixture]
  60. public class AttachmentsModuleTests : OpenSimTestCase
  61. {
  62. private AutoResetEvent m_chatEvent = new AutoResetEvent(false);
  63. // private OSChatMessage m_osChatMessageReceived;
  64. // Used to test whether the operations have fired the attach event. Must be reset after each test.
  65. private int m_numberOfAttachEventsFired;
  66. [TestFixtureSetUp]
  67. public void FixtureInit()
  68. {
  69. // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
  70. Util.FireAndForgetMethod = FireAndForgetMethod.None;
  71. }
  72. [TestFixtureTearDown]
  73. public void TearDown()
  74. {
  75. // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
  76. // threads. Possibly, later tests should be rewritten not to worry about such things.
  77. Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
  78. }
  79. private void OnChatFromWorld(object sender, OSChatMessage oscm)
  80. {
  81. // Console.WriteLine("Got chat [{0}]", oscm.Message);
  82. // m_osChatMessageReceived = oscm;
  83. m_chatEvent.Set();
  84. }
  85. private Scene CreateTestScene()
  86. {
  87. IConfigSource config = new IniConfigSource();
  88. List<object> modules = new List<object>();
  89. AddCommonConfig(config, modules);
  90. Scene scene
  91. = new SceneHelpers().SetupScene(
  92. "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
  93. SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
  94. scene.EventManager.OnAttach += (localID, itemID, avatarID) => m_numberOfAttachEventsFired++;
  95. return scene;
  96. }
  97. private Scene CreateScriptingEnabledTestScene()
  98. {
  99. IConfigSource config = new IniConfigSource();
  100. List<object> modules = new List<object>();
  101. AddCommonConfig(config, modules);
  102. AddScriptingConfig(config, modules);
  103. Scene scene
  104. = new SceneHelpers().SetupScene(
  105. "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
  106. SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
  107. scene.StartScripts();
  108. return scene;
  109. }
  110. private void AddCommonConfig(IConfigSource config, List<object> modules)
  111. {
  112. config.AddConfig("Modules");
  113. config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
  114. modules.Add(new AttachmentsModule());
  115. modules.Add(new BasicInventoryAccessModule());
  116. }
  117. private void AddScriptingConfig(IConfigSource config, List<object> modules)
  118. {
  119. IConfig startupConfig = config.AddConfig("Startup");
  120. startupConfig.Set("DefaultScriptEngine", "XEngine");
  121. IConfig xEngineConfig = config.AddConfig("XEngine");
  122. xEngineConfig.Set("Enabled", "true");
  123. xEngineConfig.Set("StartDelay", "0");
  124. // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call
  125. // to AssemblyResolver.OnAssemblyResolve fails.
  126. xEngineConfig.Set("AppDomainLoading", "false");
  127. modules.Add(new XEngine());
  128. // Necessary to stop serialization complaining
  129. // FIXME: Stop this being necessary if at all possible
  130. // modules.Add(new WorldCommModule());
  131. }
  132. /// <summary>
  133. /// Creates an attachment item in the given user's inventory. Does not attach.
  134. /// </summary>
  135. /// <remarks>
  136. /// A user with the given ID and an inventory must already exist.
  137. /// </remarks>
  138. /// <returns>
  139. /// The attachment item.
  140. /// </returns>
  141. /// <param name='scene'></param>
  142. /// <param name='userId'></param>
  143. /// <param name='attName'></param>
  144. /// <param name='rawItemId'></param>
  145. /// <param name='rawAssetId'></param>
  146. private InventoryItemBase CreateAttachmentItem(
  147. Scene scene, UUID userId, string attName, int rawItemId, int rawAssetId)
  148. {
  149. return UserInventoryHelpers.CreateInventoryItem(
  150. scene,
  151. attName,
  152. TestHelpers.ParseTail(rawItemId),
  153. TestHelpers.ParseTail(rawAssetId),
  154. userId,
  155. InventoryType.Object);
  156. }
  157. [Test]
  158. public void TestAddAttachmentFromGround()
  159. {
  160. TestHelpers.InMethod();
  161. // TestHelpers.EnableLogging();
  162. m_numberOfAttachEventsFired = 0;
  163. Scene scene = CreateTestScene();
  164. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  165. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  166. string attName = "att";
  167. SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
  168. m_numberOfAttachEventsFired = 0;
  169. scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
  170. // Check status on scene presence
  171. Assert.That(sp.HasAttachments(), Is.True);
  172. List<SceneObjectGroup> attachments = sp.GetAttachments();
  173. Assert.That(attachments.Count, Is.EqualTo(1));
  174. SceneObjectGroup attSo = attachments[0];
  175. Assert.That(attSo.Name, Is.EqualTo(attName));
  176. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
  177. Assert.That(attSo.IsAttachment);
  178. Assert.That(attSo.UsesPhysics, Is.False);
  179. Assert.That(attSo.IsTemporary, Is.False);
  180. // Check item status
  181. Assert.That(
  182. sp.Appearance.GetAttachpoint(attSo.FromItemID),
  183. Is.EqualTo((int)AttachmentPoint.Chest));
  184. InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
  185. Assert.That(attachmentItem, Is.Not.Null);
  186. Assert.That(attachmentItem.Name, Is.EqualTo(attName));
  187. InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
  188. Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
  189. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  190. // Check events
  191. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  192. }
  193. /// <summary>
  194. /// Test that we do not attempt to attach an in-world object that someone else is sitting on.
  195. /// </summary>
  196. [Test]
  197. public void TestAddSatOnAttachmentFromGround()
  198. {
  199. TestHelpers.InMethod();
  200. // TestHelpers.EnableLogging();
  201. m_numberOfAttachEventsFired = 0;
  202. Scene scene = CreateTestScene();
  203. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  204. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  205. string attName = "att";
  206. SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
  207. UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(scene, 0x2);
  208. ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, ua2);
  209. // Put avatar within 10m of the prim so that sit doesn't fail.
  210. sp2.AbsolutePosition = new Vector3(0, 0, 0);
  211. sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
  212. scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
  213. Assert.That(sp.HasAttachments(), Is.False);
  214. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  215. // Check events
  216. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  217. }
  218. [Test]
  219. public void TestRezAttachmentFromInventory()
  220. {
  221. TestHelpers.InMethod();
  222. // log4net.Config.XmlConfigurator.Configure();
  223. Scene scene = CreateTestScene();
  224. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  225. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
  226. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  227. m_numberOfAttachEventsFired = 0;
  228. scene.AttachmentsModule.RezSingleAttachmentFromInventory(
  229. sp, attItem.ID, (uint)AttachmentPoint.Chest);
  230. // Check scene presence status
  231. Assert.That(sp.HasAttachments(), Is.True);
  232. List<SceneObjectGroup> attachments = sp.GetAttachments();
  233. Assert.That(attachments.Count, Is.EqualTo(1));
  234. SceneObjectGroup attSo = attachments[0];
  235. Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
  236. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
  237. Assert.That(attSo.IsAttachment);
  238. Assert.That(attSo.UsesPhysics, Is.False);
  239. Assert.That(attSo.IsTemporary, Is.False);
  240. // Check appearance status
  241. Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
  242. Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  243. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  244. // Check events
  245. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  246. }
  247. /// <summary>
  248. /// Test specific conditions associated with rezzing a scripted attachment from inventory.
  249. /// </summary>
  250. [Test]
  251. public void TestRezScriptedAttachmentFromInventory()
  252. {
  253. TestHelpers.InMethod();
  254. Scene scene = CreateScriptingEnabledTestScene();
  255. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  256. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  257. SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
  258. TaskInventoryItem scriptItem
  259. = TaskInventoryHelpers.AddScript(
  260. scene,
  261. so.RootPart,
  262. "scriptItem",
  263. "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
  264. InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
  265. // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
  266. // In the future, we need to be able to do this programatically more predicably.
  267. scene.EventManager.OnChatFromWorld += OnChatFromWorld;
  268. scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
  269. m_chatEvent.WaitOne(60000);
  270. // TODO: Need to have a test that checks the script is actually started but this involves a lot more
  271. // plumbing of the script engine and either pausing for events or more infrastructure to turn off various
  272. // script engine delays/asychronicity that isn't helpful in an automated regression testing context.
  273. SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name);
  274. Assert.That(attSo.ContainsScripts(), Is.True);
  275. TaskInventoryItem reRezzedScriptItem = attSo.RootPart.Inventory.GetInventoryItem(scriptItem.Name);
  276. IScriptModule xengine = scene.RequestModuleInterface<IScriptModule>();
  277. Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
  278. }
  279. [Test]
  280. public void TestDetachAttachmentToGround()
  281. {
  282. TestHelpers.InMethod();
  283. // log4net.Config.XmlConfigurator.Configure();
  284. Scene scene = CreateTestScene();
  285. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  286. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
  287. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  288. ISceneEntity so
  289. = scene.AttachmentsModule.RezSingleAttachmentFromInventory(
  290. sp, attItem.ID, (uint)AttachmentPoint.Chest);
  291. m_numberOfAttachEventsFired = 0;
  292. scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId);
  293. // Check scene presence status
  294. Assert.That(sp.HasAttachments(), Is.False);
  295. List<SceneObjectGroup> attachments = sp.GetAttachments();
  296. Assert.That(attachments.Count, Is.EqualTo(0));
  297. // Check appearance status
  298. Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(0));
  299. // Check item status
  300. Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null);
  301. // Check object in scene
  302. Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
  303. // Check events
  304. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  305. }
  306. [Test]
  307. public void TestDetachAttachmentToInventory()
  308. {
  309. TestHelpers.InMethod();
  310. Scene scene = CreateTestScene();
  311. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  312. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
  313. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  314. SceneObjectGroup so
  315. = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(
  316. sp, attItem.ID, (uint)AttachmentPoint.Chest);
  317. m_numberOfAttachEventsFired = 0;
  318. scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so);
  319. // Check status on scene presence
  320. Assert.That(sp.HasAttachments(), Is.False);
  321. List<SceneObjectGroup> attachments = sp.GetAttachments();
  322. Assert.That(attachments.Count, Is.EqualTo(0));
  323. // Check item status
  324. Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0));
  325. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0));
  326. // Check events
  327. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  328. }
  329. /// <summary>
  330. /// Test specific conditions associated with detaching a scripted attachment from inventory.
  331. /// </summary>
  332. [Test]
  333. public void TestDetachScriptedAttachmentToInventory()
  334. {
  335. TestHelpers.InMethod();
  336. // TestHelpers.EnableLogging();
  337. Scene scene = CreateScriptingEnabledTestScene();
  338. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  339. ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
  340. SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
  341. TaskInventoryItem scriptTaskItem
  342. = TaskInventoryHelpers.AddScript(
  343. scene,
  344. so.RootPart,
  345. "scriptItem",
  346. "default { attach(key id) { if (id != NULL_KEY) { llSay(0, \"Hello World\"); } } }");
  347. InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
  348. // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
  349. // In the future, we need to be able to do this programatically more predicably.
  350. scene.EventManager.OnChatFromWorld += OnChatFromWorld;
  351. SceneObjectGroup rezzedSo
  352. = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
  353. // Wait for chat to signal rezzed script has been started.
  354. m_chatEvent.WaitOne(60000);
  355. scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, rezzedSo);
  356. InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem);
  357. AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString());
  358. // TODO: It would probably be better here to check script state via the saving and retrieval of state
  359. // information at a higher level, rather than having to inspect the serialization.
  360. XmlDocument soXml = new XmlDocument();
  361. soXml.LoadXml(Encoding.UTF8.GetString(asset.Data));
  362. XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState");
  363. Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
  364. // Re-rez the attachment to check script running state
  365. SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
  366. // Wait for chat to signal rezzed script has been started.
  367. m_chatEvent.WaitOne(60000);
  368. TaskInventoryItem reRezzedScriptItem = reRezzedSo.RootPart.Inventory.GetInventoryItem(scriptTaskItem.Name);
  369. IScriptModule xengine = scene.RequestModuleInterface<IScriptModule>();
  370. Assert.That(xengine.GetScriptState(reRezzedScriptItem.ItemID), Is.True);
  371. // Console.WriteLine(soXml.OuterXml);
  372. }
  373. /// <summary>
  374. /// Test that attachments don't hang about in the scene when the agent is closed
  375. /// </summary>
  376. [Test]
  377. public void TestRemoveAttachmentsOnAvatarExit()
  378. {
  379. TestHelpers.InMethod();
  380. // log4net.Config.XmlConfigurator.Configure();
  381. Scene scene = CreateTestScene();
  382. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  383. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  384. AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
  385. acd.Appearance = new AvatarAppearance();
  386. acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
  387. ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
  388. SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
  389. m_numberOfAttachEventsFired = 0;
  390. scene.IncomingCloseAgent(presence.UUID, false);
  391. // Check that we can't retrieve this attachment from the scene.
  392. Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
  393. // Check events
  394. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  395. }
  396. [Test]
  397. public void TestRezAttachmentsOnAvatarEntrance()
  398. {
  399. TestHelpers.InMethod();
  400. // log4net.Config.XmlConfigurator.Configure();
  401. Scene scene = CreateTestScene();
  402. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  403. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  404. AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
  405. acd.Appearance = new AvatarAppearance();
  406. acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
  407. m_numberOfAttachEventsFired = 0;
  408. ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
  409. Assert.That(presence.HasAttachments(), Is.True);
  410. List<SceneObjectGroup> attachments = presence.GetAttachments();
  411. Assert.That(attachments.Count, Is.EqualTo(1));
  412. SceneObjectGroup attSo = attachments[0];
  413. Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
  414. Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
  415. Assert.That(attSo.IsAttachment);
  416. Assert.That(attSo.UsesPhysics, Is.False);
  417. Assert.That(attSo.IsTemporary, Is.False);
  418. // Check appearance status
  419. List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
  420. Assert.That(retreivedAttachments.Count, Is.EqualTo(1));
  421. Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
  422. Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID));
  423. Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
  424. Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  425. Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
  426. // Check events. We expect OnAttach to fire on login.
  427. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
  428. }
  429. [Test]
  430. public void TestUpdateAttachmentPosition()
  431. {
  432. TestHelpers.InMethod();
  433. Scene scene = CreateTestScene();
  434. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
  435. InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
  436. AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
  437. acd.Appearance = new AvatarAppearance();
  438. acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
  439. ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd);
  440. SceneObjectGroup attSo = sp.GetAttachments()[0];
  441. Vector3 newPosition = new Vector3(1, 2, 4);
  442. m_numberOfAttachEventsFired = 0;
  443. scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient);
  444. Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition));
  445. Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition));
  446. // Check events
  447. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  448. }
  449. [Test]
  450. public void TestSameSimulatorNeighbouringRegionsTeleport()
  451. {
  452. TestHelpers.InMethod();
  453. // TestHelpers.EnableLogging();
  454. AttachmentsModule attModA = new AttachmentsModule();
  455. AttachmentsModule attModB = new AttachmentsModule();
  456. EntityTransferModule etmA = new EntityTransferModule();
  457. EntityTransferModule etmB = new EntityTransferModule();
  458. LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
  459. IConfigSource config = new IniConfigSource();
  460. IConfig modulesConfig = config.AddConfig("Modules");
  461. modulesConfig.Set("EntityTransferModule", etmA.Name);
  462. modulesConfig.Set("SimulationServices", lscm.Name);
  463. IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
  464. // In order to run a single threaded regression test we do not want the entity transfer module waiting
  465. // for a callback from the destination scene before removing its avatar data.
  466. entityTransferConfig.Set("wait_for_callback", false);
  467. modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule");
  468. SceneHelpers sh = new SceneHelpers();
  469. TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
  470. TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
  471. SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
  472. SceneHelpers.SetupSceneModules(
  473. sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule());
  474. SceneHelpers.SetupSceneModules(
  475. sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
  476. UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
  477. ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager);
  478. beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
  479. InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
  480. sceneA.AttachmentsModule.RezSingleAttachmentFromInventory(
  481. beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest);
  482. Vector3 teleportPosition = new Vector3(10, 11, 12);
  483. Vector3 teleportLookAt = new Vector3(20, 21, 22);
  484. m_numberOfAttachEventsFired = 0;
  485. sceneA.RequestTeleportLocation(
  486. beforeTeleportSp.ControllingClient,
  487. sceneB.RegionInfo.RegionHandle,
  488. teleportPosition,
  489. teleportLookAt,
  490. (uint)TeleportFlags.ViaLocation);
  491. ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide();
  492. // Check attachments have made it into sceneB
  493. ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID);
  494. // This is appearance data, as opposed to actually rezzed attachments
  495. List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments();
  496. Assert.That(sceneBAttachments.Count, Is.EqualTo(1));
  497. Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
  498. Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID));
  499. Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
  500. Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  501. // This is the actual attachment
  502. List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments();
  503. Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1));
  504. SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
  505. Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
  506. Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
  507. Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
  508. // Check attachments have been removed from sceneA
  509. ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID);
  510. // Since this is appearance data, it is still present on the child avatar!
  511. List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments();
  512. Assert.That(sceneAAttachments.Count, Is.EqualTo(1));
  513. Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
  514. // This is the actual attachment, which should no longer exist
  515. List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments();
  516. Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
  517. Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
  518. // Check events
  519. Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
  520. }
  521. }
  522. }