aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/InventoryFolderImpl.cs932
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs1046
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs546
-rw-r--r--OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs552
4 files changed, 1538 insertions, 1538 deletions
diff --git a/OpenSim/Framework/InventoryFolderImpl.cs b/OpenSim/Framework/InventoryFolderImpl.cs
index 248783f..00462f9 100644
--- a/OpenSim/Framework/InventoryFolderImpl.cs
+++ b/OpenSim/Framework/InventoryFolderImpl.cs
@@ -1,466 +1,466 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31 31
32namespace OpenSim.Framework 32namespace OpenSim.Framework
33{ 33{
34 public class InventoryFolderImpl : InventoryFolderBase 34 public class InventoryFolderImpl : InventoryFolderBase
35 { 35 {
36 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 36 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
37 37
38 public static readonly string PATH_DELIMITER = "/"; 38 public static readonly string PATH_DELIMITER = "/";
39 39
40 /// <summary> 40 /// <summary>
41 /// Items that are contained in this folder 41 /// Items that are contained in this folder
42 /// </summary> 42 /// </summary>
43 public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>(); 43 public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>();
44 44
45 /// <summary> 45 /// <summary>
46 /// Child folders that are contained in this folder 46 /// Child folders that are contained in this folder
47 /// </summary> 47 /// </summary>
48 protected Dictionary<UUID, InventoryFolderImpl> m_childFolders = new Dictionary<UUID, InventoryFolderImpl>(); 48 protected Dictionary<UUID, InventoryFolderImpl> m_childFolders = new Dictionary<UUID, InventoryFolderImpl>();
49 49
50 // Constructors 50 // Constructors
51 public InventoryFolderImpl(InventoryFolderBase folderbase) 51 public InventoryFolderImpl(InventoryFolderBase folderbase)
52 { 52 {
53 Owner = folderbase.Owner; 53 Owner = folderbase.Owner;
54 ID = folderbase.ID; 54 ID = folderbase.ID;
55 Name = folderbase.Name; 55 Name = folderbase.Name;
56 ParentID = folderbase.ParentID; 56 ParentID = folderbase.ParentID;
57 Type = folderbase.Type; 57 Type = folderbase.Type;
58 Version = folderbase.Version; 58 Version = folderbase.Version;
59 } 59 }
60 60
61 public InventoryFolderImpl() 61 public InventoryFolderImpl()
62 { 62 {
63 } 63 }
64 64
65 /// <summary> 65 /// <summary>
66 /// Create a new subfolder. 66 /// Create a new subfolder.
67 /// </summary> 67 /// </summary>
68 /// <param name="folderID"></param> 68 /// <param name="folderID"></param>
69 /// <param name="folderName"></param> 69 /// <param name="folderName"></param>
70 /// <param name="type"></param> 70 /// <param name="type"></param>
71 /// <returns>The newly created subfolder. Returns null if the folder already exists</returns> 71 /// <returns>The newly created subfolder. Returns null if the folder already exists</returns>
72 public InventoryFolderImpl CreateChildFolder(UUID folderID, string folderName, ushort type) 72 public InventoryFolderImpl CreateChildFolder(UUID folderID, string folderName, ushort type)
73 { 73 {
74 lock (m_childFolders) 74 lock (m_childFolders)
75 { 75 {
76 if (!m_childFolders.ContainsKey(folderID)) 76 if (!m_childFolders.ContainsKey(folderID))
77 { 77 {
78 InventoryFolderImpl subFold = new InventoryFolderImpl(); 78 InventoryFolderImpl subFold = new InventoryFolderImpl();
79 subFold.Name = folderName; 79 subFold.Name = folderName;
80 subFold.ID = folderID; 80 subFold.ID = folderID;
81 subFold.Type = (short)type; 81 subFold.Type = (short)type;
82 subFold.ParentID = this.ID; 82 subFold.ParentID = this.ID;
83 subFold.Owner = Owner; 83 subFold.Owner = Owner;
84 m_childFolders.Add(subFold.ID, subFold); 84 m_childFolders.Add(subFold.ID, subFold);
85 85
86 return subFold; 86 return subFold;
87 } 87 }
88 } 88 }
89 89
90 return null; 90 return null;
91 } 91 }
92 92
93 /// <summary> 93 /// <summary>
94 /// Add a folder that already exists. 94 /// Add a folder that already exists.
95 /// </summary> 95 /// </summary>
96 /// <param name="folder"></param> 96 /// <param name="folder"></param>
97 public void AddChildFolder(InventoryFolderImpl folder) 97 public void AddChildFolder(InventoryFolderImpl folder)
98 { 98 {
99 lock (m_childFolders) 99 lock (m_childFolders)
100 { 100 {
101 folder.ParentID = ID; 101 folder.ParentID = ID;
102 m_childFolders[folder.ID] = folder; 102 m_childFolders[folder.ID] = folder;
103 } 103 }
104 } 104 }
105 105
106 /// <summary> 106 /// <summary>
107 /// Does this folder contain the given child folder? 107 /// Does this folder contain the given child folder?
108 /// </summary> 108 /// </summary>
109 /// <param name="folderID"></param> 109 /// <param name="folderID"></param>
110 /// <returns></returns> 110 /// <returns></returns>
111 public bool ContainsChildFolder(UUID folderID) 111 public bool ContainsChildFolder(UUID folderID)
112 { 112 {
113 return m_childFolders.ContainsKey(folderID); 113 return m_childFolders.ContainsKey(folderID);
114 } 114 }
115 115
116 /// <summary> 116 /// <summary>
117 /// Get a child folder 117 /// Get a child folder
118 /// </summary> 118 /// </summary>
119 /// <param name="folderID"></param> 119 /// <param name="folderID"></param>
120 /// <returns>The folder if it exists, null if it doesn't</returns> 120 /// <returns>The folder if it exists, null if it doesn't</returns>
121 public InventoryFolderImpl GetChildFolder(UUID folderID) 121 public InventoryFolderImpl GetChildFolder(UUID folderID)
122 { 122 {
123 InventoryFolderImpl folder = null; 123 InventoryFolderImpl folder = null;
124 124
125 lock (m_childFolders) 125 lock (m_childFolders)
126 { 126 {
127 m_childFolders.TryGetValue(folderID, out folder); 127 m_childFolders.TryGetValue(folderID, out folder);
128 } 128 }
129 129
130 return folder; 130 return folder;
131 } 131 }
132 132
133 /// <summary> 133 /// <summary>
134 /// Removes the given child subfolder. 134 /// Removes the given child subfolder.
135 /// </summary> 135 /// </summary>
136 /// <param name="folderID"></param> 136 /// <param name="folderID"></param>
137 /// <returns> 137 /// <returns>
138 /// The folder removed, or null if the folder was not present. 138 /// The folder removed, or null if the folder was not present.
139 /// </returns> 139 /// </returns>
140 public InventoryFolderImpl RemoveChildFolder(UUID folderID) 140 public InventoryFolderImpl RemoveChildFolder(UUID folderID)
141 { 141 {
142 InventoryFolderImpl removedFolder = null; 142 InventoryFolderImpl removedFolder = null;
143 143
144 lock (m_childFolders) 144 lock (m_childFolders)
145 { 145 {
146 if (m_childFolders.ContainsKey(folderID)) 146 if (m_childFolders.ContainsKey(folderID))
147 { 147 {
148 removedFolder = m_childFolders[folderID]; 148 removedFolder = m_childFolders[folderID];
149 m_childFolders.Remove(folderID); 149 m_childFolders.Remove(folderID);
150 } 150 }
151 } 151 }
152 152
153 return removedFolder; 153 return removedFolder;
154 } 154 }
155 155
156 /// <summary> 156 /// <summary>
157 /// Delete all the folders and items in this folder. 157 /// Delete all the folders and items in this folder.
158 /// </summary> 158 /// </summary>
159 public void Purge() 159 public void Purge()
160 { 160 {
161 foreach (InventoryFolderImpl folder in m_childFolders.Values) 161 foreach (InventoryFolderImpl folder in m_childFolders.Values)
162 { 162 {
163 folder.Purge(); 163 folder.Purge();
164 } 164 }
165 165
166 m_childFolders.Clear(); 166 m_childFolders.Clear();
167 Items.Clear(); 167 Items.Clear();
168 } 168 }
169 169
170 /// <summary> 170 /// <summary>
171 /// Returns the item if it exists in this folder or in any of this folder's descendant folders 171 /// Returns the item if it exists in this folder or in any of this folder's descendant folders
172 /// </summary> 172 /// </summary>
173 /// <param name="itemID"></param> 173 /// <param name="itemID"></param>
174 /// <returns>null if the item is not found</returns> 174 /// <returns>null if the item is not found</returns>
175 public InventoryItemBase FindItem(UUID itemID) 175 public InventoryItemBase FindItem(UUID itemID)
176 { 176 {
177 lock (Items) 177 lock (Items)
178 { 178 {
179 if (Items.ContainsKey(itemID)) 179 if (Items.ContainsKey(itemID))
180 { 180 {
181 return Items[itemID]; 181 return Items[itemID];
182 } 182 }
183 } 183 }
184 184
185 lock (m_childFolders) 185 lock (m_childFolders)
186 { 186 {
187 foreach (InventoryFolderImpl folder in m_childFolders.Values) 187 foreach (InventoryFolderImpl folder in m_childFolders.Values)
188 { 188 {
189 InventoryItemBase item = folder.FindItem(itemID); 189 InventoryItemBase item = folder.FindItem(itemID);
190 190
191 if (item != null) 191 if (item != null)
192 { 192 {
193 return item; 193 return item;
194 } 194 }
195 } 195 }
196 } 196 }
197 197
198 return null; 198 return null;
199 } 199 }
200 200
201 public InventoryItemBase FindAsset(UUID assetID) 201 public InventoryItemBase FindAsset(UUID assetID)
202 { 202 {
203 lock (Items) 203 lock (Items)
204 { 204 {
205 foreach (InventoryItemBase item in Items.Values) 205 foreach (InventoryItemBase item in Items.Values)
206 { 206 {
207 if (item.AssetID == assetID) 207 if (item.AssetID == assetID)
208 return item; 208 return item;
209 } 209 }
210 } 210 }
211 211
212 lock (m_childFolders) 212 lock (m_childFolders)
213 { 213 {
214 foreach (InventoryFolderImpl folder in m_childFolders.Values) 214 foreach (InventoryFolderImpl folder in m_childFolders.Values)
215 { 215 {
216 InventoryItemBase item = folder.FindAsset(assetID); 216 InventoryItemBase item = folder.FindAsset(assetID);
217 217
218 if (item != null) 218 if (item != null)
219 { 219 {
220 return item; 220 return item;
221 } 221 }
222 } 222 }
223 } 223 }
224 224
225 return null; 225 return null;
226 } 226 }
227 227
228 /// <summary> 228 /// <summary>
229 /// Deletes an item if it exists in this folder or any children 229 /// Deletes an item if it exists in this folder or any children
230 /// </summary> 230 /// </summary>
231 /// <param name="folderID"></param> 231 /// <param name="folderID"></param>
232 /// <returns></returns> 232 /// <returns></returns>
233 public bool DeleteItem(UUID itemID) 233 public bool DeleteItem(UUID itemID)
234 { 234 {
235 bool found = false; 235 bool found = false;
236 236
237 lock (Items) 237 lock (Items)
238 { 238 {
239 if (Items.ContainsKey(itemID)) 239 if (Items.ContainsKey(itemID))
240 { 240 {
241 Items.Remove(itemID); 241 Items.Remove(itemID);
242 return true; 242 return true;
243 } 243 }
244 } 244 }
245 245
246 lock (m_childFolders) 246 lock (m_childFolders)
247 { 247 {
248 foreach (InventoryFolderImpl folder in m_childFolders.Values) 248 foreach (InventoryFolderImpl folder in m_childFolders.Values)
249 { 249 {
250 found = folder.DeleteItem(itemID); 250 found = folder.DeleteItem(itemID);
251 251
252 if (found == true) 252 if (found == true)
253 { 253 {
254 break; 254 break;
255 } 255 }
256 } 256 }
257 } 257 }
258 258
259 return found; 259 return found;
260 } 260 }
261 261
262 /// <summary> 262 /// <summary>
263 /// Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth 263 /// Returns the folder requested if it is this folder or is a descendent of this folder. The search is depth
264 /// first. 264 /// first.
265 /// </summary> 265 /// </summary>
266 /// <returns>The requested folder if it exists, null if it does not.</returns> 266 /// <returns>The requested folder if it exists, null if it does not.</returns>
267 public InventoryFolderImpl FindFolder(UUID folderID) 267 public InventoryFolderImpl FindFolder(UUID folderID)
268 { 268 {
269 if (folderID == ID) 269 if (folderID == ID)
270 return this; 270 return this;
271 271
272 lock (m_childFolders) 272 lock (m_childFolders)
273 { 273 {
274 foreach (InventoryFolderImpl folder in m_childFolders.Values) 274 foreach (InventoryFolderImpl folder in m_childFolders.Values)
275 { 275 {
276 InventoryFolderImpl returnFolder = folder.FindFolder(folderID); 276 InventoryFolderImpl returnFolder = folder.FindFolder(folderID);
277 277
278 if (returnFolder != null) 278 if (returnFolder != null)
279 return returnFolder; 279 return returnFolder;
280 } 280 }
281 } 281 }
282 282
283 return null; 283 return null;
284 } 284 }
285 285
286 /// <summary> 286 /// <summary>
287 /// Look through all child subfolders for a folder marked as one for a particular asset type, and return it. 287 /// Look through all child subfolders for a folder marked as one for a particular asset type, and return it.
288 /// </summary> 288 /// </summary>
289 /// <param name="type"></param> 289 /// <param name="type"></param>
290 /// <returns>Returns null if no such folder is found</returns> 290 /// <returns>Returns null if no such folder is found</returns>
291 public InventoryFolderImpl FindFolderForType(int type) 291 public InventoryFolderImpl FindFolderForType(int type)
292 { 292 {
293 lock (m_childFolders) 293 lock (m_childFolders)
294 { 294 {
295 foreach (InventoryFolderImpl f in m_childFolders.Values) 295 foreach (InventoryFolderImpl f in m_childFolders.Values)
296 { 296 {
297 if (f.Type == type) 297 if (f.Type == type)
298 return f; 298 return f;
299 } 299 }
300 } 300 }
301 301
302 return null; 302 return null;
303 } 303 }
304 304
305 /// <summary> 305 /// <summary>
306 /// Find a folder given a PATH_DELIMITER delimited path starting from this folder 306 /// Find a folder given a PATH_DELIMITER delimited path starting from this folder
307 /// </summary> 307 /// </summary>
308 /// 308 ///
309 /// This method does not handle paths that contain multiple delimitors 309 /// This method does not handle paths that contain multiple delimitors
310 /// 310 ///
311 /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some 311 /// FIXME: We do not yet handle situations where folders have the same name. We could handle this by some
312 /// XPath like expression 312 /// XPath like expression
313 /// 313 ///
314 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 314 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
315 /// 315 ///
316 /// <param name="path"> 316 /// <param name="path">
317 /// The path to the required folder. 317 /// The path to the required folder.
318 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned. 318 /// It this is empty or consists only of the PATH_DELIMTER then this folder itself is returned.
319 /// </param> 319 /// </param>
320 /// <returns>null if the folder is not found</returns> 320 /// <returns>null if the folder is not found</returns>
321 public InventoryFolderImpl FindFolderByPath(string path) 321 public InventoryFolderImpl FindFolderByPath(string path)
322 { 322 {
323 if (path == string.Empty) 323 if (path == string.Empty)
324 return this; 324 return this;
325 325
326 path = path.Trim(); 326 path = path.Trim();
327 327
328 if (path == PATH_DELIMITER) 328 if (path == PATH_DELIMITER)
329 return this; 329 return this;
330 330
331 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 331 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
332 332
333 lock (m_childFolders) 333 lock (m_childFolders)
334 { 334 {
335 foreach (InventoryFolderImpl folder in m_childFolders.Values) 335 foreach (InventoryFolderImpl folder in m_childFolders.Values)
336 { 336 {
337 if (folder.Name == components[0]) 337 if (folder.Name == components[0])
338 if (components.Length > 1) 338 if (components.Length > 1)
339 return folder.FindFolderByPath(components[1]); 339 return folder.FindFolderByPath(components[1]);
340 else 340 else
341 return folder; 341 return folder;
342 } 342 }
343 } 343 }
344 344
345 // We didn't find a folder with the given name 345 // We didn't find a folder with the given name
346 return null; 346 return null;
347 } 347 }
348 348
349 /// <summary> 349 /// <summary>
350 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder. 350 /// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
351 /// 351 ///
352 /// This method does not handle paths that contain multiple delimitors 352 /// This method does not handle paths that contain multiple delimitors
353 /// 353 ///
354 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some 354 /// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
355 /// XPath like expression 355 /// XPath like expression
356 /// 356 ///
357 /// FIXME: Delimitors which occur in names themselves are not currently escapable. 357 /// FIXME: Delimitors which occur in names themselves are not currently escapable.
358 /// </summary> 358 /// </summary>
359 /// <param name="path"> 359 /// <param name="path">
360 /// The path to the required item. 360 /// The path to the required item.
361 /// </param> 361 /// </param>
362 /// <returns>null if the item is not found</returns> 362 /// <returns>null if the item is not found</returns>
363 public InventoryItemBase FindItemByPath(string path) 363 public InventoryItemBase FindItemByPath(string path)
364 { 364 {
365 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 365 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
366 366
367 if (components.Length == 1) 367 if (components.Length == 1)
368 { 368 {
369 lock (Items) 369 lock (Items)
370 { 370 {
371 foreach (InventoryItemBase item in Items.Values) 371 foreach (InventoryItemBase item in Items.Values)
372 { 372 {
373 if (item.Name == components[0]) 373 if (item.Name == components[0])
374 return item; 374 return item;
375 } 375 }
376 } 376 }
377 } 377 }
378 else 378 else
379 { 379 {
380 lock (m_childFolders) 380 lock (m_childFolders)
381 { 381 {
382 foreach (InventoryFolderImpl folder in m_childFolders.Values) 382 foreach (InventoryFolderImpl folder in m_childFolders.Values)
383 { 383 {
384 if (folder.Name == components[0]) 384 if (folder.Name == components[0])
385 return folder.FindItemByPath(components[1]); 385 return folder.FindItemByPath(components[1]);
386 } 386 }
387 } 387 }
388 } 388 }
389 389
390 // We didn't find an item or intermediate folder with the given name 390 // We didn't find an item or intermediate folder with the given name
391 return null; 391 return null;
392 } 392 }
393 393
394 /// <summary> 394 /// <summary>
395 /// Return a copy of the list of child items in this folder. The items themselves are the originals. 395 /// Return a copy of the list of child items in this folder. The items themselves are the originals.
396 /// </summary> 396 /// </summary>
397 public List<InventoryItemBase> RequestListOfItems() 397 public List<InventoryItemBase> RequestListOfItems()
398 { 398 {
399 List<InventoryItemBase> itemList = new List<InventoryItemBase>(); 399 List<InventoryItemBase> itemList = new List<InventoryItemBase>();
400 400
401 lock (Items) 401 lock (Items)
402 { 402 {
403 foreach (InventoryItemBase item in Items.Values) 403 foreach (InventoryItemBase item in Items.Values)
404 { 404 {
405 itemList.Add(item); 405 itemList.Add(item);
406 } 406 }
407 } 407 }
408 408
409 //m_log.DebugFormat("[INVENTORY FOLDER IMPL]: Found {0} items", itemList.Count); 409 //m_log.DebugFormat("[INVENTORY FOLDER IMPL]: Found {0} items", itemList.Count);
410 410
411 return itemList; 411 return itemList;
412 } 412 }
413 413
414 /// <summary> 414 /// <summary>
415 /// Return a copy of the list of child folders in this folder. The folders themselves are the originals. 415 /// Return a copy of the list of child folders in this folder. The folders themselves are the originals.
416 /// </summary> 416 /// </summary>
417 public List<InventoryFolderBase> RequestListOfFolders() 417 public List<InventoryFolderBase> RequestListOfFolders()
418 { 418 {
419 List<InventoryFolderBase> folderList = new List<InventoryFolderBase>(); 419 List<InventoryFolderBase> folderList = new List<InventoryFolderBase>();
420 420
421 lock (m_childFolders) 421 lock (m_childFolders)
422 { 422 {
423 foreach (InventoryFolderBase folder in m_childFolders.Values) 423 foreach (InventoryFolderBase folder in m_childFolders.Values)
424 { 424 {
425 folderList.Add(folder); 425 folderList.Add(folder);
426 } 426 }
427 } 427 }
428 428
429 return folderList; 429 return folderList;
430 } 430 }
431 431
432 public List<InventoryFolderImpl> RequestListOfFolderImpls() 432 public List<InventoryFolderImpl> RequestListOfFolderImpls()
433 { 433 {
434 List<InventoryFolderImpl> folderList = new List<InventoryFolderImpl>(); 434 List<InventoryFolderImpl> folderList = new List<InventoryFolderImpl>();
435 435
436 lock (m_childFolders) 436 lock (m_childFolders)
437 { 437 {
438 foreach (InventoryFolderImpl folder in m_childFolders.Values) 438 foreach (InventoryFolderImpl folder in m_childFolders.Values)
439 { 439 {
440 folderList.Add(folder); 440 folderList.Add(folder);
441 } 441 }
442 } 442 }
443 443
444 return folderList; 444 return folderList;
445 } 445 }
446 446
447 /// <value> 447 /// <value>
448 /// The total number of items in this folder and in the immediate child folders (though not from other 448 /// The total number of items in this folder and in the immediate child folders (though not from other
449 /// descendants). 449 /// descendants).
450 /// </value> 450 /// </value>
451 public int TotalCount 451 public int TotalCount
452 { 452 {
453 get 453 get
454 { 454 {
455 int total = Items.Count; 455 int total = Items.Count;
456 456
457 foreach (InventoryFolderImpl folder in m_childFolders.Values) 457 foreach (InventoryFolderImpl folder in m_childFolders.Values)
458 { 458 {
459 total = total + folder.TotalCount; 459 total = total + folder.TotalCount;
460 } 460 }
461 461
462 return total; 462 return total;
463 } 463 }
464 } 464 }
465 } 465 }
466} 466}
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 99282a3..9540bd4 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -1,523 +1,523 @@
1/* 1/*
2Copyright (c) Contributors, http://osflotsam.org/ 2Copyright (c) Contributors, http://osflotsam.org/
3See CONTRIBUTORS.TXT for a full list of copyright holders. 3See CONTRIBUTORS.TXT for a full list of copyright holders.
4 4
5Redistribution and use in source and binary forms, with or without 5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met: 6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright 7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer. 8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright 9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the 10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution. 11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the Flotsam Project nor the 12 * Neither the name of the Flotsam Project nor the
13 names of its contributors may be used to endorse or promote products 13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission. 14 derived from this software without specific prior written permission.
15 15
16THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 16THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
17IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 21DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
27 27
28// Uncomment to make asset Get requests for existing 28// Uncomment to make asset Get requests for existing
29// #define WAIT_ON_INPROGRESS_REQUESTS 29// #define WAIT_ON_INPROGRESS_REQUESTS
30 30
31using System; 31using System;
32using System.IO; 32using System.IO;
33using System.Collections.Generic; 33using System.Collections.Generic;
34using System.Reflection; 34using System.Reflection;
35using System.Runtime.Serialization; 35using System.Runtime.Serialization;
36using System.Runtime.Serialization.Formatters.Binary; 36using System.Runtime.Serialization.Formatters.Binary;
37using System.Threading; 37using System.Threading;
38using System.Timers; 38using System.Timers;
39 39
40using log4net; 40using log4net;
41using Nini.Config; 41using Nini.Config;
42using Mono.Addins; 42using Mono.Addins;
43using OpenMetaverse; 43using OpenMetaverse;
44 44
45using OpenSim.Framework; 45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces; 46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Services.Interfaces; 48using OpenSim.Services.Interfaces;
49 49
50 50
51[assembly: Addin("FlotsamAssetCache", "1.1")] 51[assembly: Addin("FlotsamAssetCache", "1.1")]
52[assembly: AddinDependency("OpenSim", "0.5")] 52[assembly: AddinDependency("OpenSim", "0.5")]
53 53
54namespace Flotsam.RegionModules.AssetCache 54namespace Flotsam.RegionModules.AssetCache
55{ 55{
56 /// <summary> 56 /// <summary>
57 /// OpenSim.ini Options: 57 /// OpenSim.ini Options:
58 /// ------- 58 /// -------
59 /// [Modules] 59 /// [Modules]
60 /// AssetCaching = "FlotsamAssetCache" 60 /// AssetCaching = "FlotsamAssetCache"
61 /// 61 ///
62 /// [AssetCache] 62 /// [AssetCache]
63 /// ; cache directory can be shared by multiple instances 63 /// ; cache directory can be shared by multiple instances
64 /// CacheDirectory = /directory/writable/by/OpenSim/instance 64 /// CacheDirectory = /directory/writable/by/OpenSim/instance
65 /// 65 ///
66 /// ; Log level 66 /// ; Log level
67 /// ; 0 - (Error) Errors only 67 /// ; 0 - (Error) Errors only
68 /// ; 1 - (Info) Hit Rate Stats + Level 0 68 /// ; 1 - (Info) Hit Rate Stats + Level 0
69 /// ; 2 - (Debug) Cache Activity (Reads/Writes) + Level 1 69 /// ; 2 - (Debug) Cache Activity (Reads/Writes) + Level 1
70 /// ; 70 /// ;
71 /// LogLevel = 1 71 /// LogLevel = 1
72 /// 72 ///
73 /// ; How often should hit rates be displayed (given in AssetRequests) 73 /// ; How often should hit rates be displayed (given in AssetRequests)
74 /// ; 0 to disable 74 /// ; 0 to disable
75 /// HitRateDisplay = 100 75 /// HitRateDisplay = 100
76 /// 76 ///
77 /// ; Set to false for disk cache only. 77 /// ; Set to false for disk cache only.
78 /// MemoryCacheEnabled = true 78 /// MemoryCacheEnabled = true
79 /// 79 ///
80 /// ; How long {in hours} to keep assets cached in memory, .5 == 30 minutes 80 /// ; How long {in hours} to keep assets cached in memory, .5 == 30 minutes
81 /// MemoryCacheTimeout = 2 81 /// MemoryCacheTimeout = 2
82 /// 82 ///
83 /// ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes 83 /// ; How long {in hours} to keep assets cached on disk, .5 == 30 minutes
84 /// ; Specify 0 if you do not want your disk cache to expire 84 /// ; Specify 0 if you do not want your disk cache to expire
85 /// FileCacheTimeout = 0 85 /// FileCacheTimeout = 0
86 /// 86 ///
87 /// ; How often {in hours} should the disk be checked for expired filed 87 /// ; How often {in hours} should the disk be checked for expired filed
88 /// ; Specify 0 to disable expiration checking 88 /// ; Specify 0 to disable expiration checking
89 /// FileCleanupTimer = .166 ;roughly every 10 minutes 89 /// FileCleanupTimer = .166 ;roughly every 10 minutes
90 /// 90 ///
91 /// ; If WAIT_ON_INPROGRESS_REQUESTS has been defined then this specifies how 91 /// ; If WAIT_ON_INPROGRESS_REQUESTS has been defined then this specifies how
92 /// ; long (in miliseconds) to block a request thread while trying to complete 92 /// ; long (in miliseconds) to block a request thread while trying to complete
93 /// ; writing to disk. 93 /// ; writing to disk.
94 /// WaitOnInprogressTimeout = 3000 94 /// WaitOnInprogressTimeout = 3000
95 /// ------- 95 /// -------
96 /// </summary> 96 /// </summary>
97 97
98 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 98 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
99 public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache 99 public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache
100 { 100 {
101 private static readonly ILog m_log = 101 private static readonly ILog m_log =
102 LogManager.GetLogger( 102 LogManager.GetLogger(
103 MethodBase.GetCurrentMethod().DeclaringType); 103 MethodBase.GetCurrentMethod().DeclaringType);
104 104
105 private bool m_Enabled = false; 105 private bool m_Enabled = false;
106 106
107 private const string m_ModuleName = "FlotsamAssetCache"; 107 private const string m_ModuleName = "FlotsamAssetCache";
108 private const string m_DefaultCacheDirectory = m_ModuleName; 108 private const string m_DefaultCacheDirectory = m_ModuleName;
109 private string m_CacheDirectory = m_DefaultCacheDirectory; 109 private string m_CacheDirectory = m_DefaultCacheDirectory;
110 110
111 111
112 private List<char> m_InvalidChars = new List<char>(); 112 private List<char> m_InvalidChars = new List<char>();
113 113
114 private int m_LogLevel = 1; 114 private int m_LogLevel = 1;
115 private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests 115 private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests
116 116
117 private static ulong m_Requests = 0; 117 private static ulong m_Requests = 0;
118 private static ulong m_RequestsForInprogress = 0; 118 private static ulong m_RequestsForInprogress = 0;
119 private static ulong m_DiskHits = 0; 119 private static ulong m_DiskHits = 0;
120 private static ulong m_MemoryHits = 0; 120 private static ulong m_MemoryHits = 0;
121 private static double m_HitRateMemory = 0.0; 121 private static double m_HitRateMemory = 0.0;
122 private static double m_HitRateFile = 0.0; 122 private static double m_HitRateFile = 0.0;
123 123
124#if WAIT_ON_INPROGRESS_REQUESTS 124#if WAIT_ON_INPROGRESS_REQUESTS
125 private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); 125 private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>();
126 private int m_WaitOnInprogressTimeout = 3000; 126 private int m_WaitOnInprogressTimeout = 3000;
127#else 127#else
128 private List<string> m_CurrentlyWriting = new List<string>(); 128 private List<string> m_CurrentlyWriting = new List<string>();
129#endif 129#endif
130 130
131 private ExpiringCache<string, AssetBase> m_MemoryCache = new ExpiringCache<string, AssetBase>(); 131 private ExpiringCache<string, AssetBase> m_MemoryCache = new ExpiringCache<string, AssetBase>();
132 private bool m_MemoryCacheEnabled = true; 132 private bool m_MemoryCacheEnabled = true;
133 133
134 // Expiration is expressed in hours. 134 // Expiration is expressed in hours.
135 private const double m_DefaultMemoryExpiration = 1.0; 135 private const double m_DefaultMemoryExpiration = 1.0;
136 private const double m_DefaultFileExpiration = 48; 136 private const double m_DefaultFileExpiration = 48;
137 private TimeSpan m_MemoryExpiration = TimeSpan.Zero; 137 private TimeSpan m_MemoryExpiration = TimeSpan.Zero;
138 private TimeSpan m_FileExpiration = TimeSpan.Zero; 138 private TimeSpan m_FileExpiration = TimeSpan.Zero;
139 private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.Zero; 139 private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.Zero;
140 140
141 private System.Timers.Timer m_CachCleanTimer = new System.Timers.Timer(); 141 private System.Timers.Timer m_CachCleanTimer = new System.Timers.Timer();
142 142
143 public FlotsamAssetCache() 143 public FlotsamAssetCache()
144 { 144 {
145 m_InvalidChars.AddRange(Path.GetInvalidPathChars()); 145 m_InvalidChars.AddRange(Path.GetInvalidPathChars());
146 m_InvalidChars.AddRange(Path.GetInvalidFileNameChars()); 146 m_InvalidChars.AddRange(Path.GetInvalidFileNameChars());
147 } 147 }
148 148
149 public string Name 149 public string Name
150 { 150 {
151 get { return m_ModuleName; } 151 get { return m_ModuleName; }
152 } 152 }
153 153
154 public void Initialise(IConfigSource source) 154 public void Initialise(IConfigSource source)
155 { 155 {
156 IConfig moduleConfig = source.Configs["Modules"]; 156 IConfig moduleConfig = source.Configs["Modules"];
157 157
158 if (moduleConfig != null) 158 if (moduleConfig != null)
159 { 159 {
160 string name = moduleConfig.GetString("AssetCaching", this.Name); 160 string name = moduleConfig.GetString("AssetCaching", this.Name);
161 161
162 if (name == Name) 162 if (name == Name)
163 { 163 {
164 IConfig assetConfig = source.Configs["AssetCache"]; 164 IConfig assetConfig = source.Configs["AssetCache"];
165 if (assetConfig == null) 165 if (assetConfig == null)
166 { 166 {
167 m_log.Error("[ASSET CACHE]: AssetCache missing from OpenSim.ini"); 167 m_log.Error("[ASSET CACHE]: AssetCache missing from OpenSim.ini");
168 return; 168 return;
169 } 169 }
170 170
171 m_Enabled = true; 171 m_Enabled = true;
172 172
173 m_log.InfoFormat("[ASSET CACHE]: {0} enabled", this.Name); 173 m_log.InfoFormat("[ASSET CACHE]: {0} enabled", this.Name);
174 174
175 m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); 175 m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
176 m_log.InfoFormat("[ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory); 176 m_log.InfoFormat("[ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory);
177 177
178 m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", true); 178 m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", true);
179 m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration)); 179 m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
180 180
181#if WAIT_ON_INPROGRESS_REQUESTS 181#if WAIT_ON_INPROGRESS_REQUESTS
182 m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); 182 m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
183#endif 183#endif
184 184
185 m_HitRateDisplay = (ulong)assetConfig.GetInt("HitRateDisplay", 1); 185 m_HitRateDisplay = (ulong)assetConfig.GetInt("HitRateDisplay", 1);
186 186
187 m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration)); 187 m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
188 m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration)); 188 m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration));
189 if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero)) 189 if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
190 { 190 {
191 m_CachCleanTimer.Interval = m_FileExpirationCleanupTimer.TotalMilliseconds; 191 m_CachCleanTimer.Interval = m_FileExpirationCleanupTimer.TotalMilliseconds;
192 m_CachCleanTimer.AutoReset = true; 192 m_CachCleanTimer.AutoReset = true;
193 m_CachCleanTimer.Elapsed += CleanupExpiredFiles; 193 m_CachCleanTimer.Elapsed += CleanupExpiredFiles;
194 m_CachCleanTimer.Enabled = true; 194 m_CachCleanTimer.Enabled = true;
195 m_CachCleanTimer.Start(); 195 m_CachCleanTimer.Start();
196 } 196 }
197 else 197 else
198 { 198 {
199 m_CachCleanTimer.Enabled = false; 199 m_CachCleanTimer.Enabled = false;
200 } 200 }
201 } 201 }
202 } 202 }
203 } 203 }
204 204
205 public void PostInitialise() 205 public void PostInitialise()
206 { 206 {
207 } 207 }
208 208
209 public void Close() 209 public void Close()
210 { 210 {
211 } 211 }
212 212
213 public void AddRegion(Scene scene) 213 public void AddRegion(Scene scene)
214 { 214 {
215 if (m_Enabled) 215 if (m_Enabled)
216 scene.RegisterModuleInterface<IImprovedAssetCache>(this); 216 scene.RegisterModuleInterface<IImprovedAssetCache>(this);
217 } 217 }
218 218
219 public void RemoveRegion(Scene scene) 219 public void RemoveRegion(Scene scene)
220 { 220 {
221 } 221 }
222 222
223 public void RegionLoaded(Scene scene) 223 public void RegionLoaded(Scene scene)
224 { 224 {
225 } 225 }
226 226
227 //////////////////////////////////////////////////////////// 227 ////////////////////////////////////////////////////////////
228 // IImprovedAssetCache 228 // IImprovedAssetCache
229 // 229 //
230 230
231 private void UpdateMemoryCache(string key, AssetBase asset) 231 private void UpdateMemoryCache(string key, AssetBase asset)
232 { 232 {
233 if( m_MemoryCacheEnabled ) 233 if( m_MemoryCacheEnabled )
234 { 234 {
235 if (m_MemoryExpiration > TimeSpan.Zero) 235 if (m_MemoryExpiration > TimeSpan.Zero)
236 { 236 {
237 m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration); 237 m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
238 } 238 }
239 else 239 else
240 { 240 {
241 m_MemoryCache.AddOrUpdate(key, asset, DateTime.MaxValue); 241 m_MemoryCache.AddOrUpdate(key, asset, DateTime.MaxValue);
242 } 242 }
243 } 243 }
244 } 244 }
245 245
246 public void Cache(AssetBase asset) 246 public void Cache(AssetBase asset)
247 { 247 {
248 // TODO: Spawn this off to some seperate thread to do the actual writing 248 // TODO: Spawn this off to some seperate thread to do the actual writing
249 if (asset != null) 249 if (asset != null)
250 { 250 {
251 UpdateMemoryCache(asset.ID, asset); 251 UpdateMemoryCache(asset.ID, asset);
252 252
253 string filename = GetFileName(asset.ID); 253 string filename = GetFileName(asset.ID);
254 254
255 try 255 try
256 { 256 {
257 // If the file is already cached, don't cache it, just touch it so access time is updated 257 // If the file is already cached, don't cache it, just touch it so access time is updated
258 if (File.Exists(filename)) 258 if (File.Exists(filename))
259 { 259 {
260 File.SetLastAccessTime(filename, DateTime.Now); 260 File.SetLastAccessTime(filename, DateTime.Now);
261 } else { 261 } else {
262 262
263 // Once we start writing, make sure we flag that we're writing 263 // Once we start writing, make sure we flag that we're writing
264 // that object to the cache so that we don't try to write the 264 // that object to the cache so that we don't try to write the
265 // same file multiple times. 265 // same file multiple times.
266 lock (m_CurrentlyWriting) 266 lock (m_CurrentlyWriting)
267 { 267 {
268#if WAIT_ON_INPROGRESS_REQUESTS 268#if WAIT_ON_INPROGRESS_REQUESTS
269 if (m_CurrentlyWriting.ContainsKey(filename)) 269 if (m_CurrentlyWriting.ContainsKey(filename))
270 { 270 {
271 return; 271 return;
272 } 272 }
273 else 273 else
274 { 274 {
275 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false)); 275 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
276 } 276 }
277 277
278#else 278#else
279 if (m_CurrentlyWriting.Contains(filename)) 279 if (m_CurrentlyWriting.Contains(filename))
280 { 280 {
281 return; 281 return;
282 } 282 }
283 else 283 else
284 { 284 {
285 m_CurrentlyWriting.Add(filename); 285 m_CurrentlyWriting.Add(filename);
286 } 286 }
287#endif 287#endif
288 288
289 } 289 }
290 290
291 ThreadPool.QueueUserWorkItem( 291 ThreadPool.QueueUserWorkItem(
292 delegate 292 delegate
293 { 293 {
294 WriteFileCache(filename, asset); 294 WriteFileCache(filename, asset);
295 } 295 }
296 ); 296 );
297 } 297 }
298 } 298 }
299 catch (Exception e) 299 catch (Exception e)
300 { 300 {
301 LogException(e); 301 LogException(e);
302 } 302 }
303 } 303 }
304 } 304 }
305 305
306 public AssetBase Get(string id) 306 public AssetBase Get(string id)
307 { 307 {
308 m_Requests++; 308 m_Requests++;
309 309
310 AssetBase asset = null; 310 AssetBase asset = null;
311 311
312 if (m_MemoryCacheEnabled && m_MemoryCache.TryGetValue(id, out asset)) 312 if (m_MemoryCacheEnabled && m_MemoryCache.TryGetValue(id, out asset))
313 { 313 {
314 m_MemoryHits++; 314 m_MemoryHits++;
315 } 315 }
316 else 316 else
317 { 317 {
318 string filename = GetFileName(id); 318 string filename = GetFileName(id);
319 if (File.Exists(filename)) 319 if (File.Exists(filename))
320 { 320 {
321 try 321 try
322 { 322 {
323 FileStream stream = File.Open(filename, FileMode.Open); 323 FileStream stream = File.Open(filename, FileMode.Open);
324 BinaryFormatter bformatter = new BinaryFormatter(); 324 BinaryFormatter bformatter = new BinaryFormatter();
325 325
326 asset = (AssetBase)bformatter.Deserialize(stream); 326 asset = (AssetBase)bformatter.Deserialize(stream);
327 stream.Close(); 327 stream.Close();
328 328
329 UpdateMemoryCache(id, asset); 329 UpdateMemoryCache(id, asset);
330 330
331 m_DiskHits++; 331 m_DiskHits++;
332 } 332 }
333 catch (System.Runtime.Serialization.SerializationException e) 333 catch (System.Runtime.Serialization.SerializationException e)
334 { 334 {
335 LogException(e); 335 LogException(e);
336 336
337 // If there was a problem deserializing the asset, the asset may 337 // If there was a problem deserializing the asset, the asset may
338 // either be corrupted OR was serialized under an old format 338 // either be corrupted OR was serialized under an old format
339 // {different version of AssetBase} -- we should attempt to 339 // {different version of AssetBase} -- we should attempt to
340 // delete it and re-cache 340 // delete it and re-cache
341 File.Delete(filename); 341 File.Delete(filename);
342 } 342 }
343 catch (Exception e) 343 catch (Exception e)
344 { 344 {
345 LogException(e); 345 LogException(e);
346 } 346 }
347 } 347 }
348 348
349 349
350#if WAIT_ON_INPROGRESS_REQUESTS 350#if WAIT_ON_INPROGRESS_REQUESTS
351 // Check if we're already downloading this asset. If so, try to wait for it to 351 // Check if we're already downloading this asset. If so, try to wait for it to
352 // download. 352 // download.
353 if (m_WaitOnInprogressTimeout > 0) 353 if (m_WaitOnInprogressTimeout > 0)
354 { 354 {
355 m_RequestsForInprogress++; 355 m_RequestsForInprogress++;
356 356
357 ManualResetEvent waitEvent; 357 ManualResetEvent waitEvent;
358 if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent)) 358 if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent))
359 { 359 {
360 waitEvent.WaitOne(m_WaitOnInprogressTimeout); 360 waitEvent.WaitOne(m_WaitOnInprogressTimeout);
361 return Get(id); 361 return Get(id);
362 } 362 }
363 } 363 }
364#else 364#else
365 // Track how often we have the problem that an asset is requested while 365 // Track how often we have the problem that an asset is requested while
366 // it is still being downloaded by a previous request. 366 // it is still being downloaded by a previous request.
367 if (m_CurrentlyWriting.Contains(filename)) 367 if (m_CurrentlyWriting.Contains(filename))
368 { 368 {
369 m_RequestsForInprogress++; 369 m_RequestsForInprogress++;
370 } 370 }
371#endif 371#endif
372 } 372 }
373 373
374 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) 374 if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
375 { 375 {
376 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; 376 m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0;
377 377
378 m_log.InfoFormat("[ASSET CACHE]: Cache Get :: {0} :: {1}", id, asset == null ? "Miss" : "Hit"); 378 m_log.InfoFormat("[ASSET CACHE]: Cache Get :: {0} :: {1}", id, asset == null ? "Miss" : "Hit");
379 m_log.InfoFormat("[ASSET CACHE]: File Hit Rate {0}% for {1} requests", m_HitRateFile.ToString("0.00"), m_Requests); 379 m_log.InfoFormat("[ASSET CACHE]: File Hit Rate {0}% for {1} requests", m_HitRateFile.ToString("0.00"), m_Requests);
380 380
381 if (m_MemoryCacheEnabled) 381 if (m_MemoryCacheEnabled)
382 { 382 {
383 m_HitRateMemory = (double)m_MemoryHits / m_Requests * 100.0; 383 m_HitRateMemory = (double)m_MemoryHits / m_Requests * 100.0;
384 m_log.InfoFormat("[ASSET CACHE]: Memory Hit Rate {0}% for {1} requests", m_HitRateMemory.ToString("0.00"), m_Requests); 384 m_log.InfoFormat("[ASSET CACHE]: Memory Hit Rate {0}% for {1} requests", m_HitRateMemory.ToString("0.00"), m_Requests);
385 } 385 }
386 386
387 m_log.InfoFormat("[ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); 387 m_log.InfoFormat("[ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress);
388 388
389 } 389 }
390 390
391 return asset; 391 return asset;
392 } 392 }
393 393
394 public void Expire(string id) 394 public void Expire(string id)
395 { 395 {
396 if (m_LogLevel >= 2) 396 if (m_LogLevel >= 2)
397 m_log.DebugFormat("[ASSET CACHE]: Expiring Asset {0}.", id); 397 m_log.DebugFormat("[ASSET CACHE]: Expiring Asset {0}.", id);
398 398
399 try 399 try
400 { 400 {
401 string filename = GetFileName(id); 401 string filename = GetFileName(id);
402 if (File.Exists(filename)) 402 if (File.Exists(filename))
403 { 403 {
404 File.Delete(filename); 404 File.Delete(filename);
405 } 405 }
406 406
407 if( m_MemoryCacheEnabled ) 407 if( m_MemoryCacheEnabled )
408 m_MemoryCache.Remove(id); 408 m_MemoryCache.Remove(id);
409 } 409 }
410 catch (Exception e) 410 catch (Exception e)
411 { 411 {
412 LogException(e); 412 LogException(e);
413 } 413 }
414 } 414 }
415 415
416 public void Clear() 416 public void Clear()
417 { 417 {
418 if (m_LogLevel >= 2) 418 if (m_LogLevel >= 2)
419 m_log.Debug("[ASSET CACHE]: Clearing Cache."); 419 m_log.Debug("[ASSET CACHE]: Clearing Cache.");
420 420
421 foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) 421 foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
422 { 422 {
423 Directory.Delete(dir); 423 Directory.Delete(dir);
424 } 424 }
425 425
426 if( m_MemoryCacheEnabled ) 426 if( m_MemoryCacheEnabled )
427 m_MemoryCache.Clear(); 427 m_MemoryCache.Clear();
428 } 428 }
429 429
430 private void CleanupExpiredFiles(object source, ElapsedEventArgs e) 430 private void CleanupExpiredFiles(object source, ElapsedEventArgs e)
431 { 431 {
432 if (m_LogLevel >= 2) 432 if (m_LogLevel >= 2)
433 m_log.DebugFormat("[ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration.ToString()); 433 m_log.DebugFormat("[ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration.ToString());
434 434
435 foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) 435 foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
436 { 436 {
437 foreach (string file in Directory.GetFiles(dir)) 437 foreach (string file in Directory.GetFiles(dir))
438 { 438 {
439 if (DateTime.Now - File.GetLastAccessTime(file) > m_FileExpiration) 439 if (DateTime.Now - File.GetLastAccessTime(file) > m_FileExpiration)
440 { 440 {
441 File.Delete(file); 441 File.Delete(file);
442 } 442 }
443 } 443 }
444 } 444 }
445 } 445 }
446 446
447 private string GetFileName(string id) 447 private string GetFileName(string id)
448 { 448 {
449 // Would it be faster to just hash the darn thing? 449 // Would it be faster to just hash the darn thing?
450 foreach (char c in m_InvalidChars) 450 foreach (char c in m_InvalidChars)
451 { 451 {
452 id = id.Replace(c, '_'); 452 id = id.Replace(c, '_');
453 } 453 }
454 454
455 string p = id.Substring(id.Length - 4); 455 string p = id.Substring(id.Length - 4);
456 p = Path.Combine(p, id); 456 p = Path.Combine(p, id);
457 return Path.Combine(m_CacheDirectory, p); 457 return Path.Combine(m_CacheDirectory, p);
458 } 458 }
459 459
460 private void WriteFileCache(string filename, AssetBase asset) 460 private void WriteFileCache(string filename, AssetBase asset)
461 { 461 {
462 try 462 try
463 { 463 {
464 // Make sure the target cache directory exists 464 // Make sure the target cache directory exists
465 string directory = Path.GetDirectoryName(filename); 465 string directory = Path.GetDirectoryName(filename);
466 if (!Directory.Exists(directory)) 466 if (!Directory.Exists(directory))
467 { 467 {
468 Directory.CreateDirectory(directory); 468 Directory.CreateDirectory(directory);
469 } 469 }
470 470
471 // Write file first to a temp name, so that it doesn't look 471 // Write file first to a temp name, so that it doesn't look
472 // like it's already cached while it's still writing. 472 // like it's already cached while it's still writing.
473 string tempname = Path.Combine(directory, Path.GetRandomFileName()); 473 string tempname = Path.Combine(directory, Path.GetRandomFileName());
474 Stream stream = File.Open(tempname, FileMode.Create); 474 Stream stream = File.Open(tempname, FileMode.Create);
475 BinaryFormatter bformatter = new BinaryFormatter(); 475 BinaryFormatter bformatter = new BinaryFormatter();
476 bformatter.Serialize(stream, asset); 476 bformatter.Serialize(stream, asset);
477 stream.Close(); 477 stream.Close();
478 478
479 // Now that it's written, rename it so that it can be found. 479 // Now that it's written, rename it so that it can be found.
480 File.Move(tempname, filename); 480 File.Move(tempname, filename);
481 481
482 if (m_LogLevel >= 2) 482 if (m_LogLevel >= 2)
483 m_log.DebugFormat("[ASSET CACHE]: Cache Stored :: {0}", asset.ID); 483 m_log.DebugFormat("[ASSET CACHE]: Cache Stored :: {0}", asset.ID);
484 } 484 }
485 catch (Exception e) 485 catch (Exception e)
486 { 486 {
487 LogException(e); 487 LogException(e);
488 } 488 }
489 finally 489 finally
490 { 490 {
491 // Even if the write fails with an exception, we need to make sure 491 // Even if the write fails with an exception, we need to make sure
492 // that we release the lock on that file, otherwise it'll never get 492 // that we release the lock on that file, otherwise it'll never get
493 // cached 493 // cached
494 lock (m_CurrentlyWriting) 494 lock (m_CurrentlyWriting)
495 { 495 {
496#if WAIT_ON_INPROGRESS_REQUESTS 496#if WAIT_ON_INPROGRESS_REQUESTS
497 ManualResetEvent waitEvent; 497 ManualResetEvent waitEvent;
498 if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent)) 498 if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent))
499 { 499 {
500 m_CurrentlyWriting.Remove(filename); 500 m_CurrentlyWriting.Remove(filename);
501 waitEvent.Set(); 501 waitEvent.Set();
502 } 502 }
503#else 503#else
504 if (m_CurrentlyWriting.Contains(filename)) 504 if (m_CurrentlyWriting.Contains(filename))
505 { 505 {
506 m_CurrentlyWriting.Remove(filename); 506 m_CurrentlyWriting.Remove(filename);
507 } 507 }
508#endif 508#endif
509 } 509 }
510 510
511 } 511 }
512 } 512 }
513 513
514 private static void LogException(Exception e) 514 private static void LogException(Exception e)
515 { 515 {
516 string[] text = e.ToString().Split(new char[] { '\n' }); 516 string[] text = e.ToString().Split(new char[] { '\n' });
517 foreach (string t in text) 517 foreach (string t in text)
518 { 518 {
519 m_log.ErrorFormat("[ASSET CACHE]: {0} ", t); 519 m_log.ErrorFormat("[ASSET CACHE]: {0} ", t);
520 } 520 }
521 } 521 }
522 } 522 }
523} 523}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs
index c89f295..6b72e9b 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectors/Inventory/LocalInventoryServiceConnector.cs
@@ -1,273 +1,273 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Nini.Config; 29using Nini.Config;
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Reflection; 32using System.Reflection;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Data; 34using OpenSim.Data;
35using OpenSim.Server.Base; 35using OpenSim.Server.Base;
36using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41namespace OpenSim.Region.CoreModules.ServiceConnectors.Inventory 41namespace OpenSim.Region.CoreModules.ServiceConnectors.Inventory
42{ 42{
43 public class LocalInventoryServicesConnector : 43 public class LocalInventoryServicesConnector :
44 ISharedRegionModule, IInventoryService 44 ISharedRegionModule, IInventoryService
45 { 45 {
46 private static readonly ILog m_log = 46 private static readonly ILog m_log =
47 LogManager.GetLogger( 47 LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType); 48 MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 private IInventoryService m_InventoryService; 50 private IInventoryService m_InventoryService;
51 51
52 private bool m_Enabled = false; 52 private bool m_Enabled = false;
53 53
54 public string Name 54 public string Name
55 { 55 {
56 get { return "LocalInventoryServicesConnector"; } 56 get { return "LocalInventoryServicesConnector"; }
57 } 57 }
58 58
59 public void Initialise(IConfigSource source) 59 public void Initialise(IConfigSource source)
60 { 60 {
61 IConfig moduleConfig = source.Configs["Modules"]; 61 IConfig moduleConfig = source.Configs["Modules"];
62 if (moduleConfig != null) 62 if (moduleConfig != null)
63 { 63 {
64 string name = moduleConfig.GetString("InventoryServices", ""); 64 string name = moduleConfig.GetString("InventoryServices", "");
65 if (name == Name) 65 if (name == Name)
66 { 66 {
67 IConfig assetConfig = source.Configs["InventoryService"]; 67 IConfig assetConfig = source.Configs["InventoryService"];
68 if (assetConfig == null) 68 if (assetConfig == null)
69 { 69 {
70 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); 70 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
71 return; 71 return;
72 } 72 }
73 73
74 string serviceDll = assetConfig.GetString("LocalServiceModule", 74 string serviceDll = assetConfig.GetString("LocalServiceModule",
75 String.Empty); 75 String.Empty);
76 76
77 if (serviceDll == String.Empty) 77 if (serviceDll == String.Empty)
78 { 78 {
79 m_log.Error("[INVENTORY CONNECTOR]: No LocalServiceModule named in section InventoryService"); 79 m_log.Error("[INVENTORY CONNECTOR]: No LocalServiceModule named in section InventoryService");
80 return; 80 return;
81 } 81 }
82 82
83 Object[] args = new Object[] { source }; 83 Object[] args = new Object[] { source };
84 m_InventoryService = 84 m_InventoryService =
85 ServerUtils.LoadPlugin<IInventoryService>(serviceDll, 85 ServerUtils.LoadPlugin<IInventoryService>(serviceDll,
86 args); 86 args);
87 87
88 if (m_InventoryService == null) 88 if (m_InventoryService == null)
89 { 89 {
90 m_log.Error("[INVENTORY CONNECTOR]: Can't load asset service"); 90 m_log.Error("[INVENTORY CONNECTOR]: Can't load asset service");
91 return; 91 return;
92 } 92 }
93 93
94 //List<IInventoryDataPlugin> plugins 94 //List<IInventoryDataPlugin> plugins
95 // = DataPluginFactory.LoadDataPlugins<IInventoryDataPlugin>( 95 // = DataPluginFactory.LoadDataPlugins<IInventoryDataPlugin>(
96 // configSettings.StandaloneInventoryPlugin, 96 // configSettings.StandaloneInventoryPlugin,
97 // configSettings.StandaloneInventorySource); 97 // configSettings.StandaloneInventorySource);
98 98
99 //foreach (IInventoryDataPlugin plugin in plugins) 99 //foreach (IInventoryDataPlugin plugin in plugins)
100 //{ 100 //{
101 // // Using the OSP wrapper plugin for database plugins should be made configurable at some point 101 // // Using the OSP wrapper plugin for database plugins should be made configurable at some point
102 // m_InventoryService.AddPlugin(new OspInventoryWrapperPlugin(plugin, this)); 102 // m_InventoryService.AddPlugin(new OspInventoryWrapperPlugin(plugin, this));
103 //} 103 //}
104 104
105 m_Enabled = true; 105 m_Enabled = true;
106 m_log.Info("[INVENTORY CONNECTOR]: Local asset connector enabled"); 106 m_log.Info("[INVENTORY CONNECTOR]: Local asset connector enabled");
107 } 107 }
108 } 108 }
109 } 109 }
110 110
111 public void PostInitialise() 111 public void PostInitialise()
112 { 112 {
113 } 113 }
114 114
115 public void Close() 115 public void Close()
116 { 116 {
117 } 117 }
118 118
119 public void AddRegion(Scene scene) 119 public void AddRegion(Scene scene)
120 { 120 {
121 if (!m_Enabled) 121 if (!m_Enabled)
122 return; 122 return;
123 123
124 scene.RegisterModuleInterface<IInventoryService>(this); 124 scene.RegisterModuleInterface<IInventoryService>(this);
125 } 125 }
126 126
127 public void RemoveRegion(Scene scene) 127 public void RemoveRegion(Scene scene)
128 { 128 {
129 } 129 }
130 130
131 public void RegionLoaded(Scene scene) 131 public void RegionLoaded(Scene scene)
132 { 132 {
133 if (!m_Enabled) 133 if (!m_Enabled)
134 return; 134 return;
135 135
136 m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName); 136 m_log.InfoFormat("[INVENTORY CONNECTOR]: Enabled local assets for region {0}", scene.RegionInfo.RegionName);
137 137
138 } 138 }
139 139
140 #region IInventoryService 140 #region IInventoryService
141 141
142 public bool CreateUserInventory(UUID user) 142 public bool CreateUserInventory(UUID user)
143 { 143 {
144 return m_InventoryService.CreateUserInventory(user); 144 return m_InventoryService.CreateUserInventory(user);
145 } 145 }
146 146
147 public List<InventoryFolderBase> GetInventorySkeleton(UUID userId) 147 public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
148 { 148 {
149 return m_InventoryService.GetInventorySkeleton(userId); 149 return m_InventoryService.GetInventorySkeleton(userId);
150 } 150 }
151 151
152 public InventoryCollection GetUserInventory(UUID id) 152 public InventoryCollection GetUserInventory(UUID id)
153 { 153 {
154 return m_InventoryService.GetUserInventory(id); 154 return m_InventoryService.GetUserInventory(id);
155 } 155 }
156 156
157 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) 157 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
158 { 158 {
159 m_InventoryService.GetUserInventory(userID, callback); 159 m_InventoryService.GetUserInventory(userID, callback);
160 } 160 }
161 161
162 public List<InventoryItemBase> GetFolderItems(UUID folderID) 162 public List<InventoryItemBase> GetFolderItems(UUID folderID)
163 { 163 {
164 return m_InventoryService.GetFolderItems(folderID); 164 return m_InventoryService.GetFolderItems(folderID);
165 } 165 }
166 166
167 /// <summary> 167 /// <summary>
168 /// Add a new folder to the user's inventory 168 /// Add a new folder to the user's inventory
169 /// </summary> 169 /// </summary>
170 /// <param name="folder"></param> 170 /// <param name="folder"></param>
171 /// <returns>true if the folder was successfully added</returns> 171 /// <returns>true if the folder was successfully added</returns>
172 public bool AddFolder(InventoryFolderBase folder) 172 public bool AddFolder(InventoryFolderBase folder)
173 { 173 {
174 return m_InventoryService.AddFolder(folder); 174 return m_InventoryService.AddFolder(folder);
175 } 175 }
176 176
177 /// <summary> 177 /// <summary>
178 /// Update a folder in the user's inventory 178 /// Update a folder in the user's inventory
179 /// </summary> 179 /// </summary>
180 /// <param name="folder"></param> 180 /// <param name="folder"></param>
181 /// <returns>true if the folder was successfully updated</returns> 181 /// <returns>true if the folder was successfully updated</returns>
182 public bool UpdateFolder(InventoryFolderBase folder) 182 public bool UpdateFolder(InventoryFolderBase folder)
183 { 183 {
184 return m_InventoryService.UpdateFolder(folder); 184 return m_InventoryService.UpdateFolder(folder);
185 } 185 }
186 186
187 /// <summary> 187 /// <summary>
188 /// Move an inventory folder to a new location 188 /// Move an inventory folder to a new location
189 /// </summary> 189 /// </summary>
190 /// <param name="folder">A folder containing the details of the new location</param> 190 /// <param name="folder">A folder containing the details of the new location</param>
191 /// <returns>true if the folder was successfully moved</returns> 191 /// <returns>true if the folder was successfully moved</returns>
192 public bool MoveFolder(InventoryFolderBase folder) 192 public bool MoveFolder(InventoryFolderBase folder)
193 { 193 {
194 return m_InventoryService.MoveFolder(folder); 194 return m_InventoryService.MoveFolder(folder);
195 } 195 }
196 196
197 /// <summary> 197 /// <summary>
198 /// Purge an inventory folder of all its items and subfolders. 198 /// Purge an inventory folder of all its items and subfolders.
199 /// </summary> 199 /// </summary>
200 /// <param name="folder"></param> 200 /// <param name="folder"></param>
201 /// <returns>true if the folder was successfully purged</returns> 201 /// <returns>true if the folder was successfully purged</returns>
202 public bool PurgeFolder(InventoryFolderBase folder) 202 public bool PurgeFolder(InventoryFolderBase folder)
203 { 203 {
204 return m_InventoryService.PurgeFolder(folder); 204 return m_InventoryService.PurgeFolder(folder);
205 } 205 }
206 206
207 /// <summary> 207 /// <summary>
208 /// Add a new item to the user's inventory 208 /// Add a new item to the user's inventory
209 /// </summary> 209 /// </summary>
210 /// <param name="item"></param> 210 /// <param name="item"></param>
211 /// <returns>true if the item was successfully added</returns> 211 /// <returns>true if the item was successfully added</returns>
212 public bool AddItem(InventoryItemBase item) 212 public bool AddItem(InventoryItemBase item)
213 { 213 {
214 return m_InventoryService.AddItem(item); 214 return m_InventoryService.AddItem(item);
215 } 215 }
216 216
217 /// <summary> 217 /// <summary>
218 /// Update an item in the user's inventory 218 /// Update an item in the user's inventory
219 /// </summary> 219 /// </summary>
220 /// <param name="item"></param> 220 /// <param name="item"></param>
221 /// <returns>true if the item was successfully updated</returns> 221 /// <returns>true if the item was successfully updated</returns>
222 public bool UpdateItem(InventoryItemBase item) 222 public bool UpdateItem(InventoryItemBase item)
223 { 223 {
224 return m_InventoryService.UpdateItem(item); 224 return m_InventoryService.UpdateItem(item);
225 } 225 }
226 226
227 /// <summary> 227 /// <summary>
228 /// Delete an item from the user's inventory 228 /// Delete an item from the user's inventory
229 /// </summary> 229 /// </summary>
230 /// <param name="item"></param> 230 /// <param name="item"></param>
231 /// <returns>true if the item was successfully deleted</returns> 231 /// <returns>true if the item was successfully deleted</returns>
232 public bool DeleteItem(InventoryItemBase item) 232 public bool DeleteItem(InventoryItemBase item)
233 { 233 {
234 return m_InventoryService.DeleteItem(item); 234 return m_InventoryService.DeleteItem(item);
235 } 235 }
236 236
237 public InventoryItemBase QueryItem(InventoryItemBase item) 237 public InventoryItemBase QueryItem(InventoryItemBase item)
238 { 238 {
239 return m_InventoryService.QueryItem(item); 239 return m_InventoryService.QueryItem(item);
240 } 240 }
241 241
242 public InventoryFolderBase QueryFolder(InventoryFolderBase folder) 242 public InventoryFolderBase QueryFolder(InventoryFolderBase folder)
243 { 243 {
244 return m_InventoryService.QueryFolder(folder); 244 return m_InventoryService.QueryFolder(folder);
245 } 245 }
246 246
247 /// <summary> 247 /// <summary>
248 /// Does the given user have an inventory structure? 248 /// Does the given user have an inventory structure?
249 /// </summary> 249 /// </summary>
250 /// <param name="userID"></param> 250 /// <param name="userID"></param>
251 /// <returns></returns> 251 /// <returns></returns>
252 public bool HasInventoryForUser(UUID userID) 252 public bool HasInventoryForUser(UUID userID)
253 { 253 {
254 return m_InventoryService.HasInventoryForUser(userID); 254 return m_InventoryService.HasInventoryForUser(userID);
255 } 255 }
256 256
257 /// <summary> 257 /// <summary>
258 /// Retrieve the root inventory folder for the given user. 258 /// Retrieve the root inventory folder for the given user.
259 /// </summary> 259 /// </summary>
260 /// <param name="userID"></param> 260 /// <param name="userID"></param>
261 /// <returns>null if no root folder was found</returns> 261 /// <returns>null if no root folder was found</returns>
262 public InventoryFolderBase RequestRootFolder(UUID userID) 262 public InventoryFolderBase RequestRootFolder(UUID userID)
263 { 263 {
264 return m_InventoryService.RequestRootFolder(userID); 264 return m_InventoryService.RequestRootFolder(userID);
265 } 265 }
266 266
267 public List<InventoryItemBase> GetActiveGestures(UUID userId) 267 public List<InventoryItemBase> GetActiveGestures(UUID userId)
268 { 268 {
269 return m_InventoryService.GetActiveGestures(userId); 269 return m_InventoryService.GetActiveGestures(userId);
270 } 270 }
271 #endregion IInventoryService 271 #endregion IInventoryService
272 } 272 }
273} 273}
diff --git a/OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs b/OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs
index c8d08de..3e3064a 100644
--- a/OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs
+++ b/OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs
@@ -1,276 +1,276 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Net; 31using System.Net;
32using System.Reflection; 32using System.Reflection;
33using log4net; 33using log4net;
34using Nini.Config; 34using Nini.Config;
35using Nwc.XmlRpc; 35using Nwc.XmlRpc;
36using OpenSim.Server.Base; 36using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
38using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Server.Handlers.Base; 40using OpenSim.Server.Handlers.Base;
41using OpenMetaverse; 41using OpenMetaverse;
42 42
43namespace OpenSim.Server.Handlers.Inventory 43namespace OpenSim.Server.Handlers.Inventory
44{ 44{
45 public class InventoryServiceInConnector : ServiceConnector 45 public class InventoryServiceInConnector : ServiceConnector
46 { 46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 private IInventoryService m_InventoryService; 49 private IInventoryService m_InventoryService;
50 50
51 private bool m_doLookup = false; 51 private bool m_doLookup = false;
52 52
53 //private static readonly int INVENTORY_DEFAULT_SESSION_TIME = 30; // secs 53 //private static readonly int INVENTORY_DEFAULT_SESSION_TIME = 30; // secs
54 //private AuthedSessionCache m_session_cache = new AuthedSessionCache(INVENTORY_DEFAULT_SESSION_TIME); 54 //private AuthedSessionCache m_session_cache = new AuthedSessionCache(INVENTORY_DEFAULT_SESSION_TIME);
55 55
56 private string m_userserver_url; 56 private string m_userserver_url;
57 57
58 public InventoryServiceInConnector(IConfigSource config, IHttpServer server) : 58 public InventoryServiceInConnector(IConfigSource config, IHttpServer server) :
59 base(config, server) 59 base(config, server)
60 { 60 {
61 IConfig serverConfig = config.Configs["InventoryService"]; 61 IConfig serverConfig = config.Configs["InventoryService"];
62 if (serverConfig == null) 62 if (serverConfig == null)
63 throw new Exception("No section 'InventoryService' in config file"); 63 throw new Exception("No section 'InventoryService' in config file");
64 64
65 string inventoryService = serverConfig.GetString("LocalServiceModule", 65 string inventoryService = serverConfig.GetString("LocalServiceModule",
66 String.Empty); 66 String.Empty);
67 67
68 if (inventoryService == String.Empty) 68 if (inventoryService == String.Empty)
69 throw new Exception("No InventoryService in config file"); 69 throw new Exception("No InventoryService in config file");
70 70
71 Object[] args = new Object[] { config }; 71 Object[] args = new Object[] { config };
72 m_InventoryService = 72 m_InventoryService =
73 ServerUtils.LoadPlugin<IInventoryService>(inventoryService, args); 73 ServerUtils.LoadPlugin<IInventoryService>(inventoryService, args);
74 74
75 m_userserver_url = serverConfig.GetString("UserServerURI", String.Empty); 75 m_userserver_url = serverConfig.GetString("UserServerURI", String.Empty);
76 m_doLookup = serverConfig.GetBoolean("SessionAuthentication", false); 76 m_doLookup = serverConfig.GetBoolean("SessionAuthentication", false);
77 77
78 AddHttpHandlers(server); 78 AddHttpHandlers(server);
79 } 79 }
80 80
81 protected virtual void AddHttpHandlers(IHttpServer m_httpServer) 81 protected virtual void AddHttpHandlers(IHttpServer m_httpServer)
82 { 82 {
83 m_httpServer.AddStreamHandler( 83 m_httpServer.AddStreamHandler(
84 new RestDeserialiseSecureHandler<Guid, InventoryCollection>( 84 new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
85 "POST", "/GetInventory/", GetUserInventory, CheckAuthSession)); 85 "POST", "/GetInventory/", GetUserInventory, CheckAuthSession));
86 86
87 m_httpServer.AddStreamHandler( 87 m_httpServer.AddStreamHandler(
88 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( 88 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
89 "POST", "/UpdateFolder/", m_InventoryService.UpdateFolder, CheckAuthSession)); 89 "POST", "/UpdateFolder/", m_InventoryService.UpdateFolder, CheckAuthSession));
90 90
91 m_httpServer.AddStreamHandler( 91 m_httpServer.AddStreamHandler(
92 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( 92 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
93 "POST", "/MoveFolder/", m_InventoryService.MoveFolder, CheckAuthSession)); 93 "POST", "/MoveFolder/", m_InventoryService.MoveFolder, CheckAuthSession));
94 94
95 m_httpServer.AddStreamHandler( 95 m_httpServer.AddStreamHandler(
96 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( 96 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
97 "POST", "/PurgeFolder/", m_InventoryService.PurgeFolder, CheckAuthSession)); 97 "POST", "/PurgeFolder/", m_InventoryService.PurgeFolder, CheckAuthSession));
98 98
99 m_httpServer.AddStreamHandler( 99 m_httpServer.AddStreamHandler(
100 new RestDeserialiseSecureHandler<InventoryItemBase, bool>( 100 new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
101 "POST", "/DeleteItem/", m_InventoryService.DeleteItem, CheckAuthSession)); 101 "POST", "/DeleteItem/", m_InventoryService.DeleteItem, CheckAuthSession));
102 102
103 m_httpServer.AddStreamHandler( 103 m_httpServer.AddStreamHandler(
104 new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>( 104 new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
105 "POST", "/QueryItem/", m_InventoryService.QueryItem, CheckAuthSession)); 105 "POST", "/QueryItem/", m_InventoryService.QueryItem, CheckAuthSession));
106 106
107 m_httpServer.AddStreamHandler( 107 m_httpServer.AddStreamHandler(
108 new RestDeserialiseSecureHandler<InventoryFolderBase, InventoryFolderBase>( 108 new RestDeserialiseSecureHandler<InventoryFolderBase, InventoryFolderBase>(
109 "POST", "/QueryFolder/", m_InventoryService.QueryFolder, CheckAuthSession)); 109 "POST", "/QueryFolder/", m_InventoryService.QueryFolder, CheckAuthSession));
110 110
111 m_httpServer.AddStreamHandler( 111 m_httpServer.AddStreamHandler(
112 new RestDeserialiseTrustedHandler<Guid, bool>( 112 new RestDeserialiseTrustedHandler<Guid, bool>(
113 "POST", "/CreateInventory/", CreateUsersInventory, CheckTrustSource)); 113 "POST", "/CreateInventory/", CreateUsersInventory, CheckTrustSource));
114 114
115 m_httpServer.AddStreamHandler( 115 m_httpServer.AddStreamHandler(
116 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( 116 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
117 "POST", "/NewFolder/", m_InventoryService.AddFolder, CheckAuthSession)); 117 "POST", "/NewFolder/", m_InventoryService.AddFolder, CheckAuthSession));
118 118
119 m_httpServer.AddStreamHandler( 119 m_httpServer.AddStreamHandler(
120 new RestDeserialiseTrustedHandler<InventoryFolderBase, bool>( 120 new RestDeserialiseTrustedHandler<InventoryFolderBase, bool>(
121 "POST", "/CreateFolder/", m_InventoryService.AddFolder, CheckTrustSource)); 121 "POST", "/CreateFolder/", m_InventoryService.AddFolder, CheckTrustSource));
122 122
123 m_httpServer.AddStreamHandler( 123 m_httpServer.AddStreamHandler(
124 new RestDeserialiseSecureHandler<InventoryItemBase, bool>( 124 new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
125 "POST", "/NewItem/", m_InventoryService.AddItem, CheckAuthSession)); 125 "POST", "/NewItem/", m_InventoryService.AddItem, CheckAuthSession));
126 126
127 m_httpServer.AddStreamHandler( 127 m_httpServer.AddStreamHandler(
128 new RestDeserialiseTrustedHandler<InventoryItemBase, bool>( 128 new RestDeserialiseTrustedHandler<InventoryItemBase, bool>(
129 "POST", "/AddNewItem/", m_InventoryService.AddItem, CheckTrustSource)); 129 "POST", "/AddNewItem/", m_InventoryService.AddItem, CheckTrustSource));
130 130
131 m_httpServer.AddStreamHandler( 131 m_httpServer.AddStreamHandler(
132 new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>>( 132 new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>>(
133 "POST", "/GetItems/", GetFolderItems, CheckTrustSource)); 133 "POST", "/GetItems/", GetFolderItems, CheckTrustSource));
134 134
135 // for persistent active gestures 135 // for persistent active gestures
136 m_httpServer.AddStreamHandler( 136 m_httpServer.AddStreamHandler(
137 new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>> 137 new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>>
138 ("POST", "/ActiveGestures/", GetActiveGestures, CheckTrustSource)); 138 ("POST", "/ActiveGestures/", GetActiveGestures, CheckTrustSource));
139 139
140 // WARNING: Root folders no longer just delivers the root and immediate child folders (e.g 140 // WARNING: Root folders no longer just delivers the root and immediate child folders (e.g
141 // system folders such as Objects, Textures), but it now returns the entire inventory skeleton. 141 // system folders such as Objects, Textures), but it now returns the entire inventory skeleton.
142 // It would have been better to rename this request, but complexities in the BaseHttpServer 142 // It would have been better to rename this request, but complexities in the BaseHttpServer
143 // (e.g. any http request not found is automatically treated as an xmlrpc request) make it easier 143 // (e.g. any http request not found is automatically treated as an xmlrpc request) make it easier
144 // to do this for now. 144 // to do this for now.
145 m_httpServer.AddStreamHandler( 145 m_httpServer.AddStreamHandler(
146 new RestDeserialiseTrustedHandler<Guid, List<InventoryFolderBase>> 146 new RestDeserialiseTrustedHandler<Guid, List<InventoryFolderBase>>
147 ("POST", "/RootFolders/", GetInventorySkeleton, CheckTrustSource)); 147 ("POST", "/RootFolders/", GetInventorySkeleton, CheckTrustSource));
148 } 148 }
149 149
150 #region Wrappers for converting the Guid parameter 150 #region Wrappers for converting the Guid parameter
151 151
152 public InventoryCollection GetUserInventory(Guid guid) 152 public InventoryCollection GetUserInventory(Guid guid)
153 { 153 {
154 UUID userID = new UUID(guid); 154 UUID userID = new UUID(guid);
155 return m_InventoryService.GetUserInventory(userID); 155 return m_InventoryService.GetUserInventory(userID);
156 } 156 }
157 157
158 public List<InventoryItemBase> GetFolderItems(Guid folderID) 158 public List<InventoryItemBase> GetFolderItems(Guid folderID)
159 { 159 {
160 List<InventoryItemBase> allItems = new List<InventoryItemBase>(); 160 List<InventoryItemBase> allItems = new List<InventoryItemBase>();
161 161
162 List<InventoryItemBase> items = m_InventoryService.GetFolderItems(new UUID(folderID)); 162 List<InventoryItemBase> items = m_InventoryService.GetFolderItems(new UUID(folderID));
163 163
164 if (items != null) 164 if (items != null)
165 { 165 {
166 allItems.InsertRange(0, items); 166 allItems.InsertRange(0, items);
167 } 167 }
168 return allItems; 168 return allItems;
169 } 169 }
170 170
171 public bool CreateUsersInventory(Guid rawUserID) 171 public bool CreateUsersInventory(Guid rawUserID)
172 { 172 {
173 UUID userID = new UUID(rawUserID); 173 UUID userID = new UUID(rawUserID);
174 174
175 175
176 return m_InventoryService.CreateUserInventory(userID); 176 return m_InventoryService.CreateUserInventory(userID);
177 } 177 }
178 178
179 public List<InventoryItemBase> GetActiveGestures(Guid rawUserID) 179 public List<InventoryItemBase> GetActiveGestures(Guid rawUserID)
180 { 180 {
181 UUID userID = new UUID(rawUserID); 181 UUID userID = new UUID(rawUserID);
182 182
183 return m_InventoryService.GetActiveGestures(userID); 183 return m_InventoryService.GetActiveGestures(userID);
184 } 184 }
185 185
186 public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID) 186 public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID)
187 { 187 {
188 UUID userID = new UUID(rawUserID); 188 UUID userID = new UUID(rawUserID);
189 return m_InventoryService.GetInventorySkeleton(userID); 189 return m_InventoryService.GetInventorySkeleton(userID);
190 } 190 }
191 191
192 #endregion 192 #endregion
193 193
194 /// <summary> 194 /// <summary>
195 /// Check that the source of an inventory request is one that we trust. 195 /// Check that the source of an inventory request is one that we trust.
196 /// </summary> 196 /// </summary>
197 /// <param name="peer"></param> 197 /// <param name="peer"></param>
198 /// <returns></returns> 198 /// <returns></returns>
199 public bool CheckTrustSource(IPEndPoint peer) 199 public bool CheckTrustSource(IPEndPoint peer)
200 { 200 {
201 if (m_doLookup) 201 if (m_doLookup)
202 { 202 {
203 m_log.InfoFormat("[INVENTORY IN CONNECTOR]: Checking trusted source {0}", peer); 203 m_log.InfoFormat("[INVENTORY IN CONNECTOR]: Checking trusted source {0}", peer);
204 UriBuilder ub = new UriBuilder(m_userserver_url); 204 UriBuilder ub = new UriBuilder(m_userserver_url);
205 IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host); 205 IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host);
206 foreach (IPAddress uaddr in uaddrs) 206 foreach (IPAddress uaddr in uaddrs)
207 { 207 {
208 if (uaddr.Equals(peer.Address)) 208 if (uaddr.Equals(peer.Address))
209 { 209 {
210 return true; 210 return true;
211 } 211 }
212 } 212 }
213 213
214 m_log.WarnFormat( 214 m_log.WarnFormat(
215 "[INVENTORY IN CONNECTOR]: Rejecting request since source {0} was not in the list of trusted sources", 215 "[INVENTORY IN CONNECTOR]: Rejecting request since source {0} was not in the list of trusted sources",
216 peer); 216 peer);
217 217
218 return false; 218 return false;
219 } 219 }
220 else 220 else
221 { 221 {
222 return true; 222 return true;
223 } 223 }
224 } 224 }
225 225
226 /// <summary> 226 /// <summary>
227 /// Check that the source of an inventory request for a particular agent is a current session belonging to 227 /// Check that the source of an inventory request for a particular agent is a current session belonging to
228 /// that agent. 228 /// that agent.
229 /// </summary> 229 /// </summary>
230 /// <param name="session_id"></param> 230 /// <param name="session_id"></param>
231 /// <param name="avatar_id"></param> 231 /// <param name="avatar_id"></param>
232 /// <returns></returns> 232 /// <returns></returns>
233 public bool CheckAuthSession(string session_id, string avatar_id) 233 public bool CheckAuthSession(string session_id, string avatar_id)
234 { 234 {
235 if (m_doLookup) 235 if (m_doLookup)
236 { 236 {
237 m_log.InfoFormat("[INVENTORY IN CONNECTOR]: checking authed session {0} {1}", session_id, avatar_id); 237 m_log.InfoFormat("[INVENTORY IN CONNECTOR]: checking authed session {0} {1}", session_id, avatar_id);
238 238
239 //if (m_session_cache.getCachedSession(session_id, avatar_id) == null) 239 //if (m_session_cache.getCachedSession(session_id, avatar_id) == null)
240 //{ 240 //{
241 // cache miss, ask userserver 241 // cache miss, ask userserver
242 Hashtable requestData = new Hashtable(); 242 Hashtable requestData = new Hashtable();
243 requestData["avatar_uuid"] = avatar_id; 243 requestData["avatar_uuid"] = avatar_id;
244 requestData["session_id"] = session_id; 244 requestData["session_id"] = session_id;
245 ArrayList SendParams = new ArrayList(); 245 ArrayList SendParams = new ArrayList();
246 SendParams.Add(requestData); 246 SendParams.Add(requestData);
247 XmlRpcRequest UserReq = new XmlRpcRequest("check_auth_session", SendParams); 247 XmlRpcRequest UserReq = new XmlRpcRequest("check_auth_session", SendParams);
248 XmlRpcResponse UserResp = UserReq.Send(m_userserver_url, 3000); 248 XmlRpcResponse UserResp = UserReq.Send(m_userserver_url, 3000);
249 249
250 Hashtable responseData = (Hashtable)UserResp.Value; 250 Hashtable responseData = (Hashtable)UserResp.Value;
251 if (responseData.ContainsKey("auth_session") && responseData["auth_session"].ToString() == "TRUE") 251 if (responseData.ContainsKey("auth_session") && responseData["auth_session"].ToString() == "TRUE")
252 { 252 {
253 m_log.Info("[INVENTORY IN CONNECTOR]: got authed session from userserver"); 253 m_log.Info("[INVENTORY IN CONNECTOR]: got authed session from userserver");
254 //// add to cache; the session time will be automatically renewed 254 //// add to cache; the session time will be automatically renewed
255 //m_session_cache.Add(session_id, avatar_id); 255 //m_session_cache.Add(session_id, avatar_id);
256 return true; 256 return true;
257 } 257 }
258 //} 258 //}
259 //else 259 //else
260 //{ 260 //{
261 // // cache hits 261 // // cache hits
262 // m_log.Info("[GRID AGENT INVENTORY]: got authed session from cache"); 262 // m_log.Info("[GRID AGENT INVENTORY]: got authed session from cache");
263 // return true; 263 // return true;
264 //} 264 //}
265 265
266 m_log.Warn("[INVENTORY IN CONNECTOR]: unknown session_id, request rejected"); 266 m_log.Warn("[INVENTORY IN CONNECTOR]: unknown session_id, request rejected");
267 return false; 267 return false;
268 } 268 }
269 else 269 else
270 { 270 {
271 return true; 271 return true;
272 } 272 }
273 } 273 }
274 274
275 } 275 }
276} 276}