SceneSetupHelpers.cs 21 KB

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