diff options
Diffstat (limited to 'OpenSim/Framework/Communications/InventoryServiceBase.cs')
-rw-r--r-- | OpenSim/Framework/Communications/InventoryServiceBase.cs | 255 |
1 files changed, 201 insertions, 54 deletions
diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs index da7a0ce..6283b60 100644 --- a/OpenSim/Framework/Communications/InventoryServiceBase.cs +++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs | |||
@@ -1,4 +1,9 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Text; | ||
3 | using System.IO; | ||
4 | using System.Xml; | ||
5 | using System.Xml.Serialization; | ||
6 | using System.Collections; | ||
2 | using System.Collections.Generic; | 7 | using System.Collections.Generic; |
3 | using System.Reflection; | 8 | using System.Reflection; |
4 | using libsecondlife; | 9 | using libsecondlife; |
@@ -6,21 +11,20 @@ using OpenSim.Framework.Communications; | |||
6 | using OpenSim.Framework.Console; | 11 | using OpenSim.Framework.Console; |
7 | using OpenSim.Framework.Data; | 12 | using OpenSim.Framework.Data; |
8 | using InventoryFolder=OpenSim.Framework.Communications.Caches.InventoryFolder; | 13 | using InventoryFolder=OpenSim.Framework.Communications.Caches.InventoryFolder; |
14 | using InventoryCategory = OpenSim.Framework.Data.InventoryCategory; | ||
9 | 15 | ||
10 | namespace OpenSim.Framework.Communications | 16 | namespace OpenSim.Framework.Communications |
11 | { | 17 | { |
12 | public abstract class InventoryServiceBase : IInventoryServices | 18 | public abstract class InventoryServiceBase : MarshalByRefObject, IInventoryServices |
13 | { | 19 | { |
14 | protected Dictionary<string, IInventoryData> m_plugins = new Dictionary<string, IInventoryData>(); | 20 | protected IInventoryData _databasePlugin; |
15 | //protected IAssetServer m_assetServer; | ||
16 | 21 | ||
17 | public InventoryServiceBase() | 22 | public InventoryServiceBase() |
18 | { | 23 | { |
19 | //m_assetServer = assetServer; | ||
20 | } | 24 | } |
21 | 25 | ||
22 | /// <summary> | 26 | /// <summary> |
23 | /// Adds a new user server plugin - plugins will be requested in the order they were loaded. | 27 | /// Adds a new inventory data server plugin |
24 | /// </summary> | 28 | /// </summary> |
25 | /// <param name="FileName">The filename to the user server plugin DLL</param> | 29 | /// <param name="FileName">The filename to the user server plugin DLL</param> |
26 | public void AddPlugin(string FileName) | 30 | public void AddPlugin(string FileName) |
@@ -41,8 +45,13 @@ namespace OpenSim.Framework.Communications | |||
41 | IInventoryData plug = | 45 | IInventoryData plug = |
42 | (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); | 46 | (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); |
43 | plug.Initialise(); | 47 | plug.Initialise(); |
44 | this.m_plugins.Add(plug.getName(), plug); | 48 | this._databasePlugin = 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"); | ||
45 | MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface"); | 53 | MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface"); |
54 | break; | ||
46 | } | 55 | } |
47 | } | 56 | } |
48 | } | 57 | } |
@@ -54,20 +63,20 @@ namespace OpenSim.Framework.Communications | |||
54 | /// </summary> | 63 | /// </summary> |
55 | /// <param name="userID"></param> | 64 | /// <param name="userID"></param> |
56 | /// <returns></returns> | 65 | /// <returns></returns> |
57 | public List<InventoryFolderBase> RequestFirstLevelFolders(LLUUID userID) | 66 | public List<InventoryFolderBase> RequestFirstLevelFolders(LLUUID folderID) |
58 | { | 67 | { |
59 | List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>(); | 68 | InventoryFolderBase root = _databasePlugin.getInventoryFolder(folderID); |
60 | foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) | 69 | |
70 | List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); | ||
71 | if (root != null) | ||
61 | { | 72 | { |
62 | InventoryFolderBase rootFolder = plugin.Value.getUserRootFolder(userID); | 73 | folders.Add(root); |
63 | if (rootFolder != null) | 74 | |
64 | { | 75 | List<InventoryFolderBase> subFolders = _databasePlugin.getInventoryFolders(root.folderID); |
65 | inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID); | 76 | foreach (InventoryFolderBase f in subFolders) |
66 | inventoryList.Insert(0, rootFolder); | 77 | folders.Add(f); |
67 | return inventoryList; | ||
68 | } | ||
69 | } | 78 | } |
70 | return inventoryList; | 79 | return folders; |
71 | } | 80 | } |
72 | 81 | ||
73 | /// <summary> | 82 | /// <summary> |
@@ -75,11 +84,7 @@ namespace OpenSim.Framework.Communications | |||
75 | /// </summary> | 84 | /// </summary> |
76 | public InventoryFolderBase RequestUsersRoot(LLUUID userID) | 85 | public InventoryFolderBase RequestUsersRoot(LLUUID userID) |
77 | { | 86 | { |
78 | foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) | 87 | return _databasePlugin.getInventoryFolder(userID); // the id of the root folder, is the user id |
79 | { | ||
80 | return plugin.Value.getUserRootFolder(userID); | ||
81 | } | ||
82 | return null; | ||
83 | } | 88 | } |
84 | 89 | ||
85 | /// <summary> | 90 | /// <summary> |
@@ -89,47 +94,27 @@ namespace OpenSim.Framework.Communications | |||
89 | /// <returns></returns> | 94 | /// <returns></returns> |
90 | public List<InventoryFolderBase> RequestSubFolders(LLUUID parentFolderID) | 95 | public List<InventoryFolderBase> RequestSubFolders(LLUUID parentFolderID) |
91 | { | 96 | { |
92 | List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>(); | 97 | return _databasePlugin.getInventoryFolders(parentFolderID); |
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 | List<InventoryItemBase> itemsList = new List<InventoryItemBase>(); | 102 | return _databasePlugin.getInventoryInFolder(folderID); |
103 | foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) | ||
104 | { | ||
105 | itemsList = plugin.Value.getInventoryInFolder(folderID); | ||
106 | return itemsList; | ||
107 | } | ||
108 | return itemsList; | ||
109 | } | 103 | } |
110 | 104 | ||
111 | public void AddFolder(InventoryFolderBase folder) | 105 | public void AddFolder(InventoryFolderBase folder) |
112 | { | 106 | { |
113 | foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) | 107 | _databasePlugin.addInventoryFolder(folder); |
114 | { | ||
115 | plugin.Value.addInventoryFolder(folder); | ||
116 | } | ||
117 | } | 108 | } |
118 | 109 | ||
119 | public void AddItem(InventoryItemBase item) | 110 | public void AddItem(InventoryItemBase item) |
120 | { | 111 | { |
121 | foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) | 112 | _databasePlugin.addInventoryItem(item); |
122 | { | ||
123 | plugin.Value.addInventoryItem(item); | ||
124 | } | ||
125 | } | 113 | } |
126 | 114 | ||
127 | public void deleteItem(InventoryItemBase item) | 115 | public void deleteItem(InventoryItemBase item) |
128 | { | 116 | { |
129 | foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins) | 117 | _databasePlugin.deleteInventoryItem(item); |
130 | { | ||
131 | plugin.Value.deleteInventoryItem(item); | ||
132 | } | ||
133 | } | 118 | } |
134 | 119 | ||
135 | /// <summary> | 120 | /// <summary> |
@@ -144,11 +129,53 @@ namespace OpenSim.Framework.Communications | |||
144 | } | 129 | } |
145 | } | 130 | } |
146 | 131 | ||
147 | public void CreateNewUserInventory(LLUUID user) | 132 | public void CreateNewUserInventory(LLUUID defaultFolders, LLUUID user) |
148 | { | 133 | { |
149 | UsersInventory inven = new UsersInventory(); | 134 | try |
150 | inven.CreateNewInventorySet(user); | 135 | { |
151 | this.AddNewInventorySet(inven); | 136 | // Get Default folder set from the database |
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 | } | ||
152 | } | 179 | } |
153 | 180 | ||
154 | public class UsersInventory | 181 | public class UsersInventory |
@@ -166,10 +193,11 @@ namespace OpenSim.Framework.Communications | |||
166 | InventoryFolderBase folder = new InventoryFolderBase(); | 193 | InventoryFolderBase folder = new InventoryFolderBase(); |
167 | folder.parentID = LLUUID.Zero; | 194 | folder.parentID = LLUUID.Zero; |
168 | folder.agentID = user; | 195 | folder.agentID = user; |
169 | folder.folderID = LLUUID.Random(); | 196 | folder.folderID = user; // id of root folder is the same as the agent id |
170 | folder.name = "My Inventory"; | 197 | folder.name = "My Inventory"; |
171 | folder.type = 8; | 198 | folder.type = 8; |
172 | folder.version = 1; | 199 | folder.version = 1; |
200 | folder.category = InventoryCategory.User; | ||
173 | Folders.Add(folder.folderID, folder); | 201 | Folders.Add(folder.folderID, folder); |
174 | 202 | ||
175 | LLUUID rootFolder = folder.folderID; | 203 | LLUUID rootFolder = folder.folderID; |
@@ -181,6 +209,7 @@ namespace OpenSim.Framework.Communications | |||
181 | folder.name = "Textures"; | 209 | folder.name = "Textures"; |
182 | folder.type = 0; | 210 | folder.type = 0; |
183 | folder.version = 1; | 211 | folder.version = 1; |
212 | folder.category = InventoryCategory.User; | ||
184 | Folders.Add(folder.folderID, folder); | 213 | Folders.Add(folder.folderID, folder); |
185 | 214 | ||
186 | folder = new InventoryFolderBase(); | 215 | folder = new InventoryFolderBase(); |
@@ -190,6 +219,7 @@ namespace OpenSim.Framework.Communications | |||
190 | folder.name = "Objects"; | 219 | folder.name = "Objects"; |
191 | folder.type = 6; | 220 | folder.type = 6; |
192 | folder.version = 1; | 221 | folder.version = 1; |
222 | folder.category = InventoryCategory.User; | ||
193 | Folders.Add(folder.folderID, folder); | 223 | Folders.Add(folder.folderID, folder); |
194 | 224 | ||
195 | folder = new InventoryFolderBase(); | 225 | folder = new InventoryFolderBase(); |
@@ -199,13 +229,130 @@ namespace OpenSim.Framework.Communications | |||
199 | folder.name = "Clothes"; | 229 | folder.name = "Clothes"; |
200 | folder.type = 5; | 230 | folder.type = 5; |
201 | folder.version = 1; | 231 | folder.version = 1; |
232 | folder.category = InventoryCategory.User; | ||
202 | Folders.Add(folder.folderID, folder); | 233 | Folders.Add(folder.folderID, folder); |
203 | } | 234 | } |
204 | } | 235 | } |
205 | 236 | ||
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 | |||
206 | public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); | 353 | public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); |
207 | public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder); | 354 | public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder); |
208 | public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); | 355 | public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); |
209 | public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); | 356 | public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); |
210 | } | 357 | } |
211 | } \ No newline at end of file | 358 | } |