clockwerk-opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ |
||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
||
4 | * |
||
5 | * Redistribution and use in source and binary forms, with or without |
||
6 | * modification, are permitted provided that the following conditions are met: |
||
7 | * * Redistributions of source code must retain the above copyright |
||
8 | * notice, this list of conditions and the following disclaimer. |
||
9 | * * Redistributions in binary form must reproduce the above copyright |
||
10 | * notice, this list of conditions and the following disclaimer in the |
||
11 | * documentation and/or other materials provided with the distribution. |
||
12 | * * Neither the name of the OpenSimulator Project nor the |
||
13 | * names of its contributors may be used to endorse or promote products |
||
14 | * derived from this software without specific prior written permission. |
||
15 | * |
||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
26 | */ |
||
27 | |||
28 | using System; |
||
29 | using System.Collections.Generic; |
||
30 | using System.Collections.Specialized; |
||
31 | using System.Reflection; |
||
32 | using log4net; |
||
33 | using Mono.Addins; |
||
34 | using Nini.Config; |
||
35 | using OpenMetaverse; |
||
36 | using OpenMetaverse.StructuredData; |
||
37 | using OpenSim.Framework; |
||
38 | using OpenSim.Region.Framework.Interfaces; |
||
39 | using OpenSim.Region.Framework.Scenes; |
||
40 | using OpenSim.Services.Interfaces; |
||
41 | using PermissionMask = OpenSim.Framework.PermissionMask; |
||
42 | |||
43 | namespace OpenSim.Services.Connectors.SimianGrid |
||
44 | { |
||
45 | /// <summary> |
||
46 | /// Permissions bitflags |
||
47 | /// </summary> |
||
48 | /* |
||
49 | [Flags] |
||
50 | public enum PermissionMask : uint |
||
51 | { |
||
52 | None = 0, |
||
53 | Transfer = 1 << 13, |
||
54 | Modify = 1 << 14, |
||
55 | Copy = 1 << 15, |
||
56 | Move = 1 << 19, |
||
57 | Damage = 1 << 20, |
||
58 | All = 0x7FFFFFFF |
||
59 | } |
||
60 | */ |
||
61 | |||
62 | /// <summary> |
||
63 | /// Connects avatar inventories to the SimianGrid backend |
||
64 | /// </summary> |
||
65 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianInventoryServiceConnector")] |
||
66 | public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule |
||
67 | { |
||
68 | private static readonly ILog m_log = |
||
69 | LogManager.GetLogger( |
||
70 | MethodBase.GetCurrentMethod().DeclaringType); |
||
71 | |||
72 | private string m_serverUrl = String.Empty; |
||
73 | private string m_userServerUrl = String.Empty; |
||
74 | // private object m_gestureSyncRoot = new object(); |
||
75 | private bool m_Enabled = false; |
||
76 | |||
77 | #region ISharedRegionModule |
||
78 | |||
79 | public Type ReplaceableInterface { get { return null; } } |
||
80 | public void RegionLoaded(Scene scene) { } |
||
81 | public void PostInitialise() { } |
||
82 | public void Close() { } |
||
83 | |||
84 | public SimianInventoryServiceConnector() { } |
||
85 | public string Name { get { return "SimianInventoryServiceConnector"; } } |
||
86 | public void AddRegion(Scene scene) { if (m_Enabled) { scene.RegisterModuleInterface<IInventoryService>(this); } } |
||
87 | public void RemoveRegion(Scene scene) { if (m_Enabled) { scene.UnregisterModuleInterface<IInventoryService>(this); } } |
||
88 | |||
89 | #endregion ISharedRegionModule |
||
90 | |||
91 | public SimianInventoryServiceConnector(IConfigSource source) |
||
92 | { |
||
93 | CommonInit(source); |
||
94 | } |
||
95 | |||
96 | public SimianInventoryServiceConnector(string url) |
||
97 | { |
||
98 | if (!url.EndsWith("/") && !url.EndsWith("=")) |
||
99 | url = url + '/'; |
||
100 | m_serverUrl = url; |
||
101 | |||
102 | } |
||
103 | |||
104 | public void Initialise(IConfigSource source) |
||
105 | { |
||
106 | IConfig moduleConfig = source.Configs["Modules"]; |
||
107 | if (moduleConfig != null) |
||
108 | { |
||
109 | string name = moduleConfig.GetString("InventoryServices", ""); |
||
110 | if (name == Name) |
||
111 | CommonInit(source); |
||
112 | } |
||
113 | } |
||
114 | |||
115 | private void CommonInit(IConfigSource source) |
||
116 | { |
||
117 | IConfig gridConfig = source.Configs["InventoryService"]; |
||
118 | if (gridConfig != null) |
||
119 | { |
||
120 | string serviceUrl = gridConfig.GetString("InventoryServerURI"); |
||
121 | if (!String.IsNullOrEmpty(serviceUrl)) |
||
122 | { |
||
123 | if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) |
||
124 | serviceUrl = serviceUrl + '/'; |
||
125 | m_serverUrl = serviceUrl; |
||
126 | |||
127 | gridConfig = source.Configs["UserAccountService"]; |
||
128 | if (gridConfig != null) |
||
129 | { |
||
130 | serviceUrl = gridConfig.GetString("UserAccountServerURI"); |
||
131 | if (!String.IsNullOrEmpty(serviceUrl)) |
||
132 | { |
||
133 | m_userServerUrl = serviceUrl; |
||
134 | m_Enabled = true; |
||
135 | } |
||
136 | } |
||
137 | } |
||
138 | } |
||
139 | |||
140 | if (String.IsNullOrEmpty(m_serverUrl)) |
||
141 | m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No InventoryServerURI specified, disabling connector"); |
||
142 | else if (String.IsNullOrEmpty(m_userServerUrl)) |
||
143 | m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No UserAccountServerURI specified, disabling connector"); |
||
144 | } |
||
145 | |||
146 | /// <summary> |
||
147 | /// Create the entire inventory for a given user |
||
148 | /// </summary> |
||
149 | /// <param name="user"></param> |
||
150 | /// <returns></returns> |
||
151 | public bool CreateUserInventory(UUID userID) |
||
152 | { |
||
153 | NameValueCollection requestArgs = new NameValueCollection |
||
154 | { |
||
155 | { "RequestMethod", "AddInventory" }, |
||
156 | { "OwnerID", userID.ToString() } |
||
157 | }; |
||
158 | |||
159 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
160 | bool success = response["Success"].AsBoolean(); |
||
161 | |||
162 | if (!success) |
||
163 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Inventory creation for " + userID + " failed: " + response["Message"].AsString()); |
||
164 | |||
165 | return success; |
||
166 | } |
||
167 | |||
168 | /// <summary> |
||
169 | /// Gets the skeleton of the inventory -- folders only |
||
170 | /// </summary> |
||
171 | /// <param name="userID"></param> |
||
172 | /// <returns></returns> |
||
173 | public List<InventoryFolderBase> GetInventorySkeleton(UUID userID) |
||
174 | { |
||
175 | NameValueCollection requestArgs = new NameValueCollection |
||
176 | { |
||
177 | { "RequestMethod", "GetInventoryNode" }, |
||
178 | { "ItemID", userID.ToString() }, |
||
179 | { "OwnerID", userID.ToString() }, |
||
180 | { "IncludeFolders", "1" }, |
||
181 | { "IncludeItems", "0" }, |
||
182 | { "ChildrenOnly", "0" } |
||
183 | }; |
||
184 | |||
185 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
186 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
187 | { |
||
188 | OSDArray items = (OSDArray)response["Items"]; |
||
189 | return GetFoldersFromResponse(items, userID, true); |
||
190 | } |
||
191 | else |
||
192 | { |
||
193 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to retrieve inventory skeleton for " + userID + ": " + |
||
194 | response["Message"].AsString()); |
||
195 | return new List<InventoryFolderBase>(0); |
||
196 | } |
||
197 | } |
||
198 | |||
199 | /// <summary> |
||
200 | /// Retrieve the root inventory folder for the given user. |
||
201 | /// </summary> |
||
202 | /// <param name="userID"></param> |
||
203 | /// <returns>null if no root folder was found</returns> |
||
204 | public InventoryFolderBase GetRootFolder(UUID userID) |
||
205 | { |
||
206 | NameValueCollection requestArgs = new NameValueCollection |
||
207 | { |
||
208 | { "RequestMethod", "GetInventoryNode" }, |
||
209 | { "ItemID", userID.ToString() }, |
||
210 | { "OwnerID", userID.ToString() }, |
||
211 | { "IncludeFolders", "1" }, |
||
212 | { "IncludeItems", "0" }, |
||
213 | { "ChildrenOnly", "1" } |
||
214 | }; |
||
215 | |||
216 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
217 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
218 | { |
||
219 | OSDArray items = (OSDArray)response["Items"]; |
||
220 | List<InventoryFolderBase> folders = GetFoldersFromResponse(items, userID, true); |
||
221 | |||
222 | if (folders.Count > 0) |
||
223 | return folders[0]; |
||
224 | } |
||
225 | |||
226 | return null; |
||
227 | } |
||
228 | |||
229 | /// <summary> |
||
230 | /// Gets the user folder for the given folder-type |
||
231 | /// </summary> |
||
232 | /// <param name="userID"></param> |
||
233 | /// <param name="type"></param> |
||
234 | /// <returns></returns> |
||
235 | public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) |
||
236 | { |
||
237 | string contentType = SLUtil.SLAssetTypeToContentType((int)type); |
||
238 | |||
239 | NameValueCollection requestArgs = new NameValueCollection |
||
240 | { |
||
241 | { "RequestMethod", "GetFolderForType" }, |
||
242 | { "ContentType", contentType }, |
||
243 | { "OwnerID", userID.ToString() } |
||
244 | }; |
||
245 | |||
246 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
247 | if (response["Success"].AsBoolean() && response["Folder"] is OSDMap) |
||
248 | { |
||
249 | OSDMap folder = (OSDMap)response["Folder"]; |
||
250 | |||
251 | return new InventoryFolderBase( |
||
252 | folder["ID"].AsUUID(), |
||
253 | folder["Name"].AsString(), |
||
254 | folder["OwnerID"].AsUUID(), |
||
255 | (short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()), |
||
256 | folder["ParentID"].AsUUID(), |
||
257 | (ushort)folder["Version"].AsInteger() |
||
258 | ); |
||
259 | } |
||
260 | else |
||
261 | { |
||
262 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Default folder not found for content type " + contentType + ": " + response["Message"].AsString()); |
||
263 | return GetRootFolder(userID); |
||
264 | } |
||
265 | } |
||
266 | |||
267 | /// <summary> |
||
268 | /// Get an item, given by its UUID |
||
269 | /// </summary> |
||
270 | /// <param name="item"></param> |
||
271 | /// <returns></returns> |
||
272 | public InventoryItemBase GetItem(InventoryItemBase item) |
||
273 | { |
||
274 | NameValueCollection requestArgs = new NameValueCollection |
||
275 | { |
||
276 | { "RequestMethod", "GetInventoryNode" }, |
||
277 | { "ItemID", item.ID.ToString() }, |
||
278 | { "OwnerID", item.Owner.ToString() }, |
||
279 | { "IncludeFolders", "1" }, |
||
280 | { "IncludeItems", "1" }, |
||
281 | { "ChildrenOnly", "1" } |
||
282 | }; |
||
283 | |||
284 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
285 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
286 | { |
||
287 | List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]); |
||
288 | if (items.Count > 0) |
||
289 | { |
||
290 | // The requested item should be the first in this list, but loop through |
||
291 | // and sanity check just in case |
||
292 | for (int i = 0; i < items.Count; i++) |
||
293 | { |
||
294 | if (items[i].ID == item.ID) |
||
295 | return items[i]; |
||
296 | } |
||
297 | } |
||
298 | } |
||
299 | |||
300 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found"); |
||
301 | return null; |
||
302 | } |
||
303 | |||
304 | /// <summary> |
||
305 | /// Get a folder, given by its UUID |
||
306 | /// </summary> |
||
307 | /// <param name="folder"></param> |
||
308 | /// <returns></returns> |
||
309 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) |
||
310 | { |
||
311 | NameValueCollection requestArgs = new NameValueCollection |
||
312 | { |
||
313 | { "RequestMethod", "GetInventoryNode" }, |
||
314 | { "ItemID", folder.ID.ToString() }, |
||
315 | { "OwnerID", folder.Owner.ToString() }, |
||
316 | { "IncludeFolders", "1" }, |
||
317 | { "IncludeItems", "0" }, |
||
318 | { "ChildrenOnly", "1" } |
||
319 | }; |
||
320 | |||
321 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
322 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
323 | { |
||
324 | OSDArray items = (OSDArray)response["Items"]; |
||
325 | List<InventoryFolderBase> folders = GetFoldersFromResponse(items, folder.ID, true); |
||
326 | |||
327 | if (folders.Count > 0) |
||
328 | return folders[0]; |
||
329 | } |
||
330 | |||
331 | return null; |
||
332 | } |
||
333 | |||
334 | /// <summary> |
||
335 | /// Gets everything (folders and items) inside a folder |
||
336 | /// </summary> |
||
337 | /// <param name="userID"></param> |
||
338 | /// <param name="folderID"></param> |
||
339 | /// <returns></returns> |
||
340 | public InventoryCollection GetFolderContent(UUID userID, UUID folderID) |
||
341 | { |
||
342 | InventoryCollection inventory = new InventoryCollection(); |
||
343 | inventory.UserID = userID; |
||
344 | |||
345 | NameValueCollection requestArgs = new NameValueCollection |
||
346 | { |
||
347 | { "RequestMethod", "GetInventoryNode" }, |
||
348 | { "ItemID", folderID.ToString() }, |
||
349 | { "OwnerID", userID.ToString() }, |
||
350 | { "IncludeFolders", "1" }, |
||
351 | { "IncludeItems", "1" }, |
||
352 | { "ChildrenOnly", "1" } |
||
353 | }; |
||
354 | |||
355 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
356 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
357 | { |
||
358 | OSDArray items = (OSDArray)response["Items"]; |
||
359 | |||
360 | inventory.Folders = GetFoldersFromResponse(items, folderID, false); |
||
361 | inventory.Items = GetItemsFromResponse(items); |
||
362 | } |
||
363 | else |
||
364 | { |
||
365 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " + |
||
366 | response["Message"].AsString()); |
||
367 | inventory.Folders = new List<InventoryFolderBase>(0); |
||
368 | inventory.Items = new List<InventoryItemBase>(0); |
||
369 | } |
||
370 | |||
371 | return inventory; |
||
372 | } |
||
373 | |||
374 | /// <summary> |
||
375 | /// Gets the items inside a folder |
||
376 | /// </summary> |
||
377 | /// <param name="userID"></param> |
||
378 | /// <param name="folderID"></param> |
||
379 | /// <returns></returns> |
||
380 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) |
||
381 | { |
||
382 | InventoryCollection inventory = new InventoryCollection(); |
||
383 | inventory.UserID = userID; |
||
384 | |||
385 | NameValueCollection requestArgs = new NameValueCollection |
||
386 | { |
||
387 | { "RequestMethod", "GetInventoryNode" }, |
||
388 | { "ItemID", folderID.ToString() }, |
||
389 | { "OwnerID", userID.ToString() }, |
||
390 | { "IncludeFolders", "0" }, |
||
391 | { "IncludeItems", "1" }, |
||
392 | { "ChildrenOnly", "1" } |
||
393 | }; |
||
394 | |||
395 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
396 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
397 | { |
||
398 | OSDArray items = (OSDArray)response["Items"]; |
||
399 | return GetItemsFromResponse(items); |
||
400 | } |
||
401 | else |
||
402 | { |
||
403 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " + |
||
404 | response["Message"].AsString()); |
||
405 | return new List<InventoryItemBase>(0); |
||
406 | } |
||
407 | } |
||
408 | |||
409 | /// <summary> |
||
410 | /// Add a new folder to the user's inventory |
||
411 | /// </summary> |
||
412 | /// <param name="folder"></param> |
||
413 | /// <returns>true if the folder was successfully added</returns> |
||
414 | public bool AddFolder(InventoryFolderBase folder) |
||
415 | { |
||
416 | NameValueCollection requestArgs = new NameValueCollection |
||
417 | { |
||
418 | { "RequestMethod", "AddInventoryFolder" }, |
||
419 | { "FolderID", folder.ID.ToString() }, |
||
420 | { "ParentID", folder.ParentID.ToString() }, |
||
421 | { "OwnerID", folder.Owner.ToString() }, |
||
422 | { "Name", folder.Name }, |
||
423 | { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) } |
||
424 | }; |
||
425 | |||
426 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
427 | bool success = response["Success"].AsBoolean(); |
||
428 | |||
429 | if (!success) |
||
430 | { |
||
431 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " + |
||
432 | response["Message"].AsString()); |
||
433 | } |
||
434 | |||
435 | return success; |
||
436 | } |
||
437 | |||
438 | /// <summary> |
||
439 | /// Update a folder in the user's inventory |
||
440 | /// </summary> |
||
441 | /// <param name="folder"></param> |
||
442 | /// <returns>true if the folder was successfully updated</returns> |
||
443 | public bool UpdateFolder(InventoryFolderBase folder) |
||
444 | { |
||
445 | return AddFolder(folder); |
||
446 | } |
||
447 | |||
448 | /// <summary> |
||
449 | /// Move an inventory folder to a new location |
||
450 | /// </summary> |
||
451 | /// <param name="folder">A folder containing the details of the new location</param> |
||
452 | /// <returns>true if the folder was successfully moved</returns> |
||
453 | public bool MoveFolder(InventoryFolderBase folder) |
||
454 | { |
||
455 | return AddFolder(folder); |
||
456 | } |
||
457 | |||
458 | /// <summary> |
||
459 | /// Delete an item from the user's inventory |
||
460 | /// </summary> |
||
461 | /// <param name="item"></param> |
||
462 | /// <returns>true if the item was successfully deleted</returns> |
||
463 | //bool DeleteItem(InventoryItemBase item); |
||
464 | public bool DeleteFolders(UUID userID, List<UUID> folderIDs) |
||
465 | { |
||
466 | return DeleteItems(userID, folderIDs); |
||
467 | } |
||
468 | |||
469 | /// <summary> |
||
470 | /// Delete an item from the user's inventory |
||
471 | /// </summary> |
||
472 | /// <param name="item"></param> |
||
473 | /// <returns>true if the item was successfully deleted</returns> |
||
474 | public bool DeleteItems(UUID userID, List<UUID> itemIDs) |
||
475 | { |
||
476 | // TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes |
||
477 | bool allSuccess = true; |
||
478 | |||
479 | for (int i = 0; i < itemIDs.Count; i++) |
||
480 | { |
||
481 | UUID itemID = itemIDs[i]; |
||
482 | |||
483 | NameValueCollection requestArgs = new NameValueCollection |
||
484 | { |
||
485 | { "RequestMethod", "RemoveInventoryNode" }, |
||
486 | { "OwnerID", userID.ToString() }, |
||
487 | { "ItemID", itemID.ToString() } |
||
488 | }; |
||
489 | |||
490 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
491 | bool success = response["Success"].AsBoolean(); |
||
492 | |||
493 | if (!success) |
||
494 | { |
||
495 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " + |
||
496 | response["Message"].AsString()); |
||
497 | allSuccess = false; |
||
498 | } |
||
499 | } |
||
500 | |||
501 | return allSuccess; |
||
502 | } |
||
503 | |||
504 | /// <summary> |
||
505 | /// Purge an inventory folder of all its items and subfolders. |
||
506 | /// </summary> |
||
507 | /// <param name="folder"></param> |
||
508 | /// <returns>true if the folder was successfully purged</returns> |
||
509 | public bool PurgeFolder(InventoryFolderBase folder) |
||
510 | { |
||
511 | NameValueCollection requestArgs = new NameValueCollection |
||
512 | { |
||
513 | { "RequestMethod", "PurgeInventoryFolder" }, |
||
514 | { "OwnerID", folder.Owner.ToString() }, |
||
515 | { "FolderID", folder.ID.ToString() } |
||
516 | }; |
||
517 | |||
518 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
519 | bool success = response["Success"].AsBoolean(); |
||
520 | |||
521 | if (!success) |
||
522 | { |
||
523 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " + |
||
524 | response["Message"].AsString()); |
||
525 | } |
||
526 | |||
527 | return success; |
||
528 | } |
||
529 | |||
530 | /// <summary> |
||
531 | /// Add a new item to the user's inventory |
||
532 | /// </summary> |
||
533 | /// <param name="item"></param> |
||
534 | /// <returns>true if the item was successfully added</returns> |
||
535 | public bool AddItem(InventoryItemBase item) |
||
536 | { |
||
537 | // A folder of UUID.Zero means we need to find the most appropriate home for this item |
||
538 | if (item.Folder == UUID.Zero) |
||
539 | { |
||
540 | InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType); |
||
541 | if (folder != null && folder.ID != UUID.Zero) |
||
542 | item.Folder = folder.ID; |
||
543 | else |
||
544 | item.Folder = item.Owner; // Root folder |
||
545 | } |
||
546 | |||
547 | if ((AssetType)item.AssetType == AssetType.Gesture) |
||
548 | UpdateGesture(item.Owner, item.ID, item.Flags == 1); |
||
549 | |||
550 | if (item.BasePermissions == 0) |
||
551 | m_log.WarnFormat("[SIMIAN INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID); |
||
552 | |||
553 | OSDMap permissions = new OSDMap |
||
554 | { |
||
555 | { "BaseMask", OSD.FromInteger(item.BasePermissions) }, |
||
556 | { "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) }, |
||
557 | { "GroupMask", OSD.FromInteger(item.GroupPermissions) }, |
||
558 | { "NextOwnerMask", OSD.FromInteger(item.NextPermissions) }, |
||
559 | { "OwnerMask", OSD.FromInteger(item.CurrentPermissions) } |
||
560 | }; |
||
561 | |||
562 | OSDMap extraData = new OSDMap() |
||
563 | { |
||
564 | { "Flags", OSD.FromInteger(item.Flags) }, |
||
565 | { "GroupID", OSD.FromUUID(item.GroupID) }, |
||
566 | { "GroupOwned", OSD.FromBoolean(item.GroupOwned) }, |
||
567 | { "SalePrice", OSD.FromInteger(item.SalePrice) }, |
||
568 | { "SaleType", OSD.FromInteger(item.SaleType) }, |
||
569 | { "Permissions", permissions } |
||
570 | }; |
||
571 | |||
572 | // Add different asset type only if it differs from inventory type |
||
573 | // (needed for links) |
||
574 | string invContentType = SLUtil.SLInvTypeToContentType(item.InvType); |
||
575 | string assetContentType = SLUtil.SLAssetTypeToContentType(item.AssetType); |
||
576 | |||
577 | if (invContentType != assetContentType) |
||
578 | extraData["LinkedItemType"] = OSD.FromString(assetContentType); |
||
579 | |||
580 | NameValueCollection requestArgs = new NameValueCollection |
||
581 | { |
||
582 | { "RequestMethod", "AddInventoryItem" }, |
||
583 | { "ItemID", item.ID.ToString() }, |
||
584 | { "AssetID", item.AssetID.ToString() }, |
||
585 | { "ParentID", item.Folder.ToString() }, |
||
586 | { "OwnerID", item.Owner.ToString() }, |
||
587 | { "Name", item.Name }, |
||
588 | { "Description", item.Description }, |
||
589 | { "CreatorID", item.CreatorId }, |
||
590 | { "CreatorData", item.CreatorData }, |
||
591 | { "ContentType", invContentType }, |
||
592 | { "ExtraData", OSDParser.SerializeJsonString(extraData) } |
||
593 | }; |
||
594 | |||
595 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
596 | bool success = response["Success"].AsBoolean(); |
||
597 | |||
598 | if (!success) |
||
599 | { |
||
600 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " + |
||
601 | response["Message"].AsString()); |
||
602 | } |
||
603 | |||
604 | return success; |
||
605 | } |
||
606 | |||
607 | /// <summary> |
||
608 | /// Update an item in the user's inventory |
||
609 | /// </summary> |
||
610 | /// <param name="item"></param> |
||
611 | /// <returns>true if the item was successfully updated</returns> |
||
612 | public bool UpdateItem(InventoryItemBase item) |
||
613 | { |
||
614 | if (item.AssetID != UUID.Zero) |
||
615 | { |
||
616 | return AddItem(item); |
||
617 | } |
||
618 | else |
||
619 | { |
||
620 | // This is actually a folder update |
||
621 | InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0); |
||
622 | return UpdateFolder(folder); |
||
623 | } |
||
624 | } |
||
625 | |||
626 | public bool MoveItems(UUID ownerID, List<InventoryItemBase> items) |
||
627 | { |
||
628 | bool success = true; |
||
629 | |||
630 | while (items.Count > 0) |
||
631 | { |
||
632 | List<InventoryItemBase> currentItems = new List<InventoryItemBase>(); |
||
633 | UUID destFolderID = items[0].Folder; |
||
634 | |||
635 | // Find all of the items being moved to the current destination folder |
||
636 | for (int i = 0; i < items.Count; i++) |
||
637 | { |
||
638 | InventoryItemBase item = items[i]; |
||
639 | if (item.Folder == destFolderID) |
||
640 | currentItems.Add(item); |
||
641 | } |
||
642 | |||
643 | // Do the inventory move for the current items |
||
644 | success &= MoveItems(ownerID, items, destFolderID); |
||
645 | |||
646 | // Remove the processed items from the list |
||
647 | for (int i = 0; i < currentItems.Count; i++) |
||
648 | items.Remove(currentItems[i]); |
||
649 | } |
||
650 | |||
651 | return success; |
||
652 | } |
||
653 | |||
654 | /// <summary> |
||
655 | /// Does the given user have an inventory structure? |
||
656 | /// </summary> |
||
657 | /// <param name="userID"></param> |
||
658 | /// <returns></returns> |
||
659 | public bool HasInventoryForUser(UUID userID) |
||
660 | { |
||
661 | return GetRootFolder(userID) != null; |
||
662 | } |
||
663 | |||
664 | /// <summary> |
||
665 | /// Get the active gestures of the agent. |
||
666 | /// </summary> |
||
667 | /// <param name="userID"></param> |
||
668 | /// <returns></returns> |
||
669 | public List<InventoryItemBase> GetActiveGestures(UUID userID) |
||
670 | { |
||
671 | OSDArray items = FetchGestures(userID); |
||
672 | |||
673 | string[] itemIDs = new string[items.Count]; |
||
674 | for (int i = 0; i < items.Count; i++) |
||
675 | itemIDs[i] = items[i].AsUUID().ToString(); |
||
676 | |||
677 | // NameValueCollection requestArgs = new NameValueCollection |
||
678 | // { |
||
679 | // { "RequestMethod", "GetInventoryNodes" }, |
||
680 | // { "OwnerID", userID.ToString() }, |
||
681 | // { "Items", String.Join(",", itemIDs) } |
||
682 | // }; |
||
683 | |||
684 | // FIXME: Implement this in SimianGrid |
||
685 | return new List<InventoryItemBase>(0); |
||
686 | } |
||
687 | |||
688 | /// <summary> |
||
689 | /// Get the union of permissions of all inventory items |
||
690 | /// that hold the given assetID. |
||
691 | /// </summary> |
||
692 | /// <param name="userID"></param> |
||
693 | /// <param name="assetID"></param> |
||
694 | /// <returns>The permissions or 0 if no such asset is found in |
||
695 | /// the user's inventory</returns> |
||
696 | public int GetAssetPermissions(UUID userID, UUID assetID) |
||
697 | { |
||
698 | // NameValueCollection requestArgs = new NameValueCollection |
||
699 | // { |
||
700 | // { "RequestMethod", "GetInventoryNodes" }, |
||
701 | // { "OwnerID", userID.ToString() }, |
||
702 | // { "AssetID", assetID.ToString() } |
||
703 | // }; |
||
704 | |||
705 | // FIXME: Implement this in SimianGrid |
||
706 | return (int)PermissionMask.All; |
||
707 | } |
||
708 | |||
709 | private List<InventoryFolderBase> GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder) |
||
710 | { |
||
711 | List<InventoryFolderBase> invFolders = new List<InventoryFolderBase>(items.Count); |
||
712 | |||
713 | for (int i = 0; i < items.Count; i++) |
||
714 | { |
||
715 | OSDMap item = items[i] as OSDMap; |
||
716 | |||
717 | if (item != null && item["Type"].AsString() == "Folder") |
||
718 | { |
||
719 | UUID folderID = item["ID"].AsUUID(); |
||
720 | |||
721 | if (folderID == baseFolder && !includeBaseFolder) |
||
722 | continue; |
||
723 | |||
724 | invFolders.Add(new InventoryFolderBase( |
||
725 | folderID, |
||
726 | item["Name"].AsString(), |
||
727 | item["OwnerID"].AsUUID(), |
||
728 | (short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()), |
||
729 | item["ParentID"].AsUUID(), |
||
730 | (ushort)item["Version"].AsInteger() |
||
731 | )); |
||
732 | } |
||
733 | } |
||
734 | |||
735 | // m_log.Debug("[SIMIAN INVENTORY CONNECTOR]: Parsed " + invFolders.Count + " folders from SimianGrid response"); |
||
736 | return invFolders; |
||
737 | } |
||
738 | |||
739 | private List<InventoryItemBase> GetItemsFromResponse(OSDArray items) |
||
740 | { |
||
741 | List<InventoryItemBase> invItems = new List<InventoryItemBase>(items.Count); |
||
742 | |||
743 | for (int i = 0; i < items.Count; i++) |
||
744 | { |
||
745 | OSDMap item = items[i] as OSDMap; |
||
746 | |||
747 | if (item != null && item["Type"].AsString() == "Item") |
||
748 | { |
||
749 | InventoryItemBase invItem = new InventoryItemBase(); |
||
750 | |||
751 | invItem.AssetID = item["AssetID"].AsUUID(); |
||
752 | invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()); |
||
753 | invItem.CreationDate = item["CreationDate"].AsInteger(); |
||
754 | invItem.CreatorId = item["CreatorID"].AsString(); |
||
755 | invItem.CreatorData = item["CreatorData"].AsString(); |
||
756 | invItem.Description = item["Description"].AsString(); |
||
757 | invItem.Folder = item["ParentID"].AsUUID(); |
||
758 | invItem.ID = item["ID"].AsUUID(); |
||
759 | invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString()); |
||
760 | invItem.Name = item["Name"].AsString(); |
||
761 | invItem.Owner = item["OwnerID"].AsUUID(); |
||
762 | |||
763 | OSDMap extraData = item["ExtraData"] as OSDMap; |
||
764 | if (extraData != null && extraData.Count > 0) |
||
765 | { |
||
766 | invItem.Flags = extraData["Flags"].AsUInteger(); |
||
767 | invItem.GroupID = extraData["GroupID"].AsUUID(); |
||
768 | invItem.GroupOwned = extraData["GroupOwned"].AsBoolean(); |
||
769 | invItem.SalePrice = extraData["SalePrice"].AsInteger(); |
||
770 | invItem.SaleType = (byte)extraData["SaleType"].AsInteger(); |
||
771 | |||
772 | OSDMap perms = extraData["Permissions"] as OSDMap; |
||
773 | if (perms != null) |
||
774 | { |
||
775 | invItem.BasePermissions = perms["BaseMask"].AsUInteger(); |
||
776 | invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger(); |
||
777 | invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger(); |
||
778 | invItem.GroupPermissions = perms["GroupMask"].AsUInteger(); |
||
779 | invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger(); |
||
780 | } |
||
781 | |||
782 | if (extraData.ContainsKey("LinkedItemType")) |
||
783 | invItem.AssetType = SLUtil.ContentTypeToSLAssetType(extraData["LinkedItemType"].AsString()); |
||
784 | } |
||
785 | |||
786 | if (invItem.BasePermissions == 0) |
||
787 | { |
||
788 | m_log.InfoFormat("[SIMIAN INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})", |
||
789 | invItem.Name, invItem.ID); |
||
790 | invItem.BasePermissions = (uint)PermissionMask.All; |
||
791 | invItem.CurrentPermissions = (uint)PermissionMask.All; |
||
792 | invItem.EveryOnePermissions = (uint)PermissionMask.All; |
||
793 | invItem.GroupPermissions = (uint)PermissionMask.All; |
||
794 | invItem.NextPermissions = (uint)PermissionMask.All; |
||
795 | } |
||
796 | |||
797 | invItems.Add(invItem); |
||
798 | } |
||
799 | } |
||
800 | |||
801 | // m_log.Debug("[SIMIAN INVENTORY CONNECTOR]: Parsed " + invItems.Count + " items from SimianGrid response"); |
||
802 | return invItems; |
||
803 | } |
||
804 | |||
805 | private bool MoveItems(UUID ownerID, List<InventoryItemBase> items, UUID destFolderID) |
||
806 | { |
||
807 | string[] itemIDs = new string[items.Count]; |
||
808 | for (int i = 0; i < items.Count; i++) |
||
809 | itemIDs[i] = items[i].ID.ToString(); |
||
810 | |||
811 | NameValueCollection requestArgs = new NameValueCollection |
||
812 | { |
||
813 | { "RequestMethod", "MoveInventoryNodes" }, |
||
814 | { "OwnerID", ownerID.ToString() }, |
||
815 | { "FolderID", destFolderID.ToString() }, |
||
816 | { "Items", String.Join(",", itemIDs) } |
||
817 | }; |
||
818 | |||
819 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
820 | bool success = response["Success"].AsBoolean(); |
||
821 | |||
822 | if (!success) |
||
823 | { |
||
824 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " + |
||
825 | destFolderID + ": " + response["Message"].AsString()); |
||
826 | } |
||
827 | |||
828 | return success; |
||
829 | } |
||
830 | |||
831 | private void UpdateGesture(UUID userID, UUID itemID, bool enabled) |
||
832 | { |
||
833 | OSDArray gestures = FetchGestures(userID); |
||
834 | OSDArray newGestures = new OSDArray(); |
||
835 | |||
836 | for (int i = 0; i < gestures.Count; i++) |
||
837 | { |
||
838 | UUID gesture = gestures[i].AsUUID(); |
||
839 | if (gesture != itemID) |
||
840 | newGestures.Add(OSD.FromUUID(gesture)); |
||
841 | } |
||
842 | |||
843 | if (enabled) |
||
844 | newGestures.Add(OSD.FromUUID(itemID)); |
||
845 | |||
846 | SaveGestures(userID, newGestures); |
||
847 | } |
||
848 | |||
849 | private OSDArray FetchGestures(UUID userID) |
||
850 | { |
||
851 | NameValueCollection requestArgs = new NameValueCollection |
||
852 | { |
||
853 | { "RequestMethod", "GetUser" }, |
||
854 | { "UserID", userID.ToString() } |
||
855 | }; |
||
856 | |||
857 | OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs); |
||
858 | if (response["Success"].AsBoolean()) |
||
859 | { |
||
860 | OSDMap user = response["User"] as OSDMap; |
||
861 | if (user != null && response.ContainsKey("Gestures")) |
||
862 | { |
||
863 | OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString()); |
||
864 | if (gestures != null && gestures is OSDArray) |
||
865 | return (OSDArray)gestures; |
||
866 | else |
||
867 | m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID); |
||
868 | } |
||
869 | } |
||
870 | else |
||
871 | { |
||
872 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " + |
||
873 | response["Message"].AsString()); |
||
874 | } |
||
875 | |||
876 | return new OSDArray(); |
||
877 | } |
||
878 | |||
879 | private void SaveGestures(UUID userID, OSDArray gestures) |
||
880 | { |
||
881 | NameValueCollection requestArgs = new NameValueCollection |
||
882 | { |
||
883 | { "RequestMethod", "AddUserData" }, |
||
884 | { "UserID", userID.ToString() }, |
||
885 | { "Gestures", OSDParser.SerializeJsonString(gestures) } |
||
886 | }; |
||
887 | |||
888 | OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs); |
||
889 | if (!response["Success"].AsBoolean()) |
||
890 | { |
||
891 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " + |
||
892 | response["Message"].AsString()); |
||
893 | } |
||
894 | } |
||
895 | } |
||
896 | } |