Scene.Inventory.cs 110 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657
  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. using System;
  28. using System.Collections.Generic;
  29. using System.Reflection;
  30. using System.Text;
  31. using System.Timers;
  32. using OpenMetaverse;
  33. using OpenMetaverse.Packets;
  34. using log4net;
  35. using OpenSim.Framework;
  36. using OpenSim.Framework.Communications.Cache;
  37. using OpenSim.Region.Interfaces;
  38. using OpenSim.Region.Environment.Interfaces;
  39. namespace OpenSim.Region.Environment.Scenes
  40. {
  41. public partial class Scene
  42. {
  43. private static readonly ILog m_log
  44. = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  45. /// <summary>
  46. /// Allows asynchronous derezzing of objects from the scene into a client's inventory.
  47. /// </summary>
  48. protected AsyncSceneObjectGroupDeleter m_asyncSceneObjectDeleter;
  49. /// <summary>
  50. /// Start all the scripts in the scene which should be started.
  51. /// </summary>
  52. public void CreateScriptInstances()
  53. {
  54. m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
  55. foreach (EntityBase group in Entities)
  56. {
  57. if (group is SceneObjectGroup)
  58. {
  59. ((SceneObjectGroup)group).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
  60. }
  61. }
  62. }
  63. public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
  64. {
  65. IMoneyModule money = RequestModuleInterface<IMoneyModule>();
  66. if (money != null)
  67. {
  68. money.ApplyUploadCharge(agentID);
  69. }
  70. AddInventoryItem(agentID, item);
  71. }
  72. public bool AddInventoryItemReturned(UUID AgentId, InventoryItemBase item)
  73. {
  74. CachedUserInfo userInfo
  75. = CommsManager.UserProfileCacheService.GetUserDetails(AgentId);
  76. if (userInfo != null)
  77. {
  78. userInfo.AddItem(item);
  79. return true;
  80. }
  81. else
  82. {
  83. m_log.ErrorFormat(
  84. "[AGENT INVENTORY]: Agent was not found for add of item {1} {2}", item.Name, item.ID);
  85. return false;
  86. }
  87. }
  88. public void AddInventoryItem(UUID AgentID, InventoryItemBase item)
  89. {
  90. CachedUserInfo userInfo
  91. = CommsManager.UserProfileCacheService.GetUserDetails(AgentID);
  92. if (userInfo != null)
  93. {
  94. userInfo.AddItem(item);
  95. int userlevel = 0;
  96. if (Permissions.IsGod(AgentID))
  97. {
  98. userlevel = 1;
  99. }
  100. // TODO: remove this cruft once MasterAvatar is fully deprecated
  101. //
  102. if (m_regInfo.MasterAvatarAssignedUUID == AgentID)
  103. {
  104. userlevel = 2;
  105. }
  106. EventManager.TriggerOnNewInventoryItemUploadComplete(AgentID, item.AssetID, item.Name, userlevel);
  107. }
  108. else
  109. {
  110. m_log.ErrorFormat(
  111. "[AGENT INVENTORY]: Agent {1} was not found for add of item {2} {3}",
  112. AgentID, item.Name, item.ID);
  113. return;
  114. }
  115. }
  116. /// <summary>
  117. /// Add an inventory item to an avatar's inventory.
  118. /// </summary>
  119. /// <param name="remoteClient">The remote client controlling the avatar</param>
  120. /// <param name="item">The item. This structure contains all the item metadata, including the folder
  121. /// in which the item is to be placed.</param>
  122. public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
  123. {
  124. CachedUserInfo userInfo
  125. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  126. if (userInfo != null)
  127. {
  128. AddInventoryItem(remoteClient.AgentId, item);
  129. remoteClient.SendInventoryItemCreateUpdate(item);
  130. }
  131. else
  132. {
  133. m_log.ErrorFormat(
  134. "[AGENT INVENTORY]: Could not resolve user {0} for adding an inventory item",
  135. remoteClient.AgentId);
  136. }
  137. }
  138. /// <summary>
  139. /// Capability originating call to update the asset of an item in an agent's inventory
  140. /// </summary>
  141. /// <param name="remoteClient"></param>
  142. /// <param name="itemID"></param>
  143. /// <param name="data"></param>
  144. /// <returns></returns>
  145. public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
  146. {
  147. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  148. if (userInfo != null)
  149. {
  150. if (userInfo.RootFolder != null)
  151. {
  152. InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
  153. if (item != null)
  154. {
  155. if ((InventoryType)item.InvType == InventoryType.Notecard)
  156. {
  157. if (!Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId))
  158. {
  159. remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
  160. return UUID.Zero;
  161. }
  162. remoteClient.SendAgentAlertMessage("Notecard saved", false);
  163. }
  164. else if ((InventoryType)item.InvType == InventoryType.LSL)
  165. {
  166. if (!Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
  167. {
  168. remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
  169. return UUID.Zero;
  170. }
  171. remoteClient.SendAgentAlertMessage("Script saved", false);
  172. }
  173. AssetBase asset =
  174. CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data);
  175. AssetCache.AddAsset(asset);
  176. item.AssetID = asset.FullID;
  177. userInfo.UpdateItem(item);
  178. // remoteClient.SendInventoryItemCreateUpdate(item);
  179. return (asset.FullID);
  180. }
  181. }
  182. }
  183. else
  184. {
  185. m_log.ErrorFormat(
  186. "[AGENT INVENTORY]: Could not resolve user {0} for caps inventory update",
  187. remoteClient.AgentId);
  188. }
  189. return UUID.Zero;
  190. }
  191. /// <summary>
  192. /// <see>CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])</see>
  193. /// </summary>
  194. private UUID CapsUpdateInventoryItemAsset(UUID avatarId, UUID itemID, byte[] data)
  195. {
  196. ScenePresence avatar;
  197. if (TryGetAvatar(avatarId, out avatar))
  198. {
  199. return CapsUpdateInventoryItemAsset(avatar.ControllingClient, itemID, data);
  200. }
  201. else
  202. {
  203. m_log.ErrorFormat(
  204. "[AGENT INVENTORY]: " +
  205. "Avatar {0} cannot be found to update its inventory item asset",
  206. avatarId);
  207. }
  208. return UUID.Zero;
  209. }
  210. /// <summary>
  211. /// Capability originating call to update the asset of a script in a prim's (task's) inventory
  212. /// </summary>
  213. /// <param name="remoteClient"></param>
  214. /// <param name="itemID"></param>
  215. /// <param name="primID">The prim which contains the item to update</param>
  216. /// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
  217. /// <param name="data"></param>
  218. public void CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId,
  219. UUID primId, bool isScriptRunning, byte[] data)
  220. {
  221. if (!Permissions.CanEditScript(itemId, primId, remoteClient.AgentId))
  222. {
  223. remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
  224. return;
  225. }
  226. // Retrieve group
  227. SceneObjectPart part = GetSceneObjectPart(primId);
  228. SceneObjectGroup group = part.ParentGroup;
  229. if (null == group)
  230. {
  231. m_log.ErrorFormat(
  232. "[PRIM INVENTORY]: " +
  233. "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
  234. itemId, primId);
  235. return;
  236. }
  237. // Retrieve item
  238. TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId);
  239. if (null == item)
  240. {
  241. m_log.ErrorFormat(
  242. "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for caps script update "
  243. + " but the item does not exist in this inventory",
  244. itemId, part.Name, part.UUID);
  245. return;
  246. }
  247. AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data);
  248. AssetCache.AddAsset(asset);
  249. if (isScriptRunning)
  250. {
  251. part.Inventory.RemoveScriptInstance(item.ItemID);
  252. }
  253. // Update item with new asset
  254. item.AssetID = asset.FullID;
  255. group.UpdateInventoryItem(item);
  256. part.GetProperties(remoteClient);
  257. // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
  258. if (isScriptRunning)
  259. {
  260. // Needs to determine which engine was running it and use that
  261. //
  262. part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0);
  263. }
  264. else
  265. {
  266. remoteClient.SendAgentAlertMessage("Script saved", false);
  267. }
  268. }
  269. /// <summary>
  270. /// <see>CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[])</see>
  271. /// </summary>
  272. private void CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId,
  273. UUID primId, bool isScriptRunning, byte[] data)
  274. {
  275. ScenePresence avatar;
  276. if (TryGetAvatar(avatarId, out avatar))
  277. {
  278. CapsUpdateTaskInventoryScriptAsset(
  279. avatar.ControllingClient, itemId, primId, isScriptRunning, data);
  280. }
  281. else
  282. {
  283. m_log.ErrorFormat(
  284. "[PRIM INVENTORY]: " +
  285. "Avatar {0} cannot be found to update its prim item asset",
  286. avatarId);
  287. }
  288. }
  289. /// <summary>
  290. /// Update an item which is either already in the client's inventory or is within
  291. /// a transaction
  292. /// </summary>
  293. /// <param name="remoteClient"></param>
  294. /// <param name="transactionID">The transaction ID. If this is UUID.Zero we will
  295. /// assume that we are not in a transaction</param>
  296. /// <param name="itemID">The ID of the updated item</param>
  297. /// <param name="name">The name of the updated item</param>
  298. /// <param name="description">The description of the updated item</param>
  299. /// <param name="nextOwnerMask">The permissions of the updated item</param>
  300. /* public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
  301. UUID itemID, string name, string description,
  302. uint nextOwnerMask)*/
  303. public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
  304. UUID itemID, InventoryItemBase itemUpd)
  305. {
  306. CachedUserInfo userInfo
  307. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  308. if (userInfo != null && userInfo.RootFolder != null)
  309. {
  310. InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
  311. if (item != null)
  312. {
  313. if (UUID.Zero == transactionID)
  314. {
  315. item.Name = itemUpd.Name;
  316. item.Description = itemUpd.Description;
  317. item.NextPermissions = itemUpd.NextPermissions;
  318. item.CurrentPermissions |= 8; // Slam!
  319. item.EveryOnePermissions = itemUpd.EveryOnePermissions;
  320. item.GroupPermissions = itemUpd.GroupPermissions;
  321. item.GroupID = itemUpd.GroupID;
  322. item.GroupOwned = itemUpd.GroupOwned;
  323. item.CreationDate = itemUpd.CreationDate;
  324. // The client sends zero if its newly created?
  325. if (itemUpd.CreationDate == 0)
  326. item.CreationDate = Util.UnixTimeSinceEpoch();
  327. else
  328. item.CreationDate = itemUpd.CreationDate;
  329. // TODO: Check if folder changed and move item
  330. //item.NextPermissions = itemUpd.Folder;
  331. item.InvType = itemUpd.InvType;
  332. item.SalePrice = itemUpd.SalePrice;
  333. item.SaleType = itemUpd.SaleType;
  334. item.Flags = itemUpd.Flags;
  335. userInfo.UpdateItem(item);
  336. }
  337. else
  338. {
  339. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  340. if (agentTransactions != null)
  341. {
  342. agentTransactions.HandleItemUpdateFromTransaction(
  343. remoteClient, transactionID, item);
  344. }
  345. }
  346. }
  347. else
  348. {
  349. m_log.Error(
  350. "[AGENTINVENTORY]: Item ID " + itemID + " not found for an inventory item update.");
  351. }
  352. }
  353. else
  354. {
  355. m_log.Error(
  356. "[AGENT INVENTORY]: Agent ID " + remoteClient.AgentId + " not found for an inventory item update.");
  357. }
  358. }
  359. /// <summary>
  360. /// Give an inventory item from one user to another
  361. /// </summary>
  362. /// <param name="recipientClient"></param>
  363. /// <param name="senderId">ID of the sender of the item</param>
  364. /// <param name="itemId"></param>
  365. public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId)
  366. {
  367. InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId);
  368. if (itemCopy != null)
  369. recipientClient.SendBulkUpdateInventory(itemCopy);
  370. }
  371. /// <summary>
  372. /// Give an inventory item from one user to another
  373. /// </summary>
  374. /// <param name="recipient"></param>
  375. /// <param name="senderId">ID of the sender of the item</param>
  376. /// <param name="itemId"></param>
  377. /// <returns>The inventory item copy given, null if the give was unsuccessful</returns>
  378. public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId)
  379. {
  380. return GiveInventoryItem(recipient, senderId, itemId, UUID.Zero);
  381. }
  382. /// <summary>
  383. /// Give an inventory item from one user to another
  384. /// </summary>
  385. /// <param name="recipient"></param>
  386. /// <param name="senderId">ID of the sender of the item</param>
  387. /// <param name="itemId"></param>
  388. /// <param name="recipientFolderId">
  389. /// The id of the folder in which the copy item should go. If UUID.Zero then the item is placed in the most
  390. /// appropriate default folder.
  391. /// </param>
  392. /// <returns>
  393. /// The inventory item copy given, null if the give was unsuccessful
  394. /// </returns>
  395. public virtual InventoryItemBase GiveInventoryItem(
  396. UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId)
  397. {
  398. // Retrieve the item from the sender
  399. CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId);
  400. if (senderUserInfo == null)
  401. {
  402. m_log.ErrorFormat(
  403. "[AGENT INVENTORY]: Failed to find sending user {0} for item {1}", senderId, itemId);
  404. return null;
  405. }
  406. if (senderUserInfo.RootFolder != null)
  407. {
  408. InventoryItemBase item = senderUserInfo.RootFolder.FindItem(itemId);
  409. if (item != null)
  410. {
  411. if (!Permissions.BypassPermissions())
  412. {
  413. if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
  414. return null;
  415. }
  416. CachedUserInfo recipientUserInfo
  417. = CommsManager.UserProfileCacheService.GetUserDetails(recipient);
  418. if (recipientUserInfo != null)
  419. {
  420. if (!recipientUserInfo.HasReceivedInventory)
  421. CommsManager.UserProfileCacheService.RequestInventoryForUser(recipient);
  422. // Insert a copy of the item into the recipient
  423. InventoryItemBase itemCopy = new InventoryItemBase();
  424. itemCopy.Owner = recipient;
  425. itemCopy.Creator = item.Creator;
  426. itemCopy.ID = UUID.Random();
  427. itemCopy.AssetID = item.AssetID;
  428. itemCopy.Description = item.Description;
  429. itemCopy.Name = item.Name;
  430. itemCopy.AssetType = item.AssetType;
  431. itemCopy.InvType = item.InvType;
  432. itemCopy.Folder = recipientFolderId;
  433. if (Permissions.PropagatePermissions())
  434. {
  435. if (item.InvType == 6)
  436. {
  437. itemCopy.BasePermissions &= ~(uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
  438. itemCopy.BasePermissions |= (item.CurrentPermissions & 7) << 13;
  439. }
  440. else
  441. {
  442. itemCopy.BasePermissions = item.BasePermissions & item.NextPermissions;
  443. }
  444. itemCopy.CurrentPermissions = itemCopy.BasePermissions;
  445. if ((item.CurrentPermissions & 8) != 0) // Propagate slam bit
  446. {
  447. itemCopy.BasePermissions &= item.NextPermissions;
  448. itemCopy.CurrentPermissions = itemCopy.BasePermissions;
  449. itemCopy.CurrentPermissions |= 8;
  450. }
  451. itemCopy.NextPermissions = item.NextPermissions;
  452. itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
  453. itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
  454. }
  455. else
  456. {
  457. itemCopy.CurrentPermissions = item.CurrentPermissions;
  458. itemCopy.NextPermissions = item.NextPermissions;
  459. itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
  460. itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
  461. itemCopy.BasePermissions = item.BasePermissions;
  462. }
  463. itemCopy.GroupID = UUID.Zero;
  464. itemCopy.GroupOwned = false;
  465. itemCopy.Flags = item.Flags;
  466. itemCopy.SalePrice = item.SalePrice;
  467. itemCopy.SaleType = item.SaleType;
  468. itemCopy.CreationDate = item.CreationDate;
  469. recipientUserInfo.AddItem(itemCopy);
  470. if (!Permissions.BypassPermissions())
  471. {
  472. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  473. senderUserInfo.DeleteItem(itemId);
  474. }
  475. return itemCopy;
  476. }
  477. else
  478. {
  479. m_log.ErrorFormat(
  480. "[AGENT INVENTORY]: Could not find userinfo for recipient user {0} of item {1}, {2} from {3}",
  481. recipient, item.Name,
  482. item.ID, senderId);
  483. }
  484. }
  485. else
  486. {
  487. m_log.ErrorFormat(
  488. "[AGENT INVENTORY]: Failed to find item {0} to give to {1}", itemId, senderId);
  489. return null;
  490. }
  491. }
  492. else
  493. {
  494. m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemId.ToString() + ", no root folder");
  495. return null;
  496. }
  497. return null;
  498. }
  499. /// <summary>
  500. /// Give an entire inventory folder from one user to another. The entire contents (including all descendent
  501. /// folders) is given.
  502. /// </summary>
  503. /// <param name="recipientId"></param>
  504. /// <param name="senderId">ID of the sender of the item</param>
  505. /// <param name="folderId"></param>
  506. /// <param name="recipientParentFolderId">
  507. /// The id of the receipient folder in which the send folder should be placed. If UUID.Zero then the
  508. /// recipient folder is the root folder
  509. /// </param>
  510. /// <returns>
  511. /// The inventory folder copy given, null if the copy was unsuccessful
  512. /// </returns>
  513. public virtual InventoryFolderImpl GiveInventoryFolder(
  514. UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId)
  515. {
  516. // Retrieve the folder from the sender
  517. CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId);
  518. if (null == senderUserInfo)
  519. {
  520. m_log.ErrorFormat(
  521. "[AGENT INVENTORY]: Failed to find sending user {0} for folder {1}", senderId, folderId);
  522. return null;
  523. }
  524. if (!senderUserInfo.HasReceivedInventory)
  525. {
  526. m_log.DebugFormat(
  527. "[AGENT INVENTORY]: Could not give inventory folder - have not yet received inventory for {0}",
  528. senderId);
  529. return null;
  530. }
  531. InventoryFolderImpl folder = senderUserInfo.RootFolder.FindFolder(folderId);
  532. if (null == folder)
  533. {
  534. m_log.ErrorFormat(
  535. "[AGENT INVENTORY]: Could not find inventory folder {0} to give", folderId);
  536. return null;
  537. }
  538. CachedUserInfo recipientUserInfo
  539. = CommsManager.UserProfileCacheService.GetUserDetails(recipientId);
  540. if (null == recipientUserInfo)
  541. {
  542. m_log.ErrorFormat(
  543. "[AGENT INVENTORY]: Failed to find receiving user {0} for folder {1}", recipientId, folderId);
  544. return null;
  545. }
  546. if (recipientParentFolderId == UUID.Zero)
  547. recipientParentFolderId = recipientUserInfo.RootFolder.ID;
  548. UUID newFolderId = UUID.Random();
  549. recipientUserInfo.CreateFolder(folder.Name, newFolderId, (ushort)folder.Type, recipientParentFolderId);
  550. // XXX: Messy - we should really get this back in the CreateFolder call
  551. InventoryFolderImpl copiedFolder = recipientUserInfo.RootFolder.FindFolder(newFolderId);
  552. // Give all the subfolders
  553. List<InventoryFolderImpl> subFolders = folder.RequestListOfFolderImpls();
  554. foreach (InventoryFolderImpl childFolder in subFolders)
  555. {
  556. GiveInventoryFolder(recipientId, senderId, childFolder.ID, copiedFolder.ID);
  557. }
  558. // Give all the items
  559. List<InventoryItemBase> items = folder.RequestListOfItems();
  560. foreach (InventoryItemBase item in items)
  561. {
  562. GiveInventoryItem(recipientId, senderId, item.ID, copiedFolder.ID);
  563. }
  564. return copiedFolder;
  565. }
  566. public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID,
  567. UUID newFolderID, string newName)
  568. {
  569. m_log.DebugFormat(
  570. "[AGENT INVENTORY]: CopyInventoryItem received by {0} with oldAgentID {1}, oldItemID {2}, new FolderID {3}, newName {4}",
  571. remoteClient.AgentId, oldAgentID, oldItemID, newFolderID, newName);
  572. InventoryItemBase item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(oldItemID);
  573. if (item == null)
  574. {
  575. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(oldAgentID);
  576. if (userInfo == null)
  577. {
  578. m_log.Error("[AGENT INVENTORY]: Failed to find user " + oldAgentID.ToString());
  579. return;
  580. }
  581. if (userInfo.RootFolder != null)
  582. {
  583. item = userInfo.RootFolder.FindItem(oldItemID);
  584. if (item == null)
  585. {
  586. m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString());
  587. return;
  588. }
  589. }
  590. else
  591. {
  592. m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString());
  593. return;
  594. }
  595. }
  596. AssetBase asset
  597. = AssetCache.GetAsset(
  598. item.AssetID, (item.AssetType == (int)AssetType.Texture ? true : false));
  599. if (asset != null)
  600. {
  601. if (newName != String.Empty)
  602. {
  603. asset.Name = newName;
  604. }
  605. else
  606. {
  607. newName = item.Name;
  608. }
  609. if (remoteClient.AgentId == oldAgentID)
  610. {
  611. CreateNewInventoryItem(
  612. remoteClient, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
  613. item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
  614. }
  615. else
  616. {
  617. CreateNewInventoryItem(
  618. remoteClient, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
  619. item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
  620. }
  621. }
  622. else
  623. {
  624. m_log.ErrorFormat(
  625. "[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found",
  626. item.Name, item.AssetID);
  627. }
  628. }
  629. /// <summary>
  630. /// Create a new asset data structure.
  631. /// </summary>
  632. /// <param name="name"></param>
  633. /// <param name="description"></param>
  634. /// <param name="invType"></param>
  635. /// <param name="assetType"></param>
  636. /// <param name="data"></param>
  637. /// <returns></returns>
  638. private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data)
  639. {
  640. AssetBase asset = new AssetBase();
  641. asset.Name = name;
  642. asset.Description = description;
  643. asset.Type = assetType;
  644. asset.FullID = UUID.Random();
  645. asset.Data = (data == null) ? new byte[1] : data;
  646. return asset;
  647. }
  648. /// <summary>
  649. /// Move an item within the agent's inventory.
  650. /// </summary>
  651. /// <param name="remoteClient"></param>
  652. /// <param name="folderID"></param>
  653. /// <param name="itemID"></param>
  654. /// <param name="length"></param>
  655. /// <param name="newName"></param>
  656. public void MoveInventoryItem(IClientAPI remoteClient, UUID folderID, UUID itemID, int length,
  657. string newName)
  658. {
  659. m_log.DebugFormat(
  660. "[AGENT INVENTORY]: Moving item {0} to {1} for {2}", itemID, folderID, remoteClient.AgentId);
  661. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  662. if (userInfo == null)
  663. {
  664. m_log.Error("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
  665. return;
  666. }
  667. if (userInfo.RootFolder != null)
  668. {
  669. InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
  670. if (item != null)
  671. {
  672. if (newName != String.Empty)
  673. {
  674. item.Name = newName;
  675. }
  676. item.Folder = folderID;
  677. userInfo.DeleteItem(item.ID);
  678. AddInventoryItem(remoteClient, item);
  679. }
  680. else
  681. {
  682. m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemID.ToString());
  683. return;
  684. }
  685. }
  686. else
  687. {
  688. m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemID.ToString() + ", no root folder");
  689. return;
  690. }
  691. }
  692. /// <summary>
  693. /// Create a new inventory item.
  694. /// </summary>
  695. /// <param name="remoteClient"></param>
  696. /// <param name="folderID"></param>
  697. /// <param name="callbackID"></param>
  698. /// <param name="asset"></param>
  699. /// <param name="invType"></param>
  700. /// <param name="nextOwnerMask"></param>
  701. private void CreateNewInventoryItem(IClientAPI remoteClient, UUID folderID, string name, uint flags, uint callbackID,
  702. AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
  703. {
  704. CreateNewInventoryItem(
  705. remoteClient, folderID, name, flags, callbackID, asset, invType,
  706. (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate);
  707. }
  708. /// <summary>
  709. /// Create a new Inventory Item
  710. /// </summary>
  711. /// <param name="remoteClient"></param>
  712. /// <param name="folderID"></param>
  713. /// <param name="callbackID"></param>
  714. /// <param name="asset"></param>
  715. /// <param name="invType"></param>
  716. /// <param name="nextOwnerMask"></param>
  717. /// <param name="creationDate"></param>
  718. private void CreateNewInventoryItem(
  719. IClientAPI remoteClient, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType,
  720. uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
  721. {
  722. CachedUserInfo userInfo
  723. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  724. if (userInfo != null)
  725. {
  726. InventoryItemBase item = new InventoryItemBase();
  727. item.Owner = remoteClient.AgentId;
  728. item.Creator = remoteClient.AgentId;
  729. item.ID = UUID.Random();
  730. item.AssetID = asset.FullID;
  731. item.Description = asset.Description;
  732. item.Name = name;
  733. item.Flags = flags;
  734. item.AssetType = asset.Type;
  735. item.InvType = invType;
  736. item.Folder = folderID;
  737. item.CurrentPermissions = currentMask;
  738. item.NextPermissions = nextOwnerMask;
  739. item.EveryOnePermissions = everyoneMask;
  740. item.GroupPermissions = groupMask;
  741. item.BasePermissions = baseMask;
  742. item.CreationDate = creationDate;
  743. userInfo.AddItem(item);
  744. remoteClient.SendInventoryItemCreateUpdate(item);
  745. }
  746. else
  747. {
  748. m_log.WarnFormat(
  749. "No user details associated with client {0} uuid {1} in CreateNewInventoryItem!",
  750. remoteClient.Name, remoteClient.AgentId);
  751. }
  752. }
  753. /// <summary>
  754. /// Create a new inventory item. Called when the client creates a new item directly within their
  755. /// inventory (e.g. by selecting a context inventory menu option).
  756. /// </summary>
  757. /// <param name="remoteClient"></param>
  758. /// <param name="transactionID"></param>
  759. /// <param name="folderID"></param>
  760. /// <param name="callbackID"></param>
  761. /// <param name="description"></param>
  762. /// <param name="name"></param>
  763. /// <param name="invType"></param>
  764. /// <param name="type"></param>
  765. /// <param name="wearableType"></param>
  766. /// <param name="nextOwnerMask"></param>
  767. public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
  768. uint callbackID, string description, string name, sbyte invType,
  769. sbyte assetType,
  770. byte wearableType, uint nextOwnerMask, int creationDate)
  771. {
  772. m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
  773. if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
  774. return;
  775. if (transactionID == UUID.Zero)
  776. {
  777. CachedUserInfo userInfo
  778. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  779. if (userInfo != null)
  780. {
  781. ScenePresence presence;
  782. TryGetAvatar(remoteClient.AgentId, out presence);
  783. byte[] data = null;
  784. if (invType == 3 && presence != null) // OpenMetaverse.asset.assettype.landmark = 3 - needs to be turned into an enum
  785. {
  786. Vector3 pos = presence.AbsolutePosition;
  787. string strdata = String.Format(
  788. "Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
  789. presence.Scene.RegionInfo.RegionID,
  790. pos.X, pos.Y, pos.Z,
  791. presence.RegionHandle);
  792. data = Encoding.ASCII.GetBytes(strdata);
  793. }
  794. AssetBase asset = CreateAsset(name, description, assetType, data);
  795. AssetCache.AddAsset(asset);
  796. CreateNewInventoryItem(remoteClient, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
  797. }
  798. else
  799. {
  800. m_log.ErrorFormat(
  801. "userInfo for agent uuid {0} unexpectedly null in CreateNewInventoryItem",
  802. remoteClient.AgentId);
  803. }
  804. }
  805. else
  806. {
  807. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  808. if (agentTransactions != null)
  809. {
  810. agentTransactions.HandleItemCreationFromTransaction(
  811. remoteClient, transactionID, folderID, callbackID, description,
  812. name, invType, assetType, wearableType, nextOwnerMask);
  813. }
  814. }
  815. }
  816. /// <summary>
  817. /// Remove an inventory item for the client's inventory
  818. /// </summary>
  819. /// <param name="remoteClient"></param>
  820. /// <param name="itemID"></param>
  821. private void RemoveInventoryItem(IClientAPI remoteClient, UUID itemID)
  822. {
  823. CachedUserInfo userInfo
  824. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  825. if (userInfo == null)
  826. {
  827. m_log.WarnFormat(
  828. "[AGENT INVENTORY]: Failed to find user {0} {1} to delete inventory item {2}",
  829. remoteClient.Name, remoteClient.AgentId, itemID);
  830. return;
  831. }
  832. userInfo.DeleteItem(itemID);
  833. }
  834. /// <summary>
  835. /// Removes an inventory folder. Although there is a packet in the Linden protocol for this, it may be
  836. /// legacy and not currently used (purge folder is used to remove folders from trash instead).
  837. /// </summary>
  838. /// <param name="remoteClient"></param>
  839. /// <param name="folderID"></param>
  840. private void RemoveInventoryFolder(IClientAPI remoteClient, UUID folderID)
  841. {
  842. CachedUserInfo userInfo
  843. = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  844. if (userInfo == null)
  845. {
  846. m_log.Warn("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
  847. return;
  848. }
  849. if (userInfo.RootFolder != null)
  850. {
  851. InventoryItemBase folder = userInfo.RootFolder.FindItem(folderID);
  852. if (folder != null)
  853. {
  854. m_log.WarnFormat(
  855. "[AGENT INVENTORY]: Remove folder not implemented in request by {0} {1} for {2}",
  856. remoteClient.Name, remoteClient.AgentId, folderID);
  857. // doesn't work just yet, commented out. will fix in next patch.
  858. // userInfo.DeleteItem(folder);
  859. }
  860. }
  861. }
  862. private SceneObjectGroup GetGroupByPrim(uint localID)
  863. {
  864. List<EntityBase> EntityList = GetEntities();
  865. foreach (EntityBase ent in EntityList)
  866. {
  867. if (ent is SceneObjectGroup)
  868. {
  869. if (((SceneObjectGroup)ent).HasChildPrim(localID))
  870. return (SceneObjectGroup)ent;
  871. }
  872. }
  873. return null;
  874. }
  875. /// <summary>
  876. /// Send the details of a prim's inventory to the client.
  877. /// </summary>
  878. /// <param name="remoteClient"></param>
  879. /// <param name="primLocalID"></param>
  880. public void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID)
  881. {
  882. SceneObjectGroup group = GetGroupByPrim(primLocalID);
  883. if (group != null)
  884. {
  885. bool fileChange = group.GetPartInventoryFileName(remoteClient, primLocalID);
  886. if (fileChange)
  887. {
  888. if (XferManager != null)
  889. {
  890. group.RequestInventoryFile(remoteClient, primLocalID, XferManager);
  891. }
  892. }
  893. }
  894. else
  895. {
  896. m_log.ErrorFormat(
  897. "[PRIM INVENTORY]: Inventory requested of prim {0} which doesn't exist", primLocalID);
  898. }
  899. }
  900. /// <summary>
  901. /// Remove an item from a prim (task) inventory
  902. /// </summary>
  903. /// <param name="remoteClient">Unused at the moment but retained since the avatar ID might
  904. /// be necessary for a permissions check at some stage.</param>
  905. /// <param name="itemID"></param>
  906. /// <param name="localID"></param>
  907. public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
  908. {
  909. SceneObjectPart part = GetSceneObjectPart(localID);
  910. SceneObjectGroup group = part.ParentGroup;
  911. if (group != null)
  912. {
  913. TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
  914. if (item == null)
  915. return;
  916. if (item.Type == 10)
  917. {
  918. EventManager.TriggerRemoveScript(localID, itemID);
  919. }
  920. group.RemoveInventoryItem(localID, itemID);
  921. part.GetProperties(remoteClient);
  922. }
  923. else
  924. {
  925. m_log.ErrorFormat(
  926. "[PRIM INVENTORY]: " +
  927. "Removal of item {0} requested of prim {1} but this prim does not exist",
  928. itemID,
  929. localID);
  930. }
  931. }
  932. private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
  933. {
  934. TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
  935. if (null == taskItem)
  936. {
  937. m_log.ErrorFormat(
  938. "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for creating an avatar"
  939. + " inventory item from a prim's inventory item "
  940. + " but the required item does not exist in the prim's inventory",
  941. itemId, part.Name, part.UUID);
  942. return null;
  943. }
  944. if ((destAgent != taskItem.OwnerID) && ((taskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
  945. {
  946. return null;
  947. }
  948. InventoryItemBase agentItem = new InventoryItemBase();
  949. agentItem.ID = UUID.Random();
  950. agentItem.Creator = taskItem.CreatorID;
  951. agentItem.Owner = destAgent;
  952. agentItem.AssetID = taskItem.AssetID;
  953. agentItem.Description = taskItem.Description;
  954. agentItem.Name = taskItem.Name;
  955. agentItem.AssetType = taskItem.Type;
  956. agentItem.InvType = taskItem.InvType;
  957. agentItem.Flags = taskItem.Flags;
  958. if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions())
  959. {
  960. if (taskItem.InvType == 6)
  961. agentItem.BasePermissions = taskItem.BasePermissions & ((taskItem.CurrentPermissions & 7) << 13);
  962. else
  963. agentItem.BasePermissions = taskItem.BasePermissions;
  964. agentItem.BasePermissions &= taskItem.NextPermissions;
  965. agentItem.CurrentPermissions = agentItem.BasePermissions | 8;
  966. agentItem.NextPermissions = taskItem.NextPermissions;
  967. agentItem.EveryOnePermissions = taskItem.EveryonePermissions & taskItem.NextPermissions;
  968. agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions;
  969. }
  970. else
  971. {
  972. agentItem.BasePermissions = taskItem.BasePermissions;
  973. agentItem.CurrentPermissions = taskItem.CurrentPermissions;
  974. agentItem.NextPermissions = taskItem.NextPermissions;
  975. agentItem.EveryOnePermissions = taskItem.EveryonePermissions;
  976. agentItem.GroupPermissions = taskItem.GroupPermissions;
  977. }
  978. if (!Permissions.BypassPermissions())
  979. {
  980. if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  981. part.Inventory.RemoveInventoryItem(itemId);
  982. }
  983. return agentItem;
  984. }
  985. /// <summary>
  986. /// Move the given item in the given prim to a folder in the client's inventory
  987. /// </summary>
  988. /// <param name="remoteClient"></param>
  989. /// <param name="folderID"></param>
  990. /// <param name="part"></param>
  991. /// <param name="itemID"></param>
  992. public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId)
  993. {
  994. InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId);
  995. if (agentItem == null)
  996. return null;
  997. agentItem.Folder = folderId;
  998. AddInventoryItem(remoteClient, agentItem);
  999. return agentItem;
  1000. }
  1001. /// <summary>
  1002. /// <see>ClientMoveTaskInventoryItem</see>
  1003. /// </summary>
  1004. /// <param name="remoteClient"></param>
  1005. /// <param name="folderID"></param>
  1006. /// <param name="primLocalID"></param>
  1007. /// <param name="itemID"></param>
  1008. public void ClientMoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, uint primLocalId, UUID itemId)
  1009. {
  1010. SceneObjectPart part = GetSceneObjectPart(primLocalId);
  1011. if (null == part)
  1012. {
  1013. m_log.WarnFormat(
  1014. "[PRIM INVENTORY]: " +
  1015. "Move of inventory item {0} from prim with local id {1} failed because the prim could not be found",
  1016. itemId, primLocalId);
  1017. return;
  1018. }
  1019. TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
  1020. if (null == taskItem)
  1021. {
  1022. m_log.WarnFormat("[PRIM INVENTORY]: Move of inventory item {0} from prim with local id {1} failed"
  1023. + " because the inventory item could not be found",
  1024. itemId, primLocalId);
  1025. return;
  1026. }
  1027. // Only owner can copy
  1028. if (remoteClient.AgentId != taskItem.OwnerID)
  1029. return;
  1030. MoveTaskInventoryItem(remoteClient, folderId, part, itemId);
  1031. }
  1032. /// <summary>
  1033. /// <see>MoveTaskInventoryItem</see>
  1034. /// </summary>
  1035. /// <param name="remoteClient"></param>
  1036. /// <param name="folderID"></param>
  1037. /// <param name="part"></param>
  1038. /// <param name="itemID"></param>
  1039. public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId)
  1040. {
  1041. ScenePresence avatar;
  1042. if (TryGetAvatar(avatarId, out avatar))
  1043. {
  1044. return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId);
  1045. }
  1046. else
  1047. {
  1048. CachedUserInfo profile = CommsManager.UserProfileCacheService.GetUserDetails(avatarId);
  1049. if (profile == null || profile.RootFolder == null)
  1050. {
  1051. m_log.ErrorFormat(
  1052. "[PRIM INVENTORY]: " +
  1053. "Avatar {0} cannot be found to add item",
  1054. avatarId);
  1055. }
  1056. if (!profile.HasReceivedInventory)
  1057. CommsManager.UserProfileCacheService.RequestInventoryForUser(avatarId);
  1058. InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(avatarId, part, itemId);
  1059. if (agentItem == null)
  1060. return null;
  1061. agentItem.Folder = folderId;
  1062. AddInventoryItem(avatarId, agentItem);
  1063. return agentItem;
  1064. }
  1065. }
  1066. /// <summary>
  1067. /// Copy a task (prim) inventory item to another task (prim)
  1068. /// </summary>
  1069. /// <param name="destId"></param>
  1070. /// <param name="part"></param>
  1071. /// <param name="itemId"></param>
  1072. public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId)
  1073. {
  1074. TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId);
  1075. if (srcTaskItem == null)
  1076. {
  1077. m_log.ErrorFormat(
  1078. "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for moving"
  1079. + " but the item does not exist in this inventory",
  1080. itemId, part.Name, part.UUID);
  1081. return;
  1082. }
  1083. SceneObjectPart destPart = GetSceneObjectPart(destId);
  1084. if (destPart == null)
  1085. {
  1086. m_log.ErrorFormat(
  1087. "[PRIM INVENTORY]: " +
  1088. "Could not find prim for ID {0}",
  1089. destId);
  1090. return;
  1091. }
  1092. // Can't transfer this
  1093. //
  1094. if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
  1095. return;
  1096. if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
  1097. {
  1098. // object cannot copy items to an object owned by a different owner
  1099. // unless llAllowInventoryDrop has been called
  1100. return;
  1101. }
  1102. // must have both move and modify permission to put an item in an object
  1103. if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0)
  1104. {
  1105. return;
  1106. }
  1107. TaskInventoryItem destTaskItem = new TaskInventoryItem();
  1108. destTaskItem.ItemID = UUID.Random();
  1109. destTaskItem.CreatorID = srcTaskItem.CreatorID;
  1110. destTaskItem.AssetID = srcTaskItem.AssetID;
  1111. destTaskItem.GroupID = destPart.GroupID;
  1112. destTaskItem.OwnerID = destPart.OwnerID;
  1113. destTaskItem.ParentID = destPart.UUID;
  1114. destTaskItem.ParentPartID = destPart.UUID;
  1115. destTaskItem.BasePermissions = srcTaskItem.BasePermissions;
  1116. destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions;
  1117. destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions;
  1118. destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions;
  1119. destTaskItem.NextPermissions = srcTaskItem.NextPermissions;
  1120. destTaskItem.Flags = srcTaskItem.Flags;
  1121. if (destPart.OwnerID != part.OwnerID)
  1122. {
  1123. if (Permissions.PropagatePermissions())
  1124. {
  1125. destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
  1126. srcTaskItem.NextPermissions;
  1127. destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
  1128. srcTaskItem.NextPermissions;
  1129. destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
  1130. srcTaskItem.NextPermissions;
  1131. destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
  1132. srcTaskItem.NextPermissions;
  1133. destTaskItem.CurrentPermissions |= 8; // Slam!
  1134. }
  1135. }
  1136. destTaskItem.Description = srcTaskItem.Description;
  1137. destTaskItem.Name = srcTaskItem.Name;
  1138. destTaskItem.InvType = srcTaskItem.InvType;
  1139. destTaskItem.Type = srcTaskItem.Type;
  1140. destPart.Inventory.AddInventoryItem(destTaskItem, part.OwnerID != destPart.OwnerID);
  1141. if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  1142. part.Inventory.RemoveInventoryItem(itemId);
  1143. ScenePresence avatar;
  1144. if (TryGetAvatar(srcTaskItem.OwnerID, out avatar))
  1145. {
  1146. destPart.GetProperties(avatar.ControllingClient);
  1147. }
  1148. }
  1149. public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items)
  1150. {
  1151. CachedUserInfo profile = CommsManager.UserProfileCacheService.GetUserDetails(destID);
  1152. if (profile == null || profile.RootFolder == null)
  1153. {
  1154. m_log.ErrorFormat(
  1155. "[PRIM INVENTORY]: " +
  1156. "Avatar {0} cannot be found to add items",
  1157. destID);
  1158. return UUID.Zero;
  1159. }
  1160. UUID newFolderID = UUID.Random();
  1161. profile.CreateFolder(category, newFolderID, 0xffff, profile.RootFolder.ID);
  1162. foreach (UUID itemID in items)
  1163. {
  1164. InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(destID, host, itemID);
  1165. if (agentItem != null)
  1166. {
  1167. agentItem.Folder = newFolderID;
  1168. AddInventoryItem(destID, agentItem);
  1169. }
  1170. }
  1171. ScenePresence avatar;
  1172. if (TryGetAvatar(destID, out avatar))
  1173. {
  1174. profile.SendInventoryDecendents(avatar.ControllingClient,
  1175. profile.RootFolder.ID, true, false);
  1176. profile.SendInventoryDecendents(avatar.ControllingClient,
  1177. newFolderID, false, true);
  1178. }
  1179. return newFolderID;
  1180. }
  1181. /// <summary>
  1182. /// Update an item in a prim (task) inventory.
  1183. /// This method does not handle scripts, <see>RezScript(IClientAPI, UUID, unit)</see>
  1184. /// </summary>
  1185. /// <param name="remoteClient"></param>
  1186. /// <param name="transactionID"></param>
  1187. /// <param name="itemInfo"></param>
  1188. /// <param name="primLocalID"></param>
  1189. public void UpdateTaskInventory(IClientAPI remoteClient, UUID transactionID, TaskInventoryItem itemInfo,
  1190. uint primLocalID)
  1191. {
  1192. UUID itemID = itemInfo.ItemID;
  1193. // Find the prim we're dealing with
  1194. SceneObjectPart part = GetSceneObjectPart(primLocalID);
  1195. if (part != null)
  1196. {
  1197. TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID);
  1198. bool allowInventoryDrop = (part.GetEffectiveObjectFlags()
  1199. & (uint)PrimFlags.AllowInventoryDrop) != 0;
  1200. // Explicity allow anyone to add to the inventory if the
  1201. // AllowInventoryDrop flag has been set. Don't however let
  1202. // them update an item unless they pass the external checks
  1203. //
  1204. if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)
  1205. && (currentItem != null || !allowInventoryDrop))
  1206. return;
  1207. if (currentItem == null)
  1208. {
  1209. UUID copyID = UUID.Random();
  1210. if (itemID != UUID.Zero)
  1211. {
  1212. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  1213. if (userInfo != null && userInfo.RootFolder != null)
  1214. {
  1215. InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
  1216. // Try library
  1217. // XXX clumsy, possibly should be one call
  1218. if (null == item)
  1219. {
  1220. item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID);
  1221. }
  1222. if (item != null)
  1223. {
  1224. part.ParentGroup.AddInventoryItem(remoteClient, primLocalID, item, copyID);
  1225. m_log.InfoFormat(
  1226. "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
  1227. item.Name, primLocalID, remoteClient.Name);
  1228. part.GetProperties(remoteClient);
  1229. if (!Permissions.BypassPermissions())
  1230. {
  1231. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  1232. RemoveInventoryItem(remoteClient, itemID);
  1233. }
  1234. }
  1235. else
  1236. {
  1237. m_log.ErrorFormat(
  1238. "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!",
  1239. itemID, remoteClient.Name);
  1240. }
  1241. }
  1242. }
  1243. }
  1244. else // Updating existing item with new perms etc
  1245. {
  1246. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  1247. if (agentTransactions != null)
  1248. {
  1249. agentTransactions.HandleTaskItemUpdateFromTransaction(
  1250. remoteClient, part, transactionID, currentItem);
  1251. }
  1252. if (part.Inventory.UpdateInventoryItem(itemInfo))
  1253. part.GetProperties(remoteClient);
  1254. }
  1255. }
  1256. else
  1257. {
  1258. m_log.WarnFormat(
  1259. "[PRIM INVENTORY]: " +
  1260. "Update with item {0} requested of prim {1} for {2} but this prim does not exist",
  1261. itemID, primLocalID, remoteClient.Name);
  1262. }
  1263. }
  1264. /// <summary>
  1265. /// Rez a script into a prim's inventory, either ex nihilo or from an existing avatar inventory
  1266. /// </summary>
  1267. /// <param name="remoteClient"></param>
  1268. /// <param name="itemID"> </param>
  1269. /// <param name="localID"></param>
  1270. public void RezScript(IClientAPI remoteClient, InventoryItemBase itemBase, UUID transactionID, uint localID)
  1271. {
  1272. UUID itemID = itemBase.ID;
  1273. UUID copyID = UUID.Random();
  1274. if (itemID != UUID.Zero) // transferred from an avatar inventory to the prim's inventory
  1275. {
  1276. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  1277. if (userInfo != null && userInfo.RootFolder != null)
  1278. {
  1279. InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
  1280. // Try library
  1281. // XXX clumsy, possibly should be one call
  1282. if (null == item)
  1283. {
  1284. item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID);
  1285. }
  1286. if (item != null)
  1287. {
  1288. SceneObjectPart part = GetSceneObjectPart(localID);
  1289. if (part != null)
  1290. {
  1291. if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
  1292. return;
  1293. part.ParentGroup.AddInventoryItem(remoteClient, localID, item, copyID);
  1294. // TODO: switch to posting on_rez here when scripts
  1295. // have state in inventory
  1296. part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
  1297. // m_log.InfoFormat("[PRIMINVENTORY]: " +
  1298. // "Rezzed script {0} into prim local ID {1} for user {2}",
  1299. // item.inventoryName, localID, remoteClient.Name);
  1300. part.GetProperties(remoteClient);
  1301. }
  1302. else
  1303. {
  1304. m_log.ErrorFormat(
  1305. "[PRIM INVENTORY]: " +
  1306. "Could not rez script {0} into prim local ID {1} for user {2}"
  1307. + " because the prim could not be found in the region!",
  1308. item.Name, localID, remoteClient.Name);
  1309. }
  1310. }
  1311. else
  1312. {
  1313. m_log.ErrorFormat(
  1314. "[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!",
  1315. itemID, remoteClient.Name);
  1316. }
  1317. }
  1318. }
  1319. else // script has been rezzed directly into a prim's inventory
  1320. {
  1321. SceneObjectPart part = GetSceneObjectPart(itemBase.Folder);
  1322. if (part == null)
  1323. return;
  1324. if (part.OwnerID != remoteClient.AgentId)
  1325. return;
  1326. if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
  1327. return;
  1328. if (!Permissions.CanCreateObjectInventory(
  1329. itemBase.InvType, part.UUID, remoteClient.AgentId))
  1330. return;
  1331. AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"));
  1332. AssetCache.AddAsset(asset);
  1333. TaskInventoryItem taskItem = new TaskInventoryItem();
  1334. taskItem.ResetIDs(itemBase.Folder);
  1335. taskItem.ParentID = itemBase.Folder;
  1336. taskItem.CreationDate = (uint)itemBase.CreationDate;
  1337. taskItem.Name = itemBase.Name;
  1338. taskItem.Description = itemBase.Description;
  1339. taskItem.Type = itemBase.AssetType;
  1340. taskItem.InvType = itemBase.InvType;
  1341. taskItem.OwnerID = itemBase.Owner;
  1342. taskItem.CreatorID = itemBase.Creator;
  1343. taskItem.BasePermissions = itemBase.BasePermissions;
  1344. taskItem.CurrentPermissions = itemBase.CurrentPermissions;
  1345. taskItem.EveryonePermissions = itemBase.EveryOnePermissions;
  1346. taskItem.GroupPermissions = itemBase.GroupPermissions;
  1347. taskItem.NextPermissions = itemBase.NextPermissions;
  1348. taskItem.GroupID = itemBase.GroupID;
  1349. taskItem.GroupPermissions = 0;
  1350. taskItem.Flags = itemBase.Flags;
  1351. taskItem.PermsGranter = UUID.Zero;
  1352. taskItem.PermsMask = 0;
  1353. taskItem.AssetID = asset.FullID;
  1354. part.Inventory.AddInventoryItem(taskItem, false);
  1355. part.GetProperties(remoteClient);
  1356. part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
  1357. }
  1358. }
  1359. /// <summary>
  1360. /// Rez a script into a prim's inventory from another prim
  1361. /// </summary>
  1362. /// <param name="remoteClient"></param>
  1363. /// <param name="itemID"> </param>
  1364. /// <param name="localID"></param>
  1365. public void RezScript(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param)
  1366. {
  1367. TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId);
  1368. if (srcTaskItem == null)
  1369. {
  1370. m_log.ErrorFormat(
  1371. "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for rezzing a script but the "
  1372. + " item does not exist in this inventory",
  1373. srcId, srcPart.Name, srcPart.UUID);
  1374. return;
  1375. }
  1376. SceneObjectPart destPart = GetSceneObjectPart(destId);
  1377. if (destPart == null)
  1378. {
  1379. m_log.ErrorFormat(
  1380. "[PRIM INVENTORY]: " +
  1381. "Could not find script for ID {0}",
  1382. destId);
  1383. return;
  1384. }
  1385. // Must own the object, and have modify rights
  1386. if (srcPart.OwnerID != destPart.OwnerID)
  1387. return;
  1388. if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0)
  1389. return;
  1390. if (destPart.ScriptAccessPin != pin)
  1391. {
  1392. m_log.WarnFormat(
  1393. "[PRIM INVENTORY]: " +
  1394. "Script in object {0} : {1}, attempted to load script {2} : {3} into object {4} : {5} with invalid pin {6}",
  1395. srcPart.Name, srcId, srcTaskItem.Name, srcTaskItem.ItemID, destPart.Name, destId, pin);
  1396. // the LSL Wiki says we are supposed to shout on the DEBUG_CHANNEL -
  1397. // "Object: Task Object trying to illegally load script onto task Other_Object!"
  1398. // How do we shout from in here?
  1399. return;
  1400. }
  1401. TaskInventoryItem destTaskItem = new TaskInventoryItem();
  1402. destTaskItem.ItemID = UUID.Random();
  1403. destTaskItem.CreatorID = srcTaskItem.CreatorID;
  1404. destTaskItem.AssetID = srcTaskItem.AssetID;
  1405. destTaskItem.GroupID = destPart.GroupID;
  1406. destTaskItem.OwnerID = destPart.OwnerID;
  1407. destTaskItem.ParentID = destPart.UUID;
  1408. destTaskItem.ParentPartID = destPart.UUID;
  1409. destTaskItem.BasePermissions = srcTaskItem.BasePermissions;
  1410. destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions;
  1411. destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions;
  1412. destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions;
  1413. destTaskItem.NextPermissions = srcTaskItem.NextPermissions;
  1414. destTaskItem.Flags = srcTaskItem.Flags;
  1415. if (destPart.OwnerID != srcPart.OwnerID)
  1416. {
  1417. if (Permissions.PropagatePermissions())
  1418. {
  1419. destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
  1420. srcTaskItem.NextPermissions;
  1421. destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
  1422. srcTaskItem.NextPermissions;
  1423. destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
  1424. srcTaskItem.NextPermissions;
  1425. destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
  1426. srcTaskItem.NextPermissions;
  1427. destTaskItem.CurrentPermissions |= 8; // Slam!
  1428. }
  1429. }
  1430. destTaskItem.Description = srcTaskItem.Description;
  1431. destTaskItem.Name = srcTaskItem.Name;
  1432. destTaskItem.InvType = srcTaskItem.InvType;
  1433. destTaskItem.Type = srcTaskItem.Type;
  1434. destPart.Inventory.AddInventoryItemExclusive(destTaskItem, false);
  1435. if (running > 0)
  1436. {
  1437. destPart.Inventory.CreateScriptInstance(destTaskItem, 0, false, DefaultScriptEngine, 0);
  1438. }
  1439. ScenePresence avatar;
  1440. if (TryGetAvatar(srcTaskItem.OwnerID, out avatar))
  1441. {
  1442. destPart.GetProperties(avatar.ControllingClient);
  1443. }
  1444. }
  1445. /// <summary>
  1446. /// Called when an object is removed from the environment into inventory.
  1447. /// </summary>
  1448. /// <param name="remoteClient"></param>
  1449. /// <param name="localID"></param>
  1450. /// <param name="groupID"></param>
  1451. /// <param name="action"></param>
  1452. /// <param name="destinationID"></param>
  1453. public virtual void DeRezObject(IClientAPI remoteClient, uint localID,
  1454. UUID groupID, DeRezAction action, UUID destinationID)
  1455. {
  1456. SceneObjectPart part = GetSceneObjectPart(localID);
  1457. if (part == null)
  1458. return;
  1459. if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
  1460. return;
  1461. // Can't delete child prims
  1462. if (part != part.ParentGroup.RootPart)
  1463. return;
  1464. SceneObjectGroup grp = part.ParentGroup;
  1465. bool permissionToTake = false;
  1466. bool permissionToDelete = false;
  1467. if (action == DeRezAction.SaveToExistingUserInventoryItem)
  1468. {
  1469. if (grp.OwnerID == remoteClient.AgentId && grp.RootPart.FromUserInventoryItemID != UUID.Zero)
  1470. {
  1471. permissionToTake = true;
  1472. permissionToDelete = false;
  1473. }
  1474. }
  1475. else if (action == DeRezAction.TakeCopy)
  1476. {
  1477. permissionToTake =
  1478. Permissions.CanTakeCopyObject(
  1479. grp.UUID,
  1480. remoteClient.AgentId);
  1481. }
  1482. else if (action == DeRezAction.GodTakeCopy)
  1483. {
  1484. permissionToTake =
  1485. Permissions.IsGod(
  1486. remoteClient.AgentId);
  1487. }
  1488. else if (action == DeRezAction.Take)
  1489. {
  1490. permissionToTake =
  1491. Permissions.CanTakeObject(
  1492. grp.UUID,
  1493. remoteClient.AgentId);
  1494. //If they can take, they can delete!
  1495. permissionToDelete = permissionToTake;
  1496. }
  1497. else if (action == DeRezAction.Delete)
  1498. {
  1499. permissionToTake =
  1500. Permissions.CanDeleteObject(
  1501. grp.UUID,
  1502. remoteClient.AgentId);
  1503. permissionToDelete = permissionToTake;
  1504. }
  1505. else if (action == DeRezAction.Return)
  1506. {
  1507. if (remoteClient != null)
  1508. {
  1509. permissionToTake =
  1510. Permissions.CanReturnObject(
  1511. grp.UUID,
  1512. remoteClient.AgentId);
  1513. permissionToDelete = permissionToTake;
  1514. if (permissionToDelete)
  1515. {
  1516. AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
  1517. }
  1518. }
  1519. else // Auto return passes through here with null agent
  1520. {
  1521. permissionToTake = true;
  1522. permissionToDelete = true;
  1523. }
  1524. }
  1525. else
  1526. {
  1527. m_log.DebugFormat(
  1528. "[AGENT INVENTORY]: Ignoring unexpected derez action {0} for {1}", action, remoteClient.Name);
  1529. return;
  1530. }
  1531. if (permissionToTake)
  1532. {
  1533. m_asyncSceneObjectDeleter.DeleteToInventory(
  1534. action, destinationID, grp, remoteClient,
  1535. permissionToDelete);
  1536. }
  1537. else if (permissionToDelete)
  1538. {
  1539. DeleteSceneObject(grp, false);
  1540. }
  1541. }
  1542. private bool WaitForInventory(CachedUserInfo info)
  1543. {
  1544. // 200 Seconds wait. This is called in the context of the
  1545. // background delete thread, so we can afford to waste time
  1546. // here.
  1547. //
  1548. int count = 200;
  1549. while (count > 0)
  1550. {
  1551. System.Threading.Thread.Sleep(100);
  1552. count--;
  1553. if (info.HasReceivedInventory)
  1554. return true;
  1555. }
  1556. m_log.DebugFormat("Timed out waiting for inventory of user {0}",
  1557. info.UserProfile.ID.ToString());
  1558. return false;
  1559. }
  1560. /// <summary>
  1561. /// Delete a scene object from a scene and place in the given avatar's inventory.
  1562. /// Returns the UUID of the newly created asset.
  1563. /// </summary>
  1564. /// <param name="action"></param>
  1565. /// <param name="folderID"></param>
  1566. /// <param name="objectGroup"></param>
  1567. /// <param name="remoteClient"> </param>
  1568. public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
  1569. SceneObjectGroup objectGroup, IClientAPI remoteClient)
  1570. {
  1571. UUID assetID = UUID.Zero;
  1572. string sceneObjectXml = objectGroup.ToXmlString();
  1573. // Get the user info of the item destination
  1574. //
  1575. CachedUserInfo userInfo;
  1576. if (action == DeRezAction.Take || action == DeRezAction.TakeCopy ||
  1577. action == DeRezAction.SaveToExistingUserInventoryItem)
  1578. {
  1579. // Take or take copy require a taker
  1580. // Saving changes requires a local user
  1581. //
  1582. if (remoteClient == null)
  1583. return UUID.Zero;
  1584. userInfo = CommsManager.UserProfileCacheService.GetUserDetails(
  1585. remoteClient.AgentId);
  1586. }
  1587. else
  1588. {
  1589. // All returns / deletes go to the object owner
  1590. //
  1591. userInfo = CommsManager.UserProfileCacheService.GetUserDetails(
  1592. objectGroup.RootPart.OwnerID);
  1593. }
  1594. if (userInfo == null) // Can't proceed
  1595. {
  1596. return UUID.Zero;
  1597. }
  1598. if (!userInfo.HasReceivedInventory)
  1599. {
  1600. // Async inventory requests will queue, but they will never
  1601. // execute unless inventory is actually fetched
  1602. //
  1603. CommsManager.UserProfileCacheService.RequestInventoryForUser(
  1604. userInfo.UserProfile.ID);
  1605. }
  1606. if (userInfo != null)
  1607. {
  1608. // If we're returning someone's item, it goes back to the
  1609. // owner's Lost And Found folder.
  1610. // Delete is treated like return in this case
  1611. // Deleting your own items makes them go to trash
  1612. //
  1613. InventoryFolderBase folder = null;
  1614. InventoryItemBase item = null;
  1615. if (DeRezAction.SaveToExistingUserInventoryItem == action)
  1616. {
  1617. item = userInfo.RootFolder.FindItem(
  1618. objectGroup.RootPart.FromUserInventoryItemID);
  1619. if (null == item)
  1620. {
  1621. m_log.DebugFormat(
  1622. "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
  1623. objectGroup.Name, objectGroup.UUID);
  1624. return UUID.Zero;
  1625. }
  1626. }
  1627. else
  1628. {
  1629. // Folder magic
  1630. //
  1631. if (action == DeRezAction.Delete)
  1632. {
  1633. // Deleting someone else's item
  1634. //
  1635. if (remoteClient == null ||
  1636. objectGroup.OwnerID != remoteClient.AgentId)
  1637. {
  1638. // Folder skeleton may not be loaded and we
  1639. // have to wait for the inventory to find
  1640. // the destination folder
  1641. //
  1642. if (!WaitForInventory(userInfo))
  1643. return UUID.Zero;
  1644. folder = userInfo.FindFolderForType(
  1645. (int)AssetType.LostAndFoundFolder);
  1646. }
  1647. else
  1648. {
  1649. // Assume inventory skeleton was loaded during login
  1650. // and all folders can be found
  1651. //
  1652. folder = userInfo.FindFolderForType(
  1653. (int)AssetType.TrashFolder);
  1654. }
  1655. }
  1656. else if (action == DeRezAction.Return)
  1657. {
  1658. // Wait if needed
  1659. //
  1660. if (!userInfo.HasReceivedInventory)
  1661. {
  1662. if (!WaitForInventory(userInfo))
  1663. return UUID.Zero;
  1664. }
  1665. // Dump to lost + found unconditionally
  1666. //
  1667. folder = userInfo.FindFolderForType(
  1668. (int)AssetType.LostAndFoundFolder);
  1669. }
  1670. if (folderID == UUID.Zero && folder == null)
  1671. {
  1672. // Catch all. Use lost & found
  1673. //
  1674. if (!userInfo.HasReceivedInventory)
  1675. {
  1676. if (!WaitForInventory(userInfo))
  1677. return UUID.Zero;
  1678. }
  1679. folder = userInfo.FindFolderForType(
  1680. (int)AssetType.LostAndFoundFolder);
  1681. }
  1682. if (folder == null) // None of the above
  1683. {
  1684. folder = userInfo.RootFolder.FindFolder(folderID);
  1685. if (folder == null) // Nowhere to put it
  1686. {
  1687. return UUID.Zero;
  1688. }
  1689. }
  1690. item = new InventoryItemBase();
  1691. item.Creator = objectGroup.RootPart.CreatorID;
  1692. item.ID = UUID.Random();
  1693. item.InvType = (int)InventoryType.Object;
  1694. item.Folder = folder.ID;
  1695. item.Owner = userInfo.UserProfile.ID;
  1696. }
  1697. AssetBase asset = CreateAsset(
  1698. objectGroup.GetPartName(objectGroup.RootPart.LocalId),
  1699. objectGroup.GetPartDescription(objectGroup.RootPart.LocalId),
  1700. (sbyte)AssetType.Object,
  1701. Utils.StringToBytes(sceneObjectXml));
  1702. AssetCache.AddAsset(asset);
  1703. assetID = asset.FullID;
  1704. if (DeRezAction.SaveToExistingUserInventoryItem == action)
  1705. {
  1706. item.AssetID = asset.FullID;
  1707. userInfo.UpdateItem(item);
  1708. }
  1709. else
  1710. {
  1711. item.AssetID = asset.FullID;
  1712. if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && Permissions.PropagatePermissions())
  1713. {
  1714. uint perms = objectGroup.GetEffectivePermissions();
  1715. uint nextPerms = (perms & 7) << 13;
  1716. if ((nextPerms & (uint)PermissionMask.Copy) == 0)
  1717. perms &= ~(uint)PermissionMask.Copy;
  1718. if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
  1719. perms &= ~(uint)PermissionMask.Transfer;
  1720. if ((nextPerms & (uint)PermissionMask.Modify) == 0)
  1721. perms &= ~(uint)PermissionMask.Modify;
  1722. item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
  1723. item.CurrentPermissions = item.BasePermissions;
  1724. item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
  1725. item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
  1726. item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
  1727. item.CurrentPermissions |= 8; // Slam!
  1728. }
  1729. else
  1730. {
  1731. item.BasePermissions = objectGroup.GetEffectivePermissions();
  1732. item.CurrentPermissions = objectGroup.GetEffectivePermissions();
  1733. item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
  1734. item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
  1735. item.GroupPermissions = objectGroup.RootPart.GroupMask;
  1736. item.CurrentPermissions |= 8; // Slam!
  1737. }
  1738. // TODO: add the new fields (Flags, Sale info, etc)
  1739. item.CreationDate = Util.UnixTimeSinceEpoch();
  1740. item.Description = asset.Description;
  1741. item.Name = asset.Name;
  1742. item.AssetType = asset.Type;
  1743. userInfo.AddItem(item);
  1744. if (remoteClient != null && item.Owner == remoteClient.AgentId)
  1745. {
  1746. remoteClient.SendInventoryItemCreateUpdate(item);
  1747. }
  1748. else
  1749. {
  1750. ScenePresence notifyUser = GetScenePresence(item.Owner);
  1751. if (notifyUser != null)
  1752. {
  1753. notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item);
  1754. }
  1755. }
  1756. }
  1757. }
  1758. return assetID;
  1759. }
  1760. public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, UUID assetID, UUID agentID)
  1761. {
  1762. SceneObjectGroup objectGroup = grp;
  1763. if (objectGroup != null)
  1764. {
  1765. if (!grp.HasGroupChanged)
  1766. {
  1767. m_log.InfoFormat("[ATTACHMENT]: Save request for {0} which is unchanged", grp.UUID);
  1768. return;
  1769. }
  1770. m_log.InfoFormat(
  1771. "[ATTACHMENT]: Updating asset for attachment {0}, attachpoint {1}",
  1772. grp.UUID, grp.GetAttachmentPoint());
  1773. string sceneObjectXml = objectGroup.ToXmlString();
  1774. CachedUserInfo userInfo =
  1775. CommsManager.UserProfileCacheService.GetUserDetails(agentID);
  1776. if (userInfo != null && userInfo.RootFolder != null)
  1777. {
  1778. Queue<InventoryFolderImpl> searchfolders = new Queue<InventoryFolderImpl>();
  1779. searchfolders.Enqueue(userInfo.RootFolder);
  1780. UUID foundFolder = UUID.Zero;
  1781. InventoryItemBase item = null;
  1782. // search through folders to find the asset.
  1783. while (searchfolders.Count > 0)
  1784. {
  1785. InventoryFolderImpl fld = searchfolders.Dequeue();
  1786. lock (fld)
  1787. {
  1788. if (fld != null)
  1789. {
  1790. if (fld.Items.ContainsKey(assetID))
  1791. {
  1792. item = fld.Items[assetID];
  1793. foundFolder = fld.ID;
  1794. searchfolders.Clear();
  1795. break;
  1796. }
  1797. else
  1798. {
  1799. foreach (InventoryFolderImpl subfld in fld.RequestListOfFolderImpls())
  1800. {
  1801. searchfolders.Enqueue(subfld);
  1802. }
  1803. }
  1804. }
  1805. }
  1806. }
  1807. if (foundFolder != UUID.Zero && item != null)
  1808. {
  1809. AssetBase asset = CreateAsset(
  1810. objectGroup.GetPartName(objectGroup.LocalId),
  1811. objectGroup.GetPartDescription(objectGroup.LocalId),
  1812. (sbyte)AssetType.Object,
  1813. Utils.StringToBytes(sceneObjectXml));
  1814. AssetCache.AddAsset(asset);
  1815. item.AssetID = asset.FullID;
  1816. item.Description = asset.Description;
  1817. item.Name = asset.Name;
  1818. item.AssetType = asset.Type;
  1819. item.InvType = (int)InventoryType.Object;
  1820. item.Folder = foundFolder;
  1821. userInfo.UpdateItem(item);
  1822. // this gets called when the agent loggs off!
  1823. if (remoteClient != null)
  1824. {
  1825. remoteClient.SendInventoryItemCreateUpdate(item);
  1826. }
  1827. }
  1828. }
  1829. }
  1830. }
  1831. public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID)
  1832. {
  1833. itemID = UUID.Zero;
  1834. if (grp != null)
  1835. {
  1836. string sceneObjectXml = grp.ToXmlString();
  1837. CachedUserInfo userInfo =
  1838. CommsManager.UserProfileCacheService.GetUserDetails(AgentId);
  1839. if (userInfo != null)
  1840. {
  1841. AssetBase asset = CreateAsset(
  1842. grp.GetPartName(grp.LocalId),
  1843. grp.GetPartDescription(grp.LocalId),
  1844. (sbyte)AssetType.Object,
  1845. Utils.StringToBytes(sceneObjectXml));
  1846. AssetCache.AddAsset(asset);
  1847. InventoryItemBase item = new InventoryItemBase();
  1848. item.Creator = grp.RootPart.CreatorID;
  1849. item.Owner = remoteClient.AgentId;
  1850. item.ID = UUID.Random();
  1851. item.AssetID = asset.FullID;
  1852. item.Description = asset.Description;
  1853. item.Name = asset.Name;
  1854. item.AssetType = asset.Type;
  1855. item.InvType = (int)InventoryType.Object;
  1856. item.Folder = UUID.Zero; // Objects folder!
  1857. if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions())
  1858. {
  1859. item.BasePermissions = grp.RootPart.NextOwnerMask;
  1860. item.CurrentPermissions = grp.RootPart.NextOwnerMask;
  1861. item.NextPermissions = grp.RootPart.NextOwnerMask;
  1862. item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
  1863. item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
  1864. }
  1865. else
  1866. {
  1867. item.BasePermissions = grp.RootPart.BaseMask;
  1868. item.CurrentPermissions = grp.RootPart.OwnerMask;
  1869. item.NextPermissions = grp.RootPart.NextOwnerMask;
  1870. item.EveryOnePermissions = grp.RootPart.EveryoneMask;
  1871. item.GroupPermissions = grp.RootPart.GroupMask;
  1872. }
  1873. item.CreationDate = Util.UnixTimeSinceEpoch();
  1874. // sets assetID so client can show asset as 'attached' in inventory
  1875. grp.SetFromAssetID(item.ID);
  1876. userInfo.AddItem(item);
  1877. remoteClient.SendInventoryItemCreateUpdate(item);
  1878. itemID = item.ID;
  1879. return item.AssetID;
  1880. }
  1881. return UUID.Zero;
  1882. }
  1883. return UUID.Zero;
  1884. }
  1885. /// <summary>
  1886. /// Event Handler Rez an object into a scene
  1887. /// Calls the non-void event handler
  1888. /// </summary>
  1889. /// <param name="remoteClient"></param>
  1890. /// <param name="itemID"></param>
  1891. /// <param name="RayEnd"></param>
  1892. /// <param name="RayStart"></param>
  1893. /// <param name="RayTargetID"></param>
  1894. /// <param name="BypassRayCast"></param>
  1895. /// <param name="RayEndIsIntersection"></param>
  1896. /// <param name="EveryoneMask"></param>
  1897. /// <param name="GroupMask"></param>
  1898. /// <param name="RezSelected"></param>
  1899. /// <param name="RemoveItem"></param>
  1900. /// <param name="fromTaskID"></param>
  1901. public virtual void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
  1902. UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
  1903. bool RezSelected, bool RemoveItem, UUID fromTaskID)
  1904. {
  1905. RezObject(
  1906. remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
  1907. RezSelected, RemoveItem, fromTaskID, false);
  1908. }
  1909. /// <summary>
  1910. /// Rez an object into the scene from the user's inventory
  1911. /// </summary>
  1912. /// <param name="remoteClient"></param>
  1913. /// <param name="itemID"></param>
  1914. /// <param name="RayEnd"></param>
  1915. /// <param name="RayStart"></param>
  1916. /// <param name="RayTargetID"></param>
  1917. /// <param name="BypassRayCast"></param>
  1918. /// <param name="RayEndIsIntersection"></param>
  1919. /// <param name="RezSelected"></param>
  1920. /// <param name="RemoveItem"></param>
  1921. /// <param name="fromTaskID"></param>
  1922. /// <param name="attachment"></param>
  1923. /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
  1924. public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
  1925. UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
  1926. bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
  1927. {
  1928. // Work out position details
  1929. byte bRayEndIsIntersection = (byte)0;
  1930. if (RayEndIsIntersection)
  1931. {
  1932. bRayEndIsIntersection = (byte)1;
  1933. }
  1934. else
  1935. {
  1936. bRayEndIsIntersection = (byte)0;
  1937. }
  1938. Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
  1939. Vector3 pos = GetNewRezLocation(
  1940. RayStart, RayEnd, RayTargetID, Quaternion.Identity,
  1941. BypassRayCast, bRayEndIsIntersection, true, scale, false);
  1942. // Rez object
  1943. CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  1944. if (userInfo != null)
  1945. {
  1946. // Do NOT use HasReceivedInventory here, this is called
  1947. // from within ItemReceive during login for attachments.
  1948. // Using HasReceivedInventory here will break attachment
  1949. // persistence!
  1950. //
  1951. if (userInfo.RootFolder != null)
  1952. {
  1953. InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
  1954. if (item != null)
  1955. {
  1956. AssetBase rezAsset = AssetCache.GetAsset(item.AssetID, false);
  1957. if (rezAsset != null)
  1958. {
  1959. UUID itemId = UUID.Zero;
  1960. // If we have permission to copy then link the rezzed object back to the user inventory
  1961. // item that it came from. This allows us to enable 'save object to inventory'
  1962. if (!Permissions.BypassPermissions())
  1963. {
  1964. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
  1965. {
  1966. itemId = item.ID;
  1967. }
  1968. }
  1969. string xmlData = Utils.BytesToString(rezAsset.Data);
  1970. SceneObjectGroup group = new SceneObjectGroup(itemId, xmlData, true);
  1971. if (!Permissions.CanRezObject(
  1972. group.Children.Count, remoteClient.AgentId, pos)
  1973. && !attachment)
  1974. {
  1975. return null;
  1976. }
  1977. group.ResetIDs();
  1978. AddNewSceneObject(group, true);
  1979. // if attachment we set it's asset id so object updates can reflect that
  1980. // if not, we set it's position in world.
  1981. if (!attachment)
  1982. {
  1983. pos = GetNewRezLocation(
  1984. RayStart, RayEnd, RayTargetID, Quaternion.Identity,
  1985. BypassRayCast, bRayEndIsIntersection, true, group.GroupScale(), false);
  1986. group.AbsolutePosition = pos;
  1987. }
  1988. else
  1989. {
  1990. group.SetFromAssetID(itemID);
  1991. }
  1992. SceneObjectPart rootPart = null;
  1993. try
  1994. {
  1995. rootPart = group.GetChildPart(group.UUID);
  1996. }
  1997. catch (NullReferenceException)
  1998. {
  1999. string isAttachment = "";
  2000. if (attachment)
  2001. isAttachment = " Object was an attachment";
  2002. m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
  2003. }
  2004. // Since renaming the item in the inventory does not affect the name stored
  2005. // in the serialization, transfer the correct name from the inventory to the
  2006. // object itself before we rez.
  2007. rootPart.Name = item.Name;
  2008. rootPart.Description = item.Description;
  2009. List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
  2010. group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
  2011. if (rootPart.OwnerID != item.Owner)
  2012. {
  2013. //Need to kill the for sale here
  2014. rootPart.ObjectSaleType = 0;
  2015. rootPart.SalePrice = 10;
  2016. if (Permissions.PropagatePermissions())
  2017. {
  2018. if ((item.CurrentPermissions & 8) != 0)
  2019. {
  2020. foreach (SceneObjectPart part in partList)
  2021. {
  2022. part.EveryoneMask = item.EveryOnePermissions;
  2023. part.NextOwnerMask = item.NextPermissions;
  2024. part.GroupMask = 0; // DO NOT propagate here
  2025. }
  2026. }
  2027. group.ApplyNextOwnerPermissions();
  2028. }
  2029. }
  2030. foreach (SceneObjectPart part in partList)
  2031. {
  2032. if (part.OwnerID != item.Owner)
  2033. {
  2034. part.LastOwnerID = part.OwnerID;
  2035. part.OwnerID = item.Owner;
  2036. part.Inventory.ChangeInventoryOwner(item.Owner);
  2037. }
  2038. else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam!
  2039. {
  2040. part.EveryoneMask = item.EveryOnePermissions;
  2041. part.NextOwnerMask = item.NextPermissions;
  2042. part.GroupMask = 0; // DO NOT propagate here
  2043. }
  2044. }
  2045. rootPart.TrimPermissions();
  2046. if (!attachment)
  2047. {
  2048. if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
  2049. {
  2050. group.ClearPartAttachmentData();
  2051. }
  2052. }
  2053. if (!attachment)
  2054. {
  2055. // Fire on_rez
  2056. group.CreateScriptInstances(0, true, DefaultScriptEngine, 0);
  2057. rootPart.ScheduleFullUpdate();
  2058. }
  2059. if (!Permissions.BypassPermissions())
  2060. {
  2061. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  2062. {
  2063. // If this is done on attachments, no
  2064. // copy ones will be lost, so avoid it
  2065. //
  2066. if (!attachment)
  2067. userInfo.DeleteItem(item.ID);
  2068. }
  2069. }
  2070. return rootPart.ParentGroup;
  2071. }
  2072. }
  2073. }
  2074. else
  2075. m_log.WarnFormat("[AGENT INVENTORY]: Root folder not found in {0}", RegionInfo.RegionName);
  2076. }
  2077. else
  2078. m_log.WarnFormat("[AGENT INVENTORY]: User profile not found in {0}", RegionInfo.RegionName);
  2079. return null;
  2080. }
  2081. /// <summary>
  2082. /// Rez an object into the scene from a prim's inventory.
  2083. /// </summary>
  2084. /// <param name="sourcePart"></param>
  2085. /// <param name="item"></param>
  2086. /// <param name="pos"></param>
  2087. /// <param name="rot"></param>
  2088. /// <param name="vel"></param>
  2089. /// <param name="param"></param>
  2090. /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful</returns>
  2091. public virtual SceneObjectGroup RezObject(
  2092. SceneObjectPart sourcePart, TaskInventoryItem item,
  2093. Vector3 pos, Quaternion rot, Vector3 vel, int param)
  2094. {
  2095. // Rez object
  2096. if (item != null)
  2097. {
  2098. UUID ownerID = item.OwnerID;
  2099. AssetBase rezAsset = AssetCache.GetAsset(item.AssetID, false);
  2100. if (rezAsset != null)
  2101. {
  2102. string xmlData = Utils.BytesToString(rezAsset.Data);
  2103. SceneObjectGroup group = new SceneObjectGroup(xmlData, true);
  2104. if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos))
  2105. {
  2106. return null;
  2107. }
  2108. group.ResetIDs();
  2109. AddNewSceneObject(group, true);
  2110. // we set it's position in world.
  2111. group.AbsolutePosition = pos;
  2112. SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  2113. // Since renaming the item in the inventory does not affect the name stored
  2114. // in the serialization, transfer the correct name from the inventory to the
  2115. // object itself before we rez.
  2116. rootPart.Name = item.Name;
  2117. rootPart.Description = item.Description;
  2118. List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
  2119. group.SetGroup(sourcePart.GroupID, null);
  2120. if (rootPart.OwnerID != item.OwnerID)
  2121. {
  2122. if (Permissions.PropagatePermissions())
  2123. {
  2124. if ((item.CurrentPermissions & 8) != 0)
  2125. {
  2126. foreach (SceneObjectPart part in partList)
  2127. {
  2128. part.EveryoneMask = item.EveryonePermissions;
  2129. part.NextOwnerMask = item.NextPermissions;
  2130. }
  2131. }
  2132. group.ApplyNextOwnerPermissions();
  2133. }
  2134. }
  2135. foreach (SceneObjectPart part in partList)
  2136. {
  2137. if (part.OwnerID != item.OwnerID)
  2138. {
  2139. part.LastOwnerID = part.OwnerID;
  2140. part.OwnerID = item.OwnerID;
  2141. part.Inventory.ChangeInventoryOwner(item.OwnerID);
  2142. }
  2143. else if ((item.CurrentPermissions & 8) != 0) // Slam!
  2144. {
  2145. part.EveryoneMask = item.EveryonePermissions;
  2146. part.NextOwnerMask = item.NextPermissions;
  2147. }
  2148. }
  2149. rootPart.TrimPermissions();
  2150. if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
  2151. {
  2152. group.ClearPartAttachmentData();
  2153. }
  2154. group.UpdateGroupRotation(rot);
  2155. //group.ApplyPhysics(m_physicalPrim);
  2156. group.Velocity = vel;
  2157. group.CreateScriptInstances(param, true, DefaultScriptEngine, 2);
  2158. rootPart.ScheduleFullUpdate();
  2159. if (!Permissions.BypassPermissions())
  2160. {
  2161. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  2162. sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
  2163. }
  2164. return rootPart.ParentGroup;
  2165. }
  2166. }
  2167. return null;
  2168. }
  2169. public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId)
  2170. {
  2171. foreach (SceneObjectGroup grp in returnobjects)
  2172. {
  2173. AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
  2174. DeRezObject(null, grp.RootPart.LocalId,
  2175. grp.RootPart.GroupID, DeRezAction.Return, UUID.Zero);
  2176. }
  2177. return true;
  2178. }
  2179. public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running)
  2180. {
  2181. SceneObjectPart part = GetSceneObjectPart(objectID);
  2182. if (part == null)
  2183. return;
  2184. if (running)
  2185. EventManager.TriggerStartScript(part.LocalId, itemID);
  2186. else
  2187. EventManager.TriggerStopScript(part.LocalId, itemID);
  2188. }
  2189. public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID,
  2190. uint AttachmentPt)
  2191. {
  2192. SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt);
  2193. if (att == null)
  2194. {
  2195. DetachSingleAttachmentToInv(itemID, remoteClient);
  2196. return UUID.Zero;
  2197. }
  2198. return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt);
  2199. }
  2200. public UUID RezSingleAttachment(SceneObjectGroup att,
  2201. IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
  2202. {
  2203. if (!att.IsDeleted)
  2204. AttachmentPt = att.RootPart.AttachmentPoint;
  2205. ScenePresence presence;
  2206. if (TryGetAvatar(remoteClient.AgentId, out presence))
  2207. {
  2208. presence.Appearance.SetAttachment((int)AttachmentPt, itemID, att.UUID);
  2209. IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>();
  2210. if (ava != null)
  2211. {
  2212. ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
  2213. }
  2214. }
  2215. return att.UUID;
  2216. }
  2217. public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
  2218. {
  2219. m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
  2220. }
  2221. public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
  2222. {
  2223. if (UUID.Zero == itemID)
  2224. {
  2225. m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID.");
  2226. return;
  2227. }
  2228. if (0 == AttachmentPt)
  2229. {
  2230. m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error attachment point.");
  2231. return;
  2232. }
  2233. if (null == att.RootPart)
  2234. {
  2235. m_log.Error("[SCENE INVENTORY]: Unable to save attachment for a prim without the rootpart!");
  2236. return;
  2237. }
  2238. ScenePresence presence;
  2239. if (TryGetAvatar(remoteClient.AgentId, out presence))
  2240. {
  2241. presence.Appearance.SetAttachment((int)AttachmentPt, itemID, att.UUID);
  2242. IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>();
  2243. if (ava != null)
  2244. {
  2245. m_log.InfoFormat("[SCENE INVENTORY]: Saving avatar attachment. AgentID:{0} ItemID:{1} AttachmentPoint:{2}", remoteClient.AgentId, itemID, AttachmentPt);
  2246. ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
  2247. }
  2248. }
  2249. }
  2250. public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient)
  2251. {
  2252. SceneObjectPart part = GetSceneObjectPart(itemID);
  2253. if (part == null || part.ParentGroup == null)
  2254. return;
  2255. UUID inventoryID = part.ParentGroup.GetFromAssetID();
  2256. ScenePresence presence;
  2257. if (TryGetAvatar(remoteClient.AgentId, out presence))
  2258. {
  2259. if (!Permissions.CanRezObject(part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition))
  2260. return;
  2261. presence.Appearance.DetachAttachment(itemID);
  2262. IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>();
  2263. if (ava != null)
  2264. {
  2265. ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
  2266. }
  2267. part.ParentGroup.DetachToGround();
  2268. CachedUserInfo userInfo =
  2269. CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
  2270. if (userInfo != null)
  2271. {
  2272. userInfo.DeleteItem(inventoryID);
  2273. remoteClient.SendRemoveInventoryItem(inventoryID);
  2274. }
  2275. }
  2276. }
  2277. public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
  2278. {
  2279. ScenePresence presence;
  2280. if (TryGetAvatar(remoteClient.AgentId, out presence))
  2281. {
  2282. presence.Appearance.DetachAttachment(itemID);
  2283. IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>();
  2284. if (ava != null)
  2285. {
  2286. ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
  2287. }
  2288. }
  2289. m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient);
  2290. }
  2291. public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
  2292. {
  2293. EventManager.TriggerGetScriptRunning(controllingClient, objectID, itemID);
  2294. }
  2295. void ObjectOwner(IClientAPI remoteClient, UUID ownerID, UUID groupID, List<uint> localIDs)
  2296. {
  2297. if (!Permissions.IsGod(remoteClient.AgentId))
  2298. return;
  2299. foreach (uint localID in localIDs)
  2300. {
  2301. SceneObjectPart part = GetSceneObjectPart(localID);
  2302. if (part != null && part.ParentGroup != null)
  2303. {
  2304. part.ParentGroup.SetOwnerId(ownerID);
  2305. part.Inventory.ChangeInventoryOwner(ownerID);
  2306. part.ParentGroup.SetGroup(groupID, remoteClient);
  2307. }
  2308. }
  2309. }
  2310. }
  2311. }