Scene.Inventory.cs 96 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Collections;
  30. using System.Reflection;
  31. using System.Text;
  32. using System.Timers;
  33. using OpenMetaverse;
  34. using OpenMetaverse.Packets;
  35. using log4net;
  36. using OpenSim.Framework;
  37. using OpenSim.Region.Framework;
  38. using OpenSim.Region.Framework.Interfaces;
  39. using OpenSim.Region.Framework.Scenes.Serialization;
  40. namespace OpenSim.Region.Framework.Scenes
  41. {
  42. public partial class Scene
  43. {
  44. private static readonly ILog m_log
  45. = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  46. /// <summary>
  47. /// Allows asynchronous derezzing of objects from the scene into a client's inventory.
  48. /// </summary>
  49. protected AsyncSceneObjectGroupDeleter m_asyncSceneObjectDeleter;
  50. /// <summary>
  51. /// Start all the scripts in the scene which should be started.
  52. /// </summary>
  53. public void CreateScriptInstances()
  54. {
  55. m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
  56. EntityBase[] entities = Entities.GetEntities();
  57. foreach (EntityBase group in entities)
  58. {
  59. if (group is SceneObjectGroup)
  60. {
  61. ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
  62. ((SceneObjectGroup) group).ResumeScripts();
  63. }
  64. }
  65. }
  66. public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
  67. {
  68. IMoneyModule money = RequestModuleInterface<IMoneyModule>();
  69. if (money != null)
  70. {
  71. money.ApplyUploadCharge(agentID, money.UploadCharge, "Asset upload");
  72. }
  73. AddInventoryItem(item);
  74. }
  75. public bool AddInventoryItemReturned(UUID AgentId, InventoryItemBase item)
  76. {
  77. if (AddInventoryItem(item))
  78. return true;
  79. else
  80. {
  81. m_log.WarnFormat(
  82. "[AGENT INVENTORY]: Unable to add item {1} to agent {2} inventory", item.Name, AgentId);
  83. return false;
  84. }
  85. }
  86. /// <summary>
  87. /// Add the given inventory item to a user's inventory.
  88. /// </summary>
  89. /// <param name="item"></param>
  90. public bool AddInventoryItem(InventoryItemBase item)
  91. {
  92. if (UUID.Zero == item.Folder)
  93. {
  94. InventoryFolderBase f = InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType);
  95. if (f != null)
  96. {
  97. // m_log.DebugFormat(
  98. // "[LOCAL INVENTORY SERVICES CONNECTOR]: Found folder {0} type {1} for item {2}",
  99. // f.Name, (AssetType)f.Type, item.Name);
  100. item.Folder = f.ID;
  101. }
  102. else
  103. {
  104. f = InventoryService.GetRootFolder(item.Owner);
  105. if (f != null)
  106. {
  107. item.Folder = f.ID;
  108. }
  109. else
  110. {
  111. m_log.WarnFormat(
  112. "[AGENT INVENTORY]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified",
  113. item.Owner, item.Name);
  114. return false;
  115. }
  116. }
  117. }
  118. if (InventoryService.AddItem(item))
  119. {
  120. int userlevel = 0;
  121. if (Permissions.IsGod(item.Owner))
  122. {
  123. userlevel = 1;
  124. }
  125. EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel);
  126. return true;
  127. }
  128. else
  129. {
  130. m_log.WarnFormat(
  131. "[AGENT INVENTORY]: Agent {0} could not add item {1} {2}",
  132. item.Owner, item.Name, item.ID);
  133. return false;
  134. }
  135. }
  136. /// <summary>
  137. /// Add the given inventory item to a user's inventory.
  138. /// </summary>
  139. /// <param name="AgentID">
  140. /// A <see cref="UUID"/>
  141. /// </param>
  142. /// <param name="item">
  143. /// A <see cref="InventoryItemBase"/>
  144. /// </param>
  145. [Obsolete("Use AddInventoryItem(InventoryItemBase item) instead. This was deprecated in OpenSim 0.7.1")]
  146. public void AddInventoryItem(UUID AgentID, InventoryItemBase item)
  147. {
  148. AddInventoryItem(item);
  149. }
  150. /// <summary>
  151. /// Add an inventory item to an avatar's inventory.
  152. /// </summary>
  153. /// <param name="remoteClient">The remote client controlling the avatar</param>
  154. /// <param name="item">The item. This structure contains all the item metadata, including the folder
  155. /// in which the item is to be placed.</param>
  156. public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
  157. {
  158. AddInventoryItem(item);
  159. remoteClient.SendInventoryItemCreateUpdate(item, 0);
  160. }
  161. /// <summary>
  162. /// <see>CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])</see>
  163. /// </summary>
  164. public UUID CapsUpdateInventoryItemAsset(UUID avatarId, UUID itemID, byte[] data)
  165. {
  166. ScenePresence avatar;
  167. if (TryGetScenePresence(avatarId, out avatar))
  168. {
  169. IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
  170. if (invAccess != null)
  171. return invAccess.CapsUpdateInventoryItemAsset(avatar.ControllingClient, itemID, data);
  172. }
  173. else
  174. {
  175. m_log.ErrorFormat(
  176. "[AGENT INVENTORY]: " +
  177. "Avatar {0} cannot be found to update its inventory item asset",
  178. avatarId);
  179. }
  180. return UUID.Zero;
  181. }
  182. /// <summary>
  183. /// Capability originating call to update the asset of a script in a prim's (task's) inventory
  184. /// </summary>
  185. /// <param name="remoteClient"></param>
  186. /// <param name="itemID"></param>
  187. /// <param name="primID">The prim which contains the item to update</param>
  188. /// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
  189. /// <param name="data"></param>
  190. public ArrayList CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId,
  191. UUID primId, bool isScriptRunning, byte[] data)
  192. {
  193. if (!Permissions.CanEditScript(itemId, primId, remoteClient.AgentId))
  194. {
  195. remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
  196. return new ArrayList();
  197. }
  198. // Retrieve group
  199. SceneObjectPart part = GetSceneObjectPart(primId);
  200. SceneObjectGroup group = part.ParentGroup;
  201. if (null == group)
  202. {
  203. m_log.ErrorFormat(
  204. "[PRIM INVENTORY]: " +
  205. "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
  206. itemId, primId);
  207. return new ArrayList();
  208. }
  209. // Retrieve item
  210. TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId);
  211. if (null == item)
  212. {
  213. m_log.ErrorFormat(
  214. "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for caps script update "
  215. + " but the item does not exist in this inventory",
  216. itemId, part.Name, part.UUID);
  217. return new ArrayList();
  218. }
  219. AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId);
  220. AssetService.Store(asset);
  221. if (isScriptRunning)
  222. {
  223. part.Inventory.RemoveScriptInstance(item.ItemID, false);
  224. }
  225. // Update item with new asset
  226. item.AssetID = asset.FullID;
  227. if (group.UpdateInventoryItem(item))
  228. remoteClient.SendAgentAlertMessage("Script saved", false);
  229. part.GetProperties(remoteClient);
  230. // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
  231. ArrayList errors = new ArrayList();
  232. if (isScriptRunning)
  233. {
  234. // Needs to determine which engine was running it and use that
  235. //
  236. part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0);
  237. errors = part.Inventory.GetScriptErrors(item.ItemID);
  238. }
  239. else
  240. {
  241. remoteClient.SendAgentAlertMessage("Script saved", false);
  242. }
  243. part.ParentGroup.ResumeScripts();
  244. return errors;
  245. }
  246. /// <summary>
  247. /// <see>CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[])</see>
  248. /// </summary>
  249. public ArrayList CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId,
  250. UUID primId, bool isScriptRunning, byte[] data)
  251. {
  252. ScenePresence avatar;
  253. if (TryGetScenePresence(avatarId, out avatar))
  254. {
  255. return CapsUpdateTaskInventoryScriptAsset(
  256. avatar.ControllingClient, itemId, primId, isScriptRunning, data);
  257. }
  258. else
  259. {
  260. m_log.ErrorFormat(
  261. "[PRIM INVENTORY]: " +
  262. "Avatar {0} cannot be found to update its prim item asset",
  263. avatarId);
  264. return new ArrayList();
  265. }
  266. }
  267. /// <summary>
  268. /// Update an item which is either already in the client's inventory or is within
  269. /// a transaction
  270. /// </summary>
  271. /// <param name="remoteClient"></param>
  272. /// <param name="transactionID">The transaction ID. If this is UUID.Zero we will
  273. /// assume that we are not in a transaction</param>
  274. /// <param name="itemID">The ID of the updated item</param>
  275. /// <param name="name">The name of the updated item</param>
  276. /// <param name="description">The description of the updated item</param>
  277. /// <param name="nextOwnerMask">The permissions of the updated item</param>
  278. /* public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
  279. UUID itemID, string name, string description,
  280. uint nextOwnerMask)*/
  281. public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
  282. UUID itemID, InventoryItemBase itemUpd)
  283. {
  284. // This one will let people set next perms on items in agent
  285. // inventory. Rut-Roh. Whatever. Make this secure. Yeah.
  286. //
  287. // Passing something to another avatar or a an object will already
  288. InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
  289. item = InventoryService.GetItem(item);
  290. if (item.Owner != remoteClient.AgentId)
  291. return;
  292. if (item != null)
  293. {
  294. if (UUID.Zero == transactionID)
  295. {
  296. item.Name = itemUpd.Name;
  297. item.Description = itemUpd.Description;
  298. if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
  299. item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
  300. item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
  301. if (item.EveryOnePermissions != (itemUpd.EveryOnePermissions & item.BasePermissions))
  302. item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
  303. item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions;
  304. if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions))
  305. item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
  306. item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions;
  307. item.GroupID = itemUpd.GroupID;
  308. item.GroupOwned = itemUpd.GroupOwned;
  309. item.CreationDate = itemUpd.CreationDate;
  310. // The client sends zero if its newly created?
  311. if (itemUpd.CreationDate == 0)
  312. item.CreationDate = Util.UnixTimeSinceEpoch();
  313. else
  314. item.CreationDate = itemUpd.CreationDate;
  315. // TODO: Check if folder changed and move item
  316. //item.NextPermissions = itemUpd.Folder;
  317. item.InvType = itemUpd.InvType;
  318. if (item.SalePrice != itemUpd.SalePrice ||
  319. item.SaleType != itemUpd.SaleType)
  320. item.Flags |= (uint)InventoryItemFlags.ObjectSlamSale;
  321. item.SalePrice = itemUpd.SalePrice;
  322. item.SaleType = itemUpd.SaleType;
  323. InventoryService.UpdateItem(item);
  324. }
  325. else
  326. {
  327. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  328. if (agentTransactions != null)
  329. {
  330. agentTransactions.HandleItemUpdateFromTransaction(
  331. remoteClient, transactionID, item);
  332. }
  333. }
  334. }
  335. else
  336. {
  337. m_log.Error(
  338. "[AGENTINVENTORY]: Item ID " + itemID + " not found for an inventory item update.");
  339. }
  340. }
  341. /// <summary>
  342. /// Give an inventory item from one user to another
  343. /// </summary>
  344. /// <param name="recipientClient"></param>
  345. /// <param name="senderId">ID of the sender of the item</param>
  346. /// <param name="itemId"></param>
  347. public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId)
  348. {
  349. InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId);
  350. if (itemCopy != null)
  351. recipientClient.SendBulkUpdateInventory(itemCopy);
  352. }
  353. /// <summary>
  354. /// Give an inventory item from one user to another
  355. /// </summary>
  356. /// <param name="recipient"></param>
  357. /// <param name="senderId">ID of the sender of the item</param>
  358. /// <param name="itemId"></param>
  359. /// <returns>The inventory item copy given, null if the give was unsuccessful</returns>
  360. public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId)
  361. {
  362. return GiveInventoryItem(recipient, senderId, itemId, UUID.Zero);
  363. }
  364. /// <summary>
  365. /// Give an inventory item from one user to another
  366. /// </summary>
  367. /// <param name="recipient"></param>
  368. /// <param name="senderId">ID of the sender of the item</param>
  369. /// <param name="itemId"></param>
  370. /// <param name="recipientFolderId">
  371. /// The id of the folder in which the copy item should go. If UUID.Zero then the item is placed in the most
  372. /// appropriate default folder.
  373. /// </param>
  374. /// <returns>
  375. /// The inventory item copy given, null if the give was unsuccessful
  376. /// </returns>
  377. public virtual InventoryItemBase GiveInventoryItem(
  378. UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId)
  379. {
  380. //Console.WriteLine("Scene.Inventory.cs: GiveInventoryItem");
  381. InventoryItemBase item = new InventoryItemBase(itemId, senderId);
  382. item = InventoryService.GetItem(item);
  383. if ((item != null) && (item.Owner == senderId))
  384. {
  385. IUserManagement uman = RequestModuleInterface<IUserManagement>();
  386. if (uman != null)
  387. uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
  388. if (!Permissions.BypassPermissions())
  389. {
  390. if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
  391. return null;
  392. }
  393. // Insert a copy of the item into the recipient
  394. InventoryItemBase itemCopy = new InventoryItemBase();
  395. itemCopy.Owner = recipient;
  396. itemCopy.CreatorId = item.CreatorId;
  397. itemCopy.CreatorData = item.CreatorData;
  398. itemCopy.ID = UUID.Random();
  399. itemCopy.AssetID = item.AssetID;
  400. itemCopy.Description = item.Description;
  401. itemCopy.Name = item.Name;
  402. itemCopy.AssetType = item.AssetType;
  403. itemCopy.InvType = item.InvType;
  404. itemCopy.Folder = recipientFolderId;
  405. if (Permissions.PropagatePermissions() && recipient != senderId)
  406. {
  407. // Trying to do this right this time. This is evil. If
  408. // you believe in Good, go elsewhere. Vampires and other
  409. // evil creatores only beyond this point. You have been
  410. // warned.
  411. // We're going to mask a lot of things by the next perms
  412. // Tweak the next perms to be nicer to our data
  413. //
  414. // In this mask, all the bits we do NOT want to mess
  415. // with are set. These are:
  416. //
  417. // Transfer
  418. // Copy
  419. // Modufy
  420. uint permsMask = ~ ((uint)PermissionMask.Copy |
  421. (uint)PermissionMask.Transfer |
  422. (uint)PermissionMask.Modify);
  423. // Now, reduce the next perms to the mask bits
  424. // relevant to the operation
  425. uint nextPerms = permsMask | (item.NextPermissions &
  426. ((uint)PermissionMask.Copy |
  427. (uint)PermissionMask.Transfer |
  428. (uint)PermissionMask.Modify));
  429. // nextPerms now has all bits set, except for the actual
  430. // next permission bits.
  431. // This checks for no mod, no copy, no trans.
  432. // This indicates an error or messed up item. Do it like
  433. // SL and assume trans
  434. if (nextPerms == permsMask)
  435. nextPerms |= (uint)PermissionMask.Transfer;
  436. // Inventory owner perms are the logical AND of the
  437. // folded perms and the root prim perms, however, if
  438. // the root prim is mod, the inventory perms will be
  439. // mod. This happens on "take" and is of little concern
  440. // here, save for preventing escalation
  441. // This hack ensures that items previously permalocked
  442. // get unlocked when they're passed or rezzed
  443. uint basePerms = item.BasePermissions |
  444. (uint)PermissionMask.Move;
  445. uint ownerPerms = item.CurrentPermissions;
  446. // If this is an object, root prim perms may be more
  447. // permissive than folded perms. Use folded perms as
  448. // a mask
  449. if (item.InvType == (int)InventoryType.Object)
  450. {
  451. // Create a safe mask for the current perms
  452. uint foldedPerms = (item.CurrentPermissions & 7) << 13;
  453. foldedPerms |= permsMask;
  454. bool isRootMod = (item.CurrentPermissions &
  455. (uint)PermissionMask.Modify) != 0 ?
  456. true : false;
  457. // Mask the owner perms to the folded perms
  458. ownerPerms &= foldedPerms;
  459. basePerms &= foldedPerms;
  460. // If the root was mod, let the mask reflect that
  461. // We also need to adjust the base here, because
  462. // we should be able to edit in-inventory perms
  463. // for the root prim, if it's mod.
  464. if (isRootMod)
  465. {
  466. ownerPerms |= (uint)PermissionMask.Modify;
  467. basePerms |= (uint)PermissionMask.Modify;
  468. }
  469. }
  470. // These will be applied to the root prim at next rez.
  471. // The slam bit (bit 3) and folded permission (bits 0-2)
  472. // are preserved due to the above mangling
  473. ownerPerms &= nextPerms;
  474. // Mask the base permissions. This is a conservative
  475. // approach altering only the three main perms
  476. basePerms &= nextPerms;
  477. // Assign to the actual item. Make sure the slam bit is
  478. // set, if it wasn't set before.
  479. itemCopy.BasePermissions = basePerms;
  480. itemCopy.CurrentPermissions = ownerPerms;
  481. itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
  482. itemCopy.NextPermissions = item.NextPermissions;
  483. // This preserves "everyone can move"
  484. itemCopy.EveryOnePermissions = item.EveryOnePermissions &
  485. nextPerms;
  486. // Intentionally killing "share with group" here, as
  487. // the recipient will not have the group this is
  488. // set to
  489. itemCopy.GroupPermissions = 0;
  490. }
  491. else
  492. {
  493. itemCopy.CurrentPermissions = item.CurrentPermissions;
  494. itemCopy.NextPermissions = item.NextPermissions;
  495. itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
  496. itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
  497. itemCopy.BasePermissions = item.BasePermissions;
  498. }
  499. if (itemCopy.Folder == UUID.Zero)
  500. {
  501. InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType);
  502. if (folder != null)
  503. {
  504. itemCopy.Folder = folder.ID;
  505. }
  506. else
  507. {
  508. InventoryFolderBase root = InventoryService.GetRootFolder(recipient);
  509. if (root != null)
  510. itemCopy.Folder = root.ID;
  511. else
  512. return null; // No destination
  513. }
  514. }
  515. itemCopy.GroupID = UUID.Zero;
  516. itemCopy.GroupOwned = false;
  517. itemCopy.Flags = item.Flags;
  518. itemCopy.SalePrice = item.SalePrice;
  519. itemCopy.SaleType = item.SaleType;
  520. if (AddInventoryItem(itemCopy))
  521. {
  522. IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
  523. if (invAccess != null)
  524. invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
  525. }
  526. if (!Permissions.BypassPermissions())
  527. {
  528. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  529. {
  530. List<UUID> items = new List<UUID>();
  531. items.Add(itemId);
  532. InventoryService.DeleteItems(senderId, items);
  533. }
  534. }
  535. return itemCopy;
  536. }
  537. else
  538. {
  539. m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId);
  540. return null;
  541. }
  542. }
  543. /// <summary>
  544. /// Give an entire inventory folder from one user to another. The entire contents (including all descendent
  545. /// folders) is given.
  546. /// </summary>
  547. /// <param name="recipientId"></param>
  548. /// <param name="senderId">ID of the sender of the item</param>
  549. /// <param name="folderId"></param>
  550. /// <param name="recipientParentFolderId">
  551. /// The id of the receipient folder in which the send folder should be placed. If UUID.Zero then the
  552. /// recipient folder is the root folder
  553. /// </param>
  554. /// <returns>
  555. /// The inventory folder copy given, null if the copy was unsuccessful
  556. /// </returns>
  557. public virtual InventoryFolderBase GiveInventoryFolder(
  558. UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId)
  559. {
  560. //// Retrieve the folder from the sender
  561. InventoryFolderBase folder = InventoryService.GetFolder(new InventoryFolderBase(folderId));
  562. if (null == folder)
  563. {
  564. m_log.ErrorFormat(
  565. "[AGENT INVENTORY]: Could not find inventory folder {0} to give", folderId);
  566. return null;
  567. }
  568. if (recipientParentFolderId == UUID.Zero)
  569. {
  570. InventoryFolderBase recipientRootFolder = InventoryService.GetRootFolder(recipientId);
  571. if (recipientRootFolder != null)
  572. recipientParentFolderId = recipientRootFolder.ID;
  573. else
  574. {
  575. m_log.WarnFormat("[AGENT INVENTORY]: Unable to find root folder for receiving agent");
  576. return null;
  577. }
  578. }
  579. UUID newFolderId = UUID.Random();
  580. InventoryFolderBase newFolder
  581. = new InventoryFolderBase(
  582. newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version);
  583. InventoryService.AddFolder(newFolder);
  584. // Give all the subfolders
  585. InventoryCollection contents = InventoryService.GetFolderContent(senderId, folderId);
  586. foreach (InventoryFolderBase childFolder in contents.Folders)
  587. {
  588. GiveInventoryFolder(recipientId, senderId, childFolder.ID, newFolder.ID);
  589. }
  590. // Give all the items
  591. foreach (InventoryItemBase item in contents.Items)
  592. {
  593. GiveInventoryItem(recipientId, senderId, item.ID, newFolder.ID);
  594. }
  595. return newFolder;
  596. }
  597. public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID,
  598. UUID newFolderID, string newName)
  599. {
  600. m_log.DebugFormat(
  601. "[AGENT INVENTORY]: CopyInventoryItem received by {0} with oldAgentID {1}, oldItemID {2}, new FolderID {3}, newName {4}",
  602. remoteClient.AgentId, oldAgentID, oldItemID, newFolderID, newName);
  603. InventoryItemBase item = null;
  604. if (LibraryService != null && LibraryService.LibraryRootFolder != null)
  605. item = LibraryService.LibraryRootFolder.FindItem(oldItemID);
  606. if (item == null)
  607. {
  608. item = new InventoryItemBase(oldItemID, remoteClient.AgentId);
  609. item = InventoryService.GetItem(item);
  610. if (item == null)
  611. {
  612. m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString());
  613. return;
  614. }
  615. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  616. return;
  617. }
  618. AssetBase asset = AssetService.Get(item.AssetID.ToString());
  619. if (asset != null)
  620. {
  621. if (newName != String.Empty)
  622. {
  623. asset.Name = newName;
  624. }
  625. else
  626. {
  627. newName = item.Name;
  628. }
  629. if (remoteClient.AgentId == oldAgentID)
  630. {
  631. CreateNewInventoryItem(
  632. remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
  633. item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
  634. }
  635. else
  636. {
  637. // If item is transfer or permissions are off or calling agent is allowed to copy item owner's inventory item.
  638. if (((item.CurrentPermissions & (uint)PermissionMask.Transfer) != 0) && (m_permissions.BypassPermissions() || m_permissions.CanCopyUserInventory(remoteClient.AgentId, oldItemID)))
  639. {
  640. CreateNewInventoryItem(
  641. remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID,
  642. asset, (sbyte) item.InvType,
  643. item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions,
  644. item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
  645. }
  646. }
  647. }
  648. else
  649. {
  650. m_log.ErrorFormat(
  651. "[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found",
  652. item.Name, item.AssetID);
  653. }
  654. }
  655. /// <summary>
  656. /// Create a new asset data structure.
  657. /// </summary>
  658. public AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data, UUID creatorID)
  659. {
  660. AssetBase asset = new AssetBase(UUID.Random(), name, assetType, creatorID.ToString());
  661. asset.Description = description;
  662. asset.Data = (data == null) ? new byte[1] : data;
  663. return asset;
  664. }
  665. /// <summary>
  666. /// Move an item within the agent's inventory.
  667. /// </summary>
  668. /// <param name="remoteClient"></param>
  669. /// <param name="folderID"></param>
  670. /// <param name="itemID"></param>
  671. /// <param name="length"></param>
  672. /// <param name="newName"></param>
  673. public void MoveInventoryItem(IClientAPI remoteClient, List<InventoryItemBase> items)
  674. {
  675. m_log.DebugFormat(
  676. "[AGENT INVENTORY]: Moving {0} items for user {1}", items.Count, remoteClient.AgentId);
  677. if (!InventoryService.MoveItems(remoteClient.AgentId, items))
  678. m_log.Warn("[AGENT INVENTORY]: Failed to move items for user " + remoteClient.AgentId);
  679. }
  680. /// <summary>
  681. /// Create a new inventory item.
  682. /// </summary>
  683. /// <param name="remoteClient"></param>
  684. /// <param name="folderID"></param>
  685. /// <param name="callbackID"></param>
  686. /// <param name="asset"></param>
  687. /// <param name="invType"></param>
  688. /// <param name="nextOwnerMask"></param>
  689. private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
  690. AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
  691. {
  692. CreateNewInventoryItem(
  693. remoteClient, creatorID, creatorData, folderID, name, flags, callbackID, asset, invType,
  694. (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate);
  695. }
  696. /// <summary>
  697. /// Create a new Inventory Item
  698. /// </summary>
  699. /// <param name="remoteClient"></param>
  700. /// <param name="folderID"></param>
  701. /// <param name="callbackID"></param>
  702. /// <param name="asset"></param>
  703. /// <param name="invType"></param>
  704. /// <param name="nextOwnerMask"></param>
  705. /// <param name="creationDate"></param>
  706. private void CreateNewInventoryItem(
  707. IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType,
  708. uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
  709. {
  710. InventoryItemBase item = new InventoryItemBase();
  711. item.Owner = remoteClient.AgentId;
  712. item.CreatorId = creatorID;
  713. item.CreatorData = creatorData;
  714. item.ID = UUID.Random();
  715. item.AssetID = asset.FullID;
  716. item.Description = asset.Description;
  717. item.Name = name;
  718. item.Flags = flags;
  719. item.AssetType = asset.Type;
  720. item.InvType = invType;
  721. item.Folder = folderID;
  722. item.CurrentPermissions = currentMask;
  723. item.NextPermissions = nextOwnerMask;
  724. item.EveryOnePermissions = everyoneMask;
  725. item.GroupPermissions = groupMask;
  726. item.BasePermissions = baseMask;
  727. item.CreationDate = creationDate;
  728. if (AddInventoryItem(item))
  729. {
  730. remoteClient.SendInventoryItemCreateUpdate(item, callbackID);
  731. }
  732. else
  733. {
  734. m_dialogModule.SendAlertToUser(remoteClient, "Failed to create item");
  735. m_log.WarnFormat(
  736. "Failed to add item for {0} in CreateNewInventoryItem!",
  737. remoteClient.Name);
  738. }
  739. }
  740. /// <summary>
  741. /// Create a new inventory item. Called when the client creates a new item directly within their
  742. /// inventory (e.g. by selecting a context inventory menu option).
  743. /// </summary>
  744. /// <param name="remoteClient"></param>
  745. /// <param name="transactionID"></param>
  746. /// <param name="folderID"></param>
  747. /// <param name="callbackID"></param>
  748. /// <param name="description"></param>
  749. /// <param name="name"></param>
  750. /// <param name="invType"></param>
  751. /// <param name="type"></param>
  752. /// <param name="wearableType"></param>
  753. /// <param name="nextOwnerMask"></param>
  754. public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
  755. uint callbackID, string description, string name, sbyte invType,
  756. sbyte assetType,
  757. byte wearableType, uint nextOwnerMask, int creationDate)
  758. {
  759. m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
  760. if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
  761. return;
  762. InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
  763. InventoryFolderBase folder = InventoryService.GetFolder(f);
  764. if (folder == null || folder.Owner != remoteClient.AgentId)
  765. return;
  766. if (transactionID == UUID.Zero)
  767. {
  768. ScenePresence presence;
  769. if (TryGetScenePresence(remoteClient.AgentId, out presence))
  770. {
  771. byte[] data = null;
  772. if (invType == (sbyte)InventoryType.Landmark && presence != null)
  773. {
  774. Vector3 pos = presence.AbsolutePosition;
  775. string strdata = String.Format(
  776. "Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
  777. presence.Scene.RegionInfo.RegionID,
  778. pos.X, pos.Y, pos.Z,
  779. presence.RegionHandle);
  780. data = Encoding.ASCII.GetBytes(strdata);
  781. }
  782. AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
  783. AssetService.Store(asset);
  784. CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
  785. }
  786. else
  787. {
  788. m_log.ErrorFormat(
  789. "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
  790. remoteClient.AgentId);
  791. }
  792. }
  793. else
  794. {
  795. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  796. if (agentTransactions != null)
  797. {
  798. agentTransactions.HandleItemCreationFromTransaction(
  799. remoteClient, transactionID, folderID, callbackID, description,
  800. name, invType, assetType, wearableType, nextOwnerMask);
  801. }
  802. }
  803. }
  804. private void HandleLinkInventoryItem(IClientAPI remoteClient, UUID transActionID, UUID folderID,
  805. uint callbackID, string description, string name,
  806. sbyte invType, sbyte type, UUID olditemID)
  807. {
  808. m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item link {0} in folder {1} pointing to {2}", name, folderID, olditemID);
  809. if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
  810. return;
  811. ScenePresence presence;
  812. if (TryGetScenePresence(remoteClient.AgentId, out presence))
  813. {
  814. // byte[] data = null;
  815. AssetBase asset = new AssetBase();
  816. asset.FullID = olditemID;
  817. asset.Type = type;
  818. asset.Name = name;
  819. asset.Description = description;
  820. CreateNewInventoryItem(
  821. remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType,
  822. (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All,
  823. (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch());
  824. }
  825. else
  826. {
  827. m_log.ErrorFormat(
  828. "ScenePresence for agent uuid {0} unexpectedly not found in HandleLinkInventoryItem",
  829. remoteClient.AgentId);
  830. }
  831. }
  832. /// <summary>
  833. /// Remove an inventory item for the client's inventory
  834. /// </summary>
  835. /// <param name="remoteClient"></param>
  836. /// <param name="itemID"></param>
  837. private void RemoveInventoryItem(IClientAPI remoteClient, List<UUID> itemIDs)
  838. {
  839. //m_log.Debug("[SCENE INVENTORY]: user " + remoteClient.AgentId);
  840. InventoryService.DeleteItems(remoteClient.AgentId, itemIDs);
  841. }
  842. /// <summary>
  843. /// Removes an inventory folder. This packet is sent when the user
  844. /// right-clicks a folder that's already in trash and chooses "purge"
  845. /// </summary>
  846. /// <param name="remoteClient"></param>
  847. /// <param name="folderID"></param>
  848. private void RemoveInventoryFolder(IClientAPI remoteClient, List<UUID> folderIDs)
  849. {
  850. m_log.DebugFormat("[SCENE INVENTORY]: RemoveInventoryFolders count {0}", folderIDs.Count);
  851. InventoryService.DeleteFolders(remoteClient.AgentId, folderIDs);
  852. }
  853. /// <summary>
  854. /// Send the details of a prim's inventory to the client.
  855. /// </summary>
  856. /// <param name="remoteClient"></param>
  857. /// <param name="primLocalID"></param>
  858. public void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID)
  859. {
  860. SceneObjectPart part = GetSceneObjectPart(primLocalID);
  861. if (part == null)
  862. return;
  863. if (XferManager != null)
  864. part.Inventory.RequestInventoryFile(remoteClient, XferManager);
  865. }
  866. /// <summary>
  867. /// Remove an item from a prim (task) inventory
  868. /// </summary>
  869. /// <param name="remoteClient">Unused at the moment but retained since the avatar ID might
  870. /// be necessary for a permissions check at some stage.</param>
  871. /// <param name="itemID"></param>
  872. /// <param name="localID"></param>
  873. public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
  874. {
  875. SceneObjectPart part = GetSceneObjectPart(localID);
  876. SceneObjectGroup group = part.ParentGroup;
  877. if (group != null)
  878. {
  879. if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
  880. return;
  881. TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
  882. if (item == null)
  883. return;
  884. if (item.Type == 10)
  885. {
  886. part.RemoveScriptEvents(itemID);
  887. EventManager.TriggerRemoveScript(localID, itemID);
  888. }
  889. group.RemoveInventoryItem(localID, itemID);
  890. part.GetProperties(remoteClient);
  891. }
  892. else
  893. {
  894. m_log.ErrorFormat(
  895. "[PRIM INVENTORY]: " +
  896. "Removal of item {0} requested of prim {1} but this prim does not exist",
  897. itemID,
  898. localID);
  899. }
  900. }
  901. private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
  902. {
  903. TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
  904. if (null == taskItem)
  905. {
  906. m_log.ErrorFormat(
  907. "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for creating an avatar"
  908. + " inventory item from a prim's inventory item "
  909. + " but the required item does not exist in the prim's inventory",
  910. itemId, part.Name, part.UUID);
  911. return null;
  912. }
  913. if ((destAgent != taskItem.OwnerID) && ((taskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
  914. {
  915. return null;
  916. }
  917. InventoryItemBase agentItem = new InventoryItemBase();
  918. agentItem.ID = UUID.Random();
  919. agentItem.CreatorId = taskItem.CreatorID.ToString();
  920. agentItem.CreatorData = taskItem.CreatorData;
  921. agentItem.Owner = destAgent;
  922. agentItem.AssetID = taskItem.AssetID;
  923. agentItem.Description = taskItem.Description;
  924. agentItem.Name = taskItem.Name;
  925. agentItem.AssetType = taskItem.Type;
  926. agentItem.InvType = taskItem.InvType;
  927. agentItem.Flags = taskItem.Flags;
  928. if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions())
  929. {
  930. agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
  931. if (taskItem.InvType == (int)InventoryType.Object)
  932. agentItem.CurrentPermissions = agentItem.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move));
  933. else
  934. agentItem.CurrentPermissions = agentItem.BasePermissions & taskItem.CurrentPermissions;
  935. agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
  936. agentItem.NextPermissions = taskItem.NextPermissions;
  937. agentItem.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
  938. agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions;
  939. }
  940. else
  941. {
  942. agentItem.BasePermissions = taskItem.BasePermissions;
  943. agentItem.CurrentPermissions = taskItem.CurrentPermissions;
  944. agentItem.NextPermissions = taskItem.NextPermissions;
  945. agentItem.EveryOnePermissions = taskItem.EveryonePermissions;
  946. agentItem.GroupPermissions = taskItem.GroupPermissions;
  947. }
  948. if (!Permissions.BypassPermissions())
  949. {
  950. if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  951. part.Inventory.RemoveInventoryItem(itemId);
  952. }
  953. return agentItem;
  954. }
  955. /// <summary>
  956. /// Move the given item in the given prim to a folder in the client's inventory
  957. /// </summary>
  958. /// <param name="remoteClient"></param>
  959. /// <param name="folderID"></param>
  960. /// <param name="part"></param>
  961. /// <param name="itemID"></param>
  962. public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId)
  963. {
  964. m_log.DebugFormat(
  965. "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}",
  966. itemId, part.Name, folderId, remoteClient.Name);
  967. InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId);
  968. if (agentItem == null)
  969. return null;
  970. agentItem.Folder = folderId;
  971. AddInventoryItem(remoteClient, agentItem);
  972. return agentItem;
  973. }
  974. /// <summary>
  975. /// <see>ClientMoveTaskInventoryItem</see>
  976. /// </summary>
  977. /// <param name="remoteClient"></param>
  978. /// <param name="folderID"></param>
  979. /// <param name="primLocalID"></param>
  980. /// <param name="itemID"></param>
  981. public void ClientMoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, uint primLocalId, UUID itemId)
  982. {
  983. SceneObjectPart part = GetSceneObjectPart(primLocalId);
  984. if (null == part)
  985. {
  986. m_log.WarnFormat(
  987. "[PRIM INVENTORY]: " +
  988. "Move of inventory item {0} from prim with local id {1} failed because the prim could not be found",
  989. itemId, primLocalId);
  990. return;
  991. }
  992. TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
  993. if (null == taskItem)
  994. {
  995. m_log.WarnFormat("[PRIM INVENTORY]: Move of inventory item {0} from prim with local id {1} failed"
  996. + " because the inventory item could not be found",
  997. itemId, primLocalId);
  998. return;
  999. }
  1000. TaskInventoryItem item = part.Inventory.GetInventoryItem(itemId);
  1001. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  1002. {
  1003. // If the item to be moved is no copy, we need to be able to
  1004. // edit the prim.
  1005. if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
  1006. return;
  1007. }
  1008. else
  1009. {
  1010. // If the item is copiable, then we just need to have perms
  1011. // on it. The delete check is a pure rights check
  1012. if (!Permissions.CanDeleteObject(part.UUID, remoteClient.AgentId))
  1013. return;
  1014. }
  1015. MoveTaskInventoryItem(remoteClient, folderId, part, itemId);
  1016. }
  1017. /// <summary>
  1018. /// <see>MoveTaskInventoryItem</see>
  1019. /// </summary>
  1020. /// <param name="remoteClient"></param>
  1021. /// <param name="folderID">
  1022. /// The user inventory folder to move (or copy) the item to. If null, then the most
  1023. /// suitable system folder is used (e.g. the Objects folder for objects). If there is no suitable folder, then
  1024. /// the item is placed in the user's root inventory folder
  1025. /// </param>
  1026. /// <param name="part"></param>
  1027. /// <param name="itemID"></param>
  1028. public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId)
  1029. {
  1030. ScenePresence avatar;
  1031. if (TryGetScenePresence(avatarId, out avatar))
  1032. {
  1033. return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId);
  1034. }
  1035. else
  1036. {
  1037. InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(avatarId, part, itemId);
  1038. if (agentItem == null)
  1039. return null;
  1040. agentItem.Folder = folderId;
  1041. AddInventoryItem(agentItem);
  1042. return agentItem;
  1043. }
  1044. }
  1045. /// <summary>
  1046. /// Copy a task (prim) inventory item to another task (prim)
  1047. /// </summary>
  1048. /// <param name="destId"></param>
  1049. /// <param name="part"></param>
  1050. /// <param name="itemId"></param>
  1051. public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId)
  1052. {
  1053. TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId);
  1054. if (srcTaskItem == null)
  1055. {
  1056. m_log.ErrorFormat(
  1057. "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for moving"
  1058. + " but the item does not exist in this inventory",
  1059. itemId, part.Name, part.UUID);
  1060. return;
  1061. }
  1062. SceneObjectPart destPart = GetSceneObjectPart(destId);
  1063. if (destPart == null)
  1064. {
  1065. m_log.ErrorFormat(
  1066. "[PRIM INVENTORY]: " +
  1067. "Could not find prim for ID {0}",
  1068. destId);
  1069. return;
  1070. }
  1071. // Can't transfer this
  1072. //
  1073. if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
  1074. return;
  1075. if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
  1076. {
  1077. // object cannot copy items to an object owned by a different owner
  1078. // unless llAllowInventoryDrop has been called
  1079. return;
  1080. }
  1081. // must have both move and modify permission to put an item in an object
  1082. if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0)
  1083. {
  1084. return;
  1085. }
  1086. TaskInventoryItem destTaskItem = new TaskInventoryItem();
  1087. destTaskItem.ItemID = UUID.Random();
  1088. destTaskItem.CreatorID = srcTaskItem.CreatorID;
  1089. destTaskItem.CreatorData = srcTaskItem.CreatorData;
  1090. destTaskItem.AssetID = srcTaskItem.AssetID;
  1091. destTaskItem.GroupID = destPart.GroupID;
  1092. destTaskItem.OwnerID = destPart.OwnerID;
  1093. destTaskItem.ParentID = destPart.UUID;
  1094. destTaskItem.ParentPartID = destPart.UUID;
  1095. destTaskItem.BasePermissions = srcTaskItem.BasePermissions;
  1096. destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions;
  1097. destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions;
  1098. destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions;
  1099. destTaskItem.NextPermissions = srcTaskItem.NextPermissions;
  1100. destTaskItem.Flags = srcTaskItem.Flags;
  1101. if (destPart.OwnerID != part.OwnerID)
  1102. {
  1103. if (Permissions.PropagatePermissions())
  1104. {
  1105. destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
  1106. (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
  1107. destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
  1108. (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
  1109. destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
  1110. (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
  1111. destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
  1112. (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
  1113. destTaskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
  1114. }
  1115. }
  1116. destTaskItem.Description = srcTaskItem.Description;
  1117. destTaskItem.Name = srcTaskItem.Name;
  1118. destTaskItem.InvType = srcTaskItem.InvType;
  1119. destTaskItem.Type = srcTaskItem.Type;
  1120. destPart.Inventory.AddInventoryItem(destTaskItem, part.OwnerID != destPart.OwnerID);
  1121. if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  1122. part.Inventory.RemoveInventoryItem(itemId);
  1123. ScenePresence avatar;
  1124. if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
  1125. {
  1126. destPart.GetProperties(avatar.ControllingClient);
  1127. }
  1128. }
  1129. public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items)
  1130. {
  1131. InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID);
  1132. UUID newFolderID = UUID.Random();
  1133. InventoryFolderBase newFolder = new InventoryFolderBase(newFolderID, category, destID, -1, rootFolder.ID, rootFolder.Version);
  1134. InventoryService.AddFolder(newFolder);
  1135. foreach (UUID itemID in items)
  1136. {
  1137. InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(destID, host, itemID);
  1138. if (agentItem != null)
  1139. {
  1140. agentItem.Folder = newFolderID;
  1141. AddInventoryItem(agentItem);
  1142. }
  1143. }
  1144. ScenePresence avatar = null;
  1145. if (TryGetScenePresence(destID, out avatar))
  1146. {
  1147. //profile.SendInventoryDecendents(avatar.ControllingClient,
  1148. // profile.RootFolder.ID, true, false);
  1149. //profile.SendInventoryDecendents(avatar.ControllingClient,
  1150. // newFolderID, false, true);
  1151. SendInventoryUpdate(avatar.ControllingClient, rootFolder, true, false);
  1152. SendInventoryUpdate(avatar.ControllingClient, newFolder, false, true);
  1153. }
  1154. return newFolderID;
  1155. }
  1156. private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems)
  1157. {
  1158. if (folder == null)
  1159. return;
  1160. // TODO: This code for looking in the folder for the library should be folded somewhere else
  1161. // so that this class doesn't have to know the details (and so that multiple libraries, etc.
  1162. // can be handled transparently).
  1163. InventoryFolderImpl fold = null;
  1164. if (LibraryService != null && LibraryService.LibraryRootFolder != null)
  1165. {
  1166. if ((fold = LibraryService.LibraryRootFolder.FindFolder(folder.ID)) != null)
  1167. {
  1168. client.SendInventoryFolderDetails(
  1169. fold.Owner, folder.ID, fold.RequestListOfItems(),
  1170. fold.RequestListOfFolders(), fold.Version, fetchFolders, fetchItems);
  1171. return;
  1172. }
  1173. }
  1174. // Fetch the folder contents
  1175. InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID);
  1176. // Fetch the folder itself to get its current version
  1177. InventoryFolderBase containingFolder = new InventoryFolderBase(folder.ID, client.AgentId);
  1178. containingFolder = InventoryService.GetFolder(containingFolder);
  1179. //m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}",
  1180. // contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
  1181. if (containingFolder != null && containingFolder != null)
  1182. client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, containingFolder.Version, fetchFolders, fetchItems);
  1183. }
  1184. /// <summary>
  1185. /// Update an item in a prim (task) inventory.
  1186. /// This method does not handle scripts, <see>RezScript(IClientAPI, UUID, unit)</see>
  1187. /// </summary>
  1188. /// <param name="remoteClient"></param>
  1189. /// <param name="transactionID"></param>
  1190. /// <param name="itemInfo"></param>
  1191. /// <param name="primLocalID"></param>
  1192. public void UpdateTaskInventory(IClientAPI remoteClient, UUID transactionID, TaskInventoryItem itemInfo,
  1193. uint primLocalID)
  1194. {
  1195. UUID itemID = itemInfo.ItemID;
  1196. // Find the prim we're dealing with
  1197. SceneObjectPart part = GetSceneObjectPart(primLocalID);
  1198. if (part != null)
  1199. {
  1200. TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID);
  1201. bool allowInventoryDrop = (part.GetEffectiveObjectFlags()
  1202. & (uint)PrimFlags.AllowInventoryDrop) != 0;
  1203. // Explicity allow anyone to add to the inventory if the
  1204. // AllowInventoryDrop flag has been set. Don't however let
  1205. // them update an item unless they pass the external checks
  1206. //
  1207. if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)
  1208. && (currentItem != null || !allowInventoryDrop))
  1209. return;
  1210. if (currentItem == null)
  1211. {
  1212. UUID copyID = UUID.Random();
  1213. if (itemID != UUID.Zero)
  1214. {
  1215. InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
  1216. item = InventoryService.GetItem(item);
  1217. // Try library
  1218. if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null)
  1219. {
  1220. item = LibraryService.LibraryRootFolder.FindItem(itemID);
  1221. }
  1222. // If we've found the item in the user's inventory or in the library
  1223. if (item != null)
  1224. {
  1225. part.ParentGroup.AddInventoryItem(remoteClient, primLocalID, item, copyID);
  1226. m_log.InfoFormat(
  1227. "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
  1228. item.Name, primLocalID, remoteClient.Name);
  1229. part.GetProperties(remoteClient);
  1230. if (!Permissions.BypassPermissions())
  1231. {
  1232. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  1233. {
  1234. List<UUID> uuids = new List<UUID>();
  1235. uuids.Add(itemID);
  1236. RemoveInventoryItem(remoteClient, uuids);
  1237. }
  1238. }
  1239. }
  1240. else
  1241. {
  1242. m_log.ErrorFormat(
  1243. "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!",
  1244. itemID, remoteClient.Name);
  1245. }
  1246. }
  1247. }
  1248. else // Updating existing item with new perms etc
  1249. {
  1250. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  1251. if (agentTransactions != null)
  1252. {
  1253. agentTransactions.HandleTaskItemUpdateFromTransaction(
  1254. remoteClient, part, transactionID, currentItem);
  1255. if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
  1256. remoteClient.SendAgentAlertMessage("Notecard saved", false);
  1257. else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
  1258. remoteClient.SendAgentAlertMessage("Script saved", false);
  1259. else
  1260. remoteClient.SendAgentAlertMessage("Item saved", false);
  1261. }
  1262. // Base ALWAYS has move
  1263. currentItem.BasePermissions |= (uint)PermissionMask.Move;
  1264. itemInfo.Flags = currentItem.Flags;
  1265. // Check if we're allowed to mess with permissions
  1266. if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god
  1267. {
  1268. if (remoteClient.AgentId != part.OwnerID) // Not owner
  1269. {
  1270. // Friends and group members can't change any perms
  1271. itemInfo.BasePermissions = currentItem.BasePermissions;
  1272. itemInfo.EveryonePermissions = currentItem.EveryonePermissions;
  1273. itemInfo.GroupPermissions = currentItem.GroupPermissions;
  1274. itemInfo.NextPermissions = currentItem.NextPermissions;
  1275. itemInfo.CurrentPermissions = currentItem.CurrentPermissions;
  1276. }
  1277. else
  1278. {
  1279. // Owner can't change base, and can change other
  1280. // only up to base
  1281. itemInfo.BasePermissions = currentItem.BasePermissions;
  1282. if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions)
  1283. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
  1284. if (itemInfo.GroupPermissions != currentItem.GroupPermissions)
  1285. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
  1286. if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions)
  1287. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner;
  1288. if (itemInfo.NextPermissions != currentItem.NextPermissions)
  1289. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
  1290. itemInfo.EveryonePermissions &= currentItem.BasePermissions;
  1291. itemInfo.GroupPermissions &= currentItem.BasePermissions;
  1292. itemInfo.CurrentPermissions &= currentItem.BasePermissions;
  1293. itemInfo.NextPermissions &= currentItem.BasePermissions;
  1294. }
  1295. }
  1296. else
  1297. {
  1298. if (itemInfo.BasePermissions != currentItem.BasePermissions)
  1299. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteBase;
  1300. if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions)
  1301. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone;
  1302. if (itemInfo.GroupPermissions != currentItem.GroupPermissions)
  1303. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
  1304. if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions)
  1305. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner;
  1306. if (itemInfo.NextPermissions != currentItem.NextPermissions)
  1307. itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
  1308. }
  1309. // Next ALWAYS has move
  1310. itemInfo.NextPermissions |= (uint)PermissionMask.Move;
  1311. if (part.Inventory.UpdateInventoryItem(itemInfo))
  1312. {
  1313. part.GetProperties(remoteClient);
  1314. }
  1315. }
  1316. }
  1317. else
  1318. {
  1319. m_log.WarnFormat(
  1320. "[PRIM INVENTORY]: " +
  1321. "Update with item {0} requested of prim {1} for {2} but this prim does not exist",
  1322. itemID, primLocalID, remoteClient.Name);
  1323. }
  1324. }
  1325. /// <summary>
  1326. /// Rez a script into a prim's inventory, either ex nihilo or from an existing avatar inventory
  1327. /// </summary>
  1328. /// <param name="remoteClient"></param>
  1329. /// <param name="itemID"> </param>
  1330. /// <param name="localID"></param>
  1331. public void RezScript(IClientAPI remoteClient, InventoryItemBase itemBase, UUID transactionID, uint localID)
  1332. {
  1333. UUID itemID = itemBase.ID;
  1334. UUID copyID = UUID.Random();
  1335. if (itemID != UUID.Zero) // transferred from an avatar inventory to the prim's inventory
  1336. {
  1337. InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
  1338. item = InventoryService.GetItem(item);
  1339. // Try library
  1340. // XXX clumsy, possibly should be one call
  1341. if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null)
  1342. {
  1343. item = LibraryService.LibraryRootFolder.FindItem(itemID);
  1344. }
  1345. if (item != null)
  1346. {
  1347. SceneObjectPart part = GetSceneObjectPart(localID);
  1348. if (part != null)
  1349. {
  1350. if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
  1351. return;
  1352. part.ParentGroup.AddInventoryItem(remoteClient, localID, item, copyID);
  1353. // TODO: switch to posting on_rez here when scripts
  1354. // have state in inventory
  1355. part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
  1356. // m_log.InfoFormat("[PRIMINVENTORY]: " +
  1357. // "Rezzed script {0} into prim local ID {1} for user {2}",
  1358. // item.inventoryName, localID, remoteClient.Name);
  1359. part.GetProperties(remoteClient);
  1360. part.ParentGroup.ResumeScripts();
  1361. }
  1362. else
  1363. {
  1364. m_log.ErrorFormat(
  1365. "[PRIM INVENTORY]: " +
  1366. "Could not rez script {0} into prim local ID {1} for user {2}"
  1367. + " because the prim could not be found in the region!",
  1368. item.Name, localID, remoteClient.Name);
  1369. }
  1370. }
  1371. else
  1372. {
  1373. m_log.ErrorFormat(
  1374. "[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!",
  1375. itemID, remoteClient.Name);
  1376. }
  1377. }
  1378. else // script has been rezzed directly into a prim's inventory
  1379. {
  1380. SceneObjectPart part = GetSceneObjectPart(itemBase.Folder);
  1381. if (part == null)
  1382. return;
  1383. if (!Permissions.CanCreateObjectInventory(
  1384. itemBase.InvType, part.UUID, remoteClient.AgentId))
  1385. return;
  1386. AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType,
  1387. Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"),
  1388. remoteClient.AgentId);
  1389. AssetService.Store(asset);
  1390. TaskInventoryItem taskItem = new TaskInventoryItem();
  1391. taskItem.ResetIDs(itemBase.Folder);
  1392. taskItem.ParentID = itemBase.Folder;
  1393. taskItem.CreationDate = (uint)itemBase.CreationDate;
  1394. taskItem.Name = itemBase.Name;
  1395. taskItem.Description = itemBase.Description;
  1396. taskItem.Type = itemBase.AssetType;
  1397. taskItem.InvType = itemBase.InvType;
  1398. taskItem.OwnerID = itemBase.Owner;
  1399. taskItem.CreatorID = itemBase.CreatorIdAsUuid;
  1400. taskItem.BasePermissions = itemBase.BasePermissions;
  1401. taskItem.CurrentPermissions = itemBase.CurrentPermissions;
  1402. taskItem.EveryonePermissions = itemBase.EveryOnePermissions;
  1403. taskItem.GroupPermissions = itemBase.GroupPermissions;
  1404. taskItem.NextPermissions = itemBase.NextPermissions;
  1405. taskItem.GroupID = itemBase.GroupID;
  1406. taskItem.GroupPermissions = 0;
  1407. taskItem.Flags = itemBase.Flags;
  1408. taskItem.PermsGranter = UUID.Zero;
  1409. taskItem.PermsMask = 0;
  1410. taskItem.AssetID = asset.FullID;
  1411. part.Inventory.AddInventoryItem(taskItem, false);
  1412. part.GetProperties(remoteClient);
  1413. part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
  1414. part.ParentGroup.ResumeScripts();
  1415. }
  1416. }
  1417. /// <summary>
  1418. /// Rez a script into a prim's inventory from another prim
  1419. /// </summary>
  1420. /// <param name="remoteClient"></param>
  1421. /// <param name="itemID"> </param>
  1422. /// <param name="localID"></param>
  1423. public void RezScript(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param)
  1424. {
  1425. TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId);
  1426. if (srcTaskItem == null)
  1427. {
  1428. m_log.ErrorFormat(
  1429. "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for rezzing a script but the "
  1430. + " item does not exist in this inventory",
  1431. srcId, srcPart.Name, srcPart.UUID);
  1432. return;
  1433. }
  1434. SceneObjectPart destPart = GetSceneObjectPart(destId);
  1435. if (destPart == null)
  1436. {
  1437. m_log.ErrorFormat(
  1438. "[PRIM INVENTORY]: " +
  1439. "Could not find script for ID {0}",
  1440. destId);
  1441. return;
  1442. }
  1443. // Must own the object, and have modify rights
  1444. if (srcPart.OwnerID != destPart.OwnerID)
  1445. {
  1446. // Group permissions
  1447. if ((destPart.GroupID == UUID.Zero) || (destPart.GroupID != srcPart.GroupID) ||
  1448. ((destPart.GroupMask & (uint)PermissionMask.Modify) == 0))
  1449. return;
  1450. } else {
  1451. if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0)
  1452. return;
  1453. }
  1454. if (destPart.ScriptAccessPin != pin)
  1455. {
  1456. m_log.WarnFormat(
  1457. "[PRIM INVENTORY]: " +
  1458. "Script in object {0} : {1}, attempted to load script {2} : {3} into object {4} : {5} with invalid pin {6}",
  1459. srcPart.Name, srcId, srcTaskItem.Name, srcTaskItem.ItemID, destPart.Name, destId, pin);
  1460. // the LSL Wiki says we are supposed to shout on the DEBUG_CHANNEL -
  1461. // "Object: Task Object trying to illegally load script onto task Other_Object!"
  1462. // How do we shout from in here?
  1463. return;
  1464. }
  1465. TaskInventoryItem destTaskItem = new TaskInventoryItem();
  1466. destTaskItem.ItemID = UUID.Random();
  1467. destTaskItem.CreatorID = srcTaskItem.CreatorID;
  1468. destTaskItem.CreatorData = srcTaskItem.CreatorData;
  1469. destTaskItem.AssetID = srcTaskItem.AssetID;
  1470. destTaskItem.GroupID = destPart.GroupID;
  1471. destTaskItem.OwnerID = destPart.OwnerID;
  1472. destTaskItem.ParentID = destPart.UUID;
  1473. destTaskItem.ParentPartID = destPart.UUID;
  1474. destTaskItem.BasePermissions = srcTaskItem.BasePermissions;
  1475. destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions;
  1476. destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions;
  1477. destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions;
  1478. destTaskItem.NextPermissions = srcTaskItem.NextPermissions;
  1479. destTaskItem.Flags = srcTaskItem.Flags;
  1480. if (destPart.OwnerID != srcPart.OwnerID)
  1481. {
  1482. if (Permissions.PropagatePermissions())
  1483. {
  1484. destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
  1485. srcTaskItem.NextPermissions;
  1486. destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
  1487. srcTaskItem.NextPermissions;
  1488. destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
  1489. srcTaskItem.NextPermissions;
  1490. destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
  1491. srcTaskItem.NextPermissions;
  1492. destTaskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
  1493. }
  1494. }
  1495. destTaskItem.Description = srcTaskItem.Description;
  1496. destTaskItem.Name = srcTaskItem.Name;
  1497. destTaskItem.InvType = srcTaskItem.InvType;
  1498. destTaskItem.Type = srcTaskItem.Type;
  1499. destPart.Inventory.AddInventoryItemExclusive(destTaskItem, false);
  1500. if (running > 0)
  1501. {
  1502. destPart.Inventory.CreateScriptInstance(destTaskItem, start_param, false, DefaultScriptEngine, 0);
  1503. }
  1504. destPart.ParentGroup.ResumeScripts();
  1505. ScenePresence avatar;
  1506. if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
  1507. {
  1508. destPart.GetProperties(avatar.ControllingClient);
  1509. }
  1510. }
  1511. public virtual void DeRezObjects(IClientAPI remoteClient, List<uint> localIDs,
  1512. UUID groupID, DeRezAction action, UUID destinationID)
  1513. {
  1514. // First, see of we can perform the requested action and
  1515. // build a list of eligible objects
  1516. List<uint> deleteIDs = new List<uint>();
  1517. List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
  1518. // Start with true for both, then remove the flags if objects
  1519. // that we can't derez are part of the selection
  1520. bool permissionToTake = true;
  1521. bool permissionToTakeCopy = true;
  1522. bool permissionToDelete = true;
  1523. foreach (uint localID in localIDs)
  1524. {
  1525. // Invalid id
  1526. SceneObjectPart part = GetSceneObjectPart(localID);
  1527. if (part == null)
  1528. continue;
  1529. // Already deleted by someone else
  1530. if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
  1531. continue;
  1532. // Can't delete child prims
  1533. if (part != part.ParentGroup.RootPart)
  1534. continue;
  1535. SceneObjectGroup grp = part.ParentGroup;
  1536. deleteIDs.Add(localID);
  1537. deleteGroups.Add(grp);
  1538. if (remoteClient == null)
  1539. {
  1540. // Autoreturn has a null client. Nothing else does. So
  1541. // allow only returns
  1542. if (action != DeRezAction.Return)
  1543. {
  1544. m_log.WarnFormat(
  1545. "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client",
  1546. action, grp.Name, grp.UUID);
  1547. return;
  1548. }
  1549. permissionToTakeCopy = false;
  1550. }
  1551. else
  1552. {
  1553. if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId))
  1554. permissionToTakeCopy = false;
  1555. if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId))
  1556. permissionToTake = false;
  1557. if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId))
  1558. permissionToDelete = false;
  1559. }
  1560. }
  1561. // Handle god perms
  1562. if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
  1563. {
  1564. permissionToTake = true;
  1565. permissionToTakeCopy = true;
  1566. permissionToDelete = true;
  1567. }
  1568. // If we're re-saving, we don't even want to delete
  1569. if (action == DeRezAction.SaveToExistingUserInventoryItem)
  1570. permissionToDelete = false;
  1571. // if we want to take a copy, we also don't want to delete
  1572. // Note: after this point, the permissionToTakeCopy flag
  1573. // becomes irrelevant. It already includes the permissionToTake
  1574. // permission and after excluding no copy items here, we can
  1575. // just use that.
  1576. if (action == DeRezAction.TakeCopy)
  1577. {
  1578. // If we don't have permission, stop right here
  1579. if (!permissionToTakeCopy)
  1580. return;
  1581. permissionToTake = true;
  1582. // Don't delete
  1583. permissionToDelete = false;
  1584. }
  1585. if (action == DeRezAction.Return)
  1586. {
  1587. if (remoteClient != null)
  1588. {
  1589. if (Permissions.CanReturnObjects(
  1590. null,
  1591. remoteClient.AgentId,
  1592. deleteGroups))
  1593. {
  1594. permissionToTake = true;
  1595. permissionToDelete = true;
  1596. foreach (SceneObjectGroup g in deleteGroups)
  1597. {
  1598. AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return");
  1599. }
  1600. }
  1601. }
  1602. else // Auto return passes through here with null agent
  1603. {
  1604. permissionToTake = true;
  1605. permissionToDelete = true;
  1606. }
  1607. }
  1608. if (permissionToTake)
  1609. {
  1610. m_asyncSceneObjectDeleter.DeleteToInventory(
  1611. action, destinationID, deleteGroups, remoteClient,
  1612. permissionToDelete);
  1613. }
  1614. else if (permissionToDelete)
  1615. {
  1616. foreach (SceneObjectGroup g in deleteGroups)
  1617. DeleteSceneObject(g, false);
  1618. }
  1619. }
  1620. public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID)
  1621. {
  1622. itemID = UUID.Zero;
  1623. if (grp != null)
  1624. {
  1625. Vector3 inventoryStoredPosition = new Vector3
  1626. (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
  1627. ? 250
  1628. : grp.AbsolutePosition.X)
  1629. ,
  1630. (grp.AbsolutePosition.X > (int)Constants.RegionSize)
  1631. ? 250
  1632. : grp.AbsolutePosition.X,
  1633. grp.AbsolutePosition.Z);
  1634. Vector3 originalPosition = grp.AbsolutePosition;
  1635. grp.AbsolutePosition = inventoryStoredPosition;
  1636. string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
  1637. grp.AbsolutePosition = originalPosition;
  1638. AssetBase asset = CreateAsset(
  1639. grp.GetPartName(grp.LocalId),
  1640. grp.GetPartDescription(grp.LocalId),
  1641. (sbyte)AssetType.Object,
  1642. Utils.StringToBytes(sceneObjectXml),
  1643. remoteClient.AgentId);
  1644. AssetService.Store(asset);
  1645. InventoryItemBase item = new InventoryItemBase();
  1646. item.CreatorId = grp.RootPart.CreatorID.ToString();
  1647. item.CreatorData = grp.RootPart.CreatorData;
  1648. item.Owner = remoteClient.AgentId;
  1649. item.ID = UUID.Random();
  1650. item.AssetID = asset.FullID;
  1651. item.Description = asset.Description;
  1652. item.Name = asset.Name;
  1653. item.AssetType = asset.Type;
  1654. item.InvType = (int)InventoryType.Object;
  1655. InventoryFolderBase folder = InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object);
  1656. if (folder != null)
  1657. item.Folder = folder.ID;
  1658. else // oopsies
  1659. item.Folder = UUID.Zero;
  1660. if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions())
  1661. {
  1662. item.BasePermissions = grp.RootPart.NextOwnerMask;
  1663. item.CurrentPermissions = grp.RootPart.NextOwnerMask;
  1664. item.NextPermissions = grp.RootPart.NextOwnerMask;
  1665. item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
  1666. item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
  1667. }
  1668. else
  1669. {
  1670. item.BasePermissions = grp.RootPart.BaseMask;
  1671. item.CurrentPermissions = grp.RootPart.OwnerMask;
  1672. item.NextPermissions = grp.RootPart.NextOwnerMask;
  1673. item.EveryOnePermissions = grp.RootPart.EveryoneMask;
  1674. item.GroupPermissions = grp.RootPart.GroupMask;
  1675. }
  1676. item.CreationDate = Util.UnixTimeSinceEpoch();
  1677. // sets itemID so client can show item as 'attached' in inventory
  1678. grp.SetFromItemID(item.ID);
  1679. if (AddInventoryItem(item))
  1680. remoteClient.SendInventoryItemCreateUpdate(item, 0);
  1681. else
  1682. m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
  1683. itemID = item.ID;
  1684. return item.AssetID;
  1685. }
  1686. return UUID.Zero;
  1687. }
  1688. /// <summary>
  1689. /// Event Handler Rez an object into a scene
  1690. /// Calls the non-void event handler
  1691. /// </summary>
  1692. /// <param name="remoteClient"></param>
  1693. /// <param name="itemID"></param>
  1694. /// <param name="RayEnd"></param>
  1695. /// <param name="RayStart"></param>
  1696. /// <param name="RayTargetID"></param>
  1697. /// <param name="BypassRayCast"></param>
  1698. /// <param name="RayEndIsIntersection"></param>
  1699. /// <param name="EveryoneMask"></param>
  1700. /// <param name="GroupMask"></param>
  1701. /// <param name="RezSelected"></param>
  1702. /// <param name="RemoveItem"></param>
  1703. /// <param name="fromTaskID"></param>
  1704. public virtual void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
  1705. UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
  1706. bool RezSelected, bool RemoveItem, UUID fromTaskID)
  1707. {
  1708. // m_log.DebugFormat(
  1709. // "[PRIM INVENTORY]: RezObject from {0} for item {1} from task id {2}",
  1710. // remoteClient.Name, itemID, fromTaskID);
  1711. if (fromTaskID == UUID.Zero)
  1712. {
  1713. IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
  1714. if (invAccess != null)
  1715. invAccess.RezObject(
  1716. remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
  1717. RezSelected, RemoveItem, fromTaskID, false);
  1718. }
  1719. else
  1720. {
  1721. SceneObjectPart part = GetSceneObjectPart(fromTaskID);
  1722. if (part == null)
  1723. {
  1724. m_log.ErrorFormat(
  1725. "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such scene object",
  1726. remoteClient.Name, itemID, fromTaskID);
  1727. return;
  1728. }
  1729. TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID);
  1730. if (item == null)
  1731. {
  1732. m_log.ErrorFormat(
  1733. "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such item",
  1734. remoteClient.Name, itemID, fromTaskID);
  1735. return;
  1736. }
  1737. byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
  1738. Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
  1739. Vector3 pos
  1740. = GetNewRezLocation(
  1741. RayStart, RayEnd, RayTargetID, Quaternion.Identity,
  1742. BypassRayCast, bRayEndIsIntersection, true, scale, false);
  1743. RezObject(part, item, pos, null, Vector3.Zero, 0);
  1744. }
  1745. }
  1746. /// <summary>
  1747. /// Rez an object into the scene from a prim's inventory.
  1748. /// </summary>
  1749. /// <param name="sourcePart"></param>
  1750. /// <param name="item"></param>
  1751. /// <param name="pos">The position of the rezzed object.</param>
  1752. /// <param name="rot">The rotation of the rezzed object. If null, then the rotation stored with the object
  1753. /// will be used if it exists.</param>
  1754. /// <param name="vel">The velocity of the rezzed object.</param>
  1755. /// <param name="param"></param>
  1756. /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful</returns>
  1757. public virtual SceneObjectGroup RezObject(
  1758. SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param)
  1759. {
  1760. if (null == item)
  1761. return null;
  1762. SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item);
  1763. if (null == group)
  1764. return null;
  1765. if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos))
  1766. return null;
  1767. if (!Permissions.BypassPermissions())
  1768. {
  1769. if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
  1770. sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
  1771. }
  1772. AddNewSceneObject(group, true);
  1773. group.AbsolutePosition = pos;
  1774. group.Velocity = vel;
  1775. if (rot != null)
  1776. group.UpdateGroupRotationR((Quaternion)rot);
  1777. // We can only call this after adding the scene object, since the scene object references the scene
  1778. // to find out if scripts should be activated at all.
  1779. group.CreateScriptInstances(param, true, DefaultScriptEngine, 3);
  1780. group.ScheduleGroupForFullUpdate();
  1781. return group;
  1782. }
  1783. public virtual bool returnObjects(SceneObjectGroup[] returnobjects,
  1784. UUID AgentId)
  1785. {
  1786. List<uint> localIDs = new List<uint>();
  1787. foreach (SceneObjectGroup grp in returnobjects)
  1788. {
  1789. AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition,
  1790. "parcel owner return");
  1791. localIDs.Add(grp.RootPart.LocalId);
  1792. }
  1793. DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return,
  1794. UUID.Zero);
  1795. return true;
  1796. }
  1797. public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running)
  1798. {
  1799. SceneObjectPart part = GetSceneObjectPart(objectID);
  1800. if (part == null)
  1801. return;
  1802. if (running)
  1803. EventManager.TriggerStartScript(part.LocalId, itemID);
  1804. else
  1805. EventManager.TriggerStopScript(part.LocalId, itemID);
  1806. }
  1807. public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
  1808. {
  1809. EventManager.TriggerGetScriptRunning(controllingClient, objectID, itemID);
  1810. }
  1811. void ObjectOwner(IClientAPI remoteClient, UUID ownerID, UUID groupID, List<uint> localIDs)
  1812. {
  1813. if (!Permissions.IsGod(remoteClient.AgentId))
  1814. {
  1815. if (ownerID != UUID.Zero)
  1816. return;
  1817. if (!Permissions.CanDeedObject(remoteClient.AgentId, groupID))
  1818. return;
  1819. }
  1820. List<SceneObjectGroup> groups = new List<SceneObjectGroup>();
  1821. foreach (uint localID in localIDs)
  1822. {
  1823. SceneObjectPart part = GetSceneObjectPart(localID);
  1824. if (!groups.Contains(part.ParentGroup))
  1825. groups.Add(part.ParentGroup);
  1826. }
  1827. foreach (SceneObjectGroup sog in groups)
  1828. {
  1829. if (ownerID != UUID.Zero)
  1830. {
  1831. sog.SetOwnerId(ownerID);
  1832. sog.SetGroup(groupID, remoteClient);
  1833. sog.ScheduleGroupForFullUpdate();
  1834. SceneObjectPart[] partList = sog.Parts;
  1835. foreach (SceneObjectPart child in partList)
  1836. {
  1837. child.Inventory.ChangeInventoryOwner(ownerID);
  1838. child.TriggerScriptChangedEvent(Changed.OWNER);
  1839. }
  1840. }
  1841. else
  1842. {
  1843. if (!Permissions.CanEditObject(sog.UUID, remoteClient.AgentId))
  1844. continue;
  1845. if (sog.GroupID != groupID)
  1846. continue;
  1847. SceneObjectPart[] partList = sog.Parts;
  1848. foreach (SceneObjectPart child in partList)
  1849. {
  1850. child.LastOwnerID = child.OwnerID;
  1851. child.Inventory.ChangeInventoryOwner(groupID);
  1852. child.TriggerScriptChangedEvent(Changed.OWNER);
  1853. }
  1854. sog.SetOwnerId(groupID);
  1855. sog.ApplyNextOwnerPermissions();
  1856. }
  1857. }
  1858. foreach (uint localID in localIDs)
  1859. {
  1860. SceneObjectPart part = GetSceneObjectPart(localID);
  1861. part.GetProperties(remoteClient);
  1862. }
  1863. }
  1864. public void DelinkObjects(List<uint> primIds, IClientAPI client)
  1865. {
  1866. List<SceneObjectPart> parts = new List<SceneObjectPart>();
  1867. foreach (uint localID in primIds)
  1868. {
  1869. SceneObjectPart part = GetSceneObjectPart(localID);
  1870. if (part == null)
  1871. continue;
  1872. if (Permissions.CanDelinkObject(client.AgentId, part.ParentGroup.RootPart.UUID))
  1873. parts.Add(part);
  1874. }
  1875. m_sceneGraph.DelinkObjects(parts);
  1876. }
  1877. public void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds)
  1878. {
  1879. List<UUID> owners = new List<UUID>();
  1880. List<SceneObjectPart> children = new List<SceneObjectPart>();
  1881. SceneObjectPart root = GetSceneObjectPart(parentPrimId);
  1882. if (root == null)
  1883. {
  1884. m_log.DebugFormat("[LINK]: Can't find linkset root prim {0}", parentPrimId);
  1885. return;
  1886. }
  1887. if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID))
  1888. {
  1889. m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim");
  1890. return;
  1891. }
  1892. foreach (uint localID in childPrimIds)
  1893. {
  1894. SceneObjectPart part = GetSceneObjectPart(localID);
  1895. if (part == null)
  1896. continue;
  1897. if (!owners.Contains(part.OwnerID))
  1898. owners.Add(part.OwnerID);
  1899. if (Permissions.CanLinkObject(client.AgentId, part.ParentGroup.RootPart.UUID))
  1900. children.Add(part);
  1901. }
  1902. // Must be all one owner
  1903. //
  1904. if (owners.Count > 1)
  1905. {
  1906. m_log.DebugFormat("[LINK]: Refusing link. Too many owners");
  1907. return;
  1908. }
  1909. if (children.Count == 0)
  1910. {
  1911. m_log.DebugFormat("[LINK]: Refusing link. No permissions to link any of the children");
  1912. return;
  1913. }
  1914. m_sceneGraph.LinkObjects(root, children);
  1915. }
  1916. private string PermissionString(uint permissions)
  1917. {
  1918. PermissionMask perms = (PermissionMask)permissions &
  1919. (PermissionMask.Move |
  1920. PermissionMask.Copy |
  1921. PermissionMask.Transfer |
  1922. PermissionMask.Modify);
  1923. return perms.ToString();
  1924. }
  1925. }
  1926. }