diff options
author | Mike Mazur | 2009-02-16 02:26:27 +0000 |
---|---|---|
committer | Mike Mazur | 2009-02-16 02:26:27 +0000 |
commit | 74a2bd237aed26b49d88045fe6afa526ed19c00d (patch) | |
tree | c72262c4343a6b95b8aa20616094e1b0fbc640a4 /OpenSim/Grid/AssetInventoryServer/Plugins | |
parent | - added Simple AssetInventoryServer plugin (asset storage only) (diff) | |
download | opensim-SC_OLD-74a2bd237aed26b49d88045fe6afa526ed19c00d.zip opensim-SC_OLD-74a2bd237aed26b49d88045fe6afa526ed19c00d.tar.gz opensim-SC_OLD-74a2bd237aed26b49d88045fe6afa526ed19c00d.tar.bz2 opensim-SC_OLD-74a2bd237aed26b49d88045fe6afa526ed19c00d.tar.xz |
Add OpenSim & Simple inventory storage plugins and Null metrics plugin.
Diffstat (limited to 'OpenSim/Grid/AssetInventoryServer/Plugins')
-rw-r--r-- | OpenSim/Grid/AssetInventoryServer/Plugins/NullMetricsPlugin.cs (renamed from OpenSim/Grid/AssetInventoryServer/Plugins/NullMetrics.cs) | 4 | ||||
-rw-r--r-- | OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryStoragePlugin.cs | 835 | ||||
-rw-r--r-- | OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml | 3 | ||||
-rw-r--r-- | OpenSim/Grid/AssetInventoryServer/Plugins/Resources/AssetInventoryServerPlugins.addin.xml | 2 | ||||
-rw-r--r-- | OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml | 3 | ||||
-rw-r--r-- | OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleInventoryStoragePlugin.cs | 627 |
6 files changed, 1471 insertions, 3 deletions
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/NullMetrics.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/NullMetricsPlugin.cs index 86ae5cd..caa4efd 100644 --- a/OpenSim/Grid/AssetInventoryServer/Plugins/NullMetrics.cs +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/NullMetricsPlugin.cs | |||
@@ -32,11 +32,11 @@ using OpenMetaverse; | |||
32 | 32 | ||
33 | namespace OpenSim.Grid.AssetInventoryServer.Plugins | 33 | namespace OpenSim.Grid.AssetInventoryServer.Plugins |
34 | { | 34 | { |
35 | public class NullMetrics : IMetricsProvider | 35 | public class NullMetricsPlugin : IMetricsProvider |
36 | { | 36 | { |
37 | AssetInventoryServer server; | 37 | AssetInventoryServer server; |
38 | 38 | ||
39 | public NullMetrics() | 39 | public NullMetricsPlugin() |
40 | { | 40 | { |
41 | } | 41 | } |
42 | 42 | ||
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryStoragePlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryStoragePlugin.cs new file mode 100644 index 0000000..3fd06c0 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/OpenSimInventoryStoragePlugin.cs | |||
@@ -0,0 +1,835 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Intel Corporation | ||
3 | * All rights reserved. | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * -- Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * -- Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * -- Neither the name of the Intel Corporation nor the names of its | ||
14 | * contributors may be used to endorse or promote products derived from | ||
15 | * this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
20 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS | ||
21 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Net; | ||
33 | using System.Data; | ||
34 | using MySql.Data.MySqlClient; | ||
35 | using ExtensionLoader; | ||
36 | using ExtensionLoader.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenMetaverse.StructuredData; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Grid.AssetInventoryServer.Extensions; | ||
41 | using OpenSim.Data; | ||
42 | |||
43 | namespace OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim | ||
44 | { | ||
45 | public class OpenSimInventoryStoragePlugin : IInventoryStorageProvider | ||
46 | { | ||
47 | const string EXTENSION_NAME = "OpenSimInventoryStorage"; // Used in metrics reporting | ||
48 | |||
49 | private AssetInventoryServer server; | ||
50 | private IInventoryDataPlugin m_inventoryProvider; | ||
51 | |||
52 | public OpenSimInventoryStoragePlugin() | ||
53 | { | ||
54 | } | ||
55 | |||
56 | #region Required Interfaces | ||
57 | |||
58 | public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item) | ||
59 | { | ||
60 | item = null; | ||
61 | BackendResponse ret; | ||
62 | |||
63 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
64 | { | ||
65 | IDataReader reader; | ||
66 | |||
67 | try | ||
68 | { | ||
69 | dbConnection.Open(); | ||
70 | |||
71 | IDbCommand command = dbConnection.CreateCommand(); | ||
72 | command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + | ||
73 | "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + | ||
74 | "creationDate,groupID,groupOwned,flags,avatarID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE inventoryID='{0}'", | ||
75 | itemID.ToString()); | ||
76 | reader = command.ExecuteReader(); | ||
77 | |||
78 | if (reader.Read()) | ||
79 | { | ||
80 | item = new InventoryItem(); | ||
81 | item.ID = itemID; | ||
82 | item.AssetID = UUID.Parse(reader.GetString(0)); | ||
83 | item.AssetType = reader.GetInt32(1); | ||
84 | item.Name = reader.GetString(2); | ||
85 | item.Description = reader.GetString(3); | ||
86 | item.NextPermissions = (uint)reader.GetInt32(4); | ||
87 | item.CurrentPermissions = (uint)reader.GetInt32(5); | ||
88 | item.InvType = reader.GetInt32(6); | ||
89 | item.Creator = UUID.Parse(reader.GetString(7)); | ||
90 | item.BasePermissions = (uint)reader.GetInt32(8); | ||
91 | item.EveryOnePermissions = (uint)reader.GetInt32(9); | ||
92 | item.SalePrice = reader.GetInt32(10); | ||
93 | item.SaleType = reader.GetByte(11); | ||
94 | item.CreationDate = reader.GetInt32(12); | ||
95 | item.GroupID = UUID.Parse(reader.GetString(13)); | ||
96 | item.GroupOwned = reader.GetBoolean(14); | ||
97 | item.Flags = (uint)reader.GetInt32(15); | ||
98 | item.Owner = UUID.Parse(reader.GetString(16)); | ||
99 | item.Folder = UUID.Parse(reader.GetString(17)); | ||
100 | item.GroupPermissions = (uint)reader.GetInt32(18); | ||
101 | |||
102 | ret = BackendResponse.Success; | ||
103 | } | ||
104 | else | ||
105 | { | ||
106 | ret = BackendResponse.NotFound; | ||
107 | } | ||
108 | } | ||
109 | catch (MySqlException ex) | ||
110 | { | ||
111 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
112 | ret = BackendResponse.Failure; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); | ||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder) | ||
121 | { | ||
122 | folder = null; | ||
123 | BackendResponse ret; | ||
124 | |||
125 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
126 | { | ||
127 | IDataReader reader; | ||
128 | |||
129 | try | ||
130 | { | ||
131 | dbConnection.Open(); | ||
132 | |||
133 | IDbCommand command = dbConnection.CreateCommand(); | ||
134 | command.CommandText = String.Format("SELECT folderName,type,version,agentID,parentFolderID FROM inventoryfolders WHERE folderID='{0}'", | ||
135 | folderID.ToString()); | ||
136 | reader = command.ExecuteReader(); | ||
137 | |||
138 | if (reader.Read()) | ||
139 | { | ||
140 | folder = new InventoryFolder(); | ||
141 | folder.Children = null; // This call only returns data for the folder itself, no children data | ||
142 | folder.ID = folderID; | ||
143 | folder.Name = reader.GetString(0); | ||
144 | folder.Type = reader.GetInt16(1); | ||
145 | folder.Version = (ushort)reader.GetInt16(2); | ||
146 | folder.Owner = UUID.Parse(reader.GetString(3)); | ||
147 | folder.ParentID = UUID.Parse(reader.GetString(4)); | ||
148 | |||
149 | ret = BackendResponse.Success; | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | ret = BackendResponse.NotFound; | ||
154 | } | ||
155 | } | ||
156 | catch (MySqlException ex) | ||
157 | { | ||
158 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
159 | ret = BackendResponse.Failure; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents) | ||
168 | { | ||
169 | contents = null; | ||
170 | BackendResponse ret; | ||
171 | |||
172 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
173 | { | ||
174 | IDataReader reader; | ||
175 | |||
176 | try | ||
177 | { | ||
178 | dbConnection.Open(); | ||
179 | |||
180 | contents = new InventoryCollection(); | ||
181 | |||
182 | #region Folder retrieval | ||
183 | |||
184 | IDbCommand command = dbConnection.CreateCommand(); | ||
185 | command.CommandText = String.Format("SELECT folderName,type,version,agentID,folderID FROM inventoryfolders WHERE parentFolderID='{0}'", | ||
186 | folderID.ToString()); | ||
187 | reader = command.ExecuteReader(); | ||
188 | |||
189 | contents.Folders = new Dictionary<UUID, InventoryFolder>(); | ||
190 | |||
191 | while (reader.Read()) | ||
192 | { | ||
193 | InventoryFolder folder = new InventoryFolder(); | ||
194 | folder.ParentID = folderID; | ||
195 | folder.Children = null; // This call doesn't do recursion | ||
196 | folder.Name = reader.GetString(0); | ||
197 | folder.Type = reader.GetInt16(1); | ||
198 | folder.Version = (ushort)reader.GetInt16(2); | ||
199 | folder.Owner = UUID.Parse(reader.GetString(3)); | ||
200 | folder.ID = UUID.Parse(reader.GetString(4)); | ||
201 | |||
202 | contents.Folders.Add(folder.ID, folder); | ||
203 | contents.UserID = folder.Owner; | ||
204 | } | ||
205 | |||
206 | reader.Close(); | ||
207 | |||
208 | #endregion Folder retrieval | ||
209 | |||
210 | #region Item retrieval | ||
211 | |||
212 | command = dbConnection.CreateCommand(); | ||
213 | command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + | ||
214 | "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + | ||
215 | "creationDate,groupID,groupOwned,flags,avatarID,inventoryID,inventoryGroupPermissions FROM inventoryitems WHERE parentFolderID='{0}'", | ||
216 | folderID.ToString()); | ||
217 | reader = command.ExecuteReader(); | ||
218 | |||
219 | contents.Items = new Dictionary<UUID, InventoryItem>(); | ||
220 | |||
221 | while (reader.Read()) | ||
222 | { | ||
223 | InventoryItem item = new InventoryItem(); | ||
224 | item.Folder = folderID; | ||
225 | item.AssetID = UUID.Parse(reader.GetString(0)); | ||
226 | item.AssetType = reader.GetInt32(1); | ||
227 | item.Name = reader.GetString(2); | ||
228 | item.Description = reader.GetString(3); | ||
229 | item.NextPermissions = (uint)reader.GetInt32(4); | ||
230 | item.CurrentPermissions = (uint)reader.GetInt32(5); | ||
231 | item.InvType = reader.GetInt32(6); | ||
232 | item.Creator = UUID.Parse(reader.GetString(7)); | ||
233 | item.BasePermissions = (uint)reader.GetInt32(8); | ||
234 | item.EveryOnePermissions = (uint)reader.GetInt32(9); | ||
235 | item.SalePrice = reader.GetInt32(10); | ||
236 | item.SaleType = reader.GetByte(11); | ||
237 | item.CreationDate = reader.GetInt32(12); | ||
238 | item.GroupID = UUID.Parse(reader.GetString(13)); | ||
239 | item.GroupOwned = reader.GetBoolean(14); | ||
240 | item.Flags = (uint)reader.GetInt32(15); | ||
241 | item.Owner = UUID.Parse(reader.GetString(16)); | ||
242 | item.ID = UUID.Parse(reader.GetString(17)); | ||
243 | item.GroupPermissions = (uint)reader.GetInt32(18); | ||
244 | |||
245 | contents.Items.Add(item.ID, item); | ||
246 | contents.UserID = item.Owner; | ||
247 | } | ||
248 | |||
249 | #endregion Item retrieval | ||
250 | |||
251 | ret = BackendResponse.Success; | ||
252 | } | ||
253 | catch (MySqlException ex) | ||
254 | { | ||
255 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
256 | ret = BackendResponse.Failure; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); | ||
261 | return ret; | ||
262 | } | ||
263 | |||
264 | public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders) | ||
265 | { | ||
266 | folders = null; | ||
267 | BackendResponse ret; | ||
268 | UUID ownerID; | ||
269 | |||
270 | if (Utils.TryGetOpenSimUUID(owner, out ownerID)) | ||
271 | { | ||
272 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
273 | { | ||
274 | IDataReader reader; | ||
275 | |||
276 | try | ||
277 | { | ||
278 | dbConnection.Open(); | ||
279 | folders = new List<InventoryFolder>(); | ||
280 | |||
281 | IDbCommand command = dbConnection.CreateCommand(); | ||
282 | command.CommandText = String.Format("SELECT folderName,type,version,folderID,parentFolderID FROM inventoryfolders WHERE agentID='{0}'", | ||
283 | ownerID.ToString()); | ||
284 | reader = command.ExecuteReader(); | ||
285 | |||
286 | while (reader.Read()) | ||
287 | { | ||
288 | InventoryFolder folder = new InventoryFolder(); | ||
289 | folder.Owner = ownerID; | ||
290 | folder.Children = null; // This call does not create a folder hierarchy | ||
291 | folder.Name = reader.GetString(0); | ||
292 | folder.Type = reader.GetInt16(1); | ||
293 | folder.Version = (ushort)reader.GetInt16(2); | ||
294 | folder.ID = UUID.Parse(reader.GetString(3)); | ||
295 | folder.ParentID = UUID.Parse(reader.GetString(4)); | ||
296 | |||
297 | folders.Add(folder); | ||
298 | } | ||
299 | |||
300 | ret = BackendResponse.Success; | ||
301 | } | ||
302 | catch (MySqlException ex) | ||
303 | { | ||
304 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
305 | ret = BackendResponse.Failure; | ||
306 | } | ||
307 | } | ||
308 | } | ||
309 | else | ||
310 | { | ||
311 | ret = BackendResponse.NotFound; | ||
312 | } | ||
313 | |||
314 | server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now); | ||
315 | return ret; | ||
316 | } | ||
317 | |||
318 | public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory) | ||
319 | { | ||
320 | inventory = null; | ||
321 | BackendResponse ret; | ||
322 | List<InventoryFolder> folders; | ||
323 | UUID ownerID; | ||
324 | |||
325 | ret = TryFetchFolderList(owner, out folders); | ||
326 | |||
327 | if (ret == BackendResponse.Success) | ||
328 | { | ||
329 | // Add the retrieved folders to the inventory collection | ||
330 | inventory = new InventoryCollection(); | ||
331 | inventory.Folders = new Dictionary<UUID, InventoryFolder>(folders.Count); | ||
332 | foreach (InventoryFolder folder in folders) | ||
333 | inventory.Folders[folder.ID] = folder; | ||
334 | |||
335 | // Fetch inventory items | ||
336 | if (Utils.TryGetOpenSimUUID(owner, out ownerID)) | ||
337 | { | ||
338 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
339 | { | ||
340 | IDataReader reader; | ||
341 | |||
342 | try | ||
343 | { | ||
344 | dbConnection.Open(); | ||
345 | |||
346 | IDbCommand command = dbConnection.CreateCommand(); | ||
347 | command.CommandText = String.Format("SELECT assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + | ||
348 | "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + | ||
349 | "creationDate,groupID,groupOwned,flags,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " + | ||
350 | "avatarID='{0}'", ownerID.ToString()); | ||
351 | reader = command.ExecuteReader(); | ||
352 | |||
353 | inventory.UserID = ownerID; | ||
354 | inventory.Items = new Dictionary<UUID, InventoryItem>(); | ||
355 | |||
356 | while (reader.Read()) | ||
357 | { | ||
358 | InventoryItem item = new InventoryItem(); | ||
359 | item.Owner = ownerID; | ||
360 | item.AssetID = UUID.Parse(reader.GetString(0)); | ||
361 | item.AssetType = reader.GetInt32(1); | ||
362 | item.Name = reader.GetString(2); | ||
363 | item.Description = reader.GetString(3); | ||
364 | item.NextPermissions = (uint)reader.GetInt32(4); | ||
365 | item.CurrentPermissions = (uint)reader.GetInt32(5); | ||
366 | item.InvType = reader.GetInt32(6); | ||
367 | item.Creator = UUID.Parse(reader.GetString(7)); | ||
368 | item.BasePermissions = (uint)reader.GetInt32(8); | ||
369 | item.EveryOnePermissions = (uint)reader.GetInt32(9); | ||
370 | item.SalePrice = reader.GetInt32(10); | ||
371 | item.SaleType = reader.GetByte(11); | ||
372 | item.CreationDate = reader.GetInt32(12); | ||
373 | item.GroupID = UUID.Parse(reader.GetString(13)); | ||
374 | item.GroupOwned = reader.GetBoolean(14); | ||
375 | item.Flags = (uint)reader.GetInt32(15); | ||
376 | item.ID = UUID.Parse(reader.GetString(16)); | ||
377 | item.Folder = UUID.Parse(reader.GetString(17)); | ||
378 | item.GroupPermissions = (uint)reader.GetInt32(18); | ||
379 | |||
380 | inventory.Items.Add(item.ID, item); | ||
381 | } | ||
382 | |||
383 | ret = BackendResponse.Success; | ||
384 | } | ||
385 | catch (MySqlException ex) | ||
386 | { | ||
387 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
388 | ret = BackendResponse.Failure; | ||
389 | } | ||
390 | } | ||
391 | } | ||
392 | else | ||
393 | { | ||
394 | ret = BackendResponse.NotFound; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now); | ||
399 | return ret; | ||
400 | } | ||
401 | |||
402 | public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures) | ||
403 | { | ||
404 | gestures = null; | ||
405 | BackendResponse ret; | ||
406 | UUID ownerID; | ||
407 | |||
408 | if (Utils.TryGetOpenSimUUID(owner, out ownerID)) | ||
409 | { | ||
410 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
411 | { | ||
412 | IDataReader reader; | ||
413 | |||
414 | try | ||
415 | { | ||
416 | dbConnection.Open(); | ||
417 | |||
418 | MySqlCommand command = new MySqlCommand("SELECT assetID,inventoryName,inventoryDescription,inventoryNextPermissions," + | ||
419 | "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + | ||
420 | "creationDate,groupID,groupOwned,inventoryID,parentFolderID,inventoryGroupPermissions FROM inventoryitems WHERE " + | ||
421 | "avatarId=?uuid AND assetType=?type AND flags=1", dbConnection); | ||
422 | command.Parameters.AddWithValue("?uuid", ownerID.ToString()); | ||
423 | command.Parameters.AddWithValue("?type", (int)AssetType.Gesture); | ||
424 | reader = command.ExecuteReader(); | ||
425 | |||
426 | while (reader.Read()) | ||
427 | { | ||
428 | InventoryItem item = new InventoryItem(); | ||
429 | item.Owner = ownerID; | ||
430 | item.AssetType = (int)AssetType.Gesture; | ||
431 | item.Flags = (uint)1; | ||
432 | item.AssetID = UUID.Parse(reader.GetString(0)); | ||
433 | item.Name = reader.GetString(1); | ||
434 | item.Description = reader.GetString(2); | ||
435 | item.NextPermissions = (uint)reader.GetInt32(3); | ||
436 | item.CurrentPermissions = (uint)reader.GetInt32(4); | ||
437 | item.InvType = reader.GetInt32(5); | ||
438 | item.Creator = UUID.Parse(reader.GetString(6)); | ||
439 | item.BasePermissions = (uint)reader.GetInt32(7); | ||
440 | item.EveryOnePermissions = (uint)reader.GetInt32(8); | ||
441 | item.SalePrice = reader.GetInt32(9); | ||
442 | item.SaleType = reader.GetByte(10); | ||
443 | item.CreationDate = reader.GetInt32(11); | ||
444 | item.GroupID = UUID.Parse(reader.GetString(12)); | ||
445 | item.GroupOwned = reader.GetBoolean(13); | ||
446 | item.ID = UUID.Parse(reader.GetString(14)); | ||
447 | item.Folder = UUID.Parse(reader.GetString(15)); | ||
448 | item.GroupPermissions = (uint)reader.GetInt32(16); | ||
449 | |||
450 | gestures.Add(item); | ||
451 | } | ||
452 | |||
453 | ret = BackendResponse.Success; | ||
454 | } | ||
455 | catch (MySqlException ex) | ||
456 | { | ||
457 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
458 | ret = BackendResponse.Failure; | ||
459 | } | ||
460 | } | ||
461 | } | ||
462 | else | ||
463 | { | ||
464 | ret = BackendResponse.NotFound; | ||
465 | } | ||
466 | |||
467 | server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now); | ||
468 | return ret; | ||
469 | } | ||
470 | |||
471 | public BackendResponse TryCreateItem(Uri owner, InventoryItem item) | ||
472 | { | ||
473 | BackendResponse ret; | ||
474 | |||
475 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
476 | { | ||
477 | try | ||
478 | { | ||
479 | dbConnection.Open(); | ||
480 | |||
481 | MySqlCommand command = new MySqlCommand( | ||
482 | "REPLACE INTO inventoryitems (assetID,assetType,inventoryName,inventoryDescription,inventoryNextPermissions," + | ||
483 | "inventoryCurrentPermissions,invType,creatorID,inventoryBasePermissions,inventoryEveryOnePermissions,salePrice,saleType," + | ||
484 | "creationDate,groupID,groupOwned,flags,inventoryID,avatarID,parentFolderID,inventoryGroupPermissions) VALUES " + | ||
485 | |||
486 | "(?assetID,?assetType,?inventoryName,?inventoryDescription,?inventoryNextPermissions,?inventoryCurrentPermissions,?invType," + | ||
487 | "?creatorID,?inventoryBasePermissions,?inventoryEveryOnePermissions,?salePrice,?saleType,?creationDate,?groupID,?groupOwned," + | ||
488 | "?flags,?inventoryID,?avatarID,?parentFolderID,?inventoryGroupPermissions)", dbConnection); | ||
489 | |||
490 | command.Parameters.AddWithValue("?assetID", item.AssetID.ToString()); | ||
491 | command.Parameters.AddWithValue("?assetType", item.AssetType); | ||
492 | command.Parameters.AddWithValue("?inventoryName", item.Name); | ||
493 | command.Parameters.AddWithValue("?inventoryDescription", item.Description); | ||
494 | command.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions); | ||
495 | command.Parameters.AddWithValue("?inventoryCurrentPermissions", item.CurrentPermissions); | ||
496 | command.Parameters.AddWithValue("?invType", item.InvType); | ||
497 | command.Parameters.AddWithValue("?creatorID", item.Creator.ToString()); | ||
498 | command.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions); | ||
499 | command.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions); | ||
500 | command.Parameters.AddWithValue("?salePrice", item.SalePrice); | ||
501 | command.Parameters.AddWithValue("?saleType", item.SaleType); | ||
502 | command.Parameters.AddWithValue("?creationDate", item.CreationDate); | ||
503 | command.Parameters.AddWithValue("?groupID", item.GroupID.ToString()); | ||
504 | command.Parameters.AddWithValue("?groupOwned", item.GroupOwned); | ||
505 | command.Parameters.AddWithValue("?flags", item.Flags); | ||
506 | command.Parameters.AddWithValue("?inventoryID", item.ID); | ||
507 | command.Parameters.AddWithValue("?avatarID", item.Owner); | ||
508 | command.Parameters.AddWithValue("?parentFolderID", item.Folder); | ||
509 | command.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions); | ||
510 | |||
511 | int rowsAffected = command.ExecuteNonQuery(); | ||
512 | if (rowsAffected == 1) | ||
513 | { | ||
514 | ret = BackendResponse.Success; | ||
515 | } | ||
516 | else if (rowsAffected == 2) | ||
517 | { | ||
518 | Logger.Log.Info("Replaced inventory item " + item.ID.ToString()); | ||
519 | ret = BackendResponse.Success; | ||
520 | } | ||
521 | else | ||
522 | { | ||
523 | Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); | ||
524 | ret = BackendResponse.Failure; | ||
525 | } | ||
526 | } | ||
527 | catch (MySqlException ex) | ||
528 | { | ||
529 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
530 | ret = BackendResponse.Failure; | ||
531 | } | ||
532 | } | ||
533 | |||
534 | server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now); | ||
535 | return ret; | ||
536 | } | ||
537 | |||
538 | public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder) | ||
539 | { | ||
540 | BackendResponse ret; | ||
541 | |||
542 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
543 | { | ||
544 | try | ||
545 | { | ||
546 | dbConnection.Open(); | ||
547 | |||
548 | MySqlCommand command = new MySqlCommand( | ||
549 | "REPLACE INTO inventoryfolders (folderName,type,version,folderID,agentID,parentFolderID) VALUES " + | ||
550 | "(?folderName,?type,?version,?folderID,?agentID,?parentFolderID)", dbConnection); | ||
551 | |||
552 | command.Parameters.AddWithValue("?folderName", folder.Name); | ||
553 | command.Parameters.AddWithValue("?type", folder.Type); | ||
554 | command.Parameters.AddWithValue("?version", folder.Version); | ||
555 | command.Parameters.AddWithValue("?folderID", folder.ID); | ||
556 | command.Parameters.AddWithValue("?agentID", folder.Owner); | ||
557 | command.Parameters.AddWithValue("?parentFolderID", folder.ParentID); | ||
558 | |||
559 | int rowsAffected = command.ExecuteNonQuery(); | ||
560 | if (rowsAffected == 1) | ||
561 | { | ||
562 | ret = BackendResponse.Success; | ||
563 | } | ||
564 | else if (rowsAffected == 2) | ||
565 | { | ||
566 | Logger.Log.Info("Replaced inventory folder " + folder.ID.ToString()); | ||
567 | ret = BackendResponse.Success; | ||
568 | } | ||
569 | else | ||
570 | { | ||
571 | Logger.Log.ErrorFormat("MySQL REPLACE query affected {0} rows", rowsAffected); | ||
572 | ret = BackendResponse.Failure; | ||
573 | } | ||
574 | } | ||
575 | catch (MySqlException ex) | ||
576 | { | ||
577 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
578 | ret = BackendResponse.Failure; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now); | ||
583 | return ret; | ||
584 | } | ||
585 | |||
586 | public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder) | ||
587 | { | ||
588 | return TryCreateFolder(owner, rootFolder); | ||
589 | } | ||
590 | |||
591 | public BackendResponse TryDeleteItem(Uri owner, UUID itemID) | ||
592 | { | ||
593 | BackendResponse ret; | ||
594 | UUID ownerID; | ||
595 | |||
596 | if (Utils.TryGetOpenSimUUID(owner, out ownerID)) | ||
597 | { | ||
598 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
599 | { | ||
600 | try | ||
601 | { | ||
602 | dbConnection.Open(); | ||
603 | |||
604 | MySqlCommand command = new MySqlCommand( | ||
605 | "DELETE FROM inventoryitems WHERE inventoryID=?inventoryID AND avatarID=?avatarID", dbConnection); | ||
606 | |||
607 | command.Parameters.AddWithValue("?inventoryID", itemID.ToString()); | ||
608 | command.Parameters.AddWithValue("?avatarID", ownerID.ToString()); | ||
609 | |||
610 | int rowsAffected = command.ExecuteNonQuery(); | ||
611 | if (rowsAffected == 1) | ||
612 | { | ||
613 | ret = BackendResponse.Success; | ||
614 | } | ||
615 | else | ||
616 | { | ||
617 | Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected); | ||
618 | ret = BackendResponse.NotFound; | ||
619 | } | ||
620 | } | ||
621 | catch (MySqlException ex) | ||
622 | { | ||
623 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
624 | ret = BackendResponse.Failure; | ||
625 | } | ||
626 | } | ||
627 | } | ||
628 | else | ||
629 | { | ||
630 | ret = BackendResponse.NotFound; | ||
631 | } | ||
632 | |||
633 | server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); | ||
634 | return ret; | ||
635 | } | ||
636 | |||
637 | public BackendResponse TryDeleteFolder(Uri owner, UUID folderID) | ||
638 | { | ||
639 | BackendResponse ret; | ||
640 | UUID ownerID; | ||
641 | |||
642 | if (Utils.TryGetOpenSimUUID(owner, out ownerID)) | ||
643 | { | ||
644 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
645 | { | ||
646 | try | ||
647 | { | ||
648 | dbConnection.Open(); | ||
649 | |||
650 | MySqlCommand command = new MySqlCommand( | ||
651 | "DELETE FROM inventoryfolders WHERE folderID=?folderID AND agentID=?agentID", dbConnection); | ||
652 | |||
653 | command.Parameters.AddWithValue("?folderID", folderID.ToString()); | ||
654 | command.Parameters.AddWithValue("?agentID", ownerID.ToString()); | ||
655 | |||
656 | int rowsAffected = command.ExecuteNonQuery(); | ||
657 | if (rowsAffected == 1) | ||
658 | { | ||
659 | ret = BackendResponse.Success; | ||
660 | } | ||
661 | else | ||
662 | { | ||
663 | Logger.Log.ErrorFormat("MySQL DELETE query affected {0} rows", rowsAffected); | ||
664 | ret = BackendResponse.NotFound; | ||
665 | } | ||
666 | } | ||
667 | catch (MySqlException ex) | ||
668 | { | ||
669 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
670 | ret = BackendResponse.Failure; | ||
671 | } | ||
672 | } | ||
673 | } | ||
674 | else | ||
675 | { | ||
676 | ret = BackendResponse.NotFound; | ||
677 | } | ||
678 | |||
679 | server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); | ||
680 | return ret; | ||
681 | } | ||
682 | |||
683 | public BackendResponse TryPurgeFolder(Uri owner, UUID folderID) | ||
684 | { | ||
685 | BackendResponse ret; | ||
686 | UUID ownerID; | ||
687 | |||
688 | if (Utils.TryGetOpenSimUUID(owner, out ownerID)) | ||
689 | { | ||
690 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
691 | { | ||
692 | try | ||
693 | { | ||
694 | dbConnection.Open(); | ||
695 | |||
696 | #region Delete items | ||
697 | |||
698 | MySqlCommand command = new MySqlCommand( | ||
699 | "DELETE FROM inventoryitems WHERE parentFolderID=?parentFolderID AND avatarID=?avatarID", dbConnection); | ||
700 | |||
701 | command.Parameters.AddWithValue("?parentFolderID", folderID.ToString()); | ||
702 | command.Parameters.AddWithValue("?avatarID", ownerID.ToString()); | ||
703 | |||
704 | int rowsAffected = command.ExecuteNonQuery(); | ||
705 | |||
706 | #endregion Delete items | ||
707 | |||
708 | #region Delete folders | ||
709 | |||
710 | command = new MySqlCommand( | ||
711 | "DELETE FROM inventoryfolders WHERE parentFolderID=?parentFolderID AND agentID=?agentID", dbConnection); | ||
712 | |||
713 | command.Parameters.AddWithValue("?parentFolderID", folderID.ToString()); | ||
714 | command.Parameters.AddWithValue("?agentID", ownerID.ToString()); | ||
715 | |||
716 | rowsAffected += command.ExecuteNonQuery(); | ||
717 | |||
718 | #endregion Delete folders | ||
719 | |||
720 | Logger.Log.DebugFormat("Deleted {0} inventory objects from MySQL in a folder purge", rowsAffected); | ||
721 | |||
722 | ret = BackendResponse.Success; | ||
723 | } | ||
724 | catch (MySqlException ex) | ||
725 | { | ||
726 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
727 | ret = BackendResponse.Failure; | ||
728 | } | ||
729 | } | ||
730 | } | ||
731 | else | ||
732 | { | ||
733 | ret = BackendResponse.NotFound; | ||
734 | } | ||
735 | |||
736 | server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); | ||
737 | return ret; | ||
738 | } | ||
739 | |||
740 | public int ForEach(Action<Metadata> action, int start, int count) | ||
741 | { | ||
742 | int rowCount = 0; | ||
743 | |||
744 | using (MySqlConnection dbConnection = new MySqlConnection(DBConnString.GetConnectionString(server.ConfigFile))) | ||
745 | { | ||
746 | MySqlDataReader reader; | ||
747 | |||
748 | try | ||
749 | { | ||
750 | dbConnection.Open(); | ||
751 | |||
752 | MySqlCommand command = dbConnection.CreateCommand(); | ||
753 | command.CommandText = String.Format("SELECT name,description,assetType,temporary,data,id FROM assets LIMIT {0}, {1}", | ||
754 | start, count); | ||
755 | reader = command.ExecuteReader(); | ||
756 | } | ||
757 | catch (MySqlException ex) | ||
758 | { | ||
759 | Logger.Log.Error("Connection to MySQL backend failed: " + ex.Message); | ||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | while (reader.Read()) | ||
764 | { | ||
765 | Metadata metadata = new Metadata(); | ||
766 | metadata.CreationDate = OpenMetaverse.Utils.Epoch; | ||
767 | metadata.Description = reader.GetString(1); | ||
768 | metadata.ID = UUID.Parse(reader.GetString(5)); | ||
769 | metadata.Name = reader.GetString(0); | ||
770 | metadata.SHA1 = OpenMetaverse.Utils.SHA1((byte[])reader.GetValue(4)); | ||
771 | metadata.Temporary = reader.GetBoolean(3); | ||
772 | metadata.ContentType = Utils.SLAssetTypeToContentType(reader.GetInt32(2)); | ||
773 | |||
774 | action(metadata); | ||
775 | ++rowCount; | ||
776 | } | ||
777 | |||
778 | reader.Close(); | ||
779 | } | ||
780 | |||
781 | return rowCount; | ||
782 | } | ||
783 | |||
784 | #endregion Required Interfaces | ||
785 | |||
786 | #region IPlugin implementation | ||
787 | |||
788 | public void Initialise(AssetInventoryServer server) | ||
789 | { | ||
790 | this.server = server; | ||
791 | |||
792 | try | ||
793 | { | ||
794 | m_inventoryProvider = DataPluginFactory.LoadInventoryDataPlugin("OpenSim.Data.MySQL.dll", server.ConfigFile.Configs["MySQL"].GetString("database_connect", null)); | ||
795 | if (m_inventoryProvider == null) | ||
796 | { | ||
797 | Logger.Log.Error("[INVENTORY]: Failed to load a database plugin, server halting."); | ||
798 | Environment.Exit(-1); | ||
799 | } | ||
800 | else | ||
801 | Logger.Log.InfoFormat("[INVENTORY]: Loaded storage backend: {0}", Version); | ||
802 | } | ||
803 | catch (Exception e) | ||
804 | { | ||
805 | Logger.Log.WarnFormat("[INVENTORY]: Failure loading data plugin: {0}", e.ToString()); | ||
806 | } | ||
807 | } | ||
808 | |||
809 | public void Stop() | ||
810 | { | ||
811 | } | ||
812 | |||
813 | public void Initialise() | ||
814 | { | ||
815 | Logger.Log.InfoFormat("[INVENTORY]: {0} cannot be default-initialized!", Name); | ||
816 | throw new PluginNotInitialisedException(Name); | ||
817 | } | ||
818 | |||
819 | public void Dispose() | ||
820 | { | ||
821 | } | ||
822 | |||
823 | public string Version | ||
824 | { | ||
825 | get { return m_inventoryProvider.Version; } | ||
826 | } | ||
827 | |||
828 | public string Name | ||
829 | { | ||
830 | get { return "AssetInventoryServer OpenSim inventory storage provider"; } | ||
831 | } | ||
832 | |||
833 | #endregion IPlugin implementation | ||
834 | } | ||
835 | } | ||
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml index f458909..6d21327 100644 --- a/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/OpenSim/Resources/AssetInventoryServerOpenSimPlugins.addin.xml | |||
@@ -15,6 +15,9 @@ | |||
15 | <Extension path="/OpenSim/AssetInventoryServer/StorageProvider"> | 15 | <Extension path="/OpenSim/AssetInventoryServer/StorageProvider"> |
16 | <Plugin id="OpenSimAssetStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimAssetStoragePlugin" /> | 16 | <Plugin id="OpenSimAssetStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimAssetStoragePlugin" /> |
17 | </Extension> | 17 | </Extension> |
18 | <Extension path="/OpenSim/AssetInventoryServer/InventoryProvider"> | ||
19 | <Plugin id="OpenSimInventoryStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimInventoryStoragePlugin" /> | ||
20 | </Extension> | ||
18 | <Extension path="/OpenSim/AssetInventoryServer/Frontend"> | 21 | <Extension path="/OpenSim/AssetInventoryServer/Frontend"> |
19 | <Plugin id="OpenSimAssetFrontend" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimAssetFrontendPlugin" /> | 22 | <Plugin id="OpenSimAssetFrontend" provider="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.OpenSim.OpenSimAssetFrontendPlugin" /> |
20 | </Extension> | 23 | </Extension> |
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/Resources/AssetInventoryServerPlugins.addin.xml b/OpenSim/Grid/AssetInventoryServer/Plugins/Resources/AssetInventoryServerPlugins.addin.xml index bca7ee1..089c6a2 100644 --- a/OpenSim/Grid/AssetInventoryServer/Plugins/Resources/AssetInventoryServerPlugins.addin.xml +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Resources/AssetInventoryServerPlugins.addin.xml | |||
@@ -8,6 +8,6 @@ | |||
8 | </Dependencies> | 8 | </Dependencies> |
9 | 9 | ||
10 | <Extension path="/OpenSim/AssetInventoryServer/MetricsProvider"> | 10 | <Extension path="/OpenSim/AssetInventoryServer/MetricsProvider"> |
11 | <Plugin id="OpenSimMetrics" provider="OpenSim.Grid.AssetInventoryServer.Plugins.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.NullMetrics" /> | 11 | <Plugin id="AssetInventoryMetrics" provider="OpenSim.Grid.AssetInventoryServer.Plugins.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.NullMetricsPlugin" /> |
12 | </Extension> | 12 | </Extension> |
13 | </Addin> | 13 | </Addin> |
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml index 53534c4..f898145 100644 --- a/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/Resources/AssetInventoryServerSimplePlugins.addin.xml | |||
@@ -10,4 +10,7 @@ | |||
10 | <Extension path="/OpenSim/AssetInventoryServer/StorageProvider"> | 10 | <Extension path="/OpenSim/AssetInventoryServer/StorageProvider"> |
11 | <Plugin id="SimpleAssetStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.SimpleAssetStoragePlugin" /> | 11 | <Plugin id="SimpleAssetStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.SimpleAssetStoragePlugin" /> |
12 | </Extension> | 12 | </Extension> |
13 | <Extension path="/OpenSim/AssetInventoryServer/InventoryProvider"> | ||
14 | <Plugin id="SimpleInventoryStorage" provider="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.dll" type="OpenSim.Grid.AssetInventoryServer.Plugins.Simple.SimpleInventoryStoragePlugin" /> | ||
15 | </Extension> | ||
13 | </Addin> | 16 | </Addin> |
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleInventoryStoragePlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleInventoryStoragePlugin.cs new file mode 100644 index 0000000..78dae35 --- /dev/null +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/Simple/SimpleInventoryStoragePlugin.cs | |||
@@ -0,0 +1,627 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Intel Corporation | ||
3 | * All rights reserved. | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * -- Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * -- Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * -- Neither the name of the Intel Corporation nor the names of its | ||
14 | * contributors may be used to endorse or promote products derived from | ||
15 | * this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
20 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS | ||
21 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Net; | ||
33 | using System.IO; | ||
34 | using System.Text; | ||
35 | using ExtensionLoader; | ||
36 | using OpenMetaverse; | ||
37 | using OpenMetaverse.StructuredData; | ||
38 | using OpenSim.Framework; | ||
39 | |||
40 | namespace OpenSim.Grid.AssetInventoryServer.Plugins.Simple | ||
41 | { | ||
42 | public class SimpleInventoryStoragePlugin : IInventoryStorageProvider | ||
43 | { | ||
44 | const string EXTENSION_NAME = "SimpleInventoryStorage"; // Used for metrics reporting | ||
45 | const string DEFAULT_INVENTORY_DIR = "SimpleInventory"; | ||
46 | |||
47 | AssetInventoryServer server; | ||
48 | Dictionary<Uri, InventoryCollection> inventories = new Dictionary<Uri, InventoryCollection>(); | ||
49 | Dictionary<Uri, List<InventoryItem>> activeGestures = new Dictionary<Uri, List<InventoryItem>>(); | ||
50 | Utils.InventoryItemSerializer itemSerializer = new Utils.InventoryItemSerializer(); | ||
51 | Utils.InventoryFolderSerializer folderSerializer = new Utils.InventoryFolderSerializer(); | ||
52 | |||
53 | public SimpleInventoryStoragePlugin() | ||
54 | { | ||
55 | } | ||
56 | |||
57 | #region Required Interfaces | ||
58 | |||
59 | public BackendResponse TryFetchItem(Uri owner, UUID itemID, out InventoryItem item) | ||
60 | { | ||
61 | item = null; | ||
62 | BackendResponse ret; | ||
63 | |||
64 | InventoryCollection collection; | ||
65 | if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item)) | ||
66 | ret = BackendResponse.Success; | ||
67 | else | ||
68 | ret = BackendResponse.NotFound; | ||
69 | |||
70 | server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); | ||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | public BackendResponse TryFetchFolder(Uri owner, UUID folderID, out InventoryFolder folder) | ||
75 | { | ||
76 | folder = null; | ||
77 | BackendResponse ret; | ||
78 | |||
79 | InventoryCollection collection; | ||
80 | if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) | ||
81 | ret = BackendResponse.Success; | ||
82 | else | ||
83 | ret = BackendResponse.NotFound; | ||
84 | |||
85 | server.MetricsProvider.LogInventoryFetch(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | public BackendResponse TryFetchFolderContents(Uri owner, UUID folderID, out InventoryCollection contents) | ||
90 | { | ||
91 | contents = null; | ||
92 | BackendResponse ret; | ||
93 | |||
94 | InventoryCollection collection; | ||
95 | InventoryFolder folder; | ||
96 | |||
97 | if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) | ||
98 | { | ||
99 | contents = new InventoryCollection(); | ||
100 | contents.UserID = collection.UserID; | ||
101 | contents.Folders = new Dictionary<UUID, InventoryFolder>(); | ||
102 | contents.Items = new Dictionary<UUID, InventoryItem>(); | ||
103 | |||
104 | foreach (InventoryBase invBase in folder.Children.Values) | ||
105 | { | ||
106 | if (invBase is InventoryItem) | ||
107 | { | ||
108 | InventoryItem invItem = invBase as InventoryItem; | ||
109 | contents.Items.Add(invItem.ID, invItem); | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | InventoryFolder invFolder = invBase as InventoryFolder; | ||
114 | contents.Folders.Add(invFolder.ID, invFolder); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | ret = BackendResponse.Success; | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | ret = BackendResponse.NotFound; | ||
123 | } | ||
124 | |||
125 | server.MetricsProvider.LogInventoryFetchFolderContents(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | public BackendResponse TryFetchFolderList(Uri owner, out List<InventoryFolder> folders) | ||
130 | { | ||
131 | folders = null; | ||
132 | BackendResponse ret; | ||
133 | |||
134 | InventoryCollection collection; | ||
135 | if (inventories.TryGetValue(owner, out collection)) | ||
136 | { | ||
137 | folders = new List<InventoryFolder>(collection.Folders.Values); | ||
138 | return BackendResponse.Success; | ||
139 | } | ||
140 | else | ||
141 | { | ||
142 | ret = BackendResponse.NotFound; | ||
143 | } | ||
144 | |||
145 | server.MetricsProvider.LogInventoryFetchFolderList(EXTENSION_NAME, ret, owner, DateTime.Now); | ||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | public BackendResponse TryFetchInventory(Uri owner, out InventoryCollection inventory) | ||
150 | { | ||
151 | inventory = null; | ||
152 | BackendResponse ret; | ||
153 | |||
154 | if (inventories.TryGetValue(owner, out inventory)) | ||
155 | ret = BackendResponse.Success; | ||
156 | else | ||
157 | ret = BackendResponse.NotFound; | ||
158 | |||
159 | server.MetricsProvider.LogInventoryFetchInventory(EXTENSION_NAME, ret, owner, DateTime.Now); | ||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | public BackendResponse TryFetchActiveGestures(Uri owner, out List<InventoryItem> gestures) | ||
164 | { | ||
165 | gestures = null; | ||
166 | BackendResponse ret; | ||
167 | |||
168 | if (activeGestures.TryGetValue(owner, out gestures)) | ||
169 | ret = BackendResponse.Success; | ||
170 | else | ||
171 | ret = BackendResponse.NotFound; | ||
172 | |||
173 | server.MetricsProvider.LogInventoryFetchActiveGestures(EXTENSION_NAME, ret, owner, DateTime.Now); | ||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | public BackendResponse TryCreateItem(Uri owner, InventoryItem item) | ||
178 | { | ||
179 | BackendResponse ret; | ||
180 | |||
181 | InventoryCollection collection; | ||
182 | if (inventories.TryGetValue(owner, out collection)) | ||
183 | { | ||
184 | // Delete this item first if it already exists | ||
185 | InventoryItem oldItem; | ||
186 | if (collection.Items.TryGetValue(item.ID, out oldItem)) | ||
187 | TryDeleteItem(owner, item.ID); | ||
188 | |||
189 | try | ||
190 | { | ||
191 | // Create the file | ||
192 | SaveItem(item); | ||
193 | |||
194 | // Add the item to the collection | ||
195 | lock (collection) collection.Items[item.ID] = item; | ||
196 | |||
197 | // Add the item to its parent folder | ||
198 | InventoryFolder parent; | ||
199 | if (collection.Folders.TryGetValue(item.Folder, out parent)) | ||
200 | lock (parent.Children) parent.Children.Add(item.ID, item); | ||
201 | |||
202 | // Add active gestures to our list | ||
203 | if (item.InvType == (int)InventoryType.Gesture && item.Flags == 1) | ||
204 | { | ||
205 | lock (activeGestures) | ||
206 | activeGestures[owner].Add(item); | ||
207 | } | ||
208 | |||
209 | ret = BackendResponse.Success; | ||
210 | } | ||
211 | catch (Exception ex) | ||
212 | { | ||
213 | Logger.Log.Error(ex.Message); | ||
214 | ret = BackendResponse.Failure; | ||
215 | } | ||
216 | } | ||
217 | else | ||
218 | { | ||
219 | return BackendResponse.NotFound; | ||
220 | } | ||
221 | |||
222 | server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, false, DateTime.Now); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | public BackendResponse TryCreateFolder(Uri owner, InventoryFolder folder) | ||
227 | { | ||
228 | BackendResponse ret; | ||
229 | |||
230 | InventoryCollection collection; | ||
231 | if (inventories.TryGetValue(owner, out collection)) | ||
232 | { | ||
233 | // Delete this folder first if it already exists | ||
234 | InventoryFolder oldFolder; | ||
235 | if (collection.Folders.TryGetValue(folder.ID, out oldFolder)) | ||
236 | TryDeleteFolder(owner, folder.ID); | ||
237 | |||
238 | try | ||
239 | { | ||
240 | // Create the file | ||
241 | SaveFolder(folder); | ||
242 | |||
243 | // Add the folder to the collection | ||
244 | lock (collection) collection.Folders[folder.ID] = folder; | ||
245 | |||
246 | // Add the folder to its parent folder | ||
247 | InventoryFolder parent; | ||
248 | if (collection.Folders.TryGetValue(folder.ParentID, out parent)) | ||
249 | lock (parent.Children) parent.Children.Add(folder.ID, folder); | ||
250 | |||
251 | ret = BackendResponse.Success; | ||
252 | } | ||
253 | catch (Exception ex) | ||
254 | { | ||
255 | Logger.Log.Error(ex.Message); | ||
256 | ret = BackendResponse.Failure; | ||
257 | } | ||
258 | } | ||
259 | else | ||
260 | { | ||
261 | ret = BackendResponse.NotFound; | ||
262 | } | ||
263 | |||
264 | server.MetricsProvider.LogInventoryCreate(EXTENSION_NAME, ret, owner, true, DateTime.Now); | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | public BackendResponse TryCreateInventory(Uri owner, InventoryFolder rootFolder) | ||
269 | { | ||
270 | BackendResponse ret; | ||
271 | |||
272 | lock (inventories) | ||
273 | { | ||
274 | if (!inventories.ContainsKey(owner)) | ||
275 | { | ||
276 | InventoryCollection collection = new InventoryCollection(); | ||
277 | collection.UserID = rootFolder.Owner; | ||
278 | collection.Folders = new Dictionary<UUID, InventoryFolder>(); | ||
279 | collection.Folders.Add(rootFolder.ID, rootFolder); | ||
280 | collection.Items = new Dictionary<UUID, InventoryItem>(); | ||
281 | |||
282 | inventories.Add(owner, collection); | ||
283 | |||
284 | ret = BackendResponse.Success; | ||
285 | } | ||
286 | else | ||
287 | { | ||
288 | ret = BackendResponse.Failure; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | if (ret == BackendResponse.Success) | ||
293 | { | ||
294 | string path = Path.Combine(DEFAULT_INVENTORY_DIR, rootFolder.Owner.ToString()); | ||
295 | try | ||
296 | { | ||
297 | // Create the directory for this agent | ||
298 | Directory.CreateDirectory(path); | ||
299 | |||
300 | // Create an index.txt containing the UUID and URI for this agent | ||
301 | string[] index = new string[] { rootFolder.Owner.ToString(), owner.ToString() }; | ||
302 | File.WriteAllLines(Path.Combine(path, "index.txt"), index); | ||
303 | |||
304 | // Create the root folder file | ||
305 | SaveFolder(rootFolder); | ||
306 | } | ||
307 | catch (Exception ex) | ||
308 | { | ||
309 | Logger.Log.Error(ex.Message); | ||
310 | ret = BackendResponse.Failure; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | server.MetricsProvider.LogInventoryCreateInventory(EXTENSION_NAME, ret, DateTime.Now); | ||
315 | return ret; | ||
316 | } | ||
317 | |||
318 | public BackendResponse TryDeleteItem(Uri owner, UUID itemID) | ||
319 | { | ||
320 | BackendResponse ret; | ||
321 | |||
322 | InventoryCollection collection; | ||
323 | InventoryItem item; | ||
324 | if (inventories.TryGetValue(owner, out collection) && collection.Items.TryGetValue(itemID, out item)) | ||
325 | { | ||
326 | // Remove the item from its parent folder | ||
327 | InventoryFolder parent; | ||
328 | if (collection.Folders.TryGetValue(item.Folder, out parent)) | ||
329 | lock (parent.Children) parent.Children.Remove(itemID); | ||
330 | |||
331 | // Remove the item from the collection | ||
332 | lock (collection) collection.Items.Remove(itemID); | ||
333 | |||
334 | // Remove from the active gestures list if applicable | ||
335 | if (item.InvType == (int)InventoryType.Gesture) | ||
336 | { | ||
337 | lock (activeGestures) | ||
338 | { | ||
339 | for (int i = 0; i < activeGestures[owner].Count; i++) | ||
340 | { | ||
341 | if (activeGestures[owner][i].ID == itemID) | ||
342 | { | ||
343 | activeGestures[owner].RemoveAt(i); | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | // Delete the file. We don't know exactly what the file name is, | ||
351 | // so search for it | ||
352 | string path = PathFromURI(owner); | ||
353 | string[] matches = Directory.GetFiles(path, String.Format("*{0}.item", itemID), SearchOption.TopDirectoryOnly); | ||
354 | foreach (string match in matches) | ||
355 | { | ||
356 | try { File.Delete(match); } | ||
357 | catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete file {0}: {1}", match, ex.Message); } | ||
358 | } | ||
359 | |||
360 | ret = BackendResponse.Success; | ||
361 | } | ||
362 | else | ||
363 | { | ||
364 | ret = BackendResponse.NotFound; | ||
365 | } | ||
366 | |||
367 | server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, itemID, false, DateTime.Now); | ||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | public BackendResponse TryDeleteFolder(Uri owner, UUID folderID) | ||
372 | { | ||
373 | BackendResponse ret; | ||
374 | |||
375 | InventoryCollection collection; | ||
376 | InventoryFolder folder; | ||
377 | if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) | ||
378 | { | ||
379 | // Remove the folder from its parent folder | ||
380 | InventoryFolder parent; | ||
381 | if (collection.Folders.TryGetValue(folder.ParentID, out parent)) | ||
382 | lock (parent.Children) parent.Children.Remove(folderID); | ||
383 | |||
384 | // Remove the folder from the collection | ||
385 | lock (collection) collection.Items.Remove(folderID); | ||
386 | |||
387 | // Delete the folder file. We don't know exactly what the file name is, | ||
388 | // so search for it | ||
389 | string path = PathFromURI(owner); | ||
390 | string[] matches = Directory.GetFiles(path, String.Format("*{0}.folder", folderID), SearchOption.TopDirectoryOnly); | ||
391 | foreach (string match in matches) | ||
392 | { | ||
393 | try { File.Delete(match); } | ||
394 | catch (Exception ex) { Logger.Log.ErrorFormat("Failed to delete folder file {0}: {1}", match, ex.Message); } | ||
395 | } | ||
396 | |||
397 | ret = BackendResponse.Success; | ||
398 | } | ||
399 | else | ||
400 | { | ||
401 | ret = BackendResponse.NotFound; | ||
402 | } | ||
403 | |||
404 | server.MetricsProvider.LogInventoryDelete(EXTENSION_NAME, ret, owner, folderID, true, DateTime.Now); | ||
405 | return ret; | ||
406 | } | ||
407 | |||
408 | public BackendResponse TryPurgeFolder(Uri owner, UUID folderID) | ||
409 | { | ||
410 | BackendResponse ret; | ||
411 | |||
412 | InventoryCollection collection; | ||
413 | InventoryFolder folder; | ||
414 | if (inventories.TryGetValue(owner, out collection) && collection.Folders.TryGetValue(folderID, out folder)) | ||
415 | { | ||
416 | // Delete all of the folder children | ||
417 | foreach (InventoryBase obj in new List<InventoryBase>(folder.Children.Values)) | ||
418 | { | ||
419 | if (obj is InventoryItem) | ||
420 | { | ||
421 | TryDeleteItem(owner, (obj as InventoryItem).ID); | ||
422 | } | ||
423 | else | ||
424 | { | ||
425 | InventoryFolder childFolder = obj as InventoryFolder; | ||
426 | TryPurgeFolder(owner, childFolder.ID); | ||
427 | TryDeleteFolder(owner, childFolder.ID); | ||
428 | } | ||
429 | } | ||
430 | |||
431 | ret = BackendResponse.Success; | ||
432 | } | ||
433 | else | ||
434 | { | ||
435 | ret = BackendResponse.NotFound; | ||
436 | } | ||
437 | |||
438 | server.MetricsProvider.LogInventoryPurgeFolder(EXTENSION_NAME, ret, owner, folderID, DateTime.Now); | ||
439 | return ret; | ||
440 | } | ||
441 | |||
442 | #endregion Required Interfaces | ||
443 | |||
444 | void SaveItem(InventoryItem item) | ||
445 | { | ||
446 | string filename = String.Format("{0}-{1}.item", SanitizeFilename(item.Name), item.ID); | ||
447 | |||
448 | string path = Path.Combine(DEFAULT_INVENTORY_DIR, item.Owner.ToString()); | ||
449 | path = Path.Combine(path, filename); | ||
450 | |||
451 | using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write)) | ||
452 | { | ||
453 | itemSerializer.Serialize(stream, item); | ||
454 | stream.Flush(); | ||
455 | } | ||
456 | } | ||
457 | |||
458 | void SaveFolder(InventoryFolder folder) | ||
459 | { | ||
460 | string filename = String.Format("{0}-{1}.folder", SanitizeFilename(folder.Name), folder.ID); | ||
461 | |||
462 | string path = Path.Combine(DEFAULT_INVENTORY_DIR, folder.Owner.ToString()); | ||
463 | path = Path.Combine(path, filename); | ||
464 | |||
465 | using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write)) | ||
466 | { | ||
467 | folderSerializer.Serialize(stream, folder); | ||
468 | stream.Flush(); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | string SanitizeFilename(string filename) | ||
473 | { | ||
474 | string output = filename; | ||
475 | |||
476 | if (output.Length > 64) | ||
477 | output = output.Substring(0, 64); | ||
478 | |||
479 | foreach (char i in Path.GetInvalidFileNameChars()) | ||
480 | output = output.Replace(i, '_'); | ||
481 | |||
482 | return output; | ||
483 | } | ||
484 | |||
485 | static string PathFromURI(Uri uri) | ||
486 | { | ||
487 | byte[] hash = OpenMetaverse.Utils.SHA1(Encoding.UTF8.GetBytes(uri.ToString())); | ||
488 | StringBuilder digest = new StringBuilder(40); | ||
489 | |||
490 | // Convert the hash to a hex string | ||
491 | foreach (byte b in hash) | ||
492 | digest.AppendFormat(OpenMetaverse.Utils.EnUsCulture, "{0:x2}", b); | ||
493 | |||
494 | return Path.Combine(DEFAULT_INVENTORY_DIR, digest.ToString()); | ||
495 | } | ||
496 | |||
497 | void LoadFiles(string folder) | ||
498 | { | ||
499 | // Try to create the directory if it doesn't already exist | ||
500 | if (!Directory.Exists(folder)) | ||
501 | { | ||
502 | try { Directory.CreateDirectory(folder); } | ||
503 | catch (Exception ex) | ||
504 | { | ||
505 | Logger.Log.Warn(ex.Message); | ||
506 | return; | ||
507 | } | ||
508 | } | ||
509 | |||
510 | try | ||
511 | { | ||
512 | string[] agentFolders = Directory.GetDirectories(DEFAULT_INVENTORY_DIR); | ||
513 | |||
514 | for (int i = 0; i < agentFolders.Length; i++) | ||
515 | { | ||
516 | string foldername = agentFolders[i]; | ||
517 | string indexPath = Path.Combine(foldername, "index.txt"); | ||
518 | UUID ownerID = UUID.Zero; | ||
519 | Uri owner = null; | ||
520 | |||
521 | try | ||
522 | { | ||
523 | string[] index = File.ReadAllLines(indexPath); | ||
524 | ownerID = UUID.Parse(index[0]); | ||
525 | owner = new Uri(index[1]); | ||
526 | } | ||
527 | catch (Exception ex) | ||
528 | { | ||
529 | Logger.Log.WarnFormat("Failed loading the index file {0}: {1}", indexPath, ex.Message); | ||
530 | } | ||
531 | |||
532 | if (ownerID != UUID.Zero && owner != null) | ||
533 | { | ||
534 | // Initialize the active gestures list for this agent | ||
535 | activeGestures.Add(owner, new List<InventoryItem>()); | ||
536 | |||
537 | InventoryCollection collection = new InventoryCollection(); | ||
538 | collection.UserID = ownerID; | ||
539 | |||
540 | // Load all of the folders for this agent | ||
541 | string[] folders = Directory.GetFiles(foldername, "*.folder", SearchOption.TopDirectoryOnly); | ||
542 | collection.Folders = new Dictionary<UUID,InventoryFolder>(folders.Length); | ||
543 | |||
544 | for (int j = 0; j < folders.Length; j++) | ||
545 | { | ||
546 | InventoryFolder invFolder = (InventoryFolder)folderSerializer.Deserialize( | ||
547 | new FileStream(folders[j], FileMode.Open, FileAccess.Read)); | ||
548 | collection.Folders[invFolder.ID] = invFolder; | ||
549 | } | ||
550 | |||
551 | // Iterate over the folders collection, adding children to their parents | ||
552 | foreach (InventoryFolder invFolder in collection.Folders.Values) | ||
553 | { | ||
554 | InventoryFolder parent; | ||
555 | if (collection.Folders.TryGetValue(invFolder.ParentID, out parent)) | ||
556 | parent.Children[invFolder.ID] = invFolder; | ||
557 | } | ||
558 | |||
559 | // Load all of the items for this agent | ||
560 | string[] files = Directory.GetFiles(foldername, "*.item", SearchOption.TopDirectoryOnly); | ||
561 | collection.Items = new Dictionary<UUID, InventoryItem>(files.Length); | ||
562 | |||
563 | for (int j = 0; j < files.Length; j++) | ||
564 | { | ||
565 | InventoryItem invItem = (InventoryItem)itemSerializer.Deserialize( | ||
566 | new FileStream(files[j], FileMode.Open, FileAccess.Read)); | ||
567 | collection.Items[invItem.ID] = invItem; | ||
568 | |||
569 | // Add items to their parent folders | ||
570 | InventoryFolder parent; | ||
571 | if (collection.Folders.TryGetValue(invItem.Folder, out parent)) | ||
572 | parent.Children[invItem.ID] = invItem; | ||
573 | |||
574 | // Add active gestures to our list | ||
575 | if (invItem.InvType == (int)InventoryType.Gesture && invItem.Flags != 0) | ||
576 | activeGestures[owner].Add(invItem); | ||
577 | } | ||
578 | |||
579 | inventories.Add(owner, collection); | ||
580 | } | ||
581 | } | ||
582 | } | ||
583 | catch (Exception ex) | ||
584 | { | ||
585 | Logger.Log.ErrorFormat("Failed loading inventory from {0}: {1}", folder, ex.Message); | ||
586 | } | ||
587 | } | ||
588 | |||
589 | #region IPlugin implementation | ||
590 | |||
591 | public void Initialise(AssetInventoryServer server) | ||
592 | { | ||
593 | this.server = server; | ||
594 | |||
595 | LoadFiles(DEFAULT_INVENTORY_DIR); | ||
596 | |||
597 | Logger.Log.InfoFormat("Initialized the inventory index with data for {0} avatars", | ||
598 | inventories.Count); | ||
599 | } | ||
600 | |||
601 | /// <summary> | ||
602 | /// <para>Initialises asset interface</para> | ||
603 | /// </summary> | ||
604 | public void Initialise() | ||
605 | { | ||
606 | Logger.Log.InfoFormat("[ASSET]: {0} cannot be default-initialized!", Name); | ||
607 | throw new PluginNotInitialisedException(Name); | ||
608 | } | ||
609 | |||
610 | public void Dispose() | ||
611 | { | ||
612 | } | ||
613 | |||
614 | public string Version | ||
615 | { | ||
616 | // TODO: this should be something meaningful and not hardcoded? | ||
617 | get { return "0.1"; } | ||
618 | } | ||
619 | |||
620 | public string Name | ||
621 | { | ||
622 | get { return "AssetInventoryServer Simple inventory storage provider"; } | ||
623 | } | ||
624 | |||
625 | #endregion IPlugin implementation | ||
626 | } | ||
627 | } | ||