aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/InventoryServiceBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Communications/InventoryServiceBase.cs')
-rw-r--r--OpenSim/Framework/Communications/InventoryServiceBase.cs255
1 files changed, 54 insertions, 201 deletions
diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs
index 6283b60..da7a0ce 100644
--- a/OpenSim/Framework/Communications/InventoryServiceBase.cs
+++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs
@@ -1,9 +1,4 @@
1using System; 1using System;
2using System.Text;
3using System.IO;
4using System.Xml;
5using System.Xml.Serialization;
6using System.Collections;
7using System.Collections.Generic; 2using System.Collections.Generic;
8using System.Reflection; 3using System.Reflection;
9using libsecondlife; 4using libsecondlife;
@@ -11,20 +6,21 @@ using OpenSim.Framework.Communications;
11using OpenSim.Framework.Console; 6using OpenSim.Framework.Console;
12using OpenSim.Framework.Data; 7using OpenSim.Framework.Data;
13using InventoryFolder=OpenSim.Framework.Communications.Caches.InventoryFolder; 8using InventoryFolder=OpenSim.Framework.Communications.Caches.InventoryFolder;
14using InventoryCategory = OpenSim.Framework.Data.InventoryCategory;
15 9
16namespace OpenSim.Framework.Communications 10namespace OpenSim.Framework.Communications
17{ 11{
18 public abstract class InventoryServiceBase : MarshalByRefObject, IInventoryServices 12 public abstract class InventoryServiceBase : IInventoryServices
19 { 13 {
20 protected IInventoryData _databasePlugin; 14 protected Dictionary<string, IInventoryData> m_plugins = new Dictionary<string, IInventoryData>();
15 //protected IAssetServer m_assetServer;
21 16
22 public InventoryServiceBase() 17 public InventoryServiceBase()
23 { 18 {
19 //m_assetServer = assetServer;
24 } 20 }
25 21
26 /// <summary> 22 /// <summary>
27 /// Adds a new inventory data server plugin 23 /// Adds a new user server plugin - plugins will be requested in the order they were loaded.
28 /// </summary> 24 /// </summary>
29 /// <param name="FileName">The filename to the user server plugin DLL</param> 25 /// <param name="FileName">The filename to the user server plugin DLL</param>
30 public void AddPlugin(string FileName) 26 public void AddPlugin(string FileName)
@@ -45,13 +41,8 @@ namespace OpenSim.Framework.Communications
45 IInventoryData plug = 41 IInventoryData plug =
46 (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); 42 (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
47 plug.Initialise(); 43 plug.Initialise();
48 this._databasePlugin = plug; 44 this.m_plugins.Add(plug.getName(), plug);
49
50 //TODO! find a better place to create inventory skeletons
51 loadInventoryFromXmlFile(InventoryCategory.Library, "Inventory_Library.xml");
52 loadInventoryFromXmlFile(InventoryCategory.Default, "Inventory_Default.xml");
53 MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface"); 45 MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface");
54 break;
55 } 46 }
56 } 47 }
57 } 48 }
@@ -63,20 +54,20 @@ namespace OpenSim.Framework.Communications
63 /// </summary> 54 /// </summary>
64 /// <param name="userID"></param> 55 /// <param name="userID"></param>
65 /// <returns></returns> 56 /// <returns></returns>
66 public List<InventoryFolderBase> RequestFirstLevelFolders(LLUUID folderID) 57 public List<InventoryFolderBase> RequestFirstLevelFolders(LLUUID userID)
67 { 58 {
68 InventoryFolderBase root = _databasePlugin.getInventoryFolder(folderID); 59 List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>();
69 60 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
70 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
71 if (root != null)
72 { 61 {
73 folders.Add(root); 62 InventoryFolderBase rootFolder = plugin.Value.getUserRootFolder(userID);
74 63 if (rootFolder != null)
75 List<InventoryFolderBase> subFolders = _databasePlugin.getInventoryFolders(root.folderID); 64 {
76 foreach (InventoryFolderBase f in subFolders) 65 inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID);
77 folders.Add(f); 66 inventoryList.Insert(0, rootFolder);
67 return inventoryList;
68 }
78 } 69 }
79 return folders; 70 return inventoryList;
80 } 71 }
81 72
82 /// <summary> 73 /// <summary>
@@ -84,7 +75,11 @@ namespace OpenSim.Framework.Communications
84 /// </summary> 75 /// </summary>
85 public InventoryFolderBase RequestUsersRoot(LLUUID userID) 76 public InventoryFolderBase RequestUsersRoot(LLUUID userID)
86 { 77 {
87 return _databasePlugin.getInventoryFolder(userID); // the id of the root folder, is the user id 78 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
79 {
80 return plugin.Value.getUserRootFolder(userID);
81 }
82 return null;
88 } 83 }
89 84
90 /// <summary> 85 /// <summary>
@@ -94,27 +89,47 @@ namespace OpenSim.Framework.Communications
94 /// <returns></returns> 89 /// <returns></returns>
95 public List<InventoryFolderBase> RequestSubFolders(LLUUID parentFolderID) 90 public List<InventoryFolderBase> RequestSubFolders(LLUUID parentFolderID)
96 { 91 {
97 return _databasePlugin.getInventoryFolders(parentFolderID); 92 List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>();
93 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
94 {
95 return plugin.Value.getInventoryFolders(parentFolderID);
96 }
97 return inventoryList;
98 } 98 }
99 99
100 public List<InventoryItemBase> RequestFolderItems(LLUUID folderID) 100 public List<InventoryItemBase> RequestFolderItems(LLUUID folderID)
101 { 101 {
102 return _databasePlugin.getInventoryInFolder(folderID); 102 List<InventoryItemBase> itemsList = new List<InventoryItemBase>();
103 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
104 {
105 itemsList = plugin.Value.getInventoryInFolder(folderID);
106 return itemsList;
107 }
108 return itemsList;
103 } 109 }
104 110
105 public void AddFolder(InventoryFolderBase folder) 111 public void AddFolder(InventoryFolderBase folder)
106 { 112 {
107 _databasePlugin.addInventoryFolder(folder); 113 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
114 {
115 plugin.Value.addInventoryFolder(folder);
116 }
108 } 117 }
109 118
110 public void AddItem(InventoryItemBase item) 119 public void AddItem(InventoryItemBase item)
111 { 120 {
112 _databasePlugin.addInventoryItem(item); 121 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
122 {
123 plugin.Value.addInventoryItem(item);
124 }
113 } 125 }
114 126
115 public void deleteItem(InventoryItemBase item) 127 public void deleteItem(InventoryItemBase item)
116 { 128 {
117 _databasePlugin.deleteInventoryItem(item); 129 foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
130 {
131 plugin.Value.deleteInventoryItem(item);
132 }
118 } 133 }
119 134
120 /// <summary> 135 /// <summary>
@@ -129,53 +144,11 @@ namespace OpenSim.Framework.Communications
129 } 144 }
130 } 145 }
131 146
132 public void CreateNewUserInventory(LLUUID defaultFolders, LLUUID user) 147 public void CreateNewUserInventory(LLUUID user)
133 { 148 {
134 try 149 UsersInventory inven = new UsersInventory();
135 { 150 inven.CreateNewInventorySet(user);
136 // Get Default folder set from the database 151 this.AddNewInventorySet(inven);
137 //TODO! We need to get the whole hierachy and not just one level down
138 List<InventoryFolderBase> folders = this.RequestFirstLevelFolders(LLUUID.Parse("00000112-000f-0000-0000-000100bba000"));
139
140 // create an index list, where each of the elements has the index of its parent in the hierachy
141 // this algorithm is pretty shoddy O(n^2), but it is only executed once per user.
142 int[] parentIdx = new int[folders.Count];
143 for (int i = 0; i < folders.Count; i++)
144 parentIdx[i] = -1;
145
146 for (int i = 0; i < folders.Count; i++)
147 for (int j = 0; j < folders.Count; j++)
148 if (folders[i].folderID == folders[j].parentID)
149 parentIdx[j] = i;
150
151
152 //assign a new owerid and a new to the folders
153 foreach (InventoryFolderBase ifb in folders)
154 {
155 if (ifb.parentID == LLUUID.Zero)
156 ifb.folderID = user;
157 else
158 ifb.folderID = LLUUID.Random();
159
160 ifb.agentID = user;
161 ifb.category = InventoryCategory.User;
162 }
163
164 // correct the parent id
165 for (int i = 0; i < folders.Count; i++)
166 {
167 if (folders[i].parentID != LLUUID.Zero)
168 folders[i].parentID = folders[parentIdx[i]].folderID; // root folder id is the same as the user id
169 }
170
171 // the list is structurally sound, using new folder id's, so save it
172 foreach (InventoryFolderBase ifb in folders)
173 _databasePlugin.addInventoryFolder(ifb);
174 }
175 catch (Exception e)
176 {
177 MainLog.Instance.Error(e.ToString());
178 }
179 } 152 }
180 153
181 public class UsersInventory 154 public class UsersInventory
@@ -193,11 +166,10 @@ namespace OpenSim.Framework.Communications
193 InventoryFolderBase folder = new InventoryFolderBase(); 166 InventoryFolderBase folder = new InventoryFolderBase();
194 folder.parentID = LLUUID.Zero; 167 folder.parentID = LLUUID.Zero;
195 folder.agentID = user; 168 folder.agentID = user;
196 folder.folderID = user; // id of root folder is the same as the agent id 169 folder.folderID = LLUUID.Random();
197 folder.name = "My Inventory"; 170 folder.name = "My Inventory";
198 folder.type = 8; 171 folder.type = 8;
199 folder.version = 1; 172 folder.version = 1;
200 folder.category = InventoryCategory.User;
201 Folders.Add(folder.folderID, folder); 173 Folders.Add(folder.folderID, folder);
202 174
203 LLUUID rootFolder = folder.folderID; 175 LLUUID rootFolder = folder.folderID;
@@ -209,7 +181,6 @@ namespace OpenSim.Framework.Communications
209 folder.name = "Textures"; 181 folder.name = "Textures";
210 folder.type = 0; 182 folder.type = 0;
211 folder.version = 1; 183 folder.version = 1;
212 folder.category = InventoryCategory.User;
213 Folders.Add(folder.folderID, folder); 184 Folders.Add(folder.folderID, folder);
214 185
215 folder = new InventoryFolderBase(); 186 folder = new InventoryFolderBase();
@@ -219,7 +190,6 @@ namespace OpenSim.Framework.Communications
219 folder.name = "Objects"; 190 folder.name = "Objects";
220 folder.type = 6; 191 folder.type = 6;
221 folder.version = 1; 192 folder.version = 1;
222 folder.category = InventoryCategory.User;
223 Folders.Add(folder.folderID, folder); 193 Folders.Add(folder.folderID, folder);
224 194
225 folder = new InventoryFolderBase(); 195 folder = new InventoryFolderBase();
@@ -229,130 +199,13 @@ namespace OpenSim.Framework.Communications
229 folder.name = "Clothes"; 199 folder.name = "Clothes";
230 folder.type = 5; 200 folder.type = 5;
231 folder.version = 1; 201 folder.version = 1;
232 folder.category = InventoryCategory.User;
233 Folders.Add(folder.folderID, folder); 202 Folders.Add(folder.folderID, folder);
234 } 203 }
235 } 204 }
236 205
237
238 public void GetRootFoldersForUser(LLUUID user, out LLUUID libraryFolder, out LLUUID personalFolder)
239 {
240 List<InventoryFolderBase> folders = _databasePlugin.getUserRootFolders(user);
241 libraryFolder = LLUUID.Zero;
242 personalFolder = LLUUID.Zero;
243
244 for (int i = 0; i < folders.Count; i++)
245 {
246 if (folders[i].category == InventoryCategory.Library)
247 libraryFolder = folders[i].folderID;
248 else if (folders[i].category == InventoryCategory.User)
249 personalFolder = folders[i].folderID;
250 }
251 }
252
253 /*
254 * Dot net has some issues, serializing a dictionary, so we cannot reuse the InventoryFolder
255 * class defined in Communications.Framework.Communications.Caches. So we serialize/deserialize
256 * into this simpler class, and then use that.
257 */
258 [XmlRoot(ElementName = "inventory", IsNullable = true)]
259 public class SerializedInventory
260 {
261 [XmlRoot(ElementName = "folder", IsNullable = true)]
262 public class SerializedFolder : InventoryFolderBase
263 {
264 [XmlArray(ElementName = "folders", IsNullable = true)]
265 [XmlArrayItem(ElementName = "folder", IsNullable = true, Type = typeof(SerializedFolder))]
266 public ArrayList SubFolders;
267
268 [XmlArray(ElementName = "items", IsNullable = true)]
269 [XmlArrayItem(ElementName = "item", IsNullable = true, Type = typeof(InventoryItemBase))]
270 public ArrayList Items;
271 }
272
273 [XmlElement(ElementName = "folder", IsNullable = true)]
274 public SerializedFolder root;
275 }
276
277 public void uploadInventory(SerializedInventory.SerializedFolder folder)
278 {
279 foreach (InventoryItemBase iib in folder.Items)
280 {
281 // assign default values, if they haven't assigned
282 iib.avatarID = folder.agentID;
283 if (iib.assetID == LLUUID.Zero)
284 iib.assetID = LLUUID.Random();
285 if (iib.creatorsID == LLUUID.Zero)
286 iib.creatorsID = folder.agentID;
287 if (iib.inventoryID == LLUUID.Zero)
288 iib.inventoryID = LLUUID.Random();
289 if (iib.inventoryName == null || iib.inventoryName.Length == 0)
290 iib.inventoryName = "new item";
291 iib.parentFolderID = folder.folderID;
292
293 _databasePlugin.addInventoryItem(iib);
294 }
295
296 foreach (SerializedInventory.SerializedFolder sf in folder.SubFolders)
297 {
298 // assign default values, if they haven't assigned
299 sf.agentID = folder.agentID;
300 sf.category = folder.category;
301 if (sf.folderID == LLUUID.Zero)
302 sf.folderID = LLUUID.Random();
303 if (sf.name == null || sf.name.Length == 0)
304 sf.name = "new folder";
305 sf.parentID = folder.folderID;
306
307 _databasePlugin.addInventoryFolder(sf);
308 uploadInventory(sf);
309 }
310 }
311
312 public void loadInventoryFromXmlFile(InventoryCategory inventoryCategory, string fileName)
313 {
314 _databasePlugin.deleteInventoryCategory(inventoryCategory);
315
316 FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
317 XmlReader reader = new XmlTextReader(fs);
318 XmlSerializer x = new XmlSerializer(typeof(SerializedInventory));
319 SerializedInventory inventory = (SerializedInventory)x.Deserialize(reader);
320
321 // the library and default inventories has no owner, so we use a random guid.
322 if (inventory.root.category == InventoryCategory.Library || inventory.root.category == InventoryCategory.Default)
323 {
324 if (inventory.root.folderID != LLUUID.Zero)
325 inventory.root.agentID = inventory.root.folderID;
326 else
327 inventory.root.agentID = LLUUID.Random();
328 }
329 else if (inventory.root.category == InventoryCategory.User)
330 {
331 if (inventory.root.agentID == LLUUID.Zero)
332 inventory.root.agentID = LLUUID.Random();
333 }
334
335 inventory.root.folderID = inventory.root.agentID; // the root folder always has the same id as the owning agent
336 inventory.root.parentID = LLUUID.Zero;
337 inventory.root.version = 0;
338 inventory.root.category = inventoryCategory;
339
340 _databasePlugin.addInventoryFolder(inventory.root);
341 uploadInventory(inventory.root);
342 }
343
344 protected void saveInventoryToXmlFile(SerializedInventory inventory, string fileName)
345 {
346 FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
347 XmlTextWriter writer = new XmlTextWriter(fs, Encoding.UTF8);
348 writer.Formatting = Formatting.Indented;
349 XmlSerializer x = new XmlSerializer(typeof(SerializedInventory));
350 x.Serialize(writer, inventory);
351 }
352
353 public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); 206 public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack);
354 public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder); 207 public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder);
355 public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); 208 public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item);
356 public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); 209 public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item);
357 } 210 }
358} 211} \ No newline at end of file