1
0

Scene.Inventory.cs 98 KB

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