diff options
Diffstat (limited to 'OpenSim/Capabilities')
8 files changed, 217 insertions, 429 deletions
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs index 53ed115..427a310 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs | |||
@@ -30,6 +30,7 @@ using System.Collections; | |||
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Linq; | 31 | using System.Linq; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using System.Text; | ||
33 | using log4net; | 34 | using log4net; |
34 | using Nini.Config; | 35 | using Nini.Config; |
35 | using OpenMetaverse; | 36 | using OpenMetaverse; |
@@ -60,26 +61,10 @@ namespace OpenSim.Capabilities.Handlers | |||
60 | m_Scene = s; | 61 | m_Scene = s; |
61 | } | 62 | } |
62 | 63 | ||
63 | |||
64 | public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | 64 | public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) |
65 | { | 65 | { |
66 | //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request); | 66 | //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request); |
67 | 67 | ||
68 | // nasty temporary hack here, the linden client falsely | ||
69 | // identifies the uuid 00000000-0000-0000-0000-000000000000 | ||
70 | // as a string which breaks us | ||
71 | // | ||
72 | // correctly mark it as a uuid | ||
73 | // | ||
74 | request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>"); | ||
75 | |||
76 | // another hack <integer>1</integer> results in a | ||
77 | // System.ArgumentException: Object type System.Int32 cannot | ||
78 | // be converted to target type: System.Boolean | ||
79 | // | ||
80 | request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>"); | ||
81 | request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>"); | ||
82 | |||
83 | Hashtable hash = new Hashtable(); | 68 | Hashtable hash = new Hashtable(); |
84 | try | 69 | try |
85 | { | 70 | { |
@@ -92,10 +77,7 @@ namespace OpenSim.Capabilities.Handlers | |||
92 | } | 77 | } |
93 | 78 | ||
94 | ArrayList foldersrequested = (ArrayList)hash["folders"]; | 79 | ArrayList foldersrequested = (ArrayList)hash["folders"]; |
95 | 80 | ||
96 | string response = ""; | ||
97 | string bad_folders_response = ""; | ||
98 | |||
99 | List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>(); | 81 | List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>(); |
100 | for (int i = 0; i < foldersrequested.Count; i++) | 82 | for (int i = 0; i < foldersrequested.Count; i++) |
101 | { | 83 | { |
@@ -113,72 +95,56 @@ namespace OpenSim.Capabilities.Handlers | |||
113 | continue; | 95 | continue; |
114 | } | 96 | } |
115 | 97 | ||
116 | // Filter duplicate folder ids that bad viewers may send | 98 | folders.Add(llsdRequest); |
117 | if (folders.Find(f => f.folder_id == llsdRequest.folder_id) == null) | ||
118 | folders.Add(llsdRequest); | ||
119 | |||
120 | } | 99 | } |
121 | 100 | ||
122 | if (folders.Count > 0) | 101 | if(folders.Count == 0) |
123 | { | 102 | return "<llsd><map><key>folders</key><array /></map></llsd>"; |
124 | List<UUID> bad_folders = new List<UUID>(); | ||
125 | List<InventoryCollectionWithDescendents> invcollSet = Fetch(folders, bad_folders); | ||
126 | //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count); | ||
127 | |||
128 | if (invcollSet == null) | ||
129 | { | ||
130 | m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol."); | ||
131 | #pragma warning disable 0612 | ||
132 | return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse); | ||
133 | #pragma warning restore 0612 | ||
134 | } | ||
135 | |||
136 | string inventoryitemstr = string.Empty; | ||
137 | foreach (InventoryCollectionWithDescendents icoll in invcollSet) | ||
138 | { | ||
139 | LLSDInventoryDescendents reply = ToLLSD(icoll.Collection, icoll.Descendents); | ||
140 | 103 | ||
141 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); | 104 | List<UUID> bad_folders = new List<UUID>(); |
142 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); | ||
143 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); | ||
144 | 105 | ||
145 | response += inventoryitemstr; | 106 | List<InventoryCollectionWithDescendents> invcollSet = Fetch(folders, bad_folders); |
146 | } | 107 | //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count); |
147 | 108 | ||
148 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders)); | 109 | if (invcollSet == null) |
149 | foreach (UUID bad in bad_folders) | 110 | { |
150 | bad_folders_response += "<uuid>" + bad + "</uuid>"; | 111 | m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol."); |
112 | #pragma warning disable 0612 | ||
113 | return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse); | ||
114 | #pragma warning restore 0612 | ||
151 | } | 115 | } |
152 | 116 | ||
153 | if (response.Length == 0) | 117 | StringBuilder lastresponse = new StringBuilder(1024); |
118 | lastresponse.Append("<llsd>"); | ||
119 | |||
120 | if(invcollSet.Count > 0) | ||
154 | { | 121 | { |
155 | /* Viewers expect a bad_folders array when not available */ | 122 | lastresponse.Append("<map><key>folders</key><array>"); |
156 | if (bad_folders_response.Length != 0) | 123 | foreach (InventoryCollectionWithDescendents icoll in invcollSet) |
157 | { | ||
158 | response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
159 | } | ||
160 | else | ||
161 | { | 124 | { |
162 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; | 125 | LLSDInventoryFolderContents thiscontents = contentsToLLSD(icoll.Collection, icoll.Descendents); |
126 | lastresponse.Append(LLSDHelpers.SerialiseLLSDReplyNoHeader(thiscontents)); | ||
163 | } | 127 | } |
128 | lastresponse.Append("</array></map>"); | ||
164 | } | 129 | } |
165 | else | 130 | else |
131 | lastresponse.Append("<map><key>folders</key><array /></map>"); | ||
132 | |||
133 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders)); | ||
134 | if(bad_folders.Count > 0) | ||
166 | { | 135 | { |
167 | if (bad_folders_response.Length != 0) | 136 | lastresponse.Append("<map><key>bad_folders</key><array>"); |
168 | { | 137 | foreach (UUID bad in bad_folders) |
169 | response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
170 | } | ||
171 | else | ||
172 | { | 138 | { |
173 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; | 139 | lastresponse.Append("<map><key>folder_id</key><uuid>"); |
140 | lastresponse.Append(bad.ToString()); | ||
141 | lastresponse.Append("</uuid><key>error</key><string>Unknown</string></map>"); | ||
174 | } | 142 | } |
143 | lastresponse.Append("</array></map>"); | ||
175 | } | 144 | } |
145 | lastresponse.Append("</llsd>"); | ||
176 | 146 | ||
177 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request for {0} folders. Item count {1}", folders.Count, item_count); | 147 | return lastresponse.ToString();; |
178 | //m_log.Debug("[WEB FETCH INV DESC HANDLER] " + response); | ||
179 | |||
180 | return response; | ||
181 | |||
182 | } | 148 | } |
183 | 149 | ||
184 | /// <summary> | 150 | /// <summary> |
@@ -240,24 +206,19 @@ namespace OpenSim.Capabilities.Handlers | |||
240 | return reply; | 206 | return reply; |
241 | } | 207 | } |
242 | 208 | ||
243 | private LLSDInventoryDescendents ToLLSD(InventoryCollection inv, int descendents) | 209 | private LLSDInventoryFolderContents contentsToLLSD(InventoryCollection inv, int descendents) |
244 | { | 210 | { |
245 | LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); | ||
246 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); | 211 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); |
247 | contents.agent_id = inv.OwnerID; | 212 | contents.agent_id = inv.OwnerID; |
248 | contents.owner_id = inv.OwnerID; | 213 | contents.owner_id = inv.OwnerID; |
249 | contents.folder_id = inv.FolderID; | 214 | contents.folder_id = inv.FolderID; |
250 | 215 | ||
251 | reply.folders.Array.Add(contents); | ||
252 | |||
253 | if (inv.Folders != null) | 216 | if (inv.Folders != null) |
254 | { | 217 | { |
255 | foreach (InventoryFolderBase invFolder in inv.Folders) | 218 | foreach (InventoryFolderBase invFolder in inv.Folders) |
256 | { | 219 | { |
257 | contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); | 220 | contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); |
258 | } | 221 | } |
259 | |||
260 | descendents += inv.Folders.Count; | ||
261 | } | 222 | } |
262 | 223 | ||
263 | if (inv.Items != null) | 224 | if (inv.Items != null) |
@@ -271,7 +232,7 @@ namespace OpenSim.Capabilities.Handlers | |||
271 | contents.descendents = descendents; | 232 | contents.descendents = descendents; |
272 | contents.version = inv.Version; | 233 | contents.version = inv.Version; |
273 | 234 | ||
274 | return reply; | 235 | return contents; |
275 | } | 236 | } |
276 | /// <summary> | 237 | /// <summary> |
277 | /// Old style. Soon to be deprecated. | 238 | /// Old style. Soon to be deprecated. |
@@ -285,8 +246,8 @@ namespace OpenSim.Capabilities.Handlers | |||
285 | { | 246 | { |
286 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count); | 247 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count); |
287 | 248 | ||
288 | string response = ""; | 249 | StringBuilder tmpresponse = new StringBuilder(1024); |
289 | string bad_folders_response = ""; | 250 | StringBuilder tmpbadfolders = new StringBuilder(1024); |
290 | 251 | ||
291 | for (int i = 0; i < foldersrequested.Count; i++) | 252 | for (int i = 0; i < foldersrequested.Count; i++) |
292 | { | 253 | { |
@@ -308,7 +269,9 @@ namespace OpenSim.Capabilities.Handlers | |||
308 | 269 | ||
309 | if (null == reply) | 270 | if (null == reply) |
310 | { | 271 | { |
311 | bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>"; | 272 | tmpbadfolders.Append("<map><key>folder_id</key><uuid>"); |
273 | tmpbadfolders.Append(llsdRequest.folder_id.ToString()); | ||
274 | tmpbadfolders.Append("</uuid><key>error</key><string>Unknown</string></map>"); | ||
312 | } | 275 | } |
313 | else | 276 | else |
314 | { | 277 | { |
@@ -317,39 +280,29 @@ namespace OpenSim.Capabilities.Handlers | |||
317 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); | 280 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); |
318 | } | 281 | } |
319 | 282 | ||
320 | response += inventoryitemstr; | 283 | tmpresponse.Append(inventoryitemstr); |
321 | } | 284 | } |
322 | 285 | ||
323 | if (response.Length == 0) | 286 | StringBuilder lastresponse = new StringBuilder(1024); |
287 | lastresponse.Append("<llsd>"); | ||
288 | if(tmpresponse.Length > 0) | ||
324 | { | 289 | { |
325 | /* Viewers expect a bad_folders array when not available */ | 290 | lastresponse.Append("<map><key>folders</key><array>"); |
326 | if (bad_folders_response.Length != 0) | 291 | lastresponse.Append(tmpresponse.ToString()); |
327 | { | 292 | lastresponse.Append("</array></map>"); |
328 | response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; | ||
333 | } | ||
334 | } | 293 | } |
335 | else | 294 | else |
295 | lastresponse.Append("<map><key>folders</key><array /></map>"); | ||
296 | |||
297 | if(tmpbadfolders.Length > 0) | ||
336 | { | 298 | { |
337 | if (bad_folders_response.Length != 0) | 299 | lastresponse.Append("<map><key>bad_folders</key><array>"); |
338 | { | 300 | lastresponse.Append(tmpbadfolders.ToString()); |
339 | response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | 301 | lastresponse.Append("</array></map>"); |
340 | } | ||
341 | else | ||
342 | { | ||
343 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; | ||
344 | } | ||
345 | } | 302 | } |
303 | lastresponse.Append("</llsd>"); | ||
346 | 304 | ||
347 | // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request"); | 305 | return lastresponse.ToString(); |
348 | //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response); | ||
349 | |||
350 | return response; | ||
351 | |||
352 | // } | ||
353 | } | 306 | } |
354 | 307 | ||
355 | /// <summary> | 308 | /// <summary> |
@@ -436,108 +389,7 @@ namespace OpenSim.Capabilities.Handlers | |||
436 | itemsToReturn.Insert(0, linkedItem); | 389 | itemsToReturn.Insert(0, linkedItem); |
437 | } | 390 | } |
438 | } | 391 | } |
439 | |||
440 | // Now scan for folder links and insert the items they target and those links at the head of the return data | ||
441 | |||
442 | /* dont send contents of LinkFolders. | ||
443 | from docs seems this was never a spec | ||
444 | |||
445 | foreach (InventoryItemBase item in originalItems) | ||
446 | { | ||
447 | if (item.AssetType == (int)AssetType.LinkFolder) | ||
448 | { | ||
449 | InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID); | ||
450 | List<InventoryItemBase> links = linkedFolderContents.Items; | ||
451 | |||
452 | itemsToReturn.InsertRange(0, links); | ||
453 | |||
454 | foreach (InventoryItemBase link in linkedFolderContents.Items) | ||
455 | { | ||
456 | // Take care of genuinely broken links where the target doesn't exist | ||
457 | // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
458 | // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
459 | // rather than having to keep track of every folder requested in the recursion. | ||
460 | if (link != null) | ||
461 | { | ||
462 | // m_log.DebugFormat( | ||
463 | // "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}", | ||
464 | // link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name); | ||
465 | |||
466 | InventoryItemBase linkedItem | ||
467 | = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID)); | ||
468 | |||
469 | if (linkedItem != null) | ||
470 | itemsToReturn.Insert(0, linkedItem); | ||
471 | } | ||
472 | } | ||
473 | } | ||
474 | } | ||
475 | */ | ||
476 | } | 392 | } |
477 | |||
478 | // foreach (InventoryItemBase item in contents.Items) | ||
479 | // { | ||
480 | // m_log.DebugFormat( | ||
481 | // "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}", | ||
482 | // item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID); | ||
483 | // } | ||
484 | |||
485 | // ===== | ||
486 | |||
487 | // | ||
488 | // foreach (InventoryItemBase linkedItem in linkedItemsToAdd) | ||
489 | // { | ||
490 | // m_log.DebugFormat( | ||
491 | // "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}", | ||
492 | // linkedItem.Name, folderID, agentID); | ||
493 | // | ||
494 | // contents.Items.Add(linkedItem); | ||
495 | // } | ||
496 | // | ||
497 | // // If the folder requested contains links, then we need to send those folders first, otherwise the links | ||
498 | // // will be broken in the viewer. | ||
499 | // HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>(); | ||
500 | // foreach (InventoryItemBase item in contents.Items) | ||
501 | // { | ||
502 | // if (item.AssetType == (int)AssetType.Link) | ||
503 | // { | ||
504 | // InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); | ||
505 | // | ||
506 | // // Take care of genuinely broken links where the target doesn't exist | ||
507 | // // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
508 | // // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
509 | // // rather than having to keep track of every folder requested in the recursion. | ||
510 | // if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) | ||
511 | // { | ||
512 | // // We don't need to send the folder if source and destination of the link are in the same | ||
513 | // // folder. | ||
514 | // if (linkedItem.Folder != containingFolder.ID) | ||
515 | // linkedItemFolderIdsToSend.Add(linkedItem.Folder); | ||
516 | // } | ||
517 | // } | ||
518 | // } | ||
519 | // | ||
520 | // foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend) | ||
521 | // { | ||
522 | // m_log.DebugFormat( | ||
523 | // "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}", | ||
524 | // linkedItemFolderId, folderID, agentID); | ||
525 | // | ||
526 | // int dummyVersion; | ||
527 | // InventoryCollection linkedCollection | ||
528 | // = Fetch( | ||
529 | // agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion); | ||
530 | // | ||
531 | // InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId); | ||
532 | // linkedFolder.Owner = agentID; | ||
533 | // linkedFolder = m_InventoryService.GetFolder(linkedFolder); | ||
534 | // | ||
535 | //// contents.Folders.AddRange(linkedCollection.Folders); | ||
536 | // | ||
537 | // contents.Folders.Add(linkedFolder); | ||
538 | // contents.Items.AddRange(linkedCollection.Items); | ||
539 | // } | ||
540 | // } | ||
541 | } | 393 | } |
542 | } | 394 | } |
543 | else | 395 | else |
@@ -550,33 +402,26 @@ from docs seems this was never a spec | |||
550 | 402 | ||
551 | } | 403 | } |
552 | 404 | ||
553 | private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> fetchFolders, List<InventoryCollectionWithDescendents> result) | 405 | private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> libFolders, List<InventoryCollectionWithDescendents> result) |
554 | { | 406 | { |
555 | InventoryFolderImpl fold; | 407 | InventoryFolderImpl fold; |
556 | if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null) | 408 | foreach (LLSDFetchInventoryDescendents f in libFolders) |
557 | { | 409 | { |
558 | List<LLSDFetchInventoryDescendents> libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner); | 410 | if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null) |
559 | fetchFolders.RemoveAll(f => libfolders.Contains(f)); | ||
560 | |||
561 | //m_log.DebugFormat("[XXX]: Found {0} library folders in request", libfolders.Count); | ||
562 | |||
563 | foreach (LLSDFetchInventoryDescendents f in libfolders) | ||
564 | { | 411 | { |
565 | if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null) | 412 | InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents(); |
566 | { | 413 | ret.Collection = new InventoryCollection(); |
567 | InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents(); | 414 | // ret.Collection.Folders = new List<InventoryFolderBase>(); |
568 | ret.Collection = new InventoryCollection(); | 415 | ret.Collection.Folders = fold.RequestListOfFolders(); |
569 | ret.Collection.Folders = new List<InventoryFolderBase>(); | 416 | ret.Collection.Items = fold.RequestListOfItems(); |
570 | ret.Collection.Items = fold.RequestListOfItems(); | 417 | ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner; |
571 | ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner; | 418 | ret.Collection.FolderID = f.folder_id; |
572 | ret.Collection.FolderID = f.folder_id; | 419 | ret.Collection.Version = fold.Version; |
573 | ret.Collection.Version = fold.Version; | 420 | |
574 | 421 | ret.Descendents = ret.Collection.Items.Count + ret.Collection.Folders.Count; | |
575 | ret.Descendents = ret.Collection.Items.Count; | 422 | result.Add(ret); |
576 | result.Add(ret); | 423 | |
577 | 424 | //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID); | |
578 | //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID); | ||
579 | } | ||
580 | } | 425 | } |
581 | } | 426 | } |
582 | } | 427 | } |
@@ -589,117 +434,122 @@ from docs seems this was never a spec | |||
589 | // FIXME MAYBE: We're not handling sortOrder! | 434 | // FIXME MAYBE: We're not handling sortOrder! |
590 | 435 | ||
591 | List<InventoryCollectionWithDescendents> result = new List<InventoryCollectionWithDescendents>(); | 436 | List<InventoryCollectionWithDescendents> result = new List<InventoryCollectionWithDescendents>(); |
437 | List<LLSDFetchInventoryDescendents> libFolders = new List<LLSDFetchInventoryDescendents>(); | ||
438 | List<LLSDFetchInventoryDescendents> otherFolders = new List<LLSDFetchInventoryDescendents>(); | ||
439 | HashSet<UUID> libIDs = new HashSet<UUID>(); | ||
440 | HashSet<UUID> otherIDs = new HashSet<UUID>(); | ||
592 | 441 | ||
593 | AddLibraryFolders(fetchFolders, result); | 442 | bool dolib = (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null); |
443 | UUID libOwner = UUID.Zero; | ||
444 | if(dolib) | ||
445 | libOwner = m_LibraryService.LibraryRootFolder.Owner; | ||
594 | 446 | ||
595 | // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense | 447 | // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense |
596 | // and can kill the sim (all root folders have parent_id Zero) | 448 | // and can kill the sim (all root folders have parent_id Zero) |
597 | LLSDFetchInventoryDescendents zero = fetchFolders.Find(f => f.folder_id == UUID.Zero); | 449 | // send something. |
598 | if (zero != null) | 450 | bool doneZeroID = false; |
451 | foreach(LLSDFetchInventoryDescendents f in fetchFolders) | ||
599 | { | 452 | { |
600 | fetchFolders.Remove(zero); | 453 | if (f.folder_id == UUID.Zero) |
601 | BadFolder(zero, null, bad_folders); | 454 | { |
455 | if(doneZeroID) | ||
456 | continue; | ||
457 | doneZeroID = true; | ||
458 | InventoryCollectionWithDescendents zeroColl = new InventoryCollectionWithDescendents(); | ||
459 | zeroColl.Collection = new InventoryCollection(); | ||
460 | zeroColl.Collection.OwnerID = f.owner_id; | ||
461 | zeroColl.Collection.Version = 0; | ||
462 | zeroColl.Collection.FolderID = f.folder_id; | ||
463 | zeroColl.Descendents = 0; | ||
464 | result.Add(zeroColl); | ||
465 | continue; | ||
466 | } | ||
467 | if(dolib && f.owner_id == libOwner) | ||
468 | { | ||
469 | if(libIDs.Contains(f.folder_id)) | ||
470 | continue; | ||
471 | libIDs.Add(f.folder_id); | ||
472 | libFolders.Add(f); | ||
473 | continue; | ||
474 | } | ||
475 | if(otherIDs.Contains(f.folder_id)) | ||
476 | continue; | ||
477 | otherIDs.Add(f.folder_id); | ||
478 | otherFolders.Add(f); | ||
602 | } | 479 | } |
603 | 480 | ||
604 | if (fetchFolders.Count > 0) | 481 | if(otherFolders.Count > 0) |
605 | { | 482 | { |
606 | UUID[] fids = new UUID[fetchFolders.Count]; | ||
607 | int i = 0; | 483 | int i = 0; |
608 | foreach (LLSDFetchInventoryDescendents f in fetchFolders) | ||
609 | fids[i++] = f.folder_id; | ||
610 | 484 | ||
611 | //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids)); | 485 | //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids)); |
612 | 486 | ||
613 | InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids); | 487 | InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(otherFolders[0].owner_id, otherIDs.ToArray()); |
614 | 488 | ||
615 | if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0)) | 489 | if (fetchedContents == null) |
490 | return null; | ||
491 | |||
492 | if (fetchedContents.Length == 0) | ||
616 | { | 493 | { |
617 | m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id); | 494 | foreach (LLSDFetchInventoryDescendents freq in otherFolders) |
618 | foreach (LLSDFetchInventoryDescendents freq in fetchFolders) | ||
619 | BadFolder(freq, null, bad_folders); | 495 | BadFolder(freq, null, bad_folders); |
620 | return null; | ||
621 | } | 496 | } |
622 | 497 | else | |
623 | i = 0; | ||
624 | // Do some post-processing. May need to fetch more from inv server for links | ||
625 | foreach (InventoryCollection contents in fetchedContents) | ||
626 | { | 498 | { |
627 | // Find the original request | 499 | i = 0; |
628 | LLSDFetchInventoryDescendents freq = fetchFolders[i++]; | 500 | // Do some post-processing. May need to fetch more from inv server for links |
501 | foreach (InventoryCollection contents in fetchedContents) | ||
502 | { | ||
503 | // Find the original request | ||
504 | LLSDFetchInventoryDescendents freq = otherFolders[i++]; | ||
629 | 505 | ||
630 | InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents(); | 506 | InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents(); |
631 | coll.Collection = contents; | 507 | coll.Collection = contents; |
632 | 508 | ||
633 | if (BadFolder(freq, contents, bad_folders)) | 509 | if (BadFolder(freq, contents, bad_folders)) |
634 | continue; | 510 | continue; |
635 | 511 | ||
636 | // Next: link management | 512 | // Next: link management |
637 | ProcessLinks(freq, coll); | 513 | ProcessLinks(freq, coll); |
638 | 514 | ||
639 | result.Add(coll); | 515 | result.Add(coll); |
516 | } | ||
640 | } | 517 | } |
641 | } | 518 | } |
642 | 519 | ||
520 | if(dolib && libFolders.Count > 0) | ||
521 | { | ||
522 | AddLibraryFolders(libFolders, result); | ||
523 | } | ||
524 | |||
643 | return result; | 525 | return result; |
644 | } | 526 | } |
645 | 527 | ||
646 | private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders) | 528 | private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders) |
647 | { | 529 | { |
648 | bool bad = false; | ||
649 | if (contents == null) | 530 | if (contents == null) |
650 | { | 531 | { |
651 | bad_folders.Add(freq.folder_id); | 532 | bad_folders.Add(freq.folder_id); |
652 | bad = true; | 533 | return true; |
653 | } | 534 | } |
654 | 535 | ||
655 | // The inventory server isn't sending FolderID in the collection... | 536 | // The inventory server isn't sending FolderID in the collection... |
656 | // Must fetch it individually | 537 | // Must fetch it individually |
657 | else if (contents.FolderID == UUID.Zero) | 538 | if (contents.FolderID == UUID.Zero) |
658 | { | 539 | { |
659 | InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id); | 540 | InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id); |
660 | 541 | if (containingFolder == null) | |
661 | if (containingFolder != null) | ||
662 | { | ||
663 | contents.FolderID = containingFolder.ID; | ||
664 | contents.OwnerID = containingFolder.Owner; | ||
665 | contents.Version = containingFolder.Version; | ||
666 | } | ||
667 | else | ||
668 | { | 542 | { |
669 | // Was it really a request for folder Zero? | 543 | m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id); |
670 | // This is an overkill, but Firestorm really asks for folder Zero. | 544 | bad_folders.Add(freq.folder_id); |
671 | // I'm leaving the code here for the time being, but commented. | 545 | return true; |
672 | if (freq.folder_id == UUID.Zero) | ||
673 | { | ||
674 | //coll.Collection.OwnerID = freq.owner_id; | ||
675 | //coll.Collection.FolderID = contents.FolderID; | ||
676 | //containingFolder = m_InventoryService.GetRootFolder(freq.owner_id); | ||
677 | //if (containingFolder != null) | ||
678 | //{ | ||
679 | // m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Request for parent of folder {0}", containingFolder.ID); | ||
680 | // coll.Collection.Folders.Clear(); | ||
681 | // coll.Collection.Folders.Add(containingFolder); | ||
682 | // if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null) | ||
683 | // { | ||
684 | // InventoryFolderBase lib = new InventoryFolderBase(m_LibraryService.LibraryRootFolder.ID, m_LibraryService.LibraryRootFolder.Owner); | ||
685 | // lib.Name = m_LibraryService.LibraryRootFolder.Name; | ||
686 | // lib.Type = m_LibraryService.LibraryRootFolder.Type; | ||
687 | // lib.Version = m_LibraryService.LibraryRootFolder.Version; | ||
688 | // coll.Collection.Folders.Add(lib); | ||
689 | // } | ||
690 | // coll.Collection.Items.Clear(); | ||
691 | //} | ||
692 | } | ||
693 | else | ||
694 | { | ||
695 | m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id); | ||
696 | bad_folders.Add(freq.folder_id); | ||
697 | } | ||
698 | bad = true; | ||
699 | } | 546 | } |
547 | contents.FolderID = containingFolder.ID; | ||
548 | contents.OwnerID = containingFolder.Owner; | ||
549 | contents.Version = containingFolder.Version; | ||
700 | } | 550 | } |
701 | 551 | ||
702 | return bad; | 552 | return false; |
703 | } | 553 | } |
704 | 554 | ||
705 | private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll) | 555 | private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll) |
@@ -708,42 +558,21 @@ from docs seems this was never a spec | |||
708 | 558 | ||
709 | if (freq.fetch_items && contents.Items != null) | 559 | if (freq.fetch_items && contents.Items != null) |
710 | { | 560 | { |
711 | List<InventoryItemBase> itemsToReturn = contents.Items; | 561 | // viewers are lasy and want a copy of the linked item sent before the link to it |
712 | 562 | ||
713 | // descendents must only include the links, not the linked items we add | 563 | // descendents must only include the links, not the linked items we add |
714 | coll.Descendents = itemsToReturn.Count; | 564 | coll.Descendents = contents.Items.Count + contents.Folders.Count; |
715 | 565 | ||
716 | // Add target items for links in this folder before the links themselves. | 566 | // look for item links |
717 | List<UUID> itemIDs = new List<UUID>(); | 567 | List<UUID> itemIDs = new List<UUID>(); |
718 | List<UUID> folderIDs = new List<UUID>(); | 568 | foreach (InventoryItemBase item in contents.Items) |
719 | foreach (InventoryItemBase item in itemsToReturn) | ||
720 | { | 569 | { |
721 | //m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType); | 570 | //m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType); |
722 | if (item.AssetType == (int)AssetType.Link) | 571 | if (item.AssetType == (int)AssetType.Link) |
723 | itemIDs.Add(item.AssetID); | 572 | itemIDs.Add(item.AssetID); |
724 | |||
725 | // else if (item.AssetType == (int)AssetType.LinkFolder) | ||
726 | // folderIDs.Add(item.AssetID); | ||
727 | } | ||
728 | |||
729 | //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count); | ||
730 | |||
731 | // Scan for folder links and insert the items they target and those links at the head of the return data | ||
732 | if (folderIDs.Count > 0) | ||
733 | { | ||
734 | InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray()); | ||
735 | foreach (InventoryCollection linkedFolderContents in linkedFolders) | ||
736 | { | ||
737 | if (linkedFolderContents == null) | ||
738 | continue; | ||
739 | |||
740 | List<InventoryItemBase> links = linkedFolderContents.Items; | ||
741 | |||
742 | itemsToReturn.InsertRange(0, links); | ||
743 | |||
744 | } | ||
745 | } | 573 | } |
746 | 574 | ||
575 | // get the linked if any | ||
747 | if (itemIDs.Count > 0) | 576 | if (itemIDs.Count > 0) |
748 | { | 577 | { |
749 | InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray()); | 578 | InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray()); |
@@ -758,13 +587,11 @@ from docs seems this was never a spec | |||
758 | linked[i++] = m_InventoryService.GetItem(freq.owner_id, id); | 587 | linked[i++] = m_InventoryService.GetItem(freq.owner_id, id); |
759 | } | 588 | } |
760 | } | 589 | } |
761 | 590 | ||
762 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id); | ||
763 | //foreach (InventoryItemBase item in itemsToReturn) | ||
764 | // m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder); | ||
765 | |||
766 | if (linked != null) | 591 | if (linked != null) |
767 | { | 592 | { |
593 | List<InventoryItemBase> linkedItems = new List<InventoryItemBase>(); | ||
594 | // check for broken | ||
768 | foreach (InventoryItemBase linkedItem in linked) | 595 | foreach (InventoryItemBase linkedItem in linked) |
769 | { | 596 | { |
770 | // Take care of genuinely broken links where the target doesn't exist | 597 | // Take care of genuinely broken links where the target doesn't exist |
@@ -773,14 +600,16 @@ from docs seems this was never a spec | |||
773 | // rather than having to keep track of every folder requested in the recursion. | 600 | // rather than having to keep track of every folder requested in the recursion. |
774 | if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) | 601 | if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) |
775 | { | 602 | { |
776 | itemsToReturn.Insert(0, linkedItem); | 603 | linkedItems.Add(linkedItem); |
777 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder); | 604 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder); |
778 | } | 605 | } |
779 | } | 606 | } |
607 | // insert them | ||
608 | if(linkedItems.Count > 0) | ||
609 | contents.Items.InsertRange(0,linkedItems); | ||
780 | } | 610 | } |
781 | } | 611 | } |
782 | } | 612 | } |
783 | |||
784 | } | 613 | } |
785 | 614 | ||
786 | /// <summary> | 615 | /// <summary> |
@@ -795,6 +624,7 @@ from docs seems this was never a spec | |||
795 | llsdFolder.parent_id = invFolder.ParentID; | 624 | llsdFolder.parent_id = invFolder.ParentID; |
796 | llsdFolder.name = invFolder.Name; | 625 | llsdFolder.name = invFolder.Name; |
797 | llsdFolder.type = invFolder.Type; | 626 | llsdFolder.type = invFolder.Type; |
627 | llsdFolder.version = invFolder.Version; | ||
798 | llsdFolder.preferred_type = -1; | 628 | llsdFolder.preferred_type = -1; |
799 | 629 | ||
800 | return llsdFolder; | 630 | return llsdFolder; |
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs index e239a90..0d7766c 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Reflection; | 28 | using System.Reflection; |
29 | using System.Text; | ||
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | using OpenMetaverse.StructuredData; | 31 | using OpenMetaverse.StructuredData; |
31 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
@@ -59,9 +60,6 @@ namespace OpenSim.Capabilities.Handlers | |||
59 | OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request)); | 60 | OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request)); |
60 | OSDArray itemsRequested = (OSDArray)requestmap["items"]; | 61 | OSDArray itemsRequested = (OSDArray)requestmap["items"]; |
61 | 62 | ||
62 | string reply; | ||
63 | LLSDFetchInventory llsdReply = new LLSDFetchInventory(); | ||
64 | |||
65 | UUID[] itemIDs = new UUID[itemsRequested.Count]; | 63 | UUID[] itemIDs = new UUID[itemsRequested.Count]; |
66 | int i = 0; | 64 | int i = 0; |
67 | 65 | ||
@@ -92,55 +90,31 @@ namespace OpenSim.Capabilities.Handlers | |||
92 | items[i++] = m_inventoryService.GetItem(UUID.Zero, id); | 90 | items[i++] = m_inventoryService.GetItem(UUID.Zero, id); |
93 | } | 91 | } |
94 | 92 | ||
95 | foreach (InventoryItemBase item in items) | 93 | StringBuilder lsl = LLSDxmlEncode.Start(4096); |
94 | LLSDxmlEncode.AddMap(lsl); | ||
95 | |||
96 | if(m_agentID == UUID.Zero && items.Length > 0) | ||
97 | LLSDxmlEncode.AddElem("agent_id", items[0].Owner, lsl); | ||
98 | else | ||
99 | LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl); | ||
100 | |||
101 | if(items == null || items.Length == 0) | ||
102 | { | ||
103 | LLSDxmlEncode.AddEmptyArray("items", lsl); | ||
104 | } | ||
105 | else | ||
96 | { | 106 | { |
97 | if (item != null) | 107 | LLSDxmlEncode.AddArray("items", lsl); |
108 | foreach (InventoryItemBase item in items) | ||
98 | { | 109 | { |
99 | // We don't know the agent that this request belongs to so we'll use the agent id of the item | 110 | if (item != null) |
100 | // which will be the same for all items. | 111 | item.ToLLSDxml(lsl); |
101 | llsdReply.agent_id = item.Owner; | ||
102 | llsdReply.items.Array.Add(ConvertInventoryItem(item)); | ||
103 | } | 112 | } |
104 | } | 113 | LLSDxmlEncode.AddEndArray(lsl); |
105 | 114 | } | |
106 | reply = LLSDHelpers.SerialiseLLSDReply(llsdReply); | ||
107 | 115 | ||
108 | return reply; | 116 | LLSDxmlEncode.AddEndMap(lsl); |
109 | } | 117 | return LLSDxmlEncode.End(lsl);; |
110 | |||
111 | /// <summary> | ||
112 | /// Convert an internal inventory item object into an LLSD object. | ||
113 | /// </summary> | ||
114 | /// <param name="invItem"></param> | ||
115 | /// <returns></returns> | ||
116 | private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) | ||
117 | { | ||
118 | LLSDInventoryItem llsdItem = new LLSDInventoryItem(); | ||
119 | llsdItem.asset_id = invItem.AssetID; | ||
120 | llsdItem.created_at = invItem.CreationDate; | ||
121 | llsdItem.desc = invItem.Description; | ||
122 | llsdItem.flags = ((int)invItem.Flags) & 0xff; | ||
123 | llsdItem.item_id = invItem.ID; | ||
124 | llsdItem.name = invItem.Name; | ||
125 | llsdItem.parent_id = invItem.Folder; | ||
126 | llsdItem.type = invItem.AssetType; | ||
127 | llsdItem.inv_type = invItem.InvType; | ||
128 | |||
129 | llsdItem.permissions = new LLSDPermissions(); | ||
130 | llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; | ||
131 | llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; | ||
132 | llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; | ||
133 | llsdItem.permissions.group_id = invItem.GroupID; | ||
134 | llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; | ||
135 | llsdItem.permissions.is_owner_group = invItem.GroupOwned; | ||
136 | llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; | ||
137 | llsdItem.permissions.owner_id = invItem.Owner; | ||
138 | llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; | ||
139 | llsdItem.sale_info = new LLSDSaleInfo(); | ||
140 | llsdItem.sale_info.sale_price = invItem.SalePrice; | ||
141 | llsdItem.sale_info.sale_type = invItem.SaleType; | ||
142 | |||
143 | return llsdItem; | ||
144 | } | 118 | } |
145 | } | 119 | } |
146 | } | 120 | } |
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs index 4143aa3..1e9a993 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs | |||
@@ -267,6 +267,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests | |||
267 | [Test] | 267 | [Test] |
268 | public void Test_005_FolderZero() | 268 | public void Test_005_FolderZero() |
269 | { | 269 | { |
270 | |||
270 | TestHelpers.InMethod(); | 271 | TestHelpers.InMethod(); |
271 | 272 | ||
272 | Init(); | 273 | Init(); |
@@ -283,11 +284,11 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests | |||
283 | 284 | ||
284 | Assert.That(llsdresponse != null, Is.True, "Incorrect null response"); | 285 | Assert.That(llsdresponse != null, Is.True, "Incorrect null response"); |
285 | Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response"); | 286 | Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response"); |
286 | Assert.That(llsdresponse.Contains("bad_folders</key><array><uuid>00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder"); | 287 | // we do return a answer now |
288 | //Assert.That(llsdresponse.Contains("bad_folders</key><array><uuid>00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder"); | ||
287 | 289 | ||
288 | Console.WriteLine(llsdresponse); | 290 | Console.WriteLine(llsdresponse); |
289 | } | 291 | } |
290 | |||
291 | } | 292 | } |
292 | 293 | ||
293 | } \ No newline at end of file | 294 | } \ No newline at end of file |
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index a9b81f3..a0471bb 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs | |||
@@ -64,10 +64,7 @@ namespace OpenSim.Capabilities.Handlers | |||
64 | Hashtable ret = new Hashtable(); | 64 | Hashtable ret = new Hashtable(); |
65 | ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; | 65 | ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; |
66 | ret["content_type"] = "text/plain"; | 66 | ret["content_type"] = "text/plain"; |
67 | ret["keepalive"] = false; | ||
68 | ret["reusecontext"] = false; | ||
69 | ret["int_bytes"] = 0; | 67 | ret["int_bytes"] = 0; |
70 | ret["int_lod"] = 0; | ||
71 | string MeshStr = (string)request["mesh_id"]; | 68 | string MeshStr = (string)request["mesh_id"]; |
72 | 69 | ||
73 | 70 | ||
@@ -76,6 +73,8 @@ namespace OpenSim.Capabilities.Handlers | |||
76 | if (m_assetService == null) | 73 | if (m_assetService == null) |
77 | { | 74 | { |
78 | m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service"); | 75 | m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service"); |
76 | ret["keepalive"] = false; | ||
77 | return ret; | ||
79 | } | 78 | } |
80 | 79 | ||
81 | UUID meshID; | 80 | UUID meshID; |
@@ -101,10 +100,7 @@ namespace OpenSim.Capabilities.Handlers | |||
101 | Hashtable responsedata = new Hashtable(); | 100 | Hashtable responsedata = new Hashtable(); |
102 | responsedata["int_response_code"] = 400; //501; //410; //404; | 101 | responsedata["int_response_code"] = 400; //501; //410; //404; |
103 | responsedata["content_type"] = "text/plain"; | 102 | responsedata["content_type"] = "text/plain"; |
104 | responsedata["keepalive"] = false; | ||
105 | responsedata["str_response_string"] = "Request wasn't what was expected"; | 103 | responsedata["str_response_string"] = "Request wasn't what was expected"; |
106 | responsedata["reusecontext"] = false; | ||
107 | responsedata["int_lod"] = 0; | ||
108 | responsedata["int_bytes"] = 0; | 104 | responsedata["int_bytes"] = 0; |
109 | 105 | ||
110 | string meshStr = string.Empty; | 106 | string meshStr = string.Empty; |
@@ -118,10 +114,8 @@ namespace OpenSim.Capabilities.Handlers | |||
118 | if (m_assetService == null) | 114 | if (m_assetService == null) |
119 | { | 115 | { |
120 | responsedata["int_response_code"] = 404; //501; //410; //404; | 116 | responsedata["int_response_code"] = 404; //501; //410; //404; |
121 | responsedata["content_type"] = "text/plain"; | ||
122 | responsedata["keepalive"] = false; | 117 | responsedata["keepalive"] = false; |
123 | responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; | 118 | responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; |
124 | responsedata["reusecontext"] = false; | ||
125 | return responsedata; | 119 | return responsedata; |
126 | } | 120 | } |
127 | 121 | ||
@@ -155,10 +149,7 @@ namespace OpenSim.Capabilities.Handlers | |||
155 | { | 149 | { |
156 | responsedata["int_response_code"] = 404; //501; //410; //404; | 150 | responsedata["int_response_code"] = 404; //501; //410; //404; |
157 | responsedata["content_type"] = "text/plain"; | 151 | responsedata["content_type"] = "text/plain"; |
158 | responsedata["keepalive"] = false; | ||
159 | responsedata["str_response_string"] = "This range doesnt exist."; | 152 | responsedata["str_response_string"] = "This range doesnt exist."; |
160 | responsedata["reusecontext"] = false; | ||
161 | responsedata["int_lod"] = 3; | ||
162 | return responsedata; | 153 | return responsedata; |
163 | } | 154 | } |
164 | else | 155 | else |
@@ -169,28 +160,11 @@ namespace OpenSim.Capabilities.Handlers | |||
169 | 160 | ||
170 | //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); | 161 | //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); |
171 | 162 | ||
172 | if (start > 20000) | ||
173 | { | ||
174 | responsedata["int_lod"] = 3; | ||
175 | } | ||
176 | else if (start < 4097) | ||
177 | { | ||
178 | responsedata["int_lod"] = 1; | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | responsedata["int_lod"] = 2; | ||
183 | } | ||
184 | |||
185 | |||
186 | if (start == 0 && len == mesh.Data.Length) // well redudante maybe | 163 | if (start == 0 && len == mesh.Data.Length) // well redudante maybe |
187 | { | 164 | { |
188 | responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; | 165 | responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; |
189 | responsedata["bin_response_data"] = mesh.Data; | 166 | responsedata["bin_response_data"] = mesh.Data; |
190 | responsedata["int_bytes"] = mesh.Data.Length; | 167 | responsedata["int_bytes"] = mesh.Data.Length; |
191 | responsedata["reusecontext"] = false; | ||
192 | responsedata["int_lod"] = 3; | ||
193 | |||
194 | } | 168 | } |
195 | else | 169 | else |
196 | { | 170 | { |
@@ -203,7 +177,6 @@ namespace OpenSim.Capabilities.Handlers | |||
203 | Array.Copy(mesh.Data, start, d, 0, len); | 177 | Array.Copy(mesh.Data, start, d, 0, len); |
204 | responsedata["bin_response_data"] = d; | 178 | responsedata["bin_response_data"] = d; |
205 | responsedata["int_bytes"] = len; | 179 | responsedata["int_bytes"] = len; |
206 | responsedata["reusecontext"] = false; | ||
207 | } | 180 | } |
208 | } | 181 | } |
209 | } | 182 | } |
@@ -213,8 +186,6 @@ namespace OpenSim.Capabilities.Handlers | |||
213 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); | 186 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); |
214 | responsedata["content_type"] = "application/vnd.ll.mesh"; | 187 | responsedata["content_type"] = "application/vnd.ll.mesh"; |
215 | responsedata["int_response_code"] = 200; | 188 | responsedata["int_response_code"] = 200; |
216 | responsedata["reusecontext"] = false; | ||
217 | responsedata["int_lod"] = 3; | ||
218 | } | 189 | } |
219 | } | 190 | } |
220 | else | 191 | else |
@@ -222,8 +193,6 @@ namespace OpenSim.Capabilities.Handlers | |||
222 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); | 193 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); |
223 | responsedata["content_type"] = "application/vnd.ll.mesh"; | 194 | responsedata["content_type"] = "application/vnd.ll.mesh"; |
224 | responsedata["int_response_code"] = 200; | 195 | responsedata["int_response_code"] = 200; |
225 | responsedata["reusecontext"] = false; | ||
226 | responsedata["int_lod"] = 3; | ||
227 | } | 196 | } |
228 | } | 197 | } |
229 | // Optionally add additional mesh types here | 198 | // Optionally add additional mesh types here |
@@ -231,10 +200,7 @@ namespace OpenSim.Capabilities.Handlers | |||
231 | { | 200 | { |
232 | responsedata["int_response_code"] = 404; //501; //410; //404; | 201 | responsedata["int_response_code"] = 404; //501; //410; //404; |
233 | responsedata["content_type"] = "text/plain"; | 202 | responsedata["content_type"] = "text/plain"; |
234 | responsedata["keepalive"] = false; | ||
235 | responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; | 203 | responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; |
236 | responsedata["reusecontext"] = false; | ||
237 | responsedata["int_lod"] = 1; | ||
238 | return responsedata; | 204 | return responsedata; |
239 | } | 205 | } |
240 | } | 206 | } |
@@ -242,10 +208,7 @@ namespace OpenSim.Capabilities.Handlers | |||
242 | { | 208 | { |
243 | responsedata["int_response_code"] = 404; //501; //410; //404; | 209 | responsedata["int_response_code"] = 404; //501; //410; //404; |
244 | responsedata["content_type"] = "text/plain"; | 210 | responsedata["content_type"] = "text/plain"; |
245 | responsedata["keepalive"] = false; | ||
246 | responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; | 211 | responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; |
247 | responsedata["reusecontext"] = false; | ||
248 | responsedata["int_lod"] = 0; | ||
249 | return responsedata; | 212 | return responsedata; |
250 | } | 213 | } |
251 | } | 214 | } |
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index e73cf9e..2499ce4 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs | |||
@@ -66,8 +66,6 @@ namespace OpenSim.Capabilities.Handlers | |||
66 | Hashtable ret = new Hashtable(); | 66 | Hashtable ret = new Hashtable(); |
67 | ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; | 67 | ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; |
68 | ret["content_type"] = "text/plain"; | 68 | ret["content_type"] = "text/plain"; |
69 | ret["keepalive"] = false; | ||
70 | ret["reusecontext"] = false; | ||
71 | ret["int_bytes"] = 0; | 69 | ret["int_bytes"] = 0; |
72 | string textureStr = (string)request["texture_id"]; | 70 | string textureStr = (string)request["texture_id"]; |
73 | string format = (string)request["format"]; | 71 | string format = (string)request["format"]; |
@@ -112,8 +110,6 @@ namespace OpenSim.Capabilities.Handlers | |||
112 | ret["error_status_text"] = "not found"; | 110 | ret["error_status_text"] = "not found"; |
113 | ret["str_response_string"] = "not found"; | 111 | ret["str_response_string"] = "not found"; |
114 | ret["content_type"] = "text/plain"; | 112 | ret["content_type"] = "text/plain"; |
115 | ret["keepalive"] = false; | ||
116 | ret["reusecontext"] = false; | ||
117 | ret["int_bytes"] = 0; | 113 | ret["int_bytes"] = 0; |
118 | } | 114 | } |
119 | } | 115 | } |
diff --git a/OpenSim/Capabilities/LLSD.cs b/OpenSim/Capabilities/LLSD.cs index fc41113..76e439f 100644 --- a/OpenSim/Capabilities/LLSD.cs +++ b/OpenSim/Capabilities/LLSD.cs | |||
@@ -83,8 +83,6 @@ namespace OpenSim.Framework.Capabilities | |||
83 | { | 83 | { |
84 | using (XmlTextReader reader = new XmlTextReader(st)) | 84 | using (XmlTextReader reader = new XmlTextReader(st)) |
85 | { | 85 | { |
86 | reader.ProhibitDtd = true; | ||
87 | |||
88 | reader.Read(); | 86 | reader.Read(); |
89 | SkipWS(reader); | 87 | SkipWS(reader); |
90 | 88 | ||
diff --git a/OpenSim/Capabilities/LLSDHelpers.cs b/OpenSim/Capabilities/LLSDHelpers.cs index d582267..4a7c6a5 100644 --- a/OpenSim/Capabilities/LLSDHelpers.cs +++ b/OpenSim/Capabilities/LLSDHelpers.cs | |||
@@ -30,6 +30,7 @@ using System.Collections; | |||
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Xml; | 32 | using System.Xml; |
33 | using OpenMetaverse; | ||
33 | 34 | ||
34 | namespace OpenSim.Framework.Capabilities | 35 | namespace OpenSim.Framework.Capabilities |
35 | { | 36 | { |
@@ -53,6 +54,19 @@ namespace OpenSim.Framework.Capabilities | |||
53 | return sw.ToString(); | 54 | return sw.ToString(); |
54 | } | 55 | } |
55 | 56 | ||
57 | public static string SerialiseLLSDReplyNoHeader(object obj) | ||
58 | { | ||
59 | StringWriter sw = new StringWriter(); | ||
60 | XmlTextWriter writer = new XmlTextWriter(sw); | ||
61 | writer.Formatting = Formatting.None; | ||
62 | SerializeOSDType(writer, obj); | ||
63 | writer.Close(); | ||
64 | |||
65 | //m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString()); | ||
66 | |||
67 | return sw.ToString(); | ||
68 | } | ||
69 | |||
56 | private static void SerializeOSDType(XmlTextWriter writer, object obj) | 70 | private static void SerializeOSDType(XmlTextWriter writer, object obj) |
57 | { | 71 | { |
58 | Type myType = obj.GetType(); | 72 | Type myType = obj.GetType(); |
@@ -160,7 +174,18 @@ namespace OpenSim.Framework.Capabilities | |||
160 | else if(enumerator.Value is Boolean && field.FieldType == typeof(int) ) | 174 | else if(enumerator.Value is Boolean && field.FieldType == typeof(int) ) |
161 | { | 175 | { |
162 | int i = (bool)enumerator.Value ? 1 : 0; | 176 | int i = (bool)enumerator.Value ? 1 : 0; |
163 | field.SetValue(obj, (object)i); | 177 | field.SetValue(obj, i); |
178 | } | ||
179 | else if(field.FieldType == typeof(bool) && enumerator.Value is int) | ||
180 | { | ||
181 | bool b = (int)enumerator.Value != 0; | ||
182 | field.SetValue(obj, b); | ||
183 | } | ||
184 | else if(field.FieldType == typeof(UUID) && enumerator.Value is string) | ||
185 | { | ||
186 | UUID u; | ||
187 | UUID.TryParse((string)enumerator.Value, out u); | ||
188 | field.SetValue(obj, u); | ||
164 | } | 189 | } |
165 | else | 190 | else |
166 | { | 191 | { |
diff --git a/OpenSim/Capabilities/LLSDInventoryFolder.cs b/OpenSim/Capabilities/LLSDInventoryFolder.cs index d085430..76b3f41 100644 --- a/OpenSim/Capabilities/LLSDInventoryFolder.cs +++ b/OpenSim/Capabilities/LLSDInventoryFolder.cs | |||
@@ -37,5 +37,6 @@ namespace OpenSim.Framework.Capabilities | |||
37 | public string name; | 37 | public string name; |
38 | public int type; | 38 | public int type; |
39 | public int preferred_type; | 39 | public int preferred_type; |
40 | public int version; | ||
40 | } | 41 | } |
41 | } | 42 | } |