OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
InventoryArchiverModule.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Reflection;
32 using log4net;
33 using NDesk.Options;
34 using Nini.Config;
35 using OpenMetaverse;
36 using OpenSim.Framework;
37 using OpenSim.Framework.Console;
38 using OpenSim.Region.Framework.Interfaces;
39 using OpenSim.Region.Framework.Scenes;
40 using OpenSim.Services.Interfaces;
41 using Mono.Addins;
42 
43 namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
44 {
48  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "InventoryArchiverModule")]
50  {
51  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 
56 // public bool DisablePresenceChecks { get; set; }
57 
60 
64  protected const string DEFAULT_INV_BACKUP_FILENAME = "user-inventory.iar";
65 
69  protected List<UUID> m_pendingConsoleTasks = new List<UUID>();
70 
74  private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
75  private Scene m_aScene;
76 
77  private IUserAccountService m_UserAccountService;
78  protected IUserAccountService UserAccountService
79  {
80  get
81  {
82  if (m_UserAccountService == null)
83  // What a strange thing to do...
84  foreach (Scene s in m_scenes.Values)
85  {
86  m_UserAccountService = s.RequestModuleInterface<IUserAccountService>();
87  break;
88  }
89 
90  return m_UserAccountService;
91  }
92  }
93 
94 
96 
97 // public InventoryArchiverModule(bool disablePresenceChecks)
98 // {
99 // DisablePresenceChecks = disablePresenceChecks;
100  // }
101 
102  #region ISharedRegionModule
103 
104  public void Initialise(IConfigSource source)
105  {
106  }
107 
108  public void AddRegion(Scene scene)
109  {
110  if (m_scenes.Count == 0)
111  {
112  scene.RegisterModuleInterface<IInventoryArchiverModule>(this);
113  OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
114  OnInventoryArchiveLoaded += LoadInvConsoleCommandCompleted;
115 
116  scene.AddCommand(
117  "Archiving", this, "load iar",
118  "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]",
119  "Load user inventory archive (IAR).",
120  "-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
121  + "<first> is user's first name." + Environment.NewLine
122  + "<last> is user's last name." + Environment.NewLine
123  + "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine
124  + "<password> is the user's password." + Environment.NewLine
125  + "<IAR path> is the filesystem path or URI from which to load the IAR."
126  + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
127  HandleLoadInvConsoleCommand);
128 
129  scene.AddCommand(
130  "Archiving", this, "save iar",
131  "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]",
132  "Save user inventory archive (IAR).",
133  "<first> is the user's first name.\n"
134  + "<last> is the user's last name.\n"
135  + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n"
136  + "<IAR path> is the filesystem path at which to save the IAR."
137  + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME)
138  + "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
139  + "-c|--creators preserves information about foreign creators.\n"
140  + "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine
141  + "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine
142  + "-v|--verbose extra debug messages.\n"
143  + "--noassets stops assets being saved to the IAR."
144  + "--perm=<permissions> stops items with insufficient permissions from being saved to the IAR.\n"
145  + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer, \"M\" = Modify.\n",
146  HandleSaveInvConsoleCommand);
147 
148  m_aScene = scene;
149  }
150 
151  m_scenes[scene.RegionInfo.RegionID] = scene;
152  }
153 
154  public void RemoveRegion(Scene scene)
155  {
156  }
157 
158  public void Close() {}
159 
160  public void RegionLoaded(Scene scene)
161  {
162  }
163 
164  public void PostInitialise()
165  {
166  }
167 
168  public Type ReplaceableInterface
169  {
170  get { return null; }
171  }
172 
173  public string Name { get { return "Inventory Archiver Module"; } }
174 
175  #endregion
176 
180  protected internal void TriggerInventoryArchiveSaved(
181  UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
182  Exception reportedException, int SaveCount, int FilterCount)
183  {
184  InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved;
185  if (handlerInventoryArchiveSaved != null)
186  handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException, SaveCount , FilterCount);
187  }
188 
192  protected internal void TriggerInventoryArchiveLoaded(
193  UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream,
194  Exception reportedException, int LoadCount)
195  {
196  InventoryArchiveLoaded handlerInventoryArchiveLoaded = OnInventoryArchiveLoaded;
197  if (handlerInventoryArchiveLoaded != null)
198  handlerInventoryArchiveLoaded(id, succeeded, userInfo, invPath, loadStream, reportedException, LoadCount);
199  }
200 
201  public bool ArchiveInventory(
202  UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
203  {
204  return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>());
205  }
206 
207  public bool ArchiveInventory(
208  UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
209  Dictionary<string, object> options)
210  {
211  if (m_scenes.Count > 0)
212  {
213  UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
214 
215  if (userInfo != null)
216  {
217 // if (CheckPresence(userInfo.PrincipalID))
218 // {
219  try
220  {
221  new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(options, UserAccountService);
222  }
223  catch (EntryPointNotFoundException e)
224  {
225  m_log.ErrorFormat(
226  "[INVENTORY ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
227  + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
228  m_log.Error(e);
229 
230  return false;
231  }
232 
233  return true;
234 // }
235 // else
236 // {
237 // m_log.ErrorFormat(
238 // "[INVENTORY ARCHIVER]: User {0} {1} {2} not logged in to this region simulator",
239 // userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID);
240 // }
241  }
242  }
243 
244  return false;
245  }
246 
247  public bool ArchiveInventory(
248  UUID id, string firstName, string lastName, string invPath, string pass, string savePath,
249  Dictionary<string, object> options)
250  {
251 // if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath))
252 // return false;
253 
254  if (m_scenes.Count > 0)
255  {
256  UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
257 
258  if (userInfo != null)
259  {
260 // if (CheckPresence(userInfo.PrincipalID))
261 // {
262  try
263  {
264  new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(options, UserAccountService);
265  }
266  catch (EntryPointNotFoundException e)
267  {
268  m_log.ErrorFormat(
269  "[INVENTORY ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
270  + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
271  m_log.Error(e);
272 
273  return false;
274  }
275 
276  return true;
277 // }
278 // else
279 // {
280 // m_log.ErrorFormat(
281 // "[INVENTORY ARCHIVER]: User {0} {1} {2} not logged in to this region simulator",
282 // userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID);
283 // }
284  }
285  }
286 
287  return false;
288  }
289 
290  public bool DearchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream)
291  {
292  return DearchiveInventory(id, firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
293  }
294 
295  public bool DearchiveInventory(
296  UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream,
297  Dictionary<string, object> options)
298  {
299  if (m_scenes.Count > 0)
300  {
301  UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
302 
303  if (userInfo != null)
304  {
305 // if (CheckPresence(userInfo.PrincipalID))
306 // {
308  bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
309 
310  try
311  {
312  request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge);
313  }
314  catch (EntryPointNotFoundException e)
315  {
316  m_log.ErrorFormat(
317  "[INVENTORY ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
318  + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
319  m_log.Error(e);
320 
321  return false;
322  }
323 
324  UpdateClientWithLoadedNodes(userInfo, request.Execute());
325 
326  return true;
327 // }
328 // else
329 // {
330 // m_log.ErrorFormat(
331 // "[INVENTORY ARCHIVER]: User {0} {1} {2} not logged in to this region simulator",
332 // userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID);
333 // }
334  }
335  else
336  m_log.ErrorFormat("[INVENTORY ARCHIVER]: User {0} {1} not found",
337  firstName, lastName);
338  }
339 
340  return false;
341  }
342 
343  public bool DearchiveInventory(
344  UUID id, string firstName, string lastName, string invPath, string pass, string loadPath,
345  Dictionary<string, object> options)
346  {
347  if (m_scenes.Count > 0)
348  {
349  UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
350 
351  if (userInfo != null)
352  {
353 // if (CheckPresence(userInfo.PrincipalID))
354 // {
356  bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
357 
358  try
359  {
360  request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge);
361  }
362  catch (EntryPointNotFoundException e)
363  {
364  m_log.ErrorFormat(
365  "[INVENTORY ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
366  + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
367  m_log.Error(e);
368 
369  return false;
370  }
371 
372  UpdateClientWithLoadedNodes(userInfo, request.Execute());
373 
374  return true;
375 // }
376 // else
377 // {
378 // m_log.ErrorFormat(
379 // "[INVENTORY ARCHIVER]: User {0} {1} {2} not logged in to this region simulator",
380 // userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID);
381 // }
382  }
383  }
384 
385  return false;
386  }
387 
392  protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams)
393  {
394  try
395  {
396  UUID id = UUID.Random();
397 
398  Dictionary<string, object> options = new Dictionary<string, object>();
399  OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
400 
401  List<string> mainParams = optionSet.Parse(cmdparams);
402 
403  if (mainParams.Count < 6)
404  {
405  m_log.Error(
406  "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]");
407  return;
408  }
409 
410  string firstName = mainParams[2];
411  string lastName = mainParams[3];
412  string invPath = mainParams[4];
413  string pass = mainParams[5];
414  string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
415 
416  m_log.InfoFormat(
417  "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}",
418  loadPath, invPath, firstName, lastName);
419 
420  lock (m_pendingConsoleTasks)
421  m_pendingConsoleTasks.Add(id);
422 
423  DearchiveInventory(id, firstName, lastName, invPath, pass, loadPath, options);
424  }
426  {
427  m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
428  }
429  }
430 
435  protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
436  {
437  UUID id = UUID.Random();
438 
439  Dictionary<string, object> options = new Dictionary<string, object>();
440 
441  OptionSet ops = new OptionSet();
442  //ops.Add("v|version=", delegate(string v) { options["version"] = v; });
443  ops.Add("h|home=", delegate(string v) { options["home"] = v; });
444  ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
445  ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
446  ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
447  ops.Add("e|exclude=", delegate(string v)
448  {
449  if (!options.ContainsKey("exclude"))
450  options["exclude"] = new List<String>();
451  ((List<String>)options["exclude"]).Add(v);
452  });
453  ops.Add("f|excludefolder=", delegate(string v)
454  {
455  if (!options.ContainsKey("excludefolders"))
456  options["excludefolders"] = new List<String>();
457  ((List<String>)options["excludefolders"]).Add(v);
458  });
459  ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
460 
461  List<string> mainParams = ops.Parse(cmdparams);
462 
463  try
464  {
465  if (mainParams.Count < 6)
466  {
467  m_log.Error(
468  "[INVENTORY ARCHIVER]: save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]");
469  return;
470  }
471 
472  if (options.ContainsKey("home"))
473  m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR");
474 
475  string firstName = mainParams[2];
476  string lastName = mainParams[3];
477  string invPath = mainParams[4];
478  string pass = mainParams[5];
479  string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
480 
481  m_log.InfoFormat(
482  "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
483  savePath, invPath, firstName, lastName);
484 
485  lock (m_pendingConsoleTasks)
486  m_pendingConsoleTasks.Add(id);
487 
488  ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
489  }
491  {
492  m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
493  }
494  }
495 
496  private void SaveInvConsoleCommandCompleted(
497  UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
498  Exception reportedException, int SaveCount, int FilterCount)
499  {
500  lock (m_pendingConsoleTasks)
501  {
502  if (m_pendingConsoleTasks.Contains(id))
503  m_pendingConsoleTasks.Remove(id);
504  else
505  return;
506  }
507 
508  if (succeeded)
509  {
510  // Report success and include item count and filter count (Skipped items due to --perm or --exclude switches)
511  if(FilterCount == 0)
512  m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}", SaveCount, userInfo.FirstName, userInfo.LastName);
513  else
514  m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}. Skipped {3} items due to exclude and/or perm switches", SaveCount, userInfo.FirstName, userInfo.LastName, FilterCount);
515  }
516  else
517  {
518  m_log.ErrorFormat(
519  "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}",
520  userInfo.FirstName, userInfo.LastName, reportedException.Message);
521  }
522  }
523 
524  private void LoadInvConsoleCommandCompleted(
525  UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream,
526  Exception reportedException, int LoadCount)
527  {
528  lock (m_pendingConsoleTasks)
529  {
530  if (m_pendingConsoleTasks.Contains(id))
531  m_pendingConsoleTasks.Remove(id);
532  else
533  return;
534  }
535 
536  if (succeeded)
537  {
538  m_log.InfoFormat("[INVENTORY ARCHIVER]: Loaded {0} items from archive {1} for {2} {3}", LoadCount, invPath, userInfo.FirstName, userInfo.LastName);
539  }
540  else
541  {
542  m_log.ErrorFormat(
543  "[INVENTORY ARCHIVER]: Archive load for {0} {1} failed - {2}",
544  userInfo.FirstName, userInfo.LastName, reportedException.Message);
545  }
546  }
547 
555  protected UserAccount GetUserInfo(string firstName, string lastName, string pass)
556  {
557  UserAccount account
558  = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName);
559 
560  if (null == account)
561  {
562  m_log.ErrorFormat(
563  "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}",
564  firstName, lastName);
565  return null;
566  }
567 
568  return account;
569  /*
570  try
571  {
572  string encpass = Util.Md5Hash(pass);
573  if (m_aScene.AuthenticationService.Authenticate(account.PrincipalID, encpass, 1) != string.Empty)
574  {
575  return account;
576  }
577  else
578  {
579  m_log.ErrorFormat(
580  "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.",
581  firstName, lastName);
582  return null;
583  }
584  }
585  catch (Exception e)
586  {
587  m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e);
588  return null;
589  }
590  */
591  }
592 
597  private void UpdateClientWithLoadedNodes(UserAccount userInfo, HashSet<InventoryNodeBase> loadedNodes)
598  {
599  if (loadedNodes.Count == 0)
600  return;
601 
602  foreach (Scene scene in m_scenes.Values)
603  {
604  ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID);
605 
606  if (user != null && !user.IsChildAgent)
607  {
608  foreach (InventoryNodeBase node in loadedNodes)
609  {
610 // m_log.DebugFormat(
611 // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}",
612 // user.Name, node.Name);
613 
614  user.ControllingClient.SendBulkUpdateInventory(node);
615  }
616 
617  break;
618  }
619  }
620  }
621 
622 // /// <summary>
623 // /// Check if the given user is present in any of the scenes.
624 // /// </summary>
625 // /// <param name="userId">The user to check</param>
626 // /// <returns>true if the user is in any of the scenes, false otherwise</returns>
627 // protected bool CheckPresence(UUID userId)
628 // {
629 // if (DisablePresenceChecks)
630 // return true;
631 //
632 // foreach (Scene scene in m_scenes.Values)
633 // {
634 // ScenePresence p;
635 // if ((p = scene.GetScenePresence(userId)) != null)
636 // {
637 // p.ControllingClient.SendAgentAlertMessage("Inventory operation has been started", false);
638 // return true;
639 // }
640 // }
641 //
642 // return false;
643 // }
644  }
645 }
delegate void InventoryArchiveSaved(UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, Exception reportedException, int saveCount, int filterCount)
Used for the OnInventoryArchiveSaved event.
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
delegate void InventoryArchiveLoaded(UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream, Exception reportedException, int loadCount)
Used for the OnInventoryArchiveLoaded event.
bool ArchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream, Dictionary< string, object > options)
Archive a user's inventory folder to the given stream
bool ArchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, string savePath, Dictionary< string, object > options)
void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
Save inventory to a file archive
bool DearchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream, Dictionary< string, object > options)
Dearchive a user's inventory folder from the given stream
bool ArchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
Archive a user's inventory folder to the given stream
This module loads and saves OpenSimulator inventory archives
void HandleLoadInvConsoleCommand(string module, string[] cmdparams)
Load inventory from an inventory file archive
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
bool DearchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, string loadPath, Dictionary< string, object > options)
UserAccount GetUserInfo(string firstName, string lastName, string pass)
Get user information for the given name.
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
Common base class for inventory nodes of different types (files, folders, etc.)
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
bool DearchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream)
Dearchive a user's inventory folder from the given stream