diff options
author | Dr Scofield | 2009-02-06 16:55:34 +0000 |
---|---|---|
committer | Dr Scofield | 2009-02-06 16:55:34 +0000 |
commit | 9b66108081a8c8cf79faaa6c541554091c40850e (patch) | |
tree | 095a232ae5a9de3a9244bcd34da08294f61eeea5 /OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs | |
parent | * removed superfluous constants class (diff) | |
download | opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.zip opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.gz opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.bz2 opensim-SC-9b66108081a8c8cf79faaa6c541554091c40850e.tar.xz |
This changeset is the step 1 of 2 in refactoring
OpenSim.Region.Environment into a "framework" part and a modules only
part. This first changeset refactors OpenSim.Region.Environment.Scenes,
OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces
into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region
modules in OpenSim.Region.Environment.
The next step will be to move region modules up from
OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and
then sort out which modules are really core modules and which should
move out to forge.
I've been very careful to NOT BREAK anything. i hope i've
succeeded. as this is the work of a whole week i hope i managed to
keep track with the applied patches of the last week --- could any of
you that did check in stuff have a look at whether it survived? thx!
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs | 892 |
1 files changed, 0 insertions, 892 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs deleted file mode 100644 index 8137a53..0000000 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPartInventory.cs +++ /dev/null | |||
@@ -1,892 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using OpenMetaverse; | ||
32 | using log4net; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Communications.Cache; | ||
35 | using OpenSim.Region.Interfaces; | ||
36 | using OpenSim.Region.Environment.Interfaces; | ||
37 | using OpenSim.Region.Environment.Scenes.Scripting; | ||
38 | |||
39 | namespace OpenSim.Region.Environment.Scenes | ||
40 | { | ||
41 | public class SceneObjectPartInventory : IEntityInventory | ||
42 | { | ||
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
44 | |||
45 | private string m_inventoryFileName = String.Empty; | ||
46 | private int m_inventoryFileNameSerial = 0; | ||
47 | |||
48 | /// <value> | ||
49 | /// The part to which the inventory belongs. | ||
50 | /// </value> | ||
51 | private SceneObjectPart m_part; | ||
52 | |||
53 | /// <summary> | ||
54 | /// Serial count for inventory file , used to tell if inventory has changed | ||
55 | /// no need for this to be part of Database backup | ||
56 | /// </summary> | ||
57 | protected uint m_inventorySerial = 0; | ||
58 | |||
59 | /// <summary> | ||
60 | /// Holds in memory prim inventory | ||
61 | /// </summary> | ||
62 | protected TaskInventoryDictionary m_items = new TaskInventoryDictionary(); | ||
63 | |||
64 | /// <summary> | ||
65 | /// Tracks whether inventory has changed since the last persistent backup | ||
66 | /// </summary> | ||
67 | internal bool HasInventoryChanged; | ||
68 | |||
69 | /// <value> | ||
70 | /// Inventory serial number | ||
71 | /// </value> | ||
72 | protected internal uint Serial | ||
73 | { | ||
74 | get { return m_inventorySerial; } | ||
75 | set { m_inventorySerial = value; } | ||
76 | } | ||
77 | |||
78 | /// <value> | ||
79 | /// Raw inventory data | ||
80 | /// </value> | ||
81 | protected internal TaskInventoryDictionary Items | ||
82 | { | ||
83 | get { return m_items; } | ||
84 | set | ||
85 | { | ||
86 | m_items = value; | ||
87 | m_inventorySerial++; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | /// <summary> | ||
92 | /// Constructor | ||
93 | /// </summary> | ||
94 | /// <param name="part"> | ||
95 | /// A <see cref="SceneObjectPart"/> | ||
96 | /// </param> | ||
97 | public SceneObjectPartInventory(SceneObjectPart part) | ||
98 | { | ||
99 | m_part = part; | ||
100 | } | ||
101 | |||
102 | /// <summary> | ||
103 | /// Force the task inventory of this prim to persist at the next update sweep | ||
104 | /// </summary> | ||
105 | public void ForceInventoryPersistence() | ||
106 | { | ||
107 | HasInventoryChanged = true; | ||
108 | } | ||
109 | |||
110 | /// <summary> | ||
111 | /// Reset UUIDs for all the items in the prim's inventory. This involves either generating | ||
112 | /// new ones or setting existing UUIDs to the correct parent UUIDs. | ||
113 | /// | ||
114 | /// If this method is called and there are inventory items, then we regard the inventory as having changed. | ||
115 | /// </summary> | ||
116 | /// <param name="linkNum">Link number for the part</param> | ||
117 | public void ResetInventoryIDs() | ||
118 | { | ||
119 | lock (Items) | ||
120 | { | ||
121 | if (0 == Items.Count) | ||
122 | return; | ||
123 | |||
124 | HasInventoryChanged = true; | ||
125 | m_part.ParentGroup.HasGroupChanged = true; | ||
126 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | ||
127 | Items.Clear(); | ||
128 | |||
129 | foreach (TaskInventoryItem item in items) | ||
130 | { | ||
131 | item.ResetIDs(m_part.UUID); | ||
132 | Items.Add(item.ItemID, item); | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /// <summary> | ||
138 | /// Change every item in this inventory to a new owner. | ||
139 | /// </summary> | ||
140 | /// <param name="ownerId"></param> | ||
141 | public void ChangeInventoryOwner(UUID ownerId) | ||
142 | { | ||
143 | lock (Items) | ||
144 | { | ||
145 | if (0 == Items.Count) | ||
146 | { | ||
147 | return; | ||
148 | } | ||
149 | |||
150 | HasInventoryChanged = true; | ||
151 | m_part.ParentGroup.HasGroupChanged = true; | ||
152 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | ||
153 | foreach (TaskInventoryItem item in items) | ||
154 | { | ||
155 | if (ownerId != item.OwnerID) | ||
156 | { | ||
157 | item.LastOwnerID = item.OwnerID; | ||
158 | item.OwnerID = ownerId; | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /// <summary> | ||
165 | /// Change every item in this inventory to a new group. | ||
166 | /// </summary> | ||
167 | /// <param name="groupID"></param> | ||
168 | public void ChangeInventoryGroup(UUID groupID) | ||
169 | { | ||
170 | lock (Items) | ||
171 | { | ||
172 | if (0 == Items.Count) | ||
173 | { | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | HasInventoryChanged = true; | ||
178 | m_part.ParentGroup.HasGroupChanged = true; | ||
179 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | ||
180 | foreach (TaskInventoryItem item in items) | ||
181 | { | ||
182 | if (groupID != item.GroupID) | ||
183 | { | ||
184 | item.GroupID = groupID; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | |||
190 | /// <summary> | ||
191 | /// Start all the scripts contained in this prim's inventory | ||
192 | /// </summary> | ||
193 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | ||
194 | { | ||
195 | lock (m_items) | ||
196 | { | ||
197 | foreach (TaskInventoryItem item in Items.Values) | ||
198 | { | ||
199 | if ((int)InventoryType.LSL == item.InvType) | ||
200 | { | ||
201 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | |||
207 | /// <summary> | ||
208 | /// Stop all the scripts in this prim. | ||
209 | /// </summary> | ||
210 | public void RemoveScriptInstances() | ||
211 | { | ||
212 | lock (Items) | ||
213 | { | ||
214 | foreach (TaskInventoryItem item in Items.Values) | ||
215 | { | ||
216 | if ((int)InventoryType.LSL == item.InvType) | ||
217 | { | ||
218 | RemoveScriptInstance(item.ItemID); | ||
219 | m_part.RemoveScriptEvents(item.ItemID); | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | /// <summary> | ||
226 | /// Start a script which is in this prim's inventory. | ||
227 | /// </summary> | ||
228 | /// <param name="item"></param> | ||
229 | /// <returns></returns> | ||
230 | public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource) | ||
231 | { | ||
232 | // m_log.InfoFormat( | ||
233 | // "[PRIM INVENTORY]: " + | ||
234 | // "Starting script {0}, {1} in prim {2}, {3}", | ||
235 | // item.Name, item.ItemID, Name, UUID); | ||
236 | |||
237 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | ||
238 | return; | ||
239 | |||
240 | m_part.AddFlag(PrimFlags.Scripted); | ||
241 | |||
242 | if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) | ||
243 | { | ||
244 | if (stateSource == 1 && // Prim crossing | ||
245 | m_part.ParentGroup.Scene.m_trustBinaries) | ||
246 | { | ||
247 | m_items[item.ItemID].PermsMask = 0; | ||
248 | m_items[item.ItemID].PermsGranter = UUID.Zero; | ||
249 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | ||
250 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | ||
251 | m_part.ParentGroup.AddActiveScriptCount(1); | ||
252 | m_part.ScheduleFullUpdate(); | ||
253 | return; | ||
254 | } | ||
255 | AssetCache cache = m_part.ParentGroup.Scene.AssetCache; | ||
256 | |||
257 | cache.GetAsset(item.AssetID, delegate(UUID assetID, AssetBase asset) | ||
258 | { | ||
259 | if (null == asset) | ||
260 | { | ||
261 | m_log.ErrorFormat( | ||
262 | "[PRIM INVENTORY]: " + | ||
263 | "Couldn't start script {0}, {1} since asset ID {2} could not be found", | ||
264 | item.Name, item.ItemID, item.AssetID); | ||
265 | } | ||
266 | else | ||
267 | { | ||
268 | m_items[item.ItemID].PermsMask = 0; | ||
269 | m_items[item.ItemID].PermsGranter = UUID.Zero; | ||
270 | string script = Utils.BytesToString(asset.Data); | ||
271 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | ||
272 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | ||
273 | m_part.ParentGroup.AddActiveScriptCount(1); | ||
274 | m_part.ScheduleFullUpdate(); | ||
275 | } | ||
276 | }, false); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | /// <summary> | ||
281 | /// Start a script which is in this prim's inventory. | ||
282 | /// </summary> | ||
283 | /// <param name="itemId"> | ||
284 | /// A <see cref="UUID"/> | ||
285 | /// </param> | ||
286 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
287 | { | ||
288 | lock (m_items) | ||
289 | { | ||
290 | if (m_items.ContainsKey(itemId)) | ||
291 | { | ||
292 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
293 | } | ||
294 | else | ||
295 | { | ||
296 | m_log.ErrorFormat( | ||
297 | "[PRIM INVENTORY]: " + | ||
298 | "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}", | ||
299 | itemId, m_part.Name, m_part.UUID); | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | |||
304 | /// <summary> | ||
305 | /// Stop a script which is in this prim's inventory. | ||
306 | /// </summary> | ||
307 | /// <param name="itemId"></param> | ||
308 | public void RemoveScriptInstance(UUID itemId) | ||
309 | { | ||
310 | if (m_items.ContainsKey(itemId)) | ||
311 | { | ||
312 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId); | ||
313 | m_part.ParentGroup.AddActiveScriptCount(-1); | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | m_log.ErrorFormat( | ||
318 | "[PRIM INVENTORY]: " + | ||
319 | "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2}", | ||
320 | itemId, m_part.Name, m_part.UUID); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | /// <summary> | ||
325 | /// Check if the inventory holds an item with a given name. | ||
326 | /// This method assumes that the task inventory is already locked. | ||
327 | /// </summary> | ||
328 | /// <param name="name"></param> | ||
329 | /// <returns></returns> | ||
330 | private bool InventoryContainsName(string name) | ||
331 | { | ||
332 | foreach (TaskInventoryItem item in Items.Values) | ||
333 | { | ||
334 | if (item.Name == name) | ||
335 | return true; | ||
336 | } | ||
337 | return false; | ||
338 | } | ||
339 | |||
340 | /// <summary> | ||
341 | /// For a given item name, return that name if it is available. Otherwise, return the next available | ||
342 | /// similar name (which is currently the original name with the next available numeric suffix). | ||
343 | /// </summary> | ||
344 | /// <param name="name"></param> | ||
345 | /// <returns></returns> | ||
346 | private string FindAvailableInventoryName(string name) | ||
347 | { | ||
348 | if (!InventoryContainsName(name)) | ||
349 | return name; | ||
350 | |||
351 | int suffix=1; | ||
352 | while (suffix < 256) | ||
353 | { | ||
354 | string tryName=String.Format("{0} {1}", name, suffix); | ||
355 | if (!InventoryContainsName(tryName)) | ||
356 | return tryName; | ||
357 | suffix++; | ||
358 | } | ||
359 | return String.Empty; | ||
360 | } | ||
361 | |||
362 | /// <summary> | ||
363 | /// Add an item to this prim's inventory. If an item with the same name already exists, then an alternative | ||
364 | /// name is chosen. | ||
365 | /// </summary> | ||
366 | /// <param name="item"></param> | ||
367 | public void AddInventoryItem(TaskInventoryItem item, bool allowedDrop) | ||
368 | { | ||
369 | AddInventoryItem(item.Name, item, allowedDrop); | ||
370 | } | ||
371 | |||
372 | /// <summary> | ||
373 | /// Add an item to this prim's inventory. If an item with the same name already exists, it is replaced. | ||
374 | /// </summary> | ||
375 | /// <param name="item"></param> | ||
376 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | ||
377 | { | ||
378 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | ||
379 | foreach (TaskInventoryItem i in il) | ||
380 | { | ||
381 | if (i.Name == item.Name) | ||
382 | { | ||
383 | if (i.InvType == (int)InventoryType.LSL) | ||
384 | RemoveScriptInstance(i.ItemID); | ||
385 | |||
386 | RemoveInventoryItem(i.ItemID); | ||
387 | break; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | AddInventoryItem(item.Name, item, allowedDrop); | ||
392 | } | ||
393 | |||
394 | /// <summary> | ||
395 | /// Add an item to this prim's inventory. | ||
396 | /// </summary> | ||
397 | /// <param name="name">The name that the new item should have.</param> | ||
398 | /// <param name="item"> | ||
399 | /// The item itself. The name within this structure is ignored in favour of the name | ||
400 | /// given in this method's arguments | ||
401 | /// </param> | ||
402 | /// <param name="allowedDrop"> | ||
403 | /// Item was only added to inventory because AllowedDrop is set | ||
404 | /// </param> | ||
405 | protected void AddInventoryItem(string name, TaskInventoryItem item, bool allowedDrop) | ||
406 | { | ||
407 | name = FindAvailableInventoryName(name); | ||
408 | if (name == String.Empty) | ||
409 | return; | ||
410 | |||
411 | item.ParentID = m_part.UUID; | ||
412 | item.ParentPartID = m_part.UUID; | ||
413 | item.Name = name; | ||
414 | |||
415 | lock (m_items) | ||
416 | { | ||
417 | m_items.Add(item.ItemID, item); | ||
418 | |||
419 | if (allowedDrop) | ||
420 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | ||
421 | else | ||
422 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
423 | } | ||
424 | |||
425 | m_inventorySerial++; | ||
426 | //m_inventorySerial += 2; | ||
427 | HasInventoryChanged = true; | ||
428 | m_part.ParentGroup.HasGroupChanged = true; | ||
429 | } | ||
430 | |||
431 | /// <summary> | ||
432 | /// Restore a whole collection of items to the prim's inventory at once. | ||
433 | /// We assume that the items already have all their fields correctly filled out. | ||
434 | /// The items are not flagged for persistence to the database, since they are being restored | ||
435 | /// from persistence rather than being newly added. | ||
436 | /// </summary> | ||
437 | /// <param name="items"></param> | ||
438 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | ||
439 | { | ||
440 | lock (m_items) | ||
441 | { | ||
442 | foreach (TaskInventoryItem item in items) | ||
443 | { | ||
444 | m_items.Add(item.ItemID, item); | ||
445 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
446 | } | ||
447 | } | ||
448 | |||
449 | m_inventorySerial++; | ||
450 | } | ||
451 | |||
452 | /// <summary> | ||
453 | /// Returns an existing inventory item. Returns the original, so any changes will be live. | ||
454 | /// </summary> | ||
455 | /// <param name="itemID"></param> | ||
456 | /// <returns>null if the item does not exist</returns> | ||
457 | public TaskInventoryItem GetInventoryItem(UUID itemId) | ||
458 | { | ||
459 | TaskInventoryItem item; | ||
460 | m_items.TryGetValue(itemId, out item); | ||
461 | |||
462 | return item; | ||
463 | } | ||
464 | |||
465 | /// <summary> | ||
466 | /// Update an existing inventory item. | ||
467 | /// </summary> | ||
468 | /// <param name="item">The updated item. An item with the same id must already exist | ||
469 | /// in this prim's inventory.</param> | ||
470 | /// <returns>false if the item did not exist, true if the update occurred successfully</returns> | ||
471 | public bool UpdateInventoryItem(TaskInventoryItem item) | ||
472 | { | ||
473 | lock (m_items) | ||
474 | { | ||
475 | if (m_items.ContainsKey(item.ItemID)) | ||
476 | { | ||
477 | item.ParentID = m_part.UUID; | ||
478 | item.ParentPartID = m_part.UUID; | ||
479 | item.Flags = m_items[item.ItemID].Flags; | ||
480 | if (item.AssetID == UUID.Zero) | ||
481 | { | ||
482 | item.AssetID = m_items[item.ItemID].AssetID; | ||
483 | } | ||
484 | else if ((InventoryType)item.Type == InventoryType.Notecard) | ||
485 | { | ||
486 | ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID); | ||
487 | |||
488 | if (presence != null) | ||
489 | { | ||
490 | presence.ControllingClient.SendAgentAlertMessage( | ||
491 | "Notecard saved", false); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | m_items[item.ItemID] = item; | ||
496 | m_inventorySerial++; | ||
497 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
498 | |||
499 | HasInventoryChanged = true; | ||
500 | m_part.ParentGroup.HasGroupChanged = true; | ||
501 | |||
502 | return true; | ||
503 | } | ||
504 | else | ||
505 | { | ||
506 | m_log.ErrorFormat( | ||
507 | "[PRIM INVENTORY]: " + | ||
508 | "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", | ||
509 | item.ItemID, m_part.Name, m_part.UUID); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | return false; | ||
514 | } | ||
515 | |||
516 | /// <summary> | ||
517 | /// Remove an item from this prim's inventory | ||
518 | /// </summary> | ||
519 | /// <param name="itemID"></param> | ||
520 | /// <returns>Numeric asset type of the item removed. Returns -1 if the item did not exist | ||
521 | /// in this prim's inventory.</returns> | ||
522 | public int RemoveInventoryItem(UUID itemID) | ||
523 | { | ||
524 | lock (m_items) | ||
525 | { | ||
526 | if (m_items.ContainsKey(itemID)) | ||
527 | { | ||
528 | int type = m_items[itemID].InvType; | ||
529 | if (type == 10) // Script | ||
530 | { | ||
531 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | ||
532 | } | ||
533 | m_items.Remove(itemID); | ||
534 | m_inventorySerial++; | ||
535 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
536 | |||
537 | HasInventoryChanged = true; | ||
538 | m_part.ParentGroup.HasGroupChanged = true; | ||
539 | |||
540 | int scriptcount = 0; | ||
541 | lock (m_items) | ||
542 | { | ||
543 | foreach (TaskInventoryItem item in m_items.Values) | ||
544 | { | ||
545 | if (item.Type == 10) | ||
546 | { | ||
547 | scriptcount++; | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | |||
552 | if (scriptcount <= 0) | ||
553 | { | ||
554 | m_part.RemFlag(PrimFlags.Scripted); | ||
555 | } | ||
556 | |||
557 | m_part.ScheduleFullUpdate(); | ||
558 | |||
559 | return type; | ||
560 | } | ||
561 | else | ||
562 | { | ||
563 | m_log.ErrorFormat( | ||
564 | "[PRIM INVENTORY]: " + | ||
565 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", | ||
566 | itemID, m_part.Name, m_part.UUID); | ||
567 | } | ||
568 | } | ||
569 | |||
570 | return -1; | ||
571 | } | ||
572 | |||
573 | public string GetInventoryFileName() | ||
574 | { | ||
575 | if (m_inventoryFileName == String.Empty) | ||
576 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | ||
577 | if (m_inventoryFileNameSerial < m_inventorySerial) | ||
578 | { | ||
579 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | ||
580 | } | ||
581 | return m_inventoryFileName; | ||
582 | } | ||
583 | |||
584 | /// <summary> | ||
585 | /// Return the name with which a client can request a xfer of this prim's inventory metadata | ||
586 | /// </summary> | ||
587 | /// <param name="client"></param> | ||
588 | /// <param name="localID"></param> | ||
589 | public bool GetInventoryFileName(IClientAPI client, uint localID) | ||
590 | { | ||
591 | // m_log.DebugFormat( | ||
592 | // "[PRIM INVENTORY]: Received request from client {0} for inventory file name of {1}, {2}", | ||
593 | // client.AgentId, Name, UUID); | ||
594 | |||
595 | if (m_inventorySerial > 0) | ||
596 | { | ||
597 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
598 | Utils.StringToBytes(GetInventoryFileName())); | ||
599 | return true; | ||
600 | } | ||
601 | else | ||
602 | { | ||
603 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
604 | return false; | ||
605 | } | ||
606 | } | ||
607 | |||
608 | /// <summary> | ||
609 | /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client | ||
610 | /// </summary> | ||
611 | /// <param name="xferManager"></param> | ||
612 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | ||
613 | { | ||
614 | byte[] fileData = new byte[0]; | ||
615 | |||
616 | // Confusingly, the folder item has to be the object id, while the 'parent id' has to be zero. This matches | ||
617 | // what appears to happen in the Second Life protocol. If this isn't the case. then various functionality | ||
618 | // isn't available (such as drag from prim inventory to agent inventory) | ||
619 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
620 | |||
621 | lock (m_items) | ||
622 | { | ||
623 | foreach (TaskInventoryItem item in m_items.Values) | ||
624 | { | ||
625 | UUID ownerID = item.OwnerID; | ||
626 | uint everyoneMask = 0; | ||
627 | uint baseMask = item.BasePermissions; | ||
628 | uint ownerMask = item.CurrentPermissions; | ||
629 | |||
630 | invString.AddItemStart(); | ||
631 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
632 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
633 | |||
634 | invString.AddPermissionsStart(); | ||
635 | |||
636 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
637 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
638 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); | ||
639 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
640 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
641 | |||
642 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
643 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
644 | |||
645 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
646 | |||
647 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
648 | invString.AddSectionEnd(); | ||
649 | |||
650 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
651 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); | ||
652 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); | ||
653 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
654 | |||
655 | invString.AddSaleStart(); | ||
656 | invString.AddNameValueLine("sale_type", "not"); | ||
657 | invString.AddNameValueLine("sale_price", "0"); | ||
658 | invString.AddSectionEnd(); | ||
659 | |||
660 | invString.AddNameValueLine("name", item.Name + "|"); | ||
661 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
662 | |||
663 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
664 | invString.AddSectionEnd(); | ||
665 | } | ||
666 | } | ||
667 | |||
668 | fileData = Utils.StringToBytes(invString.BuildString); | ||
669 | |||
670 | //Console.WriteLine(Utils.BytesToString(fileData)); | ||
671 | //m_log.Debug("[PRIM INVENTORY]: RequestInventoryFile fileData: " + Utils.BytesToString(fileData)); | ||
672 | |||
673 | if (fileData.Length > 2) | ||
674 | { | ||
675 | xferManager.AddNewFile(m_inventoryFileName, fileData); | ||
676 | } | ||
677 | } | ||
678 | |||
679 | /// <summary> | ||
680 | /// Process inventory backup | ||
681 | /// </summary> | ||
682 | /// <param name="datastore"></param> | ||
683 | public void ProcessInventoryBackup(IRegionDataStore datastore) | ||
684 | { | ||
685 | if (HasInventoryChanged) | ||
686 | { | ||
687 | lock (Items) | ||
688 | { | ||
689 | datastore.StorePrimInventory(m_part.UUID, Items.Values); | ||
690 | } | ||
691 | |||
692 | HasInventoryChanged = false; | ||
693 | } | ||
694 | } | ||
695 | |||
696 | public class InventoryStringBuilder | ||
697 | { | ||
698 | public string BuildString = String.Empty; | ||
699 | |||
700 | public InventoryStringBuilder(UUID folderID, UUID parentID) | ||
701 | { | ||
702 | BuildString += "\tinv_object\t0\n\t{\n"; | ||
703 | AddNameValueLine("obj_id", folderID.ToString()); | ||
704 | AddNameValueLine("parent_id", parentID.ToString()); | ||
705 | AddNameValueLine("type", "category"); | ||
706 | AddNameValueLine("name", "Contents|"); | ||
707 | AddSectionEnd(); | ||
708 | } | ||
709 | |||
710 | public void AddItemStart() | ||
711 | { | ||
712 | BuildString += "\tinv_item\t0\n"; | ||
713 | AddSectionStart(); | ||
714 | } | ||
715 | |||
716 | public void AddPermissionsStart() | ||
717 | { | ||
718 | BuildString += "\tpermissions 0\n"; | ||
719 | AddSectionStart(); | ||
720 | } | ||
721 | |||
722 | public void AddSaleStart() | ||
723 | { | ||
724 | BuildString += "\tsale_info\t0\n"; | ||
725 | AddSectionStart(); | ||
726 | } | ||
727 | |||
728 | protected void AddSectionStart() | ||
729 | { | ||
730 | BuildString += "\t{\n"; | ||
731 | } | ||
732 | |||
733 | public void AddSectionEnd() | ||
734 | { | ||
735 | BuildString += "\t}\n"; | ||
736 | } | ||
737 | |||
738 | public void AddLine(string addLine) | ||
739 | { | ||
740 | BuildString += addLine; | ||
741 | } | ||
742 | |||
743 | public void AddNameValueLine(string name, string value) | ||
744 | { | ||
745 | BuildString += "\t\t"; | ||
746 | BuildString += name + "\t"; | ||
747 | BuildString += value + "\n"; | ||
748 | } | ||
749 | |||
750 | public void Close() | ||
751 | { | ||
752 | } | ||
753 | } | ||
754 | |||
755 | public uint MaskEffectivePermissions() | ||
756 | { | ||
757 | uint mask=0x7fffffff; | ||
758 | |||
759 | foreach (TaskInventoryItem item in m_items.Values) | ||
760 | { | ||
761 | if (item.InvType != 6) | ||
762 | { | ||
763 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | ||
764 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
765 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
766 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
767 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
768 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
769 | } | ||
770 | else | ||
771 | { | ||
772 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
773 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
774 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
775 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
776 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
777 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
778 | } | ||
779 | |||
780 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
781 | mask &= ~(uint)PermissionMask.Copy; | ||
782 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
783 | mask &= ~(uint)PermissionMask.Transfer; | ||
784 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
785 | mask &= ~(uint)PermissionMask.Modify; | ||
786 | } | ||
787 | return mask; | ||
788 | } | ||
789 | |||
790 | public void ApplyNextOwnerPermissions() | ||
791 | { | ||
792 | foreach (TaskInventoryItem item in m_items.Values) | ||
793 | { | ||
794 | if (item.InvType == 6 && (item.CurrentPermissions & 7) != 0) | ||
795 | { | ||
796 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
797 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | ||
798 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
799 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | ||
800 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
801 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
802 | item.CurrentPermissions |= 8; | ||
803 | } | ||
804 | item.CurrentPermissions &= item.NextPermissions; | ||
805 | item.BasePermissions &= item.NextPermissions; | ||
806 | item.EveryonePermissions &= item.NextPermissions; | ||
807 | } | ||
808 | |||
809 | m_part.TriggerScriptChangedEvent(Changed.OWNER); | ||
810 | } | ||
811 | |||
812 | public void ApplyGodPermissions(uint perms) | ||
813 | { | ||
814 | foreach (TaskInventoryItem item in m_items.Values) | ||
815 | { | ||
816 | item.CurrentPermissions = perms; | ||
817 | item.BasePermissions = perms; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | public bool ContainsScripts() | ||
822 | { | ||
823 | foreach (TaskInventoryItem item in m_items.Values) | ||
824 | { | ||
825 | if (item.InvType == 10) | ||
826 | { | ||
827 | return true; | ||
828 | } | ||
829 | } | ||
830 | return false; | ||
831 | } | ||
832 | |||
833 | public List<UUID> GetInventoryList() | ||
834 | { | ||
835 | List<UUID> ret = new List<UUID>(); | ||
836 | |||
837 | foreach (TaskInventoryItem item in m_items.Values) | ||
838 | ret.Add(item.ItemID); | ||
839 | |||
840 | return ret; | ||
841 | } | ||
842 | |||
843 | public string[] GetScriptAssemblies() | ||
844 | { | ||
845 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | ||
846 | |||
847 | List<string> ret = new List<string>(); | ||
848 | |||
849 | foreach (TaskInventoryItem item in m_items.Values) | ||
850 | { | ||
851 | if (item.InvType == 10) | ||
852 | { | ||
853 | foreach (IScriptModule e in engines) | ||
854 | { | ||
855 | string n = e.GetAssemblyName(item.ItemID); | ||
856 | if (n != "") | ||
857 | { | ||
858 | if (!ret.Contains(n)) | ||
859 | ret.Add(n); | ||
860 | break; | ||
861 | } | ||
862 | } | ||
863 | } | ||
864 | } | ||
865 | return ret.ToArray(); | ||
866 | } | ||
867 | |||
868 | public Dictionary<UUID, string> GetScriptStates() | ||
869 | { | ||
870 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | ||
871 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | ||
872 | |||
873 | foreach (TaskInventoryItem item in m_items.Values) | ||
874 | { | ||
875 | if (item.InvType == 10) | ||
876 | { | ||
877 | foreach (IScriptModule e in engines) | ||
878 | { | ||
879 | string n = e.GetXMLState(item.ItemID); | ||
880 | if (n != "") | ||
881 | { | ||
882 | if (!ret.ContainsKey(item.ItemID)) | ||
883 | ret[item.ItemID] = n; | ||
884 | break; | ||
885 | } | ||
886 | } | ||
887 | } | ||
888 | } | ||
889 | return ret; | ||
890 | } | ||
891 | } | ||
892 | } | ||