aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-04-06 20:29:54 +0100
committerJustin Clark-Casey (justincc)2012-04-06 20:29:54 +0100
commit908cebbea8d7e685223b22ef8216971daccbdd53 (patch)
tree9827cf434e8013a4618bb278857d68373054f882
parentremove possible PhysActor unexpectedly null race conditions when changing pri... (diff)
parentDeleted the unused and commented code from 2 commits ago. (diff)
downloadopensim-SC_OLD-908cebbea8d7e685223b22ef8216971daccbdd53.zip
opensim-SC_OLD-908cebbea8d7e685223b22ef8216971daccbdd53.tar.gz
opensim-SC_OLD-908cebbea8d7e685223b22ef8216971daccbdd53.tar.bz2
opensim-SC_OLD-908cebbea8d7e685223b22ef8216971daccbdd53.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
-rw-r--r--OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs4
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs3
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs78
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs43
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs51
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs15
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs49
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs18
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs83
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs3
-rw-r--r--OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs72
-rw-r--r--OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs47
-rw-r--r--OpenSim/Services/HypergridService/HGInventoryService.cs6
-rw-r--r--OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs292
-rw-r--r--OpenSim/Services/InventoryService/XInventoryService.cs62
26 files changed, 684 insertions, 205 deletions
diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs
index 8b44f72..d5c062b 100644
--- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs
+++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs
@@ -162,7 +162,7 @@ namespace OpenSim.Capabilities.Handlers
162 invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, 162 invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
163 invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); 163 invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
164 164
165 if (inv.Folders != null) 165 if (inv != null && inv.Folders != null)
166 { 166 {
167 foreach (InventoryFolderBase invFolder in inv.Folders) 167 foreach (InventoryFolderBase invFolder in inv.Folders)
168 { 168 {
@@ -170,7 +170,7 @@ namespace OpenSim.Capabilities.Handlers
170 } 170 }
171 } 171 }
172 172
173 if (inv.Items != null) 173 if (inv != null && inv.Items != null)
174 { 174 {
175 foreach (InventoryItemBase invItem in inv.Items) 175 foreach (InventoryItemBase invItem in inv.Items)
176 { 176 {
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index a8ece79..9d8561b 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -662,11 +662,11 @@ namespace OpenSim.Framework.Servers.HttpServer
662 } 662 }
663 catch (IOException e) 663 catch (IOException e)
664 { 664 {
665 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e); 665 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
666 } 666 }
667 catch (Exception e) 667 catch (Exception e)
668 { 668 {
669 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw " + e.ToString()); 669 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.StackTrace);
670 SendHTML500(response); 670 SendHTML500(response);
671 } 671 }
672 finally 672 finally
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 3470fa9..9395233 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1913,7 +1913,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1913 1913
1914 folderBlock.FolderID = folder.ID; 1914 folderBlock.FolderID = folder.ID;
1915 folderBlock.ParentID = folder.ParentID; 1915 folderBlock.ParentID = folder.ParentID;
1916 folderBlock.Type = -1; 1916 //folderBlock.Type = -1;
1917 folderBlock.Type = (sbyte)folder.Type;
1917 folderBlock.Name = Util.StringToBytes256(folder.Name); 1918 folderBlock.Name = Util.StringToBytes256(folder.Name);
1918 1919
1919 return folderBlock; 1920 return folderBlock;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index ec260b4..0f422ae 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -114,7 +114,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
114 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: ViaHGLogin"); 114 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: ViaHGLogin");
115 if (m_RestrictInventoryAccessAbroad) 115 if (m_RestrictInventoryAccessAbroad)
116 { 116 {
117 RestoreRootFolderContents(client); 117 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
118 if (uMan.IsLocalGridUser(client.AgentId))
119 {
120 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local");
121 RestoreRootFolderContents(client);
122 }
123 else
124 {
125 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is foreign");
126 RestoreSuitcaseFolderContents(client);
127 }
118 } 128 }
119 } 129 }
120 } 130 }
@@ -210,7 +220,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
210 logout = success; // flag for later logout from this grid; this is an HG TP 220 logout = success; // flag for later logout from this grid; this is an HG TP
211 221
212 if (success && m_RestrictInventoryAccessAbroad) 222 if (success && m_RestrictInventoryAccessAbroad)
213 RemoveRootFolderContents(sp.ControllingClient); 223 {
224 IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>();
225 if (uMan != null && uMan.IsLocalGridUser(sp.UUID))
226 {
227 // local grid user
228 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local");
229 RemoveRootFolderContents(sp.ControllingClient);
230 }
231 else
232 {
233 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is foreign");
234 RemoveSuitcaseFolderContents(sp.ControllingClient);
235 }
236 }
214 237
215 return success; 238 return success;
216 } 239 }
@@ -401,25 +424,40 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
401 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId); 424 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId);
402 if (root != null) 425 if (root != null)
403 { 426 {
404 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Removing root inventory for user {0}", client.AgentId); 427 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Removing root inventory for user {0}", client.Name);
405 InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID); 428 InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID);
406 UUID[] ids = new UUID[content.Folders.Count]; 429 List<UUID> fids = new List<UUID>();
407 int i = 0; 430 List<UUID> iids = new List<UUID>();
431 List<InventoryFolderBase> keep = new List<InventoryFolderBase>();
432
408 foreach (InventoryFolderBase f in content.Folders) 433 foreach (InventoryFolderBase f in content.Folders)
409 ids[i++] = f.ID; 434 {
410 inv.SendRemoveInventoryFolders(ids); 435 if (f.Name != "My Suitcase")
411 ids = new UUID[content.Items.Count]; 436 {
412 i = 0; 437 f.Name = f.Name + " (Unavailable)";
438 keep.Add(f);
439 }
440 }
441
442 // items directly under the root folder
413 foreach (InventoryItemBase it in content.Items) 443 foreach (InventoryItemBase it in content.Items)
414 ids[i++] = it.ID; 444 it.Name = it.Name + " (Unavailable)"; ;
415 inv.SendRemoveInventoryItems(ids); 445
446 // Send the new names
447 inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
448
416 } 449 }
417 } 450 }
418 } 451 }
419 } 452 }
420 453
454 private void RemoveSuitcaseFolderContents(IClientAPI client)
455 {
456 }
457
421 private void RestoreRootFolderContents(IClientAPI client) 458 private void RestoreRootFolderContents(IClientAPI client)
422 { 459 {
460 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring root folder");
423 if (client is IClientCore) 461 if (client is IClientCore)
424 { 462 {
425 IClientCore core = (IClientCore)client; 463 IClientCore core = (IClientCore)client;
@@ -428,21 +466,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
428 if (core.TryGet<IClientInventory>(out inv)) 466 if (core.TryGet<IClientInventory>(out inv))
429 { 467 {
430 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId); 468 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId);
431 client.SendBulkUpdateInventory(root); 469 InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID);
432 //if (root != null) 470
433 //{ 471 inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray());
434 // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring root inventory for user {0}", client.AgentId);
435 // InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID);
436 // m_log.DebugFormat("[XXX]: Folder name {0}, id {1}, parent {2}", root.Name, root.ID, root.ParentID);
437 // foreach (InventoryItemBase i in content.Items)
438 // m_log.DebugFormat("[XXX]: Name={0}, folderID={1}", i.Name, i.Folder);
439
440 // inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray());
441 //}
442 } 472 }
443 } 473 }
444 } 474 }
445 475
476 private void RestoreSuitcaseFolderContents(IClientAPI client)
477 {
478 }
479
446 private GridRegion MakeRegion(AgentCircuitData aCircuit) 480 private GridRegion MakeRegion(AgentCircuitData aCircuit)
447 { 481 {
448 GridRegion region = new GridRegion(); 482 GridRegion region = new GridRegion();
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index 4be3804..cf6d2f7 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -297,14 +297,35 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
297 return m_LocalGridInventoryService.CreateUserInventory(userID); 297 return m_LocalGridInventoryService.CreateUserInventory(userID);
298 } 298 }
299 299
300 public List<InventoryFolderBase> GetInventorySkeleton(UUID userId) 300 public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
301 { 301 {
302 return m_LocalGridInventoryService.GetInventorySkeleton(userId); 302 string invURL = GetInventoryServiceURL(userID);
303
304 if (invURL == null) // not there, forward to local inventory connector to resolve
305 return m_LocalGridInventoryService.GetInventorySkeleton(userID);
306
307 IInventoryService connector = GetConnector(invURL);
308
309 return connector.GetInventorySkeleton(userID);
303 } 310 }
304 311
305 public InventoryCollection GetUserInventory(UUID userID) 312 public InventoryCollection GetUserInventory(UUID userID)
306 { 313 {
307 return null; 314 string invURL = GetInventoryServiceURL(userID);
315 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetUserInventory for {0} {1}", userID, invURL);
316
317 if (invURL == null) // not there, forward to local inventory connector to resolve
318 return m_LocalGridInventoryService.GetUserInventory(userID);
319
320 InventoryCollection c = m_Cache.GetUserInventory(userID);
321 if (c != null)
322 return c;
323
324 IInventoryService connector = GetConnector(invURL);
325 c = connector.GetUserInventory(userID);
326
327 m_Cache.Cache(userID, c);
328 return c;
308 } 329 }
309 330
310 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) 331 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
@@ -362,8 +383,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
362 if (invURL == null) // not there, forward to local inventory connector to resolve 383 if (invURL == null) // not there, forward to local inventory connector to resolve
363 return m_LocalGridInventoryService.GetFolderContent(userID, folderID); 384 return m_LocalGridInventoryService.GetFolderContent(userID, folderID);
364 385
365 IInventoryService connector = GetConnector(invURL); 386 InventoryCollection c = m_Cache.GetFolderContent(userID, folderID);
387 if (c != null)
388 {
389 m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderContent found content in cache " + folderID);
390 return c;
391 }
366 392
393 IInventoryService connector = GetConnector(invURL);
367 return connector.GetFolderContent(userID, folderID); 394 return connector.GetFolderContent(userID, folderID);
368 395
369 } 396 }
@@ -377,8 +404,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
377 if (invURL == null) // not there, forward to local inventory connector to resolve 404 if (invURL == null) // not there, forward to local inventory connector to resolve
378 return m_LocalGridInventoryService.GetFolderItems(userID, folderID); 405 return m_LocalGridInventoryService.GetFolderItems(userID, folderID);
379 406
380 IInventoryService connector = GetConnector(invURL); 407 List<InventoryItemBase> items = m_Cache.GetFolderItems(userID, folderID);
408 if (items != null)
409 {
410 m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems found items in cache " + folderID);
411 return items;
412 }
381 413
414 IInventoryService connector = GetConnector(invURL);
382 return connector.GetFolderItems(userID, folderID); 415 return connector.GetFolderItems(userID, folderID);
383 416
384 } 417 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
index 0fe778d..1e434b9 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
@@ -12,6 +12,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
12 12
13 private static ExpiringCache<UUID, InventoryFolderBase> m_RootFolders = new ExpiringCache<UUID, InventoryFolderBase>(); 13 private static ExpiringCache<UUID, InventoryFolderBase> m_RootFolders = new ExpiringCache<UUID, InventoryFolderBase>();
14 private static ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>> m_FolderTypes = new ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>>(); 14 private static ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>> m_FolderTypes = new ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>>();
15 private static ExpiringCache<UUID, InventoryCollection> m_Inventories = new ExpiringCache<UUID, InventoryCollection>();
15 16
16 public void Cache(UUID userID, InventoryFolderBase root) 17 public void Cache(UUID userID, InventoryFolderBase root)
17 { 18 {
@@ -55,5 +56,55 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
55 56
56 return null; 57 return null;
57 } 58 }
59
60 public void Cache(UUID userID, InventoryCollection inv)
61 {
62 lock (m_Inventories)
63 m_Inventories.AddOrUpdate(userID, inv, 120);
64 }
65
66 public InventoryCollection GetUserInventory(UUID userID)
67 {
68 InventoryCollection inv = null;
69 if (m_Inventories.TryGetValue(userID, out inv))
70 return inv;
71 return null;
72 }
73
74 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
75 {
76 InventoryCollection inv = null;
77 InventoryCollection c;
78 if (m_Inventories.TryGetValue(userID, out inv))
79 {
80 c = new InventoryCollection();
81 c.UserID = userID;
82
83 c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f)
84 {
85 return f.ParentID == folderID;
86 });
87 c.Items = inv.Items.FindAll(delegate(InventoryItemBase i)
88 {
89 return i.Folder == folderID;
90 });
91 return c;
92 }
93 return null;
94 }
95
96 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
97 {
98 InventoryCollection inv = null;
99 if (m_Inventories.TryGetValue(userID, out inv))
100 {
101 List<InventoryItemBase> items = inv.Items.FindAll(delegate(InventoryItemBase i)
102 {
103 return i.Folder == folderID;
104 });
105 return items;
106 }
107 return null;
108 }
58 } 109 }
59} 110}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index 77573c3..990dffb 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -172,7 +172,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
172 172
173 public InventoryCollection GetUserInventory(UUID userID) 173 public InventoryCollection GetUserInventory(UUID userID)
174 { 174 {
175 return null; 175 return m_RemoteConnector.GetUserInventory(userID);
176 } 176 }
177 177
178 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) 178 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
@@ -193,16 +193,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
193 { 193 {
194 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); 194 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
195 195
196 if (UserManager != null) 196 if (invCol != null && UserManager != null)
197 { 197 {
198 // Protect ourselves against the caller subsequently modifying the items list 198 // Protect ourselves against the caller subsequently modifying the items list
199 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items); 199 List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
200 200
201 Util.FireAndForget(delegate 201 if (items != null && items.Count > 0)
202 { 202 Util.FireAndForget(delegate
203 foreach (InventoryItemBase item in items) 203 {
204 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); 204 foreach (InventoryItemBase item in items)
205 }); 205 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
206 });
206 } 207 }
207 208
208 return invCol; 209 return invCol;
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index a0ed5a5..ced7b52 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -56,6 +56,9 @@ namespace OpenSim.Region.CoreModules.World.Land
56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
57 protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>(); 57 protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
58 58
59 protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
60 protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
61
59 public bool[,] LandBitmap 62 public bool[,] LandBitmap
60 { 63 {
61 get { return m_landBitmap; } 64 get { return m_landBitmap; }
@@ -417,6 +420,45 @@ namespace OpenSim.Region.CoreModules.World.Land
417 return false; 420 return false;
418 } 421 }
419 422
423 public bool HasGroupAccess(UUID avatar)
424 {
425 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
426 {
427 ScenePresence sp;
428 if (!m_scene.TryGetScenePresence(avatar, out sp))
429 {
430 bool isMember;
431 if (m_groupMemberCache.TryGetValue(avatar, out isMember))
432 return isMember;
433
434 IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
435 if (groupsModule == null)
436 return false;
437
438 GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar);
439 if (membership == null || membership.Length == 0)
440 {
441 m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
442 return false;
443 }
444
445 foreach (GroupMembershipData d in membership)
446 {
447 if (d.GroupID == LandData.GroupID)
448 {
449 m_groupMemberCache.Add(avatar, true, m_groupMemberCacheTimeout);
450 return true;
451 }
452 }
453 m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
454 return false;
455 }
456
457 return sp.ControllingClient.IsGroupMember(LandData.GroupID);
458 }
459 return false;
460 }
461
420 public bool IsBannedFromLand(UUID avatar) 462 public bool IsBannedFromLand(UUID avatar)
421 { 463 {
422 ExpireAccessList(); 464 ExpireAccessList();
@@ -448,6 +490,9 @@ namespace OpenSim.Region.CoreModules.World.Land
448 490
449 public bool IsRestrictedFromLand(UUID avatar) 491 public bool IsRestrictedFromLand(UUID avatar)
450 { 492 {
493 if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0)
494 return false;
495
451 if (m_scene.Permissions.IsAdministrator(avatar)) 496 if (m_scene.Permissions.IsAdministrator(avatar))
452 return false; 497 return false;
453 498
@@ -457,10 +502,10 @@ namespace OpenSim.Region.CoreModules.World.Land
457 if (avatar == LandData.OwnerID) 502 if (avatar == LandData.OwnerID)
458 return false; 503 return false;
459 504
460 if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0) 505 if (HasGroupAccess(avatar))
461 return false; 506 return false;
462 507
463 return (!IsInLandAccessList(avatar)); 508 return !IsInLandAccessList(avatar);
464 } 509 }
465 510
466 public bool IsInLandAccessList(UUID avatar) 511 public bool IsInLandAccessList(UUID avatar)
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs
index 90f124b..fb57c82 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/BMP.cs
@@ -72,5 +72,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
72 { 72 {
73 return "BMP"; 73 return "BMP";
74 } 74 }
75
76 //Returns true if this extension is supported for terrain save-tile
77 public override bool SupportsTileSave()
78 {
79 return false;
80 }
75 } 81 }
76} 82}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs
index f331b56..79cc50b 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GIF.cs
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
57 { 57 {
58 return "GIF"; 58 return "GIF";
59 } 59 }
60
61 //Returns true if this extension is supported for terrain save-tile
62 public override bool SupportsTileSave()
63 {
64 return false;
65 }
60 } 66 }
61} 67}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
index 58925fd..da81dc1 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
@@ -177,6 +177,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
177 return "SYS.DRAWING"; 177 return "SYS.DRAWING";
178 } 178 }
179 179
180 //Returns true if this extension is supported for terrain save-tile
181 public virtual bool SupportsTileSave()
182 {
183 return false;
184 }
185
180 /// <summary> 186 /// <summary>
181 /// Protected method, generates a grayscale bitmap 187 /// Protected method, generates a grayscale bitmap
182 /// image from a specified terrain channel. 188 /// image from a specified terrain channel.
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs
index 1a0d8ec..699d67a 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs
@@ -91,6 +91,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
91 return "JPEG"; 91 return "JPEG";
92 } 92 }
93 93
94 //Returns true if this extension is supported for terrain save-tile
95 public bool SupportsTileSave()
96 {
97 return false;
98 }
99
94 private static Bitmap CreateBitmapFromMap(ITerrainChannel map) 100 private static Bitmap CreateBitmapFromMap(ITerrainChannel map)
95 { 101 {
96 Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); 102 Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs
index fad7641..62d232e 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs
@@ -254,5 +254,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
254 { 254 {
255 return "LL/SL RAW"; 255 return "LL/SL RAW";
256 } 256 }
257
258 //Returns true if this extension is supported for terrain save-tile
259 public bool SupportsTileSave()
260 {
261 return false;
262 }
263
257 } 264 }
258} 265}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs
index e009ecf..c5c12ae 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/PNG.cs
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
57 { 57 {
58 return "PNG"; 58 return "PNG";
59 } 59 }
60
61 //Returns true if this extension is supported for terrain save-tile
62 public override bool SupportsTileSave()
63 {
64 return true;
65 }
60 } 66 }
61} 67}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs
index ba073ca..9fb7ef7 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs
@@ -173,5 +173,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
173 { 173 {
174 return "RAW32"; 174 return "RAW32";
175 } 175 }
176
177 //Returns true if this extension is supported for terrain save-tile
178 public bool SupportsTileSave()
179 {
180 return false;
181 }
176 } 182 }
177} 183}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs
index fc1ad33..5d2f893 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
57 { 57 {
58 return "TIFF"; 58 return "TIFF";
59 } 59 }
60
61 //Returns true if this extension is supported for terrain save-tile
62 public bool SupportsTileSave()
63 {
64 return false;
65 }
60 } 66 }
61} 67}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
index 2f37d9d..1ebf916 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
@@ -323,6 +323,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
323 return "Terragen"; 323 return "Terragen";
324 } 324 }
325 325
326 //Returns true if this extension is supported for terrain save-tile
327 public bool SupportsTileSave()
328 {
329 return false;
330 }
331
326 /// <summary> 332 /// <summary>
327 /// terragen SCAL floats need to be written intel ordered regardless of 333 /// terragen SCAL floats need to be written intel ordered regardless of
328 /// big or little endian system 334 /// big or little endian system
diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
index d407617..3ba3657 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
@@ -32,6 +32,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain
32{ 32{
33 public interface ITerrainLoader 33 public interface ITerrainLoader
34 { 34 {
35 // Returns true if that extension can be used for terrain save-tile
36 // (Look into each file in Region.CoreModules.World.Terrain.FileLoaders)
37 bool SupportsTileSave();
38
35 string FileExtension { get; } 39 string FileExtension { get; }
36 ITerrainChannel LoadFile(string filename); 40 ITerrainChannel LoadFile(string filename);
37 ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight); 41 ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight);
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index b3c2969..8535a5a 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -93,6 +93,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
93 /// </summary> 93 /// </summary>
94 private string m_supportedFileExtensions = ""; 94 private string m_supportedFileExtensions = "";
95 95
96 //For terrain save-tile file extensions
97 private string m_supportFileExtensionsForTileSave = "";
98
96 #region ICommandableModule Members 99 #region ICommandableModule Members
97 100
98 public ICommander CommandInterface 101 public ICommander CommandInterface
@@ -148,11 +151,20 @@ namespace OpenSim.Region.CoreModules.World.Terrain
148 151
149 // Generate user-readable extensions list 152 // Generate user-readable extensions list
150 string supportedFilesSeparator = ""; 153 string supportedFilesSeparator = "";
154 string supportedFilesSeparatorForTileSave = "";
151 155
156 m_supportFileExtensionsForTileSave = "";
152 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 157 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
153 { 158 {
154 m_supportedFileExtensions += supportedFilesSeparator + loader.Key + " (" + loader.Value + ")"; 159 m_supportedFileExtensions += supportedFilesSeparator + loader.Key + " (" + loader.Value + ")";
155 supportedFilesSeparator = ", "; 160 supportedFilesSeparator = ", ";
161
162 //For terrain save-tile file extensions
163 if (loader.Value.SupportsTileSave() == true)
164 {
165 m_supportFileExtensionsForTileSave += supportedFilesSeparatorForTileSave + loader.Key + " (" + loader.Value + ")";
166 supportedFilesSeparatorForTileSave = ", ";
167 }
156 } 168 }
157 } 169 }
158 170
@@ -589,7 +601,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
589 // this region is included in the tile request 601 // this region is included in the tile request
590 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 602 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
591 { 603 {
592 if (filename.EndsWith(loader.Key)) 604 if (filename.EndsWith(loader.Key) && loader.Value.SupportsTileSave())
593 { 605 {
594 lock (m_scene) 606 lock (m_scene)
595 { 607 {
@@ -610,7 +622,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
610 622
611 MainConsole.Instance.OutputFormat( 623 MainConsole.Instance.OutputFormat(
612 "ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}", 624 "ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
613 m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions); 625 m_scene.RegionInfo.RegionName, filename, m_supportFileExtensionsForTileSave);
614 } 626 }
615 627
616 /// <summary> 628 /// <summary>
@@ -1192,7 +1204,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1192 new Command("save-tile", CommandIntentions.COMMAND_HAZARDOUS, InterfaceSaveTileFile, "Saves the current heightmap to the larger file."); 1204 new Command("save-tile", CommandIntentions.COMMAND_HAZARDOUS, InterfaceSaveTileFile, "Saves the current heightmap to the larger file.");
1193 saveToTileCommand.AddArgument("filename", 1205 saveToTileCommand.AddArgument("filename",
1194 "The file you wish to save to, the file extension determines the loader to be used. Supported extensions include: " + 1206 "The file you wish to save to, the file extension determines the loader to be used. Supported extensions include: " +
1195 m_supportedFileExtensions, "String"); 1207 m_supportFileExtensionsForTileSave, "String");
1196 saveToTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer"); 1208 saveToTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
1197 saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); 1209 saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
1198 saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", 1210 saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 5abd74f..10b25ed 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -36,6 +36,7 @@ using OpenMetaverse.Packets;
36using log4net; 36using log4net;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Region.Framework; 38using OpenSim.Region.Framework;
39using OpenSim.Framework.Client;
39using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes.Serialization; 41using OpenSim.Region.Framework.Scenes.Serialization;
41 42
@@ -117,31 +118,42 @@ namespace OpenSim.Region.Framework.Scenes
117 /// <param name="item"></param> 118 /// <param name="item"></param>
118 public bool AddInventoryItem(InventoryItemBase item) 119 public bool AddInventoryItem(InventoryItemBase item)
119 { 120 {
120 if (UUID.Zero == item.Folder) 121 if (item.Folder != UUID.Zero && InventoryService.AddItem(item))
121 { 122 {
122 InventoryFolderBase f = InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType); 123 int userlevel = 0;
123 if (f != null) 124 if (Permissions.IsGod(item.Owner))
124 { 125 {
125// m_log.DebugFormat( 126 userlevel = 1;
126// "[LOCAL INVENTORY SERVICES CONNECTOR]: Found folder {0} type {1} for item {2}", 127 }
127// f.Name, (AssetType)f.Type, item.Name); 128 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel);
129
130 return true;
131 }
132
133 // OK so either the viewer didn't send a folderID or AddItem failed
134 UUID originalFolder = item.Folder;
135 InventoryFolderBase f = InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType);
136 if (f != null)
137 {
138 m_log.DebugFormat(
139 "[AGENT INVENTORY]: Found folder {0} type {1} for item {2}",
140 f.Name, (AssetType)f.Type, item.Name);
128 141
142 item.Folder = f.ID;
143 }
144 else
145 {
146 f = InventoryService.GetRootFolder(item.Owner);
147 if (f != null)
148 {
129 item.Folder = f.ID; 149 item.Folder = f.ID;
130 } 150 }
131 else 151 else
132 { 152 {
133 f = InventoryService.GetRootFolder(item.Owner); 153 m_log.WarnFormat(
134 if (f != null) 154 "[AGENT INVENTORY]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified",
135 { 155 item.Owner, item.Name);
136 item.Folder = f.ID; 156 return false;
137 }
138 else
139 {
140 m_log.WarnFormat(
141 "[AGENT INVENTORY]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified",
142 item.Owner, item.Name);
143 return false;
144 }
145 } 157 }
146 } 158 }
147 159
@@ -153,7 +165,13 @@ namespace OpenSim.Region.Framework.Scenes
153 userlevel = 1; 165 userlevel = 1;
154 } 166 }
155 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel); 167 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel);
156 168
169 if (originalFolder != UUID.Zero)
170 {
171 // Tell the viewer that the item didn't go there
172 ChangePlacement(item, f);
173 }
174
157 return true; 175 return true;
158 } 176 }
159 else 177 else
@@ -165,7 +183,32 @@ namespace OpenSim.Region.Framework.Scenes
165 return false; 183 return false;
166 } 184 }
167 } 185 }
168 186
187 private void ChangePlacement(InventoryItemBase item, InventoryFolderBase f)
188 {
189 ScenePresence sp = GetScenePresence(item.Owner);
190 if (sp != null)
191 {
192 if (sp.ControllingClient is IClientCore)
193 {
194 IClientCore core = (IClientCore)sp.ControllingClient;
195 IClientInventory inv;
196
197 if (core.TryGet<IClientInventory>(out inv))
198 {
199 InventoryFolderBase parent = new InventoryFolderBase(f.ParentID, f.Owner);
200 parent = InventoryService.GetFolder(parent);
201 inv.SendRemoveInventoryItems(new UUID[] { item.ID });
202 inv.SendBulkUpdateInventory(new InventoryFolderBase[0], new InventoryItemBase[] { item });
203 string message = "The item was placed in folder " + f.Name;
204 if (parent != null)
205 message += " under " + parent.Name;
206 sp.ControllingClient.SendAgentAlertMessage(message, false);
207 }
208 }
209 }
210 }
211
169 /// <summary> 212 /// <summary>
170 /// Add the given inventory item to a user's inventory. 213 /// Add the given inventory item to a user's inventory.
171 /// </summary> 214 /// </summary>
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 2a15e5d..e669f4c 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -1294,7 +1294,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1294 1294
1295 OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); 1295 OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero);
1296 1296
1297
1298 // Need to send a group membership update to the client 1297 // Need to send a group membership update to the client
1299 // UDP version doesn't seem to behave nicely. But we're going to send it out here 1298 // UDP version doesn't seem to behave nicely. But we're going to send it out here
1300 // with an empty group membership to hopefully remove groups being displayed due 1299 // with an empty group membership to hopefully remove groups being displayed due
@@ -1305,6 +1304,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1305 SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); 1304 SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray);
1306 remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); 1305 remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
1307 1306
1307 if (remoteClient.AgentId == dataForAgentID)
1308 remoteClient.RefreshGroupMembership();
1308 } 1309 }
1309 1310
1310 /// <summary> 1311 /// <summary>
diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
index 040c840..cb9b65d 100644
--- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
+++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
@@ -114,6 +114,8 @@ namespace OpenSim.Server.Handlers.Asset
114 return HandleCreateUserInventory(request); 114 return HandleCreateUserInventory(request);
115 case "GETINVENTORYSKELETON": 115 case "GETINVENTORYSKELETON":
116 return HandleGetInventorySkeleton(request); 116 return HandleGetInventorySkeleton(request);
117 case "GETUSERINVENTORY":
118 return HandleGetUserInventory(request);
117 case "GETROOTFOLDER": 119 case "GETROOTFOLDER":
118 return HandleGetRootFolder(request); 120 return HandleGetRootFolder(request);
119 case "GETFOLDERFORTYPE": 121 case "GETFOLDERFORTYPE":
@@ -153,7 +155,7 @@ namespace OpenSim.Server.Handlers.Asset
153 } 155 }
154 catch (Exception e) 156 catch (Exception e)
155 { 157 {
156 m_log.DebugFormat("[XINVENTORY HANDLER]: Exception {0}", e); 158 m_log.DebugFormat("[XINVENTORY HANDLER]: Exception {0}", e.StackTrace);
157 } 159 }
158 160
159 return FailureResult(); 161 return FailureResult();
@@ -248,6 +250,45 @@ namespace OpenSim.Server.Handlers.Asset
248 return encoding.GetBytes(xmlString); 250 return encoding.GetBytes(xmlString);
249 } 251 }
250 252
253 byte[] HandleGetUserInventory(Dictionary<string, object> request)
254 {
255 Dictionary<string, object> result = new Dictionary<string, object>();
256 UUID principal = UUID.Zero;
257 UUID.TryParse(request["PRINCIPAL"].ToString(), out principal);
258
259 InventoryCollection icoll = m_InventoryService.GetUserInventory(principal);
260 if (icoll != null)
261 {
262 Dictionary<string, object> folders = new Dictionary<string, object>();
263 int i = 0;
264 if (icoll.Folders != null)
265 {
266 foreach (InventoryFolderBase f in icoll.Folders)
267 {
268 folders["folder_" + i.ToString()] = EncodeFolder(f);
269 i++;
270 }
271 result["FOLDERS"] = folders;
272 }
273 if (icoll.Items != null)
274 {
275 i = 0;
276 Dictionary<string, object> items = new Dictionary<string, object>();
277 foreach (InventoryItemBase it in icoll.Items)
278 {
279 items["item_" + i.ToString()] = EncodeItem(it);
280 i++;
281 }
282 result["ITEMS"] = items;
283 }
284 }
285
286 string xmlString = ServerUtils.BuildXmlResponse(result);
287 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
288 UTF8Encoding encoding = new UTF8Encoding();
289 return encoding.GetBytes(xmlString);
290 }
291
251 byte[] HandleGetRootFolder(Dictionary<string,object> request) 292 byte[] HandleGetRootFolder(Dictionary<string,object> request)
252 { 293 {
253 Dictionary<string,object> result = new Dictionary<string,object>(); 294 Dictionary<string,object> result = new Dictionary<string,object>();
@@ -293,22 +334,27 @@ namespace OpenSim.Server.Handlers.Asset
293 if (icoll != null) 334 if (icoll != null)
294 { 335 {
295 Dictionary<string, object> folders = new Dictionary<string, object>(); 336 Dictionary<string, object> folders = new Dictionary<string, object>();
296 int i = 0; 337 int i = 0;
297 foreach (InventoryFolderBase f in icoll.Folders) 338 if (icoll.Folders != null)
298 { 339 {
299 folders["folder_" + i.ToString()] = EncodeFolder(f); 340 foreach (InventoryFolderBase f in icoll.Folders)
300 i++; 341 {
342 folders["folder_" + i.ToString()] = EncodeFolder(f);
343 i++;
344 }
345 result["FOLDERS"] = folders;
301 } 346 }
302 result["FOLDERS"] = folders; 347 if (icoll.Items != null)
303
304 i = 0;
305 Dictionary<string, object> items = new Dictionary<string, object>();
306 foreach (InventoryItemBase it in icoll.Items)
307 { 348 {
308 items["item_" + i.ToString()] = EncodeItem(it); 349 i = 0;
309 i++; 350 Dictionary<string, object> items = new Dictionary<string, object>();
351 foreach (InventoryItemBase it in icoll.Items)
352 {
353 items["item_" + i.ToString()] = EncodeItem(it);
354 i++;
355 }
356 result["ITEMS"] = items;
310 } 357 }
311 result["ITEMS"] = items;
312 } 358 }
313 359
314 string xmlString = ServerUtils.BuildXmlResponse(result); 360 string xmlString = ServerUtils.BuildXmlResponse(result);
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
index 39e983b..9d96703 100644
--- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
@@ -111,19 +111,21 @@ namespace OpenSim.Services.Connectors
111 if (ret.Count == 0) 111 if (ret.Count == 0)
112 return null; 112 return null;
113 113
114 List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); 114 Dictionary<string, object> folders = (Dictionary<string, object>)ret["FOLDERS"];
115
116 List<InventoryFolderBase> fldrs = new List<InventoryFolderBase>();
115 117
116 try 118 try
117 { 119 {
118 foreach (Object o in ret.Values) 120 foreach (Object o in folders.Values)
119 folders.Add(BuildFolder((Dictionary<string, object>)o)); 121 fldrs.Add(BuildFolder((Dictionary<string, object>)o));
120 } 122 }
121 catch (Exception e) 123 catch (Exception e)
122 { 124 {
123 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping folder list: {0}", e.Message); 125 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping folder list: {0}", e.Message);
124 } 126 }
125 127
126 return folders; 128 return fldrs;
127 } 129 }
128 130
129 public InventoryFolderBase GetRootFolder(UUID principalID) 131 public InventoryFolderBase GetRootFolder(UUID principalID)
@@ -492,12 +494,41 @@ namespace OpenSim.Services.Connectors
492 return int.Parse(ret["RESULT"].ToString()); 494 return int.Parse(ret["RESULT"].ToString());
493 } 495 }
494 496
495
496 // These are either obsolete or unused
497 //
498 public InventoryCollection GetUserInventory(UUID principalID) 497 public InventoryCollection GetUserInventory(UUID principalID)
499 { 498 {
500 return null; 499 InventoryCollection inventory = new InventoryCollection();
500 inventory.Folders = new List<InventoryFolderBase>();
501 inventory.Items = new List<InventoryItemBase>();
502 inventory.UserID = principalID;
503
504 try
505 {
506 Dictionary<string, object> ret = MakeRequest("GETUSERINVENTORY",
507 new Dictionary<string, object> {
508 { "PRINCIPAL", principalID.ToString() }
509 });
510
511 if (ret == null)
512 return null;
513 if (ret.Count == 0)
514 return null;
515
516 Dictionary<string, object> folders =
517 (Dictionary<string, object>)ret["FOLDERS"];
518 Dictionary<string, object> items =
519 (Dictionary<string, object>)ret["ITEMS"];
520
521 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
522 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o));
523 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
524 inventory.Items.Add(BuildItem((Dictionary<string, object>)o));
525 }
526 catch (Exception e)
527 {
528 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetUserInventory: {0}", e.Message);
529 }
530
531 return inventory;
501 } 532 }
502 533
503 public void GetUserInventory(UUID principalID, InventoryReceiptCallback callback) 534 public void GetUserInventory(UUID principalID, InventoryReceiptCallback callback)
diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs
index b29d803..2e9bd40 100644
--- a/OpenSim/Services/HypergridService/HGInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGInventoryService.cs
@@ -105,6 +105,12 @@ namespace OpenSim.Services.HypergridService
105 return new List<InventoryFolderBase>(); 105 return new List<InventoryFolderBase>();
106 } 106 }
107 107
108 public override InventoryCollection GetUserInventory(UUID userID)
109 {
110 // NOGO for this inventory service
111 return null;
112 }
113
108 public override InventoryFolderBase GetRootFolder(UUID principalID) 114 public override InventoryFolderBase GetRootFolder(UUID principalID)
109 { 115 {
110 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID); 116 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID);
diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
index cb686e2..b6ec558 100644
--- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
@@ -59,7 +59,7 @@ namespace OpenSim.Services.HypergridService
59 59
60 private UserAccountCache m_Cache; 60 private UserAccountCache m_Cache;
61 61
62 private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees = new ExpiringCache<UUID,List<XInventoryFolder>>(); 62 private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees = new ExpiringCache<UUID, List<XInventoryFolder>>();
63 63
64 public HGSuitcaseInventoryService(IConfigSource config, string configName) 64 public HGSuitcaseInventoryService(IConfigSource config, string configName)
65 : base(config, configName) 65 : base(config, configName)
@@ -104,11 +104,72 @@ namespace OpenSim.Services.HypergridService
104 return false; 104 return false;
105 } 105 }
106 106
107
108 public override List<InventoryFolderBase> GetInventorySkeleton(UUID principalID) 107 public override List<InventoryFolderBase> GetInventorySkeleton(UUID principalID)
109 { 108 {
110 // NOGO for this inventory service 109 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
111 return new List<InventoryFolderBase>(); 110 XInventoryFolder root = GetRootXFolder(principalID);
111
112 List<XInventoryFolder> tree = GetFolderTree(suitcase.folderID);
113 if (tree == null || (tree != null && tree.Count == 0))
114 return null;
115
116 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
117 foreach (XInventoryFolder x in tree)
118 {
119 folders.Add(ConvertToOpenSim(x));
120 }
121
122 SetAsRootFolder(suitcase, root);
123 folders.Add(ConvertToOpenSim(suitcase));
124
125 return folders;
126 }
127
128 public override InventoryCollection GetUserInventory(UUID userID)
129 {
130 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Get Suitcase inventory for user {0}", userID);
131 InventoryCollection userInventory = new InventoryCollection();
132 userInventory.UserID = userID;
133 userInventory.Folders = new List<InventoryFolderBase>();
134 userInventory.Items = new List<InventoryItemBase>();
135
136 XInventoryFolder suitcase = GetSuitcaseXFolder(userID);
137 XInventoryFolder root = GetRootXFolder(userID);
138
139 List<XInventoryFolder> tree = GetFolderTree(suitcase.folderID);
140 if (tree == null || (tree != null && tree.Count == 0))
141 {
142 SetAsRootFolder(suitcase, root);
143 userInventory.Folders.Add(ConvertToOpenSim(suitcase));
144 return userInventory;
145 }
146
147 List<InventoryItemBase> items;
148 foreach (XInventoryFolder f in tree)
149 {
150 // Add the items of this subfolder
151 items = GetFolderItems(userID, f.folderID);
152 if (items != null && items.Count > 0)
153 {
154 userInventory.Items.AddRange(items);
155 }
156
157 // Add the folder itself
158 userInventory.Folders.Add(ConvertToOpenSim(f));
159 }
160
161 items = GetFolderItems(userID, suitcase.folderID);
162 if (items != null && items.Count > 0)
163 {
164 userInventory.Items.AddRange(items);
165 }
166
167 SetAsRootFolder(suitcase, root);
168 userInventory.Folders.Add(ConvertToOpenSim(suitcase));
169
170 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetUserInventory for user {0} returning {1} folders and {2} items",
171 userID, userInventory.Folders.Count, userInventory.Items.Count);
172 return userInventory;
112 } 173 }
113 174
114 public override InventoryFolderBase GetRootFolder(UUID principalID) 175 public override InventoryFolderBase GetRootFolder(UUID principalID)
@@ -131,51 +192,92 @@ namespace OpenSim.Services.HypergridService
131 { 192 {
132 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder. Creating it...", principalID); 193 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder. Creating it...", principalID);
133 // make one, and let's add it to the user's inventory as a direct child of the root folder 194 // make one, and let's add it to the user's inventory as a direct child of the root folder
195 // In the DB we tag it as type 100, but we use -1 (Unknown) outside
134 suitcase = CreateFolder(principalID, root.folderID, 100, "My Suitcase"); 196 suitcase = CreateFolder(principalID, root.folderID, 100, "My Suitcase");
135 if (suitcase == null) 197 if (suitcase == null)
136 m_log.ErrorFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to create suitcase folder"); 198 m_log.ErrorFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to create suitcase folder");
137
138 m_Database.StoreFolder(suitcase); 199 m_Database.StoreFolder(suitcase);
200
201 // Create System folders
202 CreateSystemFolders(principalID, suitcase.folderID);
139 } 203 }
140 204
141 // Now let's change the folder ID to match that of the real root folder 205 SetAsRootFolder(suitcase, root);
142 SetAsRootFolder(suitcase, root.folderID);
143 206
144 return ConvertToOpenSim(suitcase); 207 return ConvertToOpenSim(suitcase);
145 } 208 }
146 209
210 protected void CreateSystemFolders(UUID principalID, UUID rootID)
211 {
212 m_log.Debug("[HG SUITCASE INVENTORY SERVICE]: Creating System folders under Suitcase...");
213 XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootID);
214
215 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Animation) return true; return false; }))
216 CreateFolder(principalID, rootID, (int)AssetType.Animation, "Animations");
217 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Bodypart) return true; return false; }))
218 CreateFolder(principalID, rootID, (int)AssetType.Bodypart, "Body Parts");
219 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.CallingCard) return true; return false; }))
220 CreateFolder(principalID, rootID, (int)AssetType.CallingCard, "Calling Cards");
221 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Clothing) return true; return false; }))
222 CreateFolder(principalID, rootID, (int)AssetType.Clothing, "Clothing");
223 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Gesture) return true; return false; }))
224 CreateFolder(principalID, rootID, (int)AssetType.Gesture, "Gestures");
225 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Landmark) return true; return false; }))
226 CreateFolder(principalID, rootID, (int)AssetType.Landmark, "Landmarks");
227 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.LostAndFoundFolder) return true; return false; }))
228 CreateFolder(principalID, rootID, (int)AssetType.LostAndFoundFolder, "Lost And Found");
229 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Notecard) return true; return false; }))
230 CreateFolder(principalID, rootID, (int)AssetType.Notecard, "Notecards");
231 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Object) return true; return false; }))
232 CreateFolder(principalID, rootID, (int)AssetType.Object, "Objects");
233 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.SnapshotFolder) return true; return false; }))
234 CreateFolder(principalID, rootID, (int)AssetType.SnapshotFolder, "Photo Album");
235 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.LSLText) return true; return false; }))
236 CreateFolder(principalID, rootID, (int)AssetType.LSLText, "Scripts");
237 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Sound) return true; return false; }))
238 CreateFolder(principalID, rootID, (int)AssetType.Sound, "Sounds");
239 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Texture) return true; return false; }))
240 CreateFolder(principalID, rootID, (int)AssetType.Texture, "Textures");
241 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.TrashFolder) return true; return false; }))
242 CreateFolder(principalID, rootID, (int)AssetType.TrashFolder, "Trash");
243 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.FavoriteFolder) return true; return false; }))
244 CreateFolder(principalID, rootID, (int)AssetType.FavoriteFolder, "Favorites");
245 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.CurrentOutfitFolder) return true; return false; }))
246 CreateFolder(principalID, rootID, (int)AssetType.CurrentOutfitFolder, "Current Outfit");
247
248 }
249
147 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 250 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
148 { 251 {
149 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type); 252 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type);
150 return GetRootFolder(principalID); 253 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
254 XInventoryFolder[] folders = m_Database.GetFolders(
255 new string[] { "agentID", "type", "parentFolderID" },
256 new string[] { principalID.ToString(), ((int)type).ToString(), suitcase.folderID.ToString() });
257
258 if (folders.Length == 0)
259 {
260 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Found no folder for type {0} for user {1}", type, principalID);
261 return null;
262 }
263
264 m_log.DebugFormat(
265 "[HG SUITCASE INVENTORY SERVICE]: Found folder {0} {1} for type {2} for user {3}",
266 folders[0].folderName, folders[0].folderID, type, principalID);
267
268 return ConvertToOpenSim(folders[0]);
151 } 269 }
152 270
153 public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID) 271 public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
154 { 272 {
155 InventoryCollection coll = null; 273 InventoryCollection coll = null;
156 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); 274 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
157 XInventoryFolder root = GetRootXFolder(principalID);
158 275
159 if (!IsWithinSuitcaseTree(folderID, root, suitcase)) 276 if (!IsWithinSuitcaseTree(folderID, suitcase))
160 return new InventoryCollection(); 277 return new InventoryCollection();
161 278
162 if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase 279 coll = base.GetFolderContent(principalID, folderID);
163 { 280
164 if (suitcase != null)
165 {
166 coll = base.GetFolderContent(principalID, suitcase.folderID);
167 foreach (InventoryFolderBase f in coll.Folders)
168 f.ParentID = root.folderID;
169 foreach (InventoryItemBase i in coll.Items)
170 i.Folder = root.folderID;
171 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent for root folder returned content for suitcase folder");
172 }
173 }
174 else
175 {
176 coll = base.GetFolderContent(principalID, folderID);
177 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent for non-root folder {0}", folderID);
178 }
179 if (coll == null) 281 if (coll == null)
180 { 282 {
181 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Something wrong with user {0}'s suitcase folder", principalID); 283 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Something wrong with user {0}'s suitcase folder", principalID);
@@ -188,10 +290,9 @@ namespace OpenSim.Services.HypergridService
188 { 290 {
189 // Let's do a bit of sanity checking, more than the base service does 291 // Let's do a bit of sanity checking, more than the base service does
190 // make sure the given folder exists under the suitcase tree of this user 292 // make sure the given folder exists under the suitcase tree of this user
191 XInventoryFolder root = GetRootXFolder(principalID);
192 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); 293 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
193 294
194 if (!IsWithinSuitcaseTree(folderID, root, suitcase)) 295 if (!IsWithinSuitcaseTree(folderID, suitcase))
195 return new List<InventoryItemBase>(); 296 return new List<InventoryItemBase>();
196 297
197 return base.GetFolderItems(principalID, folderID); 298 return base.GetFolderItems(principalID, folderID);
@@ -199,52 +300,40 @@ namespace OpenSim.Services.HypergridService
199 300
200 public override bool AddFolder(InventoryFolderBase folder) 301 public override bool AddFolder(InventoryFolderBase folder)
201 { 302 {
303 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder {0} {1}", folder.Name, folder.ParentID);
202 // Let's do a bit of sanity checking, more than the base service does 304 // Let's do a bit of sanity checking, more than the base service does
203 // make sure the given folder's parent folder exists under the suitcase tree of this user 305 // make sure the given folder's parent folder exists under the suitcase tree of this user
204 XInventoryFolder root = GetRootXFolder(folder.Owner);
205 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); 306 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
206 307
207 if (!IsWithinSuitcaseTree(folder.ParentID, root, suitcase)) 308 if (!IsWithinSuitcaseTree(folder.ParentID, suitcase))
208 return false; 309 return false;
209 310
210 // OK, it's legit 311 // OK, it's legit
211 // Check if it's under the Root folder directly
212 if (folder.ParentID == root.folderID)
213 {
214 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
215 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder for root folder for user {0}. Adding in suitcase instead", folder.Owner);
216 folder.ParentID = suitcase.folderID;
217 }
218
219 return base.AddFolder(folder); 312 return base.AddFolder(folder);
220 } 313 }
221 314
222 public bool UpdateFolder(InventoryFolderBase folder) 315 public override bool UpdateFolder(InventoryFolderBase folder)
223 { 316 {
224 XInventoryFolder root = GetRootXFolder(folder.Owner);
225 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); 317 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
226 318
227 if (!IsWithinSuitcaseTree(folder.ID, root, suitcase)) 319 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Update folder {0}, version {1}", folder.ID, folder.Version);
320 if (!IsWithinSuitcaseTree(folder.ID, suitcase))
321 {
322 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: folder {0} not within Suitcase tree", folder.Name);
228 return false; 323 return false;
324 }
229 325
326 // For all others
230 return base.UpdateFolder(folder); 327 return base.UpdateFolder(folder);
231 } 328 }
232 329
233 public override bool MoveFolder(InventoryFolderBase folder) 330 public override bool MoveFolder(InventoryFolderBase folder)
234 { 331 {
235 XInventoryFolder root = GetRootXFolder(folder.Owner);
236 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); 332 XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
237 333
238 if (!IsWithinSuitcaseTree(folder.ID, root, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, root, suitcase)) 334 if (!IsWithinSuitcaseTree(folder.ID, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, suitcase))
239 return false; 335 return false;
240 336
241 if (folder.ParentID == root.folderID)
242 {
243 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
244 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveFolder to root folder for user {0}. Moving it to suitcase instead", folder.Owner);
245 folder.ParentID = suitcase.folderID;
246 }
247
248 return base.MoveFolder(folder); 337 return base.MoveFolder(folder);
249 } 338 }
250 339
@@ -264,31 +353,21 @@ namespace OpenSim.Services.HypergridService
264 { 353 {
265 // Let's do a bit of sanity checking, more than the base service does 354 // Let's do a bit of sanity checking, more than the base service does
266 // make sure the given folder's parent folder exists under the suitcase tree of this user 355 // make sure the given folder's parent folder exists under the suitcase tree of this user
267 XInventoryFolder root = GetRootXFolder(item.Owner);
268 XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner); 356 XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner);
269 357
270 if (!IsWithinSuitcaseTree(item.Folder, root, suitcase)) 358 if (!IsWithinSuitcaseTree(item.Folder, suitcase))
271 return false; 359 return false;
272 360
273 // OK, it's legit 361 // OK, it's legit
274 // Check if it's under the Root folder directly
275 if (item.Folder == root.folderID)
276 {
277 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
278 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddItem for root folder for user {0}. Adding in suitcase instead", item.Owner);
279 item.Folder = suitcase.folderID;
280 }
281
282 return base.AddItem(item); 362 return base.AddItem(item);
283 363
284 } 364 }
285 365
286 public override bool UpdateItem(InventoryItemBase item) 366 public override bool UpdateItem(InventoryItemBase item)
287 { 367 {
288 XInventoryFolder root = GetRootXFolder(item.Owner);
289 XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner); 368 XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner);
290 369
291 if (!IsWithinSuitcaseTree(item.Folder, root, suitcase)) 370 if (!IsWithinSuitcaseTree(item.Folder, suitcase))
292 return false; 371 return false;
293 372
294 return base.UpdateItem(item); 373 return base.UpdateItem(item);
@@ -298,68 +377,64 @@ namespace OpenSim.Services.HypergridService
298 { 377 {
299 // Principal is b0rked. *sigh* 378 // Principal is b0rked. *sigh*
300 379
301 XInventoryFolder root = GetRootXFolder(items[0].Owner);
302 XInventoryFolder suitcase = GetSuitcaseXFolder(items[0].Owner); 380 XInventoryFolder suitcase = GetSuitcaseXFolder(items[0].Owner);
303 381
304 if (!IsWithinSuitcaseTree(items[0].Folder, root, suitcase)) 382 if (!IsWithinSuitcaseTree(items[0].Folder, suitcase))
305 return false; 383 return false;
306 384
307 foreach (InventoryItemBase it in items)
308 if (it.Folder == root.folderID)
309 {
310 // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
311 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveItem to root folder for user {0}. Moving it to suitcase instead", it.Owner);
312 it.Folder = suitcase.folderID;
313 }
314
315 return base.MoveItems(principalID, items); 385 return base.MoveItems(principalID, items);
316 386
317 } 387 }
318 388
319 // Let these pass. Use inherited methods.
320 public override bool DeleteItems(UUID principalID, List<UUID> itemIDs) 389 public override bool DeleteItems(UUID principalID, List<UUID> itemIDs)
321 { 390 {
322 return false; 391 return false;
323 } 392 }
324 393
325 public override InventoryItemBase GetItem(InventoryItemBase item) 394 public new InventoryItemBase GetItem(InventoryItemBase item)
326 { 395 {
327 InventoryItemBase it = base.GetItem(item); 396 InventoryItemBase it = base.GetItem(item);
328 XInventoryFolder root = GetRootXFolder(it.Owner); 397 if (it == null)
398 {
399 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve item {0} ({1}) in folder {2}",
400 item.Name, item.ID, item.Folder);
401 return null;
402 }
329 XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner); 403 XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner);
330 404 if (suitcase == null)
331 if (it != null)
332 { 405 {
333 if (!IsWithinSuitcaseTree(it.Folder, root, suitcase)) 406 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Root or Suitcase are null for user {0}",
334 return null; 407 it.Owner);
408 return null;
409 }
335 410
336 if (it.Folder == suitcase.folderID) 411 if (!IsWithinSuitcaseTree(it.Folder, suitcase))
337 it.Folder = root.folderID; 412 {
413 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Item {0} (folder {1}) is not within Suitcase",
414 it.Name, it.Folder);
415 return null;
416 }
338 417
339 // UserAccount user = m_Cache.GetUser(it.CreatorId); 418 // UserAccount user = m_Cache.GetUser(it.CreatorId);
340 419
341 // // Adjust the creator data 420 // // Adjust the creator data
342 // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) 421 // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty))
343 // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName; 422 // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName;
344 //} 423 //}
345 }
346 424
347 return it; 425 return it;
348 } 426 }
349 427
350 public override InventoryFolderBase GetFolder(InventoryFolderBase folder) 428 public new InventoryFolderBase GetFolder(InventoryFolderBase folder)
351 { 429 {
352 InventoryFolderBase f = base.GetFolder(folder); 430 InventoryFolderBase f = base.GetFolder(folder);
353 XInventoryFolder root = GetRootXFolder(f.Owner);
354 XInventoryFolder suitcase = GetSuitcaseXFolder(f.Owner);
355 431
356 if (f != null) 432 if (f != null)
357 { 433 {
358 if (!IsWithinSuitcaseTree(f.ID, root, suitcase)) 434 XInventoryFolder suitcase = GetSuitcaseXFolder(f.Owner);
359 return null;
360 435
361 if (f.ParentID == suitcase.folderID) 436 if (!IsWithinSuitcaseTree(f.ID, suitcase))
362 f.ParentID = root.folderID; 437 return null;
363 } 438 }
364 439
365 return f; 440 return f;
@@ -409,20 +484,19 @@ namespace OpenSim.Services.HypergridService
409 return null; 484 return null;
410 } 485 }
411 486
412 private void SetAsRootFolder(XInventoryFolder suitcase, UUID rootID) 487 private void SetAsRootFolder(XInventoryFolder suitcase, XInventoryFolder root)
413 { 488 {
414 suitcase.folderID = rootID; 489 suitcase.type = (short)AssetType.Folder;
415 suitcase.parentFolderID = UUID.Zero;
416 } 490 }
417 491
418 private List<XInventoryFolder> GetFolderTree(UUID root) 492 private List<XInventoryFolder> GetFolderTree(UUID folder)
419 { 493 {
420 List<XInventoryFolder> t = null; 494 List<XInventoryFolder> t = null;
421 if (m_SuitcaseTrees.TryGetValue(root, out t)) 495 if (m_SuitcaseTrees.TryGetValue(folder, out t))
422 return t; 496 return t;
423 497
424 t = GetFolderTreeRecursive(root); 498 t = GetFolderTreeRecursive(folder);
425 m_SuitcaseTrees.AddOrUpdate(root, t, 120); 499 m_SuitcaseTrees.AddOrUpdate(folder, t, 120);
426 return t; 500 return t;
427 } 501 }
428 502
@@ -447,10 +521,17 @@ namespace OpenSim.Services.HypergridService
447 521
448 } 522 }
449 523
450 private bool IsWithinSuitcaseTree(UUID folderID, XInventoryFolder root, XInventoryFolder suitcase) 524 /// <summary>
525 /// Return true if the folderID is a subfolder of the Suitcase or the suitcase folder itself
526 /// </summary>
527 /// <param name="folderID"></param>
528 /// <param name="root"></param>
529 /// <param name="suitcase"></param>
530 /// <returns></returns>
531 private bool IsWithinSuitcaseTree(UUID folderID, XInventoryFolder suitcase)
451 { 532 {
452 List<XInventoryFolder> tree = new List<XInventoryFolder>(); 533 List<XInventoryFolder> tree = new List<XInventoryFolder>();
453 tree.Add(root); // Warp! the tree is the real root folder plus the children of the suitcase folder 534 tree.Add(suitcase); // Warp! the tree is the real root folder plus the children of the suitcase folder
454 tree.AddRange(GetFolderTree(suitcase.folderID)); 535 tree.AddRange(GetFolderTree(suitcase.folderID));
455 XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl) 536 XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl)
456 { 537 {
@@ -463,4 +544,5 @@ namespace OpenSim.Services.HypergridService
463 } 544 }
464 #endregion 545 #endregion
465 } 546 }
547
466} 548}
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 7b2c3a6..0e7a358 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService
40{ 40{
41 public class XInventoryService : ServiceBase, IInventoryService 41 public class XInventoryService : ServiceBase, IInventoryService
42 { 42 {
43// private static readonly ILog m_log = 43 private static readonly ILog m_log =
44// LogManager.GetLogger( 44 LogManager.GetLogger(
45// MethodBase.GetCurrentMethod().DeclaringType); 45 MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 protected IXInventoryData m_Database; 47 protected IXInventoryData m_Database;
48 protected bool m_AllowDelete = true; 48 protected bool m_AllowDelete = true;
@@ -113,7 +113,7 @@ namespace OpenSim.Services.InventoryService
113 result = true; 113 result = true;
114 } 114 }
115 115
116 XInventoryFolder[] sysFolders = GetSystemFolders(principalID); 116 XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootFolder.ID);
117 117
118 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Animation) return true; return false; })) 118 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Animation) return true; return false; }))
119 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Animation, "Animations"); 119 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Animation, "Animations");
@@ -163,13 +163,13 @@ namespace OpenSim.Services.InventoryService
163 return newFolder; 163 return newFolder;
164 } 164 }
165 165
166 protected virtual XInventoryFolder[] GetSystemFolders(UUID principalID) 166 protected virtual XInventoryFolder[] GetSystemFolders(UUID principalID, UUID rootID)
167 { 167 {
168// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting system folders for {0}", principalID); 168// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting system folders for {0}", principalID);
169 169
170 XInventoryFolder[] allFolders = m_Database.GetFolders( 170 XInventoryFolder[] allFolders = m_Database.GetFolders(
171 new string[] { "agentID" }, 171 new string[] { "agentID", "parentFolderID" },
172 new string[] { principalID.ToString() }); 172 new string[] { principalID.ToString(), rootID.ToString() });
173 173
174 XInventoryFolder[] sysFolders = Array.FindAll( 174 XInventoryFolder[] sysFolders = Array.FindAll(
175 allFolders, 175 allFolders,
@@ -301,16 +301,26 @@ namespace OpenSim.Services.InventoryService
301 301
302 public virtual bool AddFolder(InventoryFolderBase folder) 302 public virtual bool AddFolder(InventoryFolderBase folder)
303 { 303 {
304 //m_log.DebugFormat("[XINVENTORY]: Add folder {0} type {1} in parent {2}", folder.Name, folder.Type, folder.ParentID);
304 InventoryFolderBase check = GetFolder(folder); 305 InventoryFolderBase check = GetFolder(folder);
305 if (check != null) 306 if (check != null)
306 return false; 307 return false;
307 308
308 XInventoryFolder xFolder = ConvertFromOpenSim(folder); 309 if (folder.Type == (short)AssetType.Folder || folder.Type == (short)AssetType.Unknown ||
309 return m_Database.StoreFolder(xFolder); 310 GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null)
311 {
312 XInventoryFolder xFolder = ConvertFromOpenSim(folder);
313 return m_Database.StoreFolder(xFolder);
314 }
315 else
316 m_log.DebugFormat("[XINVENTORY]: Folder {0} of type {1} already exists", folder.Name, folder.Type);
317
318 return false;
310 } 319 }
311 320
312 public virtual bool UpdateFolder(InventoryFolderBase folder) 321 public virtual bool UpdateFolder(InventoryFolderBase folder)
313 { 322 {
323 //m_log.DebugFormat("[XINVENTORY]: Update folder {0} {1} ({2})", folder.Name, folder.Type, folder.ID);
314 XInventoryFolder xFolder = ConvertFromOpenSim(folder); 324 XInventoryFolder xFolder = ConvertFromOpenSim(folder);
315 InventoryFolderBase check = GetFolder(folder); 325 InventoryFolderBase check = GetFolder(folder);
316 if (check == null) 326 if (check == null)
@@ -319,9 +329,13 @@ namespace OpenSim.Services.InventoryService
319 if (check.Type != -1 || xFolder.type != -1) 329 if (check.Type != -1 || xFolder.type != -1)
320 { 330 {
321 if (xFolder.version < check.Version) 331 if (xFolder.version < check.Version)
332 {
333 //m_log.DebugFormat("[XINVENTORY]: {0} < {1} can't do", xFolder.version, check.Version);
322 return false; 334 return false;
335 }
323 check.Version = (ushort)xFolder.version; 336 check.Version = (ushort)xFolder.version;
324 xFolder = ConvertFromOpenSim(check); 337 xFolder = ConvertFromOpenSim(check);
338 //m_log.DebugFormat("[XINVENTORY]: Storing {0} {1} {2}", xFolder.folderName, xFolder.version, xFolder.type);
325 return m_Database.StoreFolder(xFolder); 339 return m_Database.StoreFolder(xFolder);
326 } 340 }
327 341
@@ -499,13 +513,30 @@ namespace OpenSim.Services.InventoryService
499 return m_Database.GetAssetPermissions(principalID, assetID); 513 return m_Database.GetAssetPermissions(principalID, assetID);
500 } 514 }
501 515
502 // CM never needed those. Left unimplemented. 516 public virtual InventoryCollection GetUserInventory(UUID userID)
503 // Obsolete in core
504 //
505 public InventoryCollection GetUserInventory(UUID userID)
506 { 517 {
507 return null; 518 InventoryCollection userInventory = new InventoryCollection();
519 userInventory.UserID = userID;
520 userInventory.Folders = new List<InventoryFolderBase>();
521 userInventory.Items = new List<InventoryItemBase>();
522
523 List<InventoryFolderBase> skel = GetInventorySkeleton(userID);
524 if (skel != null)
525 {
526 foreach (InventoryFolderBase f in skel)
527 {
528 InventoryCollection c = GetFolderContent(userID, f.ID);
529 if (c != null && c.Items != null && c.Items.Count > 0)
530 userInventory.Items.AddRange(c.Items);
531 if (c != null && c.Folders != null && c.Folders.Count > 0)
532 userInventory.Folders.AddRange(c.Folders);
533 }
534 }
535 m_log.DebugFormat("[XINVENTORY SERVICE]: GetUserInventory for user {0} returning {1} folders and {2} items",
536 userID, userInventory.Folders.Count, userInventory.Items.Count);
537 return userInventory;
508 } 538 }
539
509 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) 540 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
510 { 541 {
511 } 542 }
@@ -525,6 +556,9 @@ namespace OpenSim.Services.InventoryService
525 556
526 newFolder.ParentID = folder.parentFolderID; 557 newFolder.ParentID = folder.parentFolderID;
527 newFolder.Type = (short)folder.type; 558 newFolder.Type = (short)folder.type;
559 // Viewer can't understand anything that's not in it's LLFolderType enum
560 if (newFolder.Type == 100)
561 newFolder.Type = -1;
528 newFolder.Version = (ushort)folder.version; 562 newFolder.Version = (ushort)folder.version;
529 newFolder.Name = folder.folderName; 563 newFolder.Name = folder.folderName;
530 newFolder.Owner = folder.agentID; 564 newFolder.Owner = folder.agentID;