SceneHelpers.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  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.Net;
  29. using System.Collections.Generic;
  30. using Nini.Config;
  31. using OpenMetaverse;
  32. using OpenSim.Framework;
  33. using OpenSim.Framework.Communications;
  34. using OpenSim.Framework.Console;
  35. using OpenSim.Framework.Servers;
  36. using OpenSim.Framework.Servers.HttpServer;
  37. using OpenSim.Region.Physics.Manager;
  38. using OpenSim.Region.Framework;
  39. using OpenSim.Region.Framework.Interfaces;
  40. using OpenSim.Region.Framework.Scenes;
  41. using OpenSim.Region.CoreModules.Avatar.Gods;
  42. using OpenSim.Region.CoreModules.Asset;
  43. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset;
  44. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication;
  45. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory;
  46. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid;
  47. using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
  48. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence;
  49. using OpenSim.Services.Interfaces;
  50. using OpenSim.Tests.Common.Mock;
  51. namespace OpenSim.Tests.Common
  52. {
  53. /// <summary>
  54. /// Helpers for setting up scenes.
  55. /// </summary>
  56. public class SceneHelpers
  57. {
  58. public static TestScene SetupScene()
  59. {
  60. return SetupScene(null);
  61. }
  62. /// <summary>
  63. /// Set up a test scene
  64. /// </summary>
  65. /// <remarks>
  66. /// Automatically starts service threads, as would the normal runtime.
  67. /// </remarks>
  68. /// <returns></returns>
  69. public static TestScene SetupScene(CoreAssetCache cache)
  70. {
  71. return SetupScene("Unit test region", UUID.Random(), 1000, 1000, cache);
  72. }
  73. public static TestScene SetupScene(string name, UUID id, uint x, uint y)
  74. {
  75. return SetupScene(name, id, x, y, null);
  76. }
  77. /// <summary>
  78. /// Set up a scene. If it's more then one scene, use the same CommunicationsManager to link regions
  79. /// or a different, to get a brand new scene with new shared region modules.
  80. /// </summary>
  81. /// <param name="name">Name of the region</param>
  82. /// <param name="id">ID of the region</param>
  83. /// <param name="x">X co-ordinate of the region</param>
  84. /// <param name="y">Y co-ordinate of the region</param>
  85. /// <param name="cm">This should be the same if simulating two scenes within a standalone</param>
  86. /// <returns></returns>
  87. public static TestScene SetupScene(string name, UUID id, uint x, uint y, CoreAssetCache cache)
  88. {
  89. Console.WriteLine("Setting up test scene {0}", name);
  90. // We must set up a console otherwise setup of some modules may fail
  91. MainConsole.Instance = new MockConsole("TEST PROMPT");
  92. RegionInfo regInfo = new RegionInfo(x, y, new IPEndPoint(IPAddress.Loopback, 9000), "127.0.0.1");
  93. regInfo.RegionName = name;
  94. regInfo.RegionID = id;
  95. AgentCircuitManager acm = new AgentCircuitManager();
  96. SceneCommunicationService scs = new SceneCommunicationService();
  97. ISimulationDataService simDataService = OpenSim.Server.Base.ServerUtils.LoadPlugin<ISimulationDataService>("OpenSim.Tests.Common.dll", null);
  98. IEstateDataService estateDataService = null;
  99. IConfigSource configSource = new IniConfigSource();
  100. TestScene testScene = new TestScene(
  101. regInfo, acm, scs, simDataService, estateDataService, null, false, false, false, configSource, null);
  102. IRegionModule godsModule = new GodsModule();
  103. godsModule.Initialise(testScene, new IniConfigSource());
  104. testScene.AddModule(godsModule.Name, godsModule);
  105. LocalAssetServicesConnector assetService = StartAssetService(testScene, cache);
  106. StartAuthenticationService(testScene);
  107. LocalInventoryServicesConnector inventoryService = StartInventoryService(testScene);
  108. StartGridService(testScene);
  109. LocalUserAccountServicesConnector userAccountService = StartUserAccountService(testScene);
  110. LocalPresenceServicesConnector presenceService = StartPresenceService(testScene);
  111. inventoryService.PostInitialise();
  112. assetService.PostInitialise();
  113. userAccountService.PostInitialise();
  114. presenceService.PostInitialise();
  115. testScene.RegionInfo.EstateSettings.EstateOwner = UUID.Random();
  116. testScene.SetModuleInterfaces();
  117. testScene.LandChannel = new TestLandChannel(testScene);
  118. testScene.LoadWorldMap();
  119. PhysicsPluginManager physicsPluginManager = new PhysicsPluginManager();
  120. physicsPluginManager.LoadPluginsFromAssembly("Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll");
  121. testScene.PhysicsScene
  122. = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test");
  123. testScene.RegionInfo.EstateSettings = new EstateSettings();
  124. testScene.LoginsDisabled = false;
  125. return testScene;
  126. }
  127. private static LocalAssetServicesConnector StartAssetService(Scene testScene, CoreAssetCache cache)
  128. {
  129. LocalAssetServicesConnector assetService = new LocalAssetServicesConnector();
  130. IConfigSource config = new IniConfigSource();
  131. config.AddConfig("Modules");
  132. config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
  133. config.AddConfig("AssetService");
  134. config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
  135. config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
  136. assetService.Initialise(config);
  137. assetService.AddRegion(testScene);
  138. if (cache != null)
  139. {
  140. IConfigSource cacheConfig = new IniConfigSource();
  141. cacheConfig.AddConfig("Modules");
  142. cacheConfig.Configs["Modules"].Set("AssetCaching", "CoreAssetCache");
  143. cacheConfig.AddConfig("AssetCache");
  144. cache.Initialise(cacheConfig);
  145. cache.AddRegion(testScene);
  146. cache.RegionLoaded(testScene);
  147. testScene.AddRegionModule(cache.Name, cache);
  148. }
  149. assetService.RegionLoaded(testScene);
  150. testScene.AddRegionModule(assetService.Name, assetService);
  151. return assetService;
  152. }
  153. private static void StartAuthenticationService(Scene testScene)
  154. {
  155. ISharedRegionModule service = new LocalAuthenticationServicesConnector();
  156. IConfigSource config = new IniConfigSource();
  157. config.AddConfig("Modules");
  158. config.AddConfig("AuthenticationService");
  159. config.Configs["Modules"].Set("AuthenticationServices", "LocalAuthenticationServicesConnector");
  160. config.Configs["AuthenticationService"].Set(
  161. "LocalServiceModule", "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService");
  162. config.Configs["AuthenticationService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
  163. service.Initialise(config);
  164. service.AddRegion(testScene);
  165. service.RegionLoaded(testScene);
  166. testScene.AddRegionModule(service.Name, service);
  167. //m_authenticationService = service;
  168. }
  169. private static LocalInventoryServicesConnector StartInventoryService(Scene testScene)
  170. {
  171. LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector();
  172. IConfigSource config = new IniConfigSource();
  173. config.AddConfig("Modules");
  174. config.AddConfig("InventoryService");
  175. config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector");
  176. config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService");
  177. config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
  178. inventoryService.Initialise(config);
  179. inventoryService.AddRegion(testScene);
  180. inventoryService.RegionLoaded(testScene);
  181. testScene.AddRegionModule(inventoryService.Name, inventoryService);
  182. return inventoryService;
  183. }
  184. private static LocalGridServicesConnector StartGridService(Scene testScene)
  185. {
  186. IConfigSource config = new IniConfigSource();
  187. config.AddConfig("Modules");
  188. config.AddConfig("GridService");
  189. config.Configs["Modules"].Set("GridServices", "LocalGridServicesConnector");
  190. config.Configs["GridService"].Set("StorageProvider", "OpenSim.Data.Null.dll:NullRegionData");
  191. config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Services.GridService.dll:GridService");
  192. LocalGridServicesConnector gridService = new LocalGridServicesConnector();
  193. gridService.Initialise(config);
  194. gridService.AddRegion(testScene);
  195. gridService.RegionLoaded(testScene);
  196. return gridService;
  197. }
  198. /// <summary>
  199. /// Start a user account service
  200. /// </summary>
  201. /// <param name="testScene"></param>
  202. /// <returns></returns>
  203. private static LocalUserAccountServicesConnector StartUserAccountService(Scene testScene)
  204. {
  205. IConfigSource config = new IniConfigSource();
  206. config.AddConfig("Modules");
  207. config.AddConfig("UserAccountService");
  208. config.Configs["Modules"].Set("UserAccountServices", "LocalUserAccountServicesConnector");
  209. config.Configs["UserAccountService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
  210. config.Configs["UserAccountService"].Set(
  211. "LocalServiceModule", "OpenSim.Services.UserAccountService.dll:UserAccountService");
  212. LocalUserAccountServicesConnector userAccountService = new LocalUserAccountServicesConnector();
  213. userAccountService.Initialise(config);
  214. userAccountService.AddRegion(testScene);
  215. userAccountService.RegionLoaded(testScene);
  216. testScene.AddRegionModule(userAccountService.Name, userAccountService);
  217. return userAccountService;
  218. }
  219. /// <summary>
  220. /// Start a presence service
  221. /// </summary>
  222. /// <param name="testScene"></param>
  223. private static LocalPresenceServicesConnector StartPresenceService(Scene testScene)
  224. {
  225. IConfigSource config = new IniConfigSource();
  226. config.AddConfig("Modules");
  227. config.AddConfig("PresenceService");
  228. config.Configs["Modules"].Set("PresenceServices", "LocalPresenceServicesConnector");
  229. config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
  230. config.Configs["PresenceService"].Set(
  231. "LocalServiceModule", "OpenSim.Services.PresenceService.dll:PresenceService");
  232. LocalPresenceServicesConnector presenceService = new LocalPresenceServicesConnector();
  233. presenceService.Initialise(config);
  234. presenceService.AddRegion(testScene);
  235. presenceService.RegionLoaded(testScene);
  236. testScene.AddRegionModule(presenceService.Name, presenceService);
  237. return presenceService;
  238. }
  239. /// <summary>
  240. /// Setup modules for a scene using their default settings.
  241. /// </summary>
  242. /// <param name="scene"></param>
  243. /// <param name="modules"></param>
  244. public static void SetupSceneModules(Scene scene, params object[] modules)
  245. {
  246. SetupSceneModules(scene, new IniConfigSource(), modules);
  247. }
  248. /// <summary>
  249. /// Setup modules for a scene.
  250. /// </summary>
  251. /// <param name="scene"></param>
  252. /// <param name="config"></param>
  253. /// <param name="modules"></param>
  254. public static void SetupSceneModules(Scene scene, IConfigSource config, params object[] modules)
  255. {
  256. List<IRegionModuleBase> newModules = new List<IRegionModuleBase>();
  257. foreach (object module in modules)
  258. {
  259. if (module is IRegionModule)
  260. {
  261. IRegionModule m = (IRegionModule)module;
  262. m.Initialise(scene, config);
  263. scene.AddModule(m.Name, m);
  264. m.PostInitialise();
  265. }
  266. else if (module is IRegionModuleBase)
  267. {
  268. // for the new system, everything has to be initialised first,
  269. // shared modules have to be post-initialised, then all get an AddRegion with the scene
  270. IRegionModuleBase m = (IRegionModuleBase)module;
  271. m.Initialise(config);
  272. newModules.Add(m);
  273. }
  274. }
  275. foreach (IRegionModuleBase module in newModules)
  276. {
  277. if (module is ISharedRegionModule) ((ISharedRegionModule)module).PostInitialise();
  278. }
  279. foreach (IRegionModuleBase module in newModules)
  280. {
  281. module.AddRegion(scene);
  282. scene.AddRegionModule(module.Name, module);
  283. }
  284. // RegionLoaded is fired after all modules have been appropriately added to all scenes
  285. foreach (IRegionModuleBase module in newModules)
  286. module.RegionLoaded(scene);
  287. scene.SetModuleInterfaces();
  288. }
  289. /// <summary>
  290. /// Generate some standard agent connection data.
  291. /// </summary>
  292. /// <param name="agentId"></param>
  293. /// <returns></returns>
  294. public static AgentCircuitData GenerateAgentData(UUID agentId)
  295. {
  296. string firstName = "testfirstname";
  297. AgentCircuitData agentData = new AgentCircuitData();
  298. agentData.AgentID = agentId;
  299. agentData.firstname = firstName;
  300. agentData.lastname = "testlastname";
  301. agentData.SessionID = UUID.Zero;
  302. agentData.SecureSessionID = UUID.Zero;
  303. agentData.circuitcode = 123;
  304. agentData.BaseFolder = UUID.Zero;
  305. agentData.InventoryFolder = UUID.Zero;
  306. agentData.startpos = Vector3.Zero;
  307. agentData.CapsPath = "http://wibble.com";
  308. agentData.ServiceURLs = new Dictionary<string, object>();
  309. return agentData;
  310. }
  311. /// <summary>
  312. /// Add a root agent where the details of the agent connection (apart from the id) are unimportant for the test
  313. /// </summary>
  314. /// <param name="scene"></param>
  315. /// <param name="agentId"></param>
  316. /// <returns></returns>
  317. public static ScenePresence AddScenePresence(Scene scene, UUID agentId)
  318. {
  319. return AddScenePresence(scene, GenerateAgentData(agentId));
  320. }
  321. /// <summary>
  322. /// Add a root agent.
  323. /// </summary>
  324. /// <remarks>
  325. /// This function
  326. ///
  327. /// 1) Tells the scene that an agent is coming. Normally, the login service (local if standalone, from the
  328. /// userserver if grid) would give initial login data back to the client and separately tell the scene that the
  329. /// agent was coming.
  330. ///
  331. /// 2) Connects the agent with the scene
  332. ///
  333. /// This function performs actions equivalent with notifying the scene that an agent is
  334. /// coming and then actually connecting the agent to the scene. The one step missed out is the very first
  335. /// </remarks>
  336. /// <param name="scene"></param>
  337. /// <param name="agentData"></param>
  338. /// <returns></returns>
  339. public static ScenePresence AddScenePresence(Scene scene, AgentCircuitData agentData)
  340. {
  341. string reason;
  342. // We emulate the proper login sequence here by doing things in four stages
  343. // Stage 0: log the presence
  344. scene.PresenceService.LoginAgent(agentData.AgentID.ToString(), agentData.SessionID, agentData.SecureSessionID);
  345. // Stage 1: simulate login by telling the scene to expect a new user connection
  346. if (!scene.NewUserConnection(agentData, (uint)TeleportFlags.ViaLogin, out reason))
  347. Console.WriteLine("NewUserConnection failed: " + reason);
  348. // Stage 2: add the new client as a child agent to the scene
  349. TestClient client = new TestClient(agentData, scene);
  350. scene.AddNewClient(client, PresenceType.User);
  351. // Stage 3: Complete the entrance into the region. This converts the child agent into a root agent.
  352. ScenePresence scp = scene.GetScenePresence(agentData.AgentID);
  353. scp.CompleteMovement(client, true);
  354. //scp.MakeRootAgent(new Vector3(90, 90, 90), true);
  355. return scp;
  356. }
  357. /// <summary>
  358. /// Add a test object
  359. /// </summary>
  360. /// <param name="scene"></param>
  361. /// <returns></returns>
  362. public static SceneObjectPart AddSceneObject(Scene scene)
  363. {
  364. return AddSceneObject(scene, "Test Object");
  365. }
  366. /// <summary>
  367. /// Add a test object
  368. /// </summary>
  369. /// <param name="scene"></param>
  370. /// <param name="name"></param>
  371. /// <returns></returns>
  372. public static SceneObjectPart AddSceneObject(Scene scene, string name)
  373. {
  374. SceneObjectPart part = CreateSceneObjectPart(name, UUID.Random(), UUID.Zero);
  375. //part.UpdatePrimFlags(false, false, true);
  376. //part.ObjectFlags |= (uint)PrimFlags.Phantom;
  377. scene.AddNewSceneObject(new SceneObjectGroup(part), false);
  378. return part;
  379. }
  380. /// <summary>
  381. /// Create a scene object part.
  382. /// </summary>
  383. /// <param name="name"></param>
  384. /// <param name="id"></param>
  385. /// <param name="ownerId"></param>
  386. /// <returns></returns>
  387. public static SceneObjectPart CreateSceneObjectPart(string name, UUID id, UUID ownerId)
  388. {
  389. return new SceneObjectPart(
  390. ownerId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
  391. { Name = name, UUID = id, Scale = new Vector3(1, 1, 1) };
  392. }
  393. /// <summary>
  394. /// Create a scene object but do not add it to the scene.
  395. /// </summary>
  396. /// <remarks>
  397. /// UUID always starts at 00000000-0000-0000-0000-000000000001
  398. /// </remarks>
  399. /// <param name="parts">The number of parts that should be in the scene object</param>
  400. /// <param name="ownerId"></param>
  401. /// <returns></returns>
  402. public static SceneObjectGroup CreateSceneObject(int parts, UUID ownerId)
  403. {
  404. return CreateSceneObject(parts, ownerId, "", 0x1);
  405. }
  406. /// <summary>
  407. /// Create a scene object but do not add it to the scene.
  408. /// </summary>
  409. /// <param name="parts">
  410. /// The number of parts that should be in the scene object
  411. /// </param>
  412. /// <param name="ownerId"></param>
  413. /// <param name="partNamePrefix">
  414. /// The prefix to be given to part names. This will be suffixed with "Part<part no>"
  415. /// (e.g. mynamePart0 for the root part)
  416. /// </param>
  417. /// <param name="uuidTail">
  418. /// The hexadecimal last part of the UUID for parts created. A UUID of the form "00000000-0000-0000-0000-{0:XD12}"
  419. /// will be given to the root part, and incremented for each part thereafter.
  420. /// </param>
  421. /// <returns></returns>
  422. public static SceneObjectGroup CreateSceneObject(int parts, UUID ownerId, string partNamePrefix, int uuidTail)
  423. {
  424. string rawSogId = string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail);
  425. SceneObjectGroup sog
  426. = new SceneObjectGroup(
  427. CreateSceneObjectPart(string.Format("{0}Part0", partNamePrefix), new UUID(rawSogId), ownerId));
  428. if (parts > 1)
  429. for (int i = 1; i < parts; i++)
  430. sog.AddPart(
  431. CreateSceneObjectPart(
  432. string.Format("{0}Part{1}", partNamePrefix, i),
  433. new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail + i)),
  434. ownerId));
  435. return sog;
  436. }
  437. }
  438. }