Scene.Inventory.cs 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940
  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 OpenSim 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. */
  28. using System;
  29. using System.Collections.Generic;
  30. using libsecondlife;
  31. using libsecondlife.Packets;
  32. using OpenSim.Framework;
  33. using OpenSim.Framework.Communications.Cache;
  34. using OpenSim.Framework.Console;
  35. using System.IO;
  36. using System.Text;
  37. using System.Xml;
  38. using OpenSim.Region.Environment.Interfaces;
  39. using Axiom.Math;
  40. namespace OpenSim.Region.Environment.Scenes
  41. {
  42. public partial class Scene
  43. {
  44. private static readonly log4net.ILog m_log
  45. = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  46. /// <summary>
  47. /// Start all the scripts in the scene which should be started.
  48. /// </summary>
  49. public void StartScripts()
  50. {
  51. m_log.Info("[PRIMINVENTORY]: Starting scripts in scene");
  52. foreach (SceneObjectGroup group in Entities.Values)
  53. {
  54. group.StartScripts();
  55. }
  56. }
  57. /// <summary>
  58. /// Add an inventory item to an avatar's inventory.
  59. /// </summary>
  60. /// <param name="remoteClient">The remote client controlling the avatar</param>
  61. /// <param name="item">The item. This structure contains all the item metadata, including the folder
  62. /// in which the item is to be placed.</param>
  63. public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
  64. {
  65. CachedUserInfo userInfo
  66. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  67. if (userInfo != null)
  68. {
  69. userInfo.AddItem(remoteClient.AgentId, item);
  70. remoteClient.SendInventoryItemCreateUpdate(item);
  71. }
  72. }
  73. /// <summary>
  74. /// <see>AddInventoryItem(LLUUID, InventoryItemBase)</see>
  75. /// </summary>
  76. /// <param name="avatarId">The ID of the avatar</param>
  77. /// <param name="item">The item. This structure contains all the item metadata, including the folder
  78. /// in which the item is to be placed.</param>
  79. public void AddInventoryItem(LLUUID avatarId, InventoryItemBase item)
  80. {
  81. ScenePresence avatar;
  82. if (!TryGetAvatar(avatarId, out avatar))
  83. {
  84. m_log.ErrorFormat(
  85. "[AGENTINVENTORY]: Could not find avatar {0} to add inventory item", avatarId);
  86. return;
  87. }
  88. AddInventoryItem(avatar.ControllingClient, item);
  89. }
  90. /// <summary>
  91. /// Capability originating call to update the asset of an item in an agent's inventory
  92. /// </summary>
  93. /// <param name="remoteClient"></param>
  94. /// <param name="itemID"></param>
  95. /// <param name="data"></param>
  96. /// <returns></returns>
  97. public LLUUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, LLUUID itemID, byte[] data)
  98. {
  99. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  100. if (userInfo != null)
  101. {
  102. if (userInfo.RootFolder != null)
  103. {
  104. InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
  105. if (item != null)
  106. {
  107. AssetBase asset =
  108. CreateAsset(item.inventoryName, item.inventoryDescription, (sbyte) item.invType,
  109. (sbyte) item.assetType, data);
  110. AssetCache.AddAsset(asset);
  111. item.assetID = asset.FullID;
  112. userInfo.UpdateItem(remoteClient.AgentId, item);
  113. // remoteClient.SendInventoryItemCreateUpdate(item);
  114. if ((InventoryType) item.invType == InventoryType.Notecard)
  115. {
  116. //do we want to know about updated note cards?
  117. }
  118. else if ((InventoryType) item.invType == InventoryType.LSL)
  119. {
  120. // do we want to know about updated scripts
  121. }
  122. return (asset.FullID);
  123. }
  124. }
  125. }
  126. return LLUUID.Zero;
  127. }
  128. /// <summary>
  129. /// <see>CapsUpdatedInventoryItemAsset(IClientAPI, LLUUID, byte[])</see>
  130. /// </summary>
  131. private LLUUID CapsUpdateInventoryItemAsset(LLUUID avatarId, LLUUID itemID, byte[] data)
  132. {
  133. ScenePresence avatar;
  134. if (TryGetAvatar(avatarId, out avatar))
  135. {
  136. return CapsUpdateInventoryItemAsset(avatar.ControllingClient, itemID, data);
  137. }
  138. else
  139. {
  140. m_log.ErrorFormat(
  141. "[AGENTINVENTORY]: " +
  142. "Avatar {0} cannot be found to update its inventory item asset",
  143. avatarId);
  144. }
  145. return LLUUID.Zero;
  146. }
  147. /// <summary>
  148. /// Capability originating call to update the asset of a script in a prim's (task's) inventory
  149. /// </summary>
  150. /// <param name="remoteClient"></param>
  151. /// <param name="itemID"></param>
  152. /// <param name="primID">The prim which contains the item to update</param>
  153. /// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
  154. /// <param name="data"></param>
  155. public void CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, LLUUID itemId,
  156. LLUUID primId, bool isScriptRunning, byte[] data)
  157. {
  158. // Retrieve group
  159. SceneObjectPart part = GetSceneObjectPart(primId);
  160. SceneObjectGroup group = part.ParentGroup;
  161. if (null == group)
  162. {
  163. m_log.ErrorFormat(
  164. "[PRIMINVENTORY]: " +
  165. "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
  166. itemId, primId);
  167. return;
  168. }
  169. // Retrieve item
  170. TaskInventoryItem item = group.GetInventoryItem(part.LocalID, itemId);
  171. if (null == item)
  172. {
  173. return;
  174. }
  175. // Create new asset
  176. // XXX Hardcoding the numbers is a temporary measure - need an enumeration for this
  177. // There may well be one in libsecondlife
  178. AssetBase asset = CreateAsset(item.Name, item.Description, 10, 10, data);
  179. AssetCache.AddAsset(asset);
  180. // Update item with new asset
  181. item.AssetID = asset.FullID;
  182. group.UpdateInventoryItem(item);
  183. group.GetProperties(remoteClient);
  184. // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
  185. if (isScriptRunning)
  186. {
  187. group.StopScript(part.LocalID, item.ItemID);
  188. group.StartScript(part.LocalID, item.ItemID);
  189. }
  190. }
  191. /// <summary>
  192. /// <see>CapsUpdateTaskInventoryScriptAsset(IClientAPI, LLUUID, LLUUID, bool, byte[])</see>
  193. /// </summary>
  194. private void CapsUpdateTaskInventoryScriptAsset(LLUUID avatarId, LLUUID itemId,
  195. LLUUID primId, bool isScriptRunning, byte[] data)
  196. {
  197. ScenePresence avatar;
  198. if (TryGetAvatar(avatarId, out avatar))
  199. {
  200. CapsUpdateTaskInventoryScriptAsset(
  201. avatar.ControllingClient, itemId, primId, isScriptRunning, data);
  202. }
  203. else
  204. {
  205. m_log.ErrorFormat(
  206. "[PRIMINVENTORY]: " +
  207. "Avatar {0} cannot be found to update its prim item asset",
  208. avatarId);
  209. }
  210. }
  211. /// <summary>
  212. /// Update an item which is either already in the client's inventory or is within
  213. /// a transaction
  214. /// </summary>
  215. /// <param name="remoteClient"></param>
  216. /// <param name="transactionID">The transaction ID. If this is LLUUID.Zero we will
  217. /// assume that we are not in a transaction</param>
  218. /// <param name="itemID">The ID of the updated item</param>
  219. /// <param name="name">The name of the updated item</param>
  220. /// <param name="description">The description of the updated item</param>
  221. /// <param name="nextOwnerMask">The permissions of the updated item</param>
  222. public void UpdateInventoryItemAsset(IClientAPI remoteClient, LLUUID transactionID,
  223. LLUUID itemID, string name, string description,
  224. uint nextOwnerMask)
  225. {
  226. CachedUserInfo userInfo
  227. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  228. if (userInfo != null && userInfo.RootFolder != null)
  229. {
  230. InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
  231. if (item != null)
  232. {
  233. if (LLUUID.Zero == transactionID)
  234. {
  235. item.inventoryName = name;
  236. item.inventoryDescription = description;
  237. item.inventoryNextPermissions = nextOwnerMask;
  238. userInfo.UpdateItem(remoteClient.AgentId, item);
  239. }
  240. else
  241. {
  242. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  243. if (agentTransactions != null)
  244. {
  245. agentTransactions.HandleItemUpdateFromTransaction(
  246. remoteClient, transactionID, item);
  247. }
  248. }
  249. }
  250. else
  251. {
  252. m_log.Error(
  253. "[AGENTINVENTORY]: Item ID " + itemID + " not found for an inventory item update.");
  254. }
  255. }
  256. else
  257. {
  258. m_log.Error(
  259. "[AGENTINVENTORY]: Agent ID " + remoteClient.AgentId + " not found for an inventory item update.");
  260. }
  261. }
  262. public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, LLUUID oldAgentID, LLUUID oldItemID,
  263. LLUUID newFolderID, string newName)
  264. {
  265. InventoryItemBase item = CommsManager.UserProfileCacheService.libraryRoot.HasItem(oldItemID);
  266. if (item == null)
  267. {
  268. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(oldAgentID);
  269. if (userInfo == null)
  270. {
  271. m_log.Error("[AGENTINVENTORY]: Failed to find user " + oldAgentID.ToString());
  272. return;
  273. }
  274. if (userInfo.RootFolder != null)
  275. {
  276. item = userInfo.RootFolder.HasItem(oldItemID);
  277. if (item == null)
  278. {
  279. m_log.Error("[AGENTINVENTORY]: Failed to find item " + oldItemID.ToString());
  280. return;
  281. }
  282. }
  283. else
  284. {
  285. m_log.Error("[AGENTINVENTORY]: Failed to find item " + oldItemID.ToString());
  286. return;
  287. }
  288. }
  289. AssetBase asset = AssetCache.CopyAsset(item.assetID);
  290. if (asset == null)
  291. {
  292. m_log.Warn("[AGENTINVENTORY]: Failed to find asset " + item.assetID.ToString());
  293. return;
  294. }
  295. asset.Name = (newName.Length == 0) ? item.inventoryName : newName;
  296. // TODO: preserve current permissions?
  297. CreateNewInventoryItem(remoteClient, newFolderID, callbackID, asset, item.inventoryNextPermissions);
  298. }
  299. private AssetBase CreateAsset(string name, string description, sbyte invType, sbyte assetType, byte[] data)
  300. {
  301. AssetBase asset = new AssetBase();
  302. asset.Name = name;
  303. asset.Description = description;
  304. asset.InvType = invType;
  305. asset.Type = assetType;
  306. asset.FullID = LLUUID.Random(); // TODO: check for conflicts
  307. asset.Data = (data == null) ? new byte[1] : data;
  308. return asset;
  309. }
  310. public void MoveInventoryItem(IClientAPI remoteClient, LLUUID folderID, LLUUID itemID, int length,
  311. string newName)
  312. {
  313. m_log.Info(
  314. "[AGENTINVENTORY]: " +
  315. "Moving item for " + remoteClient.AgentId.ToString());
  316. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  317. if (userInfo == null)
  318. {
  319. m_log.Error("[AGENTINVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
  320. return;
  321. }
  322. if (userInfo.RootFolder != null)
  323. {
  324. InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
  325. if (item != null)
  326. {
  327. if (newName != System.String.Empty)
  328. {
  329. item.inventoryName = newName;
  330. }
  331. item.parentFolderID = folderID;
  332. userInfo.DeleteItem(remoteClient.AgentId, item);
  333. // TODO: preserve current permissions?
  334. AddInventoryItem(remoteClient, item);
  335. }
  336. else
  337. {
  338. m_log.Error("[AGENTINVENTORY]: Failed to find item " + itemID.ToString());
  339. return;
  340. }
  341. }
  342. else
  343. {
  344. m_log.Error("[AGENTINVENTORY]: Failed to find item " + itemID.ToString() + ", no root folder");
  345. return;
  346. }
  347. }
  348. /// <summary>
  349. /// Create a new inventory item.
  350. /// </summary>
  351. /// <param name="remoteClient"></param>
  352. /// <param name="folderID"></param>
  353. /// <param name="callbackID"></param>
  354. /// <param name="asset"></param>
  355. /// <param name="nextOwnerMask"></param>
  356. private void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID folderID, uint callbackID,
  357. AssetBase asset, uint nextOwnerMask)
  358. {
  359. CachedUserInfo userInfo
  360. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  361. if (userInfo != null)
  362. {
  363. InventoryItemBase item = new InventoryItemBase();
  364. item.avatarID = remoteClient.AgentId;
  365. item.creatorsID = remoteClient.AgentId;
  366. item.inventoryID = LLUUID.Random();
  367. item.assetID = asset.FullID;
  368. item.inventoryDescription = asset.Description;
  369. item.inventoryName = asset.Name;
  370. item.assetType = asset.Type;
  371. item.invType = asset.InvType;
  372. item.parentFolderID = folderID;
  373. item.inventoryCurrentPermissions = 2147483647;
  374. item.inventoryNextPermissions = nextOwnerMask;
  375. userInfo.AddItem(remoteClient.AgentId, item);
  376. remoteClient.SendInventoryItemCreateUpdate(item);
  377. }
  378. else
  379. {
  380. m_log.WarnFormat(
  381. "No user details associated with client {0} uuid {1} in CreateNewInventoryItem!",
  382. remoteClient.Name, remoteClient.AgentId);
  383. }
  384. }
  385. /// <summary>
  386. /// Create a new inventory item.
  387. /// </summary>
  388. /// <param name="remoteClient"></param>
  389. /// <param name="transactionID"></param>
  390. /// <param name="folderID"></param>
  391. /// <param name="callbackID"></param>
  392. /// <param name="description"></param>
  393. /// <param name="name"></param>
  394. /// <param name="invType"></param>
  395. /// <param name="type"></param>
  396. /// <param name="wearableType"></param>
  397. /// <param name="nextOwnerMask"></param>
  398. public void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
  399. uint callbackID, string description, string name, sbyte invType,
  400. sbyte assetType,
  401. byte wearableType, uint nextOwnerMask)
  402. {
  403. if (transactionID == LLUUID.Zero)
  404. {
  405. CachedUserInfo userInfo
  406. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  407. if (userInfo != null)
  408. {
  409. AssetBase asset = CreateAsset(name, description, invType, assetType, null);
  410. AssetCache.AddAsset(asset);
  411. CreateNewInventoryItem(remoteClient, folderID, callbackID, asset, nextOwnerMask);
  412. }
  413. else
  414. {
  415. m_log.ErrorFormat(
  416. "userInfo for agent uuid {0} unexpectedly null in CreateNewInventoryItem",
  417. remoteClient.AgentId);
  418. }
  419. }
  420. else
  421. {
  422. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  423. if (agentTransactions != null)
  424. {
  425. agentTransactions.HandleItemCreationFromTransaction(
  426. remoteClient, transactionID, folderID, callbackID, description,
  427. name, invType, assetType, wearableType, nextOwnerMask);
  428. }
  429. }
  430. }
  431. private void RemoveInventoryItem(IClientAPI remoteClient, LLUUID itemID)
  432. {
  433. CachedUserInfo userInfo
  434. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  435. if (userInfo == null)
  436. {
  437. m_log.Error("[AGENTINVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
  438. return;
  439. }
  440. // is going through the root folder really the best way?
  441. // this triggers a tree walk to find and remove the item. 8-(
  442. // since this only happens in Trash (in theory) shouldn't we grab
  443. // the trash folder directly instead of RootFolder?
  444. if (userInfo.RootFolder != null)
  445. {
  446. InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
  447. if (item != null)
  448. {
  449. userInfo.DeleteItem(remoteClient.AgentId, item);
  450. }
  451. }
  452. }
  453. private void RemoveInventoryFolder(IClientAPI remoteClient, LLUUID folderID)
  454. {
  455. CachedUserInfo userInfo
  456. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  457. if (userInfo == null)
  458. {
  459. m_log.Error("[AGENTINVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
  460. return;
  461. }
  462. if (userInfo.RootFolder != null)
  463. {
  464. InventoryItemBase folder = userInfo.RootFolder.HasItem(folderID);
  465. if (folder != null)
  466. {
  467. // doesn't work just yet, commented out. WIll fix in next patch.
  468. // userInfo.DeleteItem(remoteClient.AgentId, folder);
  469. }
  470. }
  471. }
  472. private SceneObjectGroup GetGroupByPrim(uint localID)
  473. {
  474. List<EntityBase> EntitieList = GetEntities();
  475. foreach (EntityBase ent in EntitieList)
  476. {
  477. if (ent is SceneObjectGroup)
  478. {
  479. if (((SceneObjectGroup) ent).HasChildPrim(localID))
  480. return (SceneObjectGroup) ent;
  481. }
  482. }
  483. return null;
  484. }
  485. /// <summary>
  486. /// Request a prim (task) inventory
  487. /// </summary>
  488. /// <param name="remoteClient"></param>
  489. /// <param name="primLocalID"></param>
  490. public void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID)
  491. {
  492. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  493. if (group != null)
  494. {
  495. bool fileChange = group.GetPartInventoryFileName(remoteClient, primLocalID);
  496. if (fileChange)
  497. {
  498. if (XferManager != null)
  499. {
  500. group.RequestInventoryFile(primLocalID, XferManager);
  501. }
  502. }
  503. }
  504. else
  505. {
  506. m_log.ErrorFormat(
  507. "[PRIMINVENTORY]: Inventory requested of prim {0} which doesn't exist", primLocalID);
  508. }
  509. }
  510. /// <summary>
  511. /// Remove an item from a prim (task) inventory
  512. /// </summary>
  513. /// <param name="remoteClient">Unused at the moment but retained since the avatar ID might
  514. /// be necessary for a permissions check at some stage.</param>
  515. /// <param name="itemID"></param>
  516. /// <param name="localID"></param>
  517. public void RemoveTaskInventory(IClientAPI remoteClient, LLUUID itemID, uint localID)
  518. {
  519. SceneObjectGroup group = GetGroupByPrim(localID);
  520. if (group != null)
  521. {
  522. int type = group.RemoveInventoryItem(localID, itemID);
  523. group.GetProperties(remoteClient);
  524. if (type == 10)
  525. {
  526. EventManager.TriggerRemoveScript(localID, itemID);
  527. }
  528. }
  529. else
  530. {
  531. m_log.ErrorFormat(
  532. "[PRIMINVENTORY]: " +
  533. "Removal of item {0} requested of prim {1} but this prim does not exist",
  534. itemID,
  535. localID);
  536. }
  537. }
  538. /// <summary>
  539. /// Update an item in a prim (task) inventory.
  540. /// This method does not handle scripts, <see>RezScript(IClientAPI, LLUUID, unit)</see>
  541. /// </summary>
  542. /// <param name="remoteClient"></param>
  543. /// <param name="itemID"></param>
  544. /// <param name="folderID"></param>
  545. /// <param name="primLocalID"></param>
  546. public void UpdateTaskInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID folderID,
  547. uint primLocalID)
  548. {
  549. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  550. if (group != null)
  551. {
  552. // TODO Retrieve itemID from client's inventory to pass on
  553. //group.AddInventoryItem(remoteClient, primLocalID, null);
  554. m_log.InfoFormat(
  555. "[PRIMINVENTORY]: " +
  556. "Non script prim inventory not yet implemented!"
  557. + "\nUpdateTaskInventory called with item {0}, folder {1}, primLocalID {2}, user {3}",
  558. itemID, folderID, primLocalID, remoteClient.Name);
  559. }
  560. else
  561. {
  562. m_log.WarnFormat(
  563. "[PRIMINVENTORY]: " +
  564. "Update with item {0} requested of prim {1} for {2} but this prim does not exist",
  565. itemID, primLocalID, remoteClient.Name);
  566. }
  567. }
  568. /// <summary>
  569. /// Rez a script into a prim's inventory
  570. /// </summary>
  571. /// <param name="remoteClient"></param>
  572. /// <param name="itemID"> </param>
  573. /// <param name="localID"></param>
  574. public void RezScript(IClientAPI remoteClient, LLUUID itemID, uint localID)
  575. {
  576. LLUUID copyID = LLUUID.Random();
  577. if (itemID != LLUUID.Zero)
  578. {
  579. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  580. if (userInfo != null && userInfo.RootFolder != null)
  581. {
  582. InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
  583. // Try library
  584. // XXX clumsy, possibly should be one call
  585. if (null == item)
  586. {
  587. item = CommsManager.UserProfileCacheService.libraryRoot.HasItem(itemID);
  588. }
  589. if (item != null)
  590. {
  591. SceneObjectGroup group = GetGroupByPrim(localID);
  592. if (group != null)
  593. {
  594. group.AddInventoryItem(remoteClient, localID, item, copyID);
  595. group.StartScript(localID, copyID);
  596. group.GetProperties(remoteClient);
  597. // m_log.InfoFormat("[PRIMINVENTORY]: " +
  598. // "Rezzed script {0} into prim local ID {1} for user {2}",
  599. // item.inventoryName, localID, remoteClient.Name);
  600. }
  601. else
  602. {
  603. m_log.ErrorFormat(
  604. "[PRIMINVENTORY]: " +
  605. "Could not rez script {0} into prim local ID {1} for user {2}"
  606. + " because the prim could not be found in the region!",
  607. item.inventoryName, localID, remoteClient.Name);
  608. }
  609. }
  610. else
  611. {
  612. m_log.ErrorFormat(
  613. "[PRIMINVENTORY]: Could not find script inventory item {0} to rez for {1}!",
  614. itemID, remoteClient.Name);
  615. }
  616. }
  617. }
  618. else // If the itemID is zero then the script has been rezzed directly in an object's inventory
  619. {
  620. // not yet implemented
  621. // TODO Need to get more details from original RezScript packet
  622. // XXX jc tmp
  623. // AssetBase asset = CreateAsset("chimney sweep", "sailor.lsl", 10, 10, null);
  624. // AssetCache.AddAsset(asset);
  625. }
  626. }
  627. /// <summary>
  628. ///
  629. /// </summary>
  630. /// <param name="packet"></param>
  631. /// <param name="simClient"></param>
  632. public virtual void DeRezObject(Packet packet, IClientAPI remoteClient)
  633. {
  634. DeRezObjectPacket DeRezPacket = (DeRezObjectPacket) packet;
  635. if (DeRezPacket.AgentBlock.DestinationID == LLUUID.Zero)
  636. {
  637. //currently following code not used (or don't know of any case of destination being zero
  638. }
  639. else
  640. {
  641. foreach (DeRezObjectPacket.ObjectDataBlock Data in DeRezPacket.ObjectData)
  642. {
  643. EntityBase selectedEnt = null;
  644. //m_log.Info("[CLIENT]: LocalID:" + Data.ObjectLocalID.ToString());
  645. List<EntityBase> EntitieList = GetEntities();
  646. foreach (EntityBase ent in EntitieList)
  647. {
  648. if (ent.LocalId == Data.ObjectLocalID)
  649. {
  650. selectedEnt = ent;
  651. break;
  652. }
  653. }
  654. if (selectedEnt != null)
  655. {
  656. if (PermissionsMngr.CanDeRezObject(remoteClient.AgentId, ((SceneObjectGroup) selectedEnt).UUID))
  657. {
  658. string sceneObjectXml = ((SceneObjectGroup) selectedEnt).ToXmlString();
  659. CachedUserInfo userInfo =
  660. CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  661. if (userInfo != null)
  662. {
  663. AssetBase asset = CreateAsset(
  664. ((SceneObjectGroup) selectedEnt).GetPartName(selectedEnt.LocalId),
  665. ((SceneObjectGroup) selectedEnt).GetPartDescription(selectedEnt.LocalId),
  666. (sbyte) InventoryType.Object,
  667. (sbyte) AssetType.Primitive,
  668. Helpers.StringToField(sceneObjectXml));
  669. AssetCache.AddAsset(asset);
  670. InventoryItemBase item = new InventoryItemBase();
  671. item.avatarID = remoteClient.AgentId;
  672. item.creatorsID = remoteClient.AgentId;
  673. item.inventoryID = LLUUID.Random(); // TODO: check for conflicts
  674. item.assetID = asset.FullID;
  675. item.inventoryDescription = asset.Description;
  676. item.inventoryName = asset.Name;
  677. item.assetType = asset.Type;
  678. item.invType = asset.InvType;
  679. item.parentFolderID = DeRezPacket.AgentBlock.DestinationID;
  680. item.inventoryCurrentPermissions = 2147483647;
  681. item.inventoryNextPermissions = 2147483647;
  682. item.inventoryEveryOnePermissions =
  683. ((SceneObjectGroup) selectedEnt).RootPart.EveryoneMask;
  684. item.inventoryBasePermissions = ((SceneObjectGroup) selectedEnt).RootPart.BaseMask;
  685. item.inventoryCurrentPermissions = ((SceneObjectGroup) selectedEnt).RootPart.OwnerMask;
  686. userInfo.AddItem(remoteClient.AgentId, item);
  687. remoteClient.SendInventoryItemCreateUpdate(item);
  688. }
  689. DeleteSceneObjectGroup((SceneObjectGroup) selectedEnt);
  690. }
  691. }
  692. }
  693. }
  694. }
  695. public void DeleteSceneObjectGroup(SceneObjectGroup group)
  696. {
  697. SceneObjectPart rootPart = (group).GetChildPart(group.UUID);
  698. if (rootPart.PhysActor != null)
  699. {
  700. PhysicsScene.RemovePrim(rootPart.PhysActor);
  701. rootPart.PhysActor = null;
  702. }
  703. m_storageManager.DataStore.RemoveObject(group.UUID, m_regInfo.RegionID);
  704. group.DeleteGroup();
  705. lock (Entities)
  706. {
  707. Entities.Remove(group.UUID);
  708. m_innerScene.RemoveAPrimCount();
  709. }
  710. group.DeleteParts();
  711. }
  712. public virtual void RezObject(IClientAPI remoteClient, LLUUID itemID, LLVector3 RayEnd, LLVector3 RayStart,
  713. LLUUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
  714. uint EveryoneMask, uint GroupMask, uint NextOwnerMask, uint ItemFlags,
  715. bool RezSelected, bool RemoveItem, LLUUID fromTaskID)
  716. {
  717. byte bRayEndIsIntersection = (byte)0;
  718. if (RayEndIsIntersection)
  719. {
  720. bRayEndIsIntersection = (byte)1;
  721. }
  722. else
  723. {
  724. bRayEndIsIntersection = (byte)0;
  725. }
  726. LLVector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, new LLQuaternion(0, 0, 0, 1), BypassRayCast, bRayEndIsIntersection);
  727. RezObject(remoteClient, itemID, pos);
  728. }
  729. public virtual void RezObject(IClientAPI remoteClient, LLUUID itemID, LLVector3 pos)
  730. {
  731. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  732. if (userInfo != null)
  733. {
  734. if (userInfo.RootFolder != null)
  735. {
  736. InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
  737. if (item != null)
  738. {
  739. AssetBase rezAsset = AssetCache.GetAsset(item.assetID, false);
  740. if (rezAsset != null)
  741. {
  742. AddRezObject(Helpers.FieldToUTF8String(rezAsset.Data), pos);
  743. //userInfo.DeleteItem(remoteClient.AgentId, item);
  744. //remoteClient.SendRemoveInventoryItem(itemID);
  745. }
  746. }
  747. }
  748. }
  749. }
  750. protected void ObjectAttach(IClientAPI remoteClient, uint localID, LLQuaternion rotation, byte attachPoint)
  751. {
  752. System.Console.WriteLine("Attaching object " + localID + " to " + attachPoint);
  753. SceneObjectPart p = GetSceneObjectPart(localID);
  754. ScenePresence av = null;
  755. if (TryGetAvatar(remoteClient.AgentId, out av))
  756. {
  757. p.AttachToAvatar(remoteClient.AgentId, av, attachPoint, rotation, m_regInfo);
  758. }
  759. }
  760. protected void ObjectDetach(IClientAPI remoteClient, uint localID)
  761. {
  762. ScenePresence av = null;
  763. if (TryGetAvatar(remoteClient.AgentId, out av))
  764. {
  765. SceneObjectPart p = GetSceneObjectPart(localID);
  766. //Place the object in front of the avatar
  767. Vector3 vecDir = new Vector3(1, 0, 0);
  768. float dist = p.Scale.X + 0.1f;
  769. vecDir = (av.Rotation * vecDir) * dist;
  770. p.ParentGroup.AbsolutePosition = av.AbsolutePosition + new LLVector3(vecDir.x, vecDir.y, vecDir.z);
  771. p.RotationOffset = new LLQuaternion(av.Rotation.x, av.Rotation.y, av.Rotation.z, av.Rotation.w);
  772. p.Detach();
  773. }
  774. else
  775. {
  776. // MainLog.Instance.Warn("SCENE", "Object detach - Unable to find avatar " + remoteClient.FirstName + " " + remoteClient.LastName);
  777. }
  778. }
  779. protected void SingleAttachmentFromInv(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID,
  780. uint itemFlags, byte attachPoint)
  781. {
  782. // MainLog.Instance.Verbose("SCENE", "SingleAttachmentFromInv for " + remoteClient.FirstName + " " + remoteClient.LastName + ": " +
  783. // "itemID=" + itemID + " ownerID=" + ownerID + " itemFlags=" + itemFlags +
  784. // "attachPoint=" + attachPoint);
  785. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  786. if (userInfo != null)
  787. {
  788. if (userInfo.RootFolder != null)
  789. {
  790. InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
  791. if (item != null)
  792. {
  793. AssetBase rezAsset = AssetCache.GetAsset(item.assetID, false);
  794. if (rezAsset != null)
  795. {
  796. // MainLog.Instance.Verbose("SCENE", "Adding inventory item to scene");
  797. ScenePresence presence = GetScenePresence(remoteClient.AgentId);
  798. SceneObjectGroup group = new SceneObjectGroup(this, m_regionHandle, Helpers.FieldToUTF8String(rezAsset.Data));
  799. group.RegenerateFullIDs();
  800. AddEntity(group);
  801. group.AbsolutePosition = presence.AbsolutePosition;
  802. SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  803. rootPart.RotationOffset = new LLQuaternion(presence.Rotation.x, presence.Rotation.y, presence.Rotation.z, presence.Rotation.w);
  804. // MainLog.Instance.Verbose("SCENE", "Attaching it to a scene presence");
  805. rootPart.AttachToAvatar(remoteClient.AgentId, presence, attachPoint, new LLQuaternion(0, 0, 0, 1), m_regInfo);
  806. }
  807. }
  808. else
  809. {
  810. //MainLog.Instance.Warn("SCENE", "RezAttach - Item not found from folder");
  811. }
  812. }
  813. else
  814. {
  815. //MainLog.Instance.Warn("SCENE", "RezAttach - No root folder found");
  816. }
  817. }
  818. else
  819. {
  820. //MainLog.Instance.Warn("SCENE", "RezAttach - Unable to get userInfo for " + remoteClient.FirstName + " " + remoteClient.LastName);
  821. }
  822. }
  823. private void AddRezObject(string xmlData, LLVector3 pos)
  824. {
  825. SceneObjectGroup group = new SceneObjectGroup(this, m_regionHandle, xmlData);
  826. group.ResetIDs();
  827. AddEntity(group);
  828. group.AbsolutePosition = pos;
  829. SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  830. rootPart.TrimPermissions();
  831. group.ApplyPhysics(m_physicalPrim);
  832. group.StartScripts();
  833. //bool UsePhysics = (((rootPart.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) > 0)&& m_physicalPrim);
  834. //if ((rootPart.ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0)
  835. //{
  836. //PrimitiveBaseShape pbs = rootPart.Shape;
  837. //rootPart.PhysActor = PhysicsScene.AddPrimShape(
  838. //rootPart.Name,
  839. //pbs,
  840. //new PhysicsVector(rootPart.AbsolutePosition.X, rootPart.AbsolutePosition.Y,
  841. // rootPart.AbsolutePosition.Z),
  842. //new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z),
  843. //new Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X,
  844. // rootPart.RotationOffset.Y, rootPart.RotationOffset.Z), UsePhysics);
  845. // rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
  846. // }
  847. //
  848. rootPart.ScheduleFullUpdate();
  849. }
  850. }
  851. }