opensim-development – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | eva | 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 | /// Synchronous inventory fetch. |
||
201 | /// </summary> |
||
202 | /// <param name="userID"></param> |
||
203 | /// <returns></returns> |
||
204 | [Obsolete] |
||
205 | public InventoryCollection GetUserInventory(UUID userID) |
||
206 | { |
||
207 | m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID); |
||
208 | |||
209 | InventoryCollection inventory = new InventoryCollection(); |
||
210 | inventory.UserID = userID; |
||
211 | inventory.Folders = new List<InventoryFolderBase>(); |
||
212 | inventory.Items = new List<InventoryItemBase>(); |
||
213 | |||
214 | return inventory; |
||
215 | } |
||
216 | |||
217 | /// <summary> |
||
218 | /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the |
||
219 | /// inventory has been received |
||
220 | /// </summary> |
||
221 | /// <param name="userID"></param> |
||
222 | /// <param name="callback"></param> |
||
223 | [Obsolete] |
||
224 | public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) |
||
225 | { |
||
226 | m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID); |
||
227 | callback(new List<InventoryFolderImpl>(0), new List<InventoryItemBase>(0)); |
||
228 | } |
||
229 | |||
230 | /// <summary> |
||
231 | /// Retrieve the root inventory folder for the given user. |
||
232 | /// </summary> |
||
233 | /// <param name="userID"></param> |
||
234 | /// <returns>null if no root folder was found</returns> |
||
235 | public InventoryFolderBase GetRootFolder(UUID userID) |
||
236 | { |
||
237 | NameValueCollection requestArgs = new NameValueCollection |
||
238 | { |
||
239 | { "RequestMethod", "GetInventoryNode" }, |
||
240 | { "ItemID", userID.ToString() }, |
||
241 | { "OwnerID", userID.ToString() }, |
||
242 | { "IncludeFolders", "1" }, |
||
243 | { "IncludeItems", "0" }, |
||
244 | { "ChildrenOnly", "1" } |
||
245 | }; |
||
246 | |||
247 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
248 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
249 | { |
||
250 | OSDArray items = (OSDArray)response["Items"]; |
||
251 | List<InventoryFolderBase> folders = GetFoldersFromResponse(items, userID, true); |
||
252 | |||
253 | if (folders.Count > 0) |
||
254 | return folders[0]; |
||
255 | } |
||
256 | |||
257 | return null; |
||
258 | } |
||
259 | |||
260 | /// <summary> |
||
261 | /// Gets the user folder for the given folder-type |
||
262 | /// </summary> |
||
263 | /// <param name="userID"></param> |
||
264 | /// <param name="type"></param> |
||
265 | /// <returns></returns> |
||
266 | public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) |
||
267 | { |
||
268 | string contentType = SLUtil.SLAssetTypeToContentType((int)type); |
||
269 | |||
270 | NameValueCollection requestArgs = new NameValueCollection |
||
271 | { |
||
272 | { "RequestMethod", "GetFolderForType" }, |
||
273 | { "ContentType", contentType }, |
||
274 | { "OwnerID", userID.ToString() } |
||
275 | }; |
||
276 | |||
277 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
278 | if (response["Success"].AsBoolean() && response["Folder"] is OSDMap) |
||
279 | { |
||
280 | OSDMap folder = (OSDMap)response["Folder"]; |
||
281 | |||
282 | return new InventoryFolderBase( |
||
283 | folder["ID"].AsUUID(), |
||
284 | folder["Name"].AsString(), |
||
285 | folder["OwnerID"].AsUUID(), |
||
286 | (short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()), |
||
287 | folder["ParentID"].AsUUID(), |
||
288 | (ushort)folder["Version"].AsInteger() |
||
289 | ); |
||
290 | } |
||
291 | else |
||
292 | { |
||
293 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Default folder not found for content type " + contentType + ": " + response["Message"].AsString()); |
||
294 | return GetRootFolder(userID); |
||
295 | } |
||
296 | } |
||
297 | |||
298 | /// <summary> |
||
299 | /// Get an item, given by its UUID |
||
300 | /// </summary> |
||
301 | /// <param name="item"></param> |
||
302 | /// <returns></returns> |
||
303 | public InventoryItemBase GetItem(InventoryItemBase item) |
||
304 | { |
||
305 | NameValueCollection requestArgs = new NameValueCollection |
||
306 | { |
||
307 | { "RequestMethod", "GetInventoryNode" }, |
||
308 | { "ItemID", item.ID.ToString() }, |
||
309 | { "OwnerID", item.Owner.ToString() }, |
||
310 | { "IncludeFolders", "1" }, |
||
311 | { "IncludeItems", "1" }, |
||
312 | { "ChildrenOnly", "1" } |
||
313 | }; |
||
314 | |||
315 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
316 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
317 | { |
||
318 | List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]); |
||
319 | if (items.Count > 0) |
||
320 | { |
||
321 | // The requested item should be the first in this list, but loop through |
||
322 | // and sanity check just in case |
||
323 | for (int i = 0; i < items.Count; i++) |
||
324 | { |
||
325 | if (items[i].ID == item.ID) |
||
326 | return items[i]; |
||
327 | } |
||
328 | } |
||
329 | } |
||
330 | |||
331 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found"); |
||
332 | return null; |
||
333 | } |
||
334 | |||
335 | /// <summary> |
||
336 | /// Get a folder, given by its UUID |
||
337 | /// </summary> |
||
338 | /// <param name="folder"></param> |
||
339 | /// <returns></returns> |
||
340 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) |
||
341 | { |
||
342 | NameValueCollection requestArgs = new NameValueCollection |
||
343 | { |
||
344 | { "RequestMethod", "GetInventoryNode" }, |
||
345 | { "ItemID", folder.ID.ToString() }, |
||
346 | { "OwnerID", folder.Owner.ToString() }, |
||
347 | { "IncludeFolders", "1" }, |
||
348 | { "IncludeItems", "0" }, |
||
349 | { "ChildrenOnly", "1" } |
||
350 | }; |
||
351 | |||
352 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
353 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
354 | { |
||
355 | OSDArray items = (OSDArray)response["Items"]; |
||
356 | List<InventoryFolderBase> folders = GetFoldersFromResponse(items, folder.ID, true); |
||
357 | |||
358 | if (folders.Count > 0) |
||
359 | return folders[0]; |
||
360 | } |
||
361 | |||
362 | return null; |
||
363 | } |
||
364 | |||
365 | /// <summary> |
||
366 | /// Gets everything (folders and items) inside a folder |
||
367 | /// </summary> |
||
368 | /// <param name="userID"></param> |
||
369 | /// <param name="folderID"></param> |
||
370 | /// <returns></returns> |
||
371 | public InventoryCollection GetFolderContent(UUID userID, UUID folderID) |
||
372 | { |
||
373 | InventoryCollection inventory = new InventoryCollection(); |
||
374 | inventory.UserID = userID; |
||
375 | |||
376 | NameValueCollection requestArgs = new NameValueCollection |
||
377 | { |
||
378 | { "RequestMethod", "GetInventoryNode" }, |
||
379 | { "ItemID", folderID.ToString() }, |
||
380 | { "OwnerID", userID.ToString() }, |
||
381 | { "IncludeFolders", "1" }, |
||
382 | { "IncludeItems", "1" }, |
||
383 | { "ChildrenOnly", "1" } |
||
384 | }; |
||
385 | |||
386 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
387 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
388 | { |
||
389 | OSDArray items = (OSDArray)response["Items"]; |
||
390 | |||
391 | inventory.Folders = GetFoldersFromResponse(items, folderID, false); |
||
392 | inventory.Items = GetItemsFromResponse(items); |
||
393 | } |
||
394 | else |
||
395 | { |
||
396 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " + |
||
397 | response["Message"].AsString()); |
||
398 | inventory.Folders = new List<InventoryFolderBase>(0); |
||
399 | inventory.Items = new List<InventoryItemBase>(0); |
||
400 | } |
||
401 | |||
402 | return inventory; |
||
403 | } |
||
404 | |||
405 | /// <summary> |
||
406 | /// Gets the items inside a folder |
||
407 | /// </summary> |
||
408 | /// <param name="userID"></param> |
||
409 | /// <param name="folderID"></param> |
||
410 | /// <returns></returns> |
||
411 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) |
||
412 | { |
||
413 | InventoryCollection inventory = new InventoryCollection(); |
||
414 | inventory.UserID = userID; |
||
415 | |||
416 | NameValueCollection requestArgs = new NameValueCollection |
||
417 | { |
||
418 | { "RequestMethod", "GetInventoryNode" }, |
||
419 | { "ItemID", folderID.ToString() }, |
||
420 | { "OwnerID", userID.ToString() }, |
||
421 | { "IncludeFolders", "0" }, |
||
422 | { "IncludeItems", "1" }, |
||
423 | { "ChildrenOnly", "1" } |
||
424 | }; |
||
425 | |||
426 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
427 | if (response["Success"].AsBoolean() && response["Items"] is OSDArray) |
||
428 | { |
||
429 | OSDArray items = (OSDArray)response["Items"]; |
||
430 | return GetItemsFromResponse(items); |
||
431 | } |
||
432 | else |
||
433 | { |
||
434 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " + |
||
435 | response["Message"].AsString()); |
||
436 | return new List<InventoryItemBase>(0); |
||
437 | } |
||
438 | } |
||
439 | |||
440 | /// <summary> |
||
441 | /// Add a new folder to the user's inventory |
||
442 | /// </summary> |
||
443 | /// <param name="folder"></param> |
||
444 | /// <returns>true if the folder was successfully added</returns> |
||
445 | public bool AddFolder(InventoryFolderBase folder) |
||
446 | { |
||
447 | NameValueCollection requestArgs = new NameValueCollection |
||
448 | { |
||
449 | { "RequestMethod", "AddInventoryFolder" }, |
||
450 | { "FolderID", folder.ID.ToString() }, |
||
451 | { "ParentID", folder.ParentID.ToString() }, |
||
452 | { "OwnerID", folder.Owner.ToString() }, |
||
453 | { "Name", folder.Name }, |
||
454 | { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) } |
||
455 | }; |
||
456 | |||
457 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
458 | bool success = response["Success"].AsBoolean(); |
||
459 | |||
460 | if (!success) |
||
461 | { |
||
462 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " + |
||
463 | response["Message"].AsString()); |
||
464 | } |
||
465 | |||
466 | return success; |
||
467 | } |
||
468 | |||
469 | /// <summary> |
||
470 | /// Update a folder in the user's inventory |
||
471 | /// </summary> |
||
472 | /// <param name="folder"></param> |
||
473 | /// <returns>true if the folder was successfully updated</returns> |
||
474 | public bool UpdateFolder(InventoryFolderBase folder) |
||
475 | { |
||
476 | return AddFolder(folder); |
||
477 | } |
||
478 | |||
479 | /// <summary> |
||
480 | /// Move an inventory folder to a new location |
||
481 | /// </summary> |
||
482 | /// <param name="folder">A folder containing the details of the new location</param> |
||
483 | /// <returns>true if the folder was successfully moved</returns> |
||
484 | public bool MoveFolder(InventoryFolderBase folder) |
||
485 | { |
||
486 | return AddFolder(folder); |
||
487 | } |
||
488 | |||
489 | /// <summary> |
||
490 | /// Delete an item from the user's inventory |
||
491 | /// </summary> |
||
492 | /// <param name="item"></param> |
||
493 | /// <returns>true if the item was successfully deleted</returns> |
||
494 | //bool DeleteItem(InventoryItemBase item); |
||
495 | public bool DeleteFolders(UUID userID, List<UUID> folderIDs) |
||
496 | { |
||
497 | return DeleteItems(userID, folderIDs); |
||
498 | } |
||
499 | |||
500 | /// <summary> |
||
501 | /// Delete an item from the user's inventory |
||
502 | /// </summary> |
||
503 | /// <param name="item"></param> |
||
504 | /// <returns>true if the item was successfully deleted</returns> |
||
505 | public bool DeleteItems(UUID userID, List<UUID> itemIDs) |
||
506 | { |
||
507 | // TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes |
||
508 | bool allSuccess = true; |
||
509 | |||
510 | for (int i = 0; i < itemIDs.Count; i++) |
||
511 | { |
||
512 | UUID itemID = itemIDs[i]; |
||
513 | |||
514 | NameValueCollection requestArgs = new NameValueCollection |
||
515 | { |
||
516 | { "RequestMethod", "RemoveInventoryNode" }, |
||
517 | { "OwnerID", userID.ToString() }, |
||
518 | { "ItemID", itemID.ToString() } |
||
519 | }; |
||
520 | |||
521 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
522 | bool success = response["Success"].AsBoolean(); |
||
523 | |||
524 | if (!success) |
||
525 | { |
||
526 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " + |
||
527 | response["Message"].AsString()); |
||
528 | allSuccess = false; |
||
529 | } |
||
530 | } |
||
531 | |||
532 | return allSuccess; |
||
533 | } |
||
534 | |||
535 | /// <summary> |
||
536 | /// Purge an inventory folder of all its items and subfolders. |
||
537 | /// </summary> |
||
538 | /// <param name="folder"></param> |
||
539 | /// <returns>true if the folder was successfully purged</returns> |
||
540 | public bool PurgeFolder(InventoryFolderBase folder) |
||
541 | { |
||
542 | NameValueCollection requestArgs = new NameValueCollection |
||
543 | { |
||
544 | { "RequestMethod", "PurgeInventoryFolder" }, |
||
545 | { "OwnerID", folder.Owner.ToString() }, |
||
546 | { "FolderID", folder.ID.ToString() } |
||
547 | }; |
||
548 | |||
549 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
550 | bool success = response["Success"].AsBoolean(); |
||
551 | |||
552 | if (!success) |
||
553 | { |
||
554 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " + |
||
555 | response["Message"].AsString()); |
||
556 | } |
||
557 | |||
558 | return success; |
||
559 | } |
||
560 | |||
561 | /// <summary> |
||
562 | /// Add a new item to the user's inventory |
||
563 | /// </summary> |
||
564 | /// <param name="item"></param> |
||
565 | /// <returns>true if the item was successfully added</returns> |
||
566 | public bool AddItem(InventoryItemBase item) |
||
567 | { |
||
568 | // A folder of UUID.Zero means we need to find the most appropriate home for this item |
||
569 | if (item.Folder == UUID.Zero) |
||
570 | { |
||
571 | InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType); |
||
572 | if (folder != null && folder.ID != UUID.Zero) |
||
573 | item.Folder = folder.ID; |
||
574 | else |
||
575 | item.Folder = item.Owner; // Root folder |
||
576 | } |
||
577 | |||
578 | if ((AssetType)item.AssetType == AssetType.Gesture) |
||
579 | UpdateGesture(item.Owner, item.ID, item.Flags == 1); |
||
580 | |||
581 | if (item.BasePermissions == 0) |
||
582 | m_log.WarnFormat("[SIMIAN INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID); |
||
583 | |||
584 | OSDMap permissions = new OSDMap |
||
585 | { |
||
586 | { "BaseMask", OSD.FromInteger(item.BasePermissions) }, |
||
587 | { "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) }, |
||
588 | { "GroupMask", OSD.FromInteger(item.GroupPermissions) }, |
||
589 | { "NextOwnerMask", OSD.FromInteger(item.NextPermissions) }, |
||
590 | { "OwnerMask", OSD.FromInteger(item.CurrentPermissions) } |
||
591 | }; |
||
592 | |||
593 | OSDMap extraData = new OSDMap() |
||
594 | { |
||
595 | { "Flags", OSD.FromInteger(item.Flags) }, |
||
596 | { "GroupID", OSD.FromUUID(item.GroupID) }, |
||
597 | { "GroupOwned", OSD.FromBoolean(item.GroupOwned) }, |
||
598 | { "SalePrice", OSD.FromInteger(item.SalePrice) }, |
||
599 | { "SaleType", OSD.FromInteger(item.SaleType) }, |
||
600 | { "Permissions", permissions } |
||
601 | }; |
||
602 | |||
603 | // Add different asset type only if it differs from inventory type |
||
604 | // (needed for links) |
||
605 | string invContentType = SLUtil.SLInvTypeToContentType(item.InvType); |
||
606 | string assetContentType = SLUtil.SLAssetTypeToContentType(item.AssetType); |
||
607 | |||
608 | if (invContentType != assetContentType) |
||
609 | extraData["LinkedItemType"] = OSD.FromString(assetContentType); |
||
610 | |||
611 | NameValueCollection requestArgs = new NameValueCollection |
||
612 | { |
||
613 | { "RequestMethod", "AddInventoryItem" }, |
||
614 | { "ItemID", item.ID.ToString() }, |
||
615 | { "AssetID", item.AssetID.ToString() }, |
||
616 | { "ParentID", item.Folder.ToString() }, |
||
617 | { "OwnerID", item.Owner.ToString() }, |
||
618 | { "Name", item.Name }, |
||
619 | { "Description", item.Description }, |
||
620 | { "CreatorID", item.CreatorId }, |
||
621 | { "CreatorData", item.CreatorData }, |
||
622 | { "ContentType", invContentType }, |
||
623 | { "ExtraData", OSDParser.SerializeJsonString(extraData) } |
||
624 | }; |
||
625 | |||
626 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
627 | bool success = response["Success"].AsBoolean(); |
||
628 | |||
629 | if (!success) |
||
630 | { |
||
631 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " + |
||
632 | response["Message"].AsString()); |
||
633 | } |
||
634 | |||
635 | return success; |
||
636 | } |
||
637 | |||
638 | /// <summary> |
||
639 | /// Update an item in the user's inventory |
||
640 | /// </summary> |
||
641 | /// <param name="item"></param> |
||
642 | /// <returns>true if the item was successfully updated</returns> |
||
643 | public bool UpdateItem(InventoryItemBase item) |
||
644 | { |
||
645 | if (item.AssetID != UUID.Zero) |
||
646 | { |
||
647 | return AddItem(item); |
||
648 | } |
||
649 | else |
||
650 | { |
||
651 | // This is actually a folder update |
||
652 | InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0); |
||
653 | return UpdateFolder(folder); |
||
654 | } |
||
655 | } |
||
656 | |||
657 | public bool MoveItems(UUID ownerID, List<InventoryItemBase> items) |
||
658 | { |
||
659 | bool success = true; |
||
660 | |||
661 | while (items.Count > 0) |
||
662 | { |
||
663 | List<InventoryItemBase> currentItems = new List<InventoryItemBase>(); |
||
664 | UUID destFolderID = items[0].Folder; |
||
665 | |||
666 | // Find all of the items being moved to the current destination folder |
||
667 | for (int i = 0; i < items.Count; i++) |
||
668 | { |
||
669 | InventoryItemBase item = items[i]; |
||
670 | if (item.Folder == destFolderID) |
||
671 | currentItems.Add(item); |
||
672 | } |
||
673 | |||
674 | // Do the inventory move for the current items |
||
675 | success &= MoveItems(ownerID, items, destFolderID); |
||
676 | |||
677 | // Remove the processed items from the list |
||
678 | for (int i = 0; i < currentItems.Count; i++) |
||
679 | items.Remove(currentItems[i]); |
||
680 | } |
||
681 | |||
682 | return success; |
||
683 | } |
||
684 | |||
685 | /// <summary> |
||
686 | /// Does the given user have an inventory structure? |
||
687 | /// </summary> |
||
688 | /// <param name="userID"></param> |
||
689 | /// <returns></returns> |
||
690 | public bool HasInventoryForUser(UUID userID) |
||
691 | { |
||
692 | return GetRootFolder(userID) != null; |
||
693 | } |
||
694 | |||
695 | /// <summary> |
||
696 | /// Get the active gestures of the agent. |
||
697 | /// </summary> |
||
698 | /// <param name="userID"></param> |
||
699 | /// <returns></returns> |
||
700 | public List<InventoryItemBase> GetActiveGestures(UUID userID) |
||
701 | { |
||
702 | OSDArray items = FetchGestures(userID); |
||
703 | |||
704 | string[] itemIDs = new string[items.Count]; |
||
705 | for (int i = 0; i < items.Count; i++) |
||
706 | itemIDs[i] = items[i].AsUUID().ToString(); |
||
707 | |||
708 | // NameValueCollection requestArgs = new NameValueCollection |
||
709 | // { |
||
710 | // { "RequestMethod", "GetInventoryNodes" }, |
||
711 | // { "OwnerID", userID.ToString() }, |
||
712 | // { "Items", String.Join(",", itemIDs) } |
||
713 | // }; |
||
714 | |||
715 | // FIXME: Implement this in SimianGrid |
||
716 | return new List<InventoryItemBase>(0); |
||
717 | } |
||
718 | |||
719 | /// <summary> |
||
720 | /// Get the union of permissions of all inventory items |
||
721 | /// that hold the given assetID. |
||
722 | /// </summary> |
||
723 | /// <param name="userID"></param> |
||
724 | /// <param name="assetID"></param> |
||
725 | /// <returns>The permissions or 0 if no such asset is found in |
||
726 | /// the user's inventory</returns> |
||
727 | public int GetAssetPermissions(UUID userID, UUID assetID) |
||
728 | { |
||
729 | // NameValueCollection requestArgs = new NameValueCollection |
||
730 | // { |
||
731 | // { "RequestMethod", "GetInventoryNodes" }, |
||
732 | // { "OwnerID", userID.ToString() }, |
||
733 | // { "AssetID", assetID.ToString() } |
||
734 | // }; |
||
735 | |||
736 | // FIXME: Implement this in SimianGrid |
||
737 | return (int)PermissionMask.All; |
||
738 | } |
||
739 | |||
740 | private List<InventoryFolderBase> GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder) |
||
741 | { |
||
742 | List<InventoryFolderBase> invFolders = new List<InventoryFolderBase>(items.Count); |
||
743 | |||
744 | for (int i = 0; i < items.Count; i++) |
||
745 | { |
||
746 | OSDMap item = items[i] as OSDMap; |
||
747 | |||
748 | if (item != null && item["Type"].AsString() == "Folder") |
||
749 | { |
||
750 | UUID folderID = item["ID"].AsUUID(); |
||
751 | |||
752 | if (folderID == baseFolder && !includeBaseFolder) |
||
753 | continue; |
||
754 | |||
755 | invFolders.Add(new InventoryFolderBase( |
||
756 | folderID, |
||
757 | item["Name"].AsString(), |
||
758 | item["OwnerID"].AsUUID(), |
||
759 | (short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()), |
||
760 | item["ParentID"].AsUUID(), |
||
761 | (ushort)item["Version"].AsInteger() |
||
762 | )); |
||
763 | } |
||
764 | } |
||
765 | |||
766 | // m_log.Debug("[SIMIAN INVENTORY CONNECTOR]: Parsed " + invFolders.Count + " folders from SimianGrid response"); |
||
767 | return invFolders; |
||
768 | } |
||
769 | |||
770 | private List<InventoryItemBase> GetItemsFromResponse(OSDArray items) |
||
771 | { |
||
772 | List<InventoryItemBase> invItems = new List<InventoryItemBase>(items.Count); |
||
773 | |||
774 | for (int i = 0; i < items.Count; i++) |
||
775 | { |
||
776 | OSDMap item = items[i] as OSDMap; |
||
777 | |||
778 | if (item != null && item["Type"].AsString() == "Item") |
||
779 | { |
||
780 | InventoryItemBase invItem = new InventoryItemBase(); |
||
781 | |||
782 | invItem.AssetID = item["AssetID"].AsUUID(); |
||
783 | invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()); |
||
784 | invItem.CreationDate = item["CreationDate"].AsInteger(); |
||
785 | invItem.CreatorId = item["CreatorID"].AsString(); |
||
786 | invItem.CreatorData = item["CreatorData"].AsString(); |
||
787 | invItem.Description = item["Description"].AsString(); |
||
788 | invItem.Folder = item["ParentID"].AsUUID(); |
||
789 | invItem.ID = item["ID"].AsUUID(); |
||
790 | invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString()); |
||
791 | invItem.Name = item["Name"].AsString(); |
||
792 | invItem.Owner = item["OwnerID"].AsUUID(); |
||
793 | |||
794 | OSDMap extraData = item["ExtraData"] as OSDMap; |
||
795 | if (extraData != null && extraData.Count > 0) |
||
796 | { |
||
797 | invItem.Flags = extraData["Flags"].AsUInteger(); |
||
798 | invItem.GroupID = extraData["GroupID"].AsUUID(); |
||
799 | invItem.GroupOwned = extraData["GroupOwned"].AsBoolean(); |
||
800 | invItem.SalePrice = extraData["SalePrice"].AsInteger(); |
||
801 | invItem.SaleType = (byte)extraData["SaleType"].AsInteger(); |
||
802 | |||
803 | OSDMap perms = extraData["Permissions"] as OSDMap; |
||
804 | if (perms != null) |
||
805 | { |
||
806 | invItem.BasePermissions = perms["BaseMask"].AsUInteger(); |
||
807 | invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger(); |
||
808 | invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger(); |
||
809 | invItem.GroupPermissions = perms["GroupMask"].AsUInteger(); |
||
810 | invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger(); |
||
811 | } |
||
812 | |||
813 | if (extraData.ContainsKey("LinkedItemType")) |
||
814 | invItem.AssetType = SLUtil.ContentTypeToSLAssetType(extraData["LinkedItemType"].AsString()); |
||
815 | } |
||
816 | |||
817 | if (invItem.BasePermissions == 0) |
||
818 | { |
||
819 | m_log.InfoFormat("[SIMIAN INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})", |
||
820 | invItem.Name, invItem.ID); |
||
821 | invItem.BasePermissions = (uint)PermissionMask.All; |
||
822 | invItem.CurrentPermissions = (uint)PermissionMask.All; |
||
823 | invItem.EveryOnePermissions = (uint)PermissionMask.All; |
||
824 | invItem.GroupPermissions = (uint)PermissionMask.All; |
||
825 | invItem.NextPermissions = (uint)PermissionMask.All; |
||
826 | } |
||
827 | |||
828 | invItems.Add(invItem); |
||
829 | } |
||
830 | } |
||
831 | |||
832 | // m_log.Debug("[SIMIAN INVENTORY CONNECTOR]: Parsed " + invItems.Count + " items from SimianGrid response"); |
||
833 | return invItems; |
||
834 | } |
||
835 | |||
836 | private bool MoveItems(UUID ownerID, List<InventoryItemBase> items, UUID destFolderID) |
||
837 | { |
||
838 | string[] itemIDs = new string[items.Count]; |
||
839 | for (int i = 0; i < items.Count; i++) |
||
840 | itemIDs[i] = items[i].ID.ToString(); |
||
841 | |||
842 | NameValueCollection requestArgs = new NameValueCollection |
||
843 | { |
||
844 | { "RequestMethod", "MoveInventoryNodes" }, |
||
845 | { "OwnerID", ownerID.ToString() }, |
||
846 | { "FolderID", destFolderID.ToString() }, |
||
847 | { "Items", String.Join(",", itemIDs) } |
||
848 | }; |
||
849 | |||
850 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
851 | bool success = response["Success"].AsBoolean(); |
||
852 | |||
853 | if (!success) |
||
854 | { |
||
855 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " + |
||
856 | destFolderID + ": " + response["Message"].AsString()); |
||
857 | } |
||
858 | |||
859 | return success; |
||
860 | } |
||
861 | |||
862 | private void UpdateGesture(UUID userID, UUID itemID, bool enabled) |
||
863 | { |
||
864 | OSDArray gestures = FetchGestures(userID); |
||
865 | OSDArray newGestures = new OSDArray(); |
||
866 | |||
867 | for (int i = 0; i < gestures.Count; i++) |
||
868 | { |
||
869 | UUID gesture = gestures[i].AsUUID(); |
||
870 | if (gesture != itemID) |
||
871 | newGestures.Add(OSD.FromUUID(gesture)); |
||
872 | } |
||
873 | |||
874 | if (enabled) |
||
875 | newGestures.Add(OSD.FromUUID(itemID)); |
||
876 | |||
877 | SaveGestures(userID, newGestures); |
||
878 | } |
||
879 | |||
880 | private OSDArray FetchGestures(UUID userID) |
||
881 | { |
||
882 | NameValueCollection requestArgs = new NameValueCollection |
||
883 | { |
||
884 | { "RequestMethod", "GetUser" }, |
||
885 | { "UserID", userID.ToString() } |
||
886 | }; |
||
887 | |||
888 | OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs); |
||
889 | if (response["Success"].AsBoolean()) |
||
890 | { |
||
891 | OSDMap user = response["User"] as OSDMap; |
||
892 | if (user != null && response.ContainsKey("Gestures")) |
||
893 | { |
||
894 | OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString()); |
||
895 | if (gestures != null && gestures is OSDArray) |
||
896 | return (OSDArray)gestures; |
||
897 | else |
||
898 | m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID); |
||
899 | } |
||
900 | } |
||
901 | else |
||
902 | { |
||
903 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " + |
||
904 | response["Message"].AsString()); |
||
905 | } |
||
906 | |||
907 | return new OSDArray(); |
||
908 | } |
||
909 | |||
910 | private void SaveGestures(UUID userID, OSDArray gestures) |
||
911 | { |
||
912 | NameValueCollection requestArgs = new NameValueCollection |
||
913 | { |
||
914 | { "RequestMethod", "AddUserData" }, |
||
915 | { "UserID", userID.ToString() }, |
||
916 | { "Gestures", OSDParser.SerializeJsonString(gestures) } |
||
917 | }; |
||
918 | |||
919 | OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs); |
||
920 | if (!response["Success"].AsBoolean()) |
||
921 | { |
||
922 | m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " + |
||
923 | response["Message"].AsString()); |
||
924 | } |
||
925 | } |
||
926 | } |
||
927 | } |