aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs168
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs13
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs13
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs96
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs9
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs139
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs40
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs111
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs125
12 files changed, 480 insertions, 251 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs
index 75efb79..8aa87fd 100644
--- a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs
@@ -1,4 +1,4 @@
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 *
@@ -190,7 +190,7 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps
190 end = Utils.Clamp(end, 1, texture.Data.Length); 190 end = Utils.Clamp(end, 1, texture.Data.Length);
191 start = Utils.Clamp(start, 0, end - 1); 191 start = Utils.Clamp(start, 0, end - 1);
192 192
193 m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); 193 //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
194 194
195 if (end - start < texture.Data.Length) 195 if (end - start < texture.Data.Length)
196 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; 196 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index a7b4c66..d895bb1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenMetaverse.Packets; 35using OpenMetaverse.Packets;
@@ -39,37 +40,65 @@ using OpenSim.Region.Framework.Scenes;
39 40
40namespace OpenSim.Region.CoreModules.Avatar.Attachments 41namespace OpenSim.Region.CoreModules.Avatar.Attachments
41{ 42{
42 public class AttachmentsModule : IAttachmentsModule, IRegionModule 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsModule")]
44 public class AttachmentsModule : IAttachmentsModule, INonSharedRegionModule
43 { 45 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 47
46 protected Scene m_scene = null; 48 protected Scene m_scene = null;
49
50 public string Name { get { return "Attachments Module"; } }
51 public Type ReplaceableInterface { get { return null; } }
47 52
48 public void Initialise(Scene scene, IConfigSource source) 53 public void Initialise(IConfigSource source) {}
54
55 public void AddRegion(Scene scene)
49 { 56 {
50 scene.RegisterModuleInterface<IAttachmentsModule>(this);
51 m_scene = scene; 57 m_scene = scene;
58 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
59 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
60 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
52 } 61 }
53 62
54 public void PostInitialise() 63 public void RemoveRegion(Scene scene)
55 { 64 {
65 m_scene.UnregisterModuleInterface<IAttachmentsModule>(this);
66 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
56 } 67 }
57 68
58 public void Close() 69 public void RegionLoaded(Scene scene) {}
70
71 public void Close()
59 { 72 {
73 RemoveRegion(m_scene);
60 } 74 }
61 75
62 public string Name 76 public void SubscribeToClientEvents(IClientAPI client)
63 { 77 {
64 get { return "Attachments Module"; } 78 client.OnRezSingleAttachmentFromInv += RezSingleAttachmentFromInventory;
79 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory;
80 client.OnObjectAttach += AttachObject;
81 client.OnObjectDetach += DetachObject;
82 client.OnDetachAttachmentIntoInv += ShowDetachInUserInventory;
65 } 83 }
66 84
67 public bool IsSharedModule 85 public void UnsubscribeFromClientEvents(IClientAPI client)
68 { 86 {
69 get { return false; } 87 client.OnRezSingleAttachmentFromInv -= RezSingleAttachmentFromInventory;
88 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory;
89 client.OnObjectAttach -= AttachObject;
90 client.OnObjectDetach -= DetachObject;
91 client.OnDetachAttachmentIntoInv -= ShowDetachInUserInventory;
70 } 92 }
71 93
72 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) 94 /// <summary>
95 /// Called by client
96 /// </summary>
97 /// <param name="remoteClient"></param>
98 /// <param name="objectLocalID"></param>
99 /// <param name="AttachmentPt"></param>
100 /// <param name="silent"></param>
101 public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
73 { 102 {
74 m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); 103 m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject");
75 104
@@ -84,7 +113,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
84 return; 113 return;
85 114
86 // Calls attach with a Zero position 115 // Calls attach with a Zero position
87 if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false)) 116 if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false))
88 { 117 {
89 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); 118 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
90 119
@@ -106,72 +135,78 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
106 } 135 }
107 } 136 }
108 137
109 public bool AttachObject( 138 public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent)
110 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
111 { 139 {
112 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); 140 Vector3 attachPos = group.AbsolutePosition;
113 if (group != null) 141
142 if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId))
114 { 143 {
115 if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) 144 // If the attachment point isn't the same as the one previously used
145 // set it's offset position = 0 so that it appears on the attachment point
146 // and not in a weird location somewhere unknown.
147 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
116 { 148 {
117 // If the attachment point isn't the same as the one previously used 149 attachPos = Vector3.Zero;
118 // set it's offset position = 0 so that it appears on the attachment point 150 }
119 // and not in a weird location somewhere unknown.
120 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
121 {
122 attachPos = Vector3.Zero;
123 }
124
125 // AttachmentPt 0 means the client chose to 'wear' the attachment.
126 if (AttachmentPt == 0)
127 {
128 // Check object for stored attachment point
129 AttachmentPt = (uint)group.GetAttachmentPoint();
130 }
131 151
132 // if we still didn't find a suitable attachment point....... 152 // AttachmentPt 0 means the client chose to 'wear' the attachment.
133 if (AttachmentPt == 0) 153 if (AttachmentPt == 0)
134 { 154 {
135 // Stick it on left hand with Zero Offset from the attachment point. 155 // Check object for stored attachment point
136 AttachmentPt = (uint)AttachmentPoint.LeftHand; 156 AttachmentPt = (uint)group.GetAttachmentPoint();
137 attachPos = Vector3.Zero; 157 }
138 }
139 158
140 group.SetAttachmentPoint((byte)AttachmentPt); 159 // if we still didn't find a suitable attachment point.......
141 group.AbsolutePosition = attachPos; 160 if (AttachmentPt == 0)
161 {
162 // Stick it on left hand with Zero Offset from the attachment point.
163 AttachmentPt = (uint)AttachmentPoint.LeftHand;
164 attachPos = Vector3.Zero;
165 }
142 166
143 // Saves and gets itemID 167 group.SetAttachmentPoint((byte)AttachmentPt);
144 UUID itemId; 168 group.AbsolutePosition = attachPos;
145 169
146 if (group.GetFromItemID() == UUID.Zero) 170 // Remove any previous attachments
147 { 171 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
148 m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); 172 UUID itemID = UUID.Zero;
149 } 173 if (sp != null)
150 else 174 {
175 foreach(SceneObjectGroup grp in sp.Attachments)
151 { 176 {
152 itemId = group.GetFromItemID(); 177 if (grp.GetAttachmentPoint() == (byte)AttachmentPt)
178 {
179 itemID = grp.GetFromItemID();
180 break;
181 }
153 } 182 }
183 if (itemID != UUID.Zero)
184 DetachSingleAttachmentToInv(itemID, remoteClient);
185 }
154 186
155 SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group); 187 if (group.GetFromItemID() == UUID.Zero)
156 188 {
157 group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); 189 m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID);
158
159 // In case it is later dropped again, don't let
160 // it get cleaned up
161 group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
162 group.HasGroupChanged = false;
163 } 190 }
164 else 191 else
165 { 192 {
166 remoteClient.SendAgentAlertMessage( 193 itemID = group.GetFromItemID();
167 "You don't have sufficient permissions to attach this object", false);
168
169 return false;
170 } 194 }
195
196 SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemID, group);
197
198 group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent);
199
200 // In case it is later dropped again, don't let
201 // it get cleaned up
202 group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
203 group.HasGroupChanged = false;
171 } 204 }
172 else 205 else
173 { 206 {
174 m_log.DebugFormat("[ATTACHMENTS MODULE]: AttachObject found no such scene object {0}", objectLocalID); 207 remoteClient.SendAgentAlertMessage(
208 "You don't have sufficient permissions to attach this object", false);
209
175 return false; 210 return false;
176 } 211 }
177 212
@@ -237,8 +272,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
237 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) 272 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
238 tainted = true; 273 tainted = true;
239 274
240 AttachObject( 275 AttachObject(remoteClient, objatt, AttachmentPt, false);
241 remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
242 //objatt.ScheduleGroupForFullUpdate(); 276 //objatt.ScheduleGroupForFullUpdate();
243 277
244 if (tainted) 278 if (tainted)
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index b5c3176..2105f3c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -81,14 +81,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
81 { 81 {
82 ScenePresence sp = m_scene.GetScenePresence(agentID); 82 ScenePresence sp = m_scene.GetScenePresence(agentID);
83 83
84 if (sp != null && !sp.IsChildAgent) 84 if (sp != null)
85 sp.ControllingClient.SendAgentAlertMessage(message, modal); 85 sp.ControllingClient.SendAgentAlertMessage(message, modal);
86 } 86 }
87 87
88 public void SendAlertToUser(string firstName, string lastName, string message, bool modal) 88 public void SendAlertToUser(string firstName, string lastName, string message, bool modal)
89 { 89 {
90 ScenePresence presence = m_scene.GetScenePresence(firstName, lastName); 90 ScenePresence presence = m_scene.GetScenePresence(firstName, lastName);
91 if (presence != null && !presence.IsChildAgent) 91 if (presence != null)
92 presence.ControllingClient.SendAgentAlertMessage(message, modal); 92 presence.ControllingClient.SendAgentAlertMessage(message, modal);
93 } 93 }
94 94
@@ -119,7 +119,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
119 } 119 }
120 120
121 ScenePresence sp = m_scene.GetScenePresence(avatarID); 121 ScenePresence sp = m_scene.GetScenePresence(avatarID);
122 if (sp != null && !sp.IsChildAgent) 122 if (sp != null)
123 sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); 123 sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
124 } 124 }
125 125
@@ -128,7 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
128 { 128 {
129 ScenePresence sp = m_scene.GetScenePresence(avatarID); 129 ScenePresence sp = m_scene.GetScenePresence(avatarID);
130 130
131 if (sp != null && !sp.IsChildAgent) 131 if (sp != null)
132 sp.ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, message, url); 132 sp.ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, message, url);
133 } 133 }
134 134
@@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
149 149
150 ScenePresence sp = m_scene.GetScenePresence(avatarid); 150 ScenePresence sp = m_scene.GetScenePresence(avatarid);
151 151
152 if (sp != null && !sp.IsChildAgent) 152 if (sp != null)
153 sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid); 153 sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid);
154 } 154 }
155 155
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 50171a3..4b30b0d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -47,6 +47,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
47 m_scene = scene; 47 m_scene = scene;
48 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>(); 48 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
49 m_scene.RegisterModuleInterface<IGodsModule>(this); 49 m_scene.RegisterModuleInterface<IGodsModule>(this);
50 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
50 } 51 }
51 52
52 public void PostInitialise() {} 53 public void PostInitialise() {}
@@ -54,6 +55,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
54 public string Name { get { return "Gods Module"; } } 55 public string Name { get { return "Gods Module"; } }
55 public bool IsSharedModule { get { return false; } } 56 public bool IsSharedModule { get { return false; } }
56 57
58 public void SubscribeToClientEvents(IClientAPI client)
59 {
60 client.OnGodKickUser += KickUser;
61 client.OnRequestGodlikePowers += RequestGodlikePowers;
62 }
63
64 public void UnsubscribeFromClientEvents(IClientAPI client)
65 {
66 client.OnGodKickUser -= KickUser;
67 client.OnRequestGodlikePowers -= RequestGodlikePowers;
68 }
69
57 public void RequestGodlikePowers( 70 public void RequestGodlikePowers(
58 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) 71 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient)
59 { 72 {
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
index ab141eb..a3c40e0 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -162,7 +162,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
162 delegate(bool success) 162 delegate(bool success)
163 { 163 {
164 if (dialog == (uint)InstantMessageDialog.StartTyping || 164 if (dialog == (uint)InstantMessageDialog.StartTyping ||
165 dialog == (uint)InstantMessageDialog.StopTyping) 165 dialog == (uint)InstantMessageDialog.StopTyping ||
166 dialog == (uint)InstantMessageDialog.MessageFromObject)
166 { 167 {
167 return; 168 return;
168 } 169 }
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 83209fc..d025f0c 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -185,13 +185,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
185 { 185 {
186 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage; 186 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
187 187
188 // If this event has handlers, then the IM will be considered 188 // If this event has handlers, then an IM from an agent will be
189 // delivered. This will suppress the error message. 189 // considered delivered. This will suppress the error message.
190 // 190 //
191 if (handlerUndeliveredMessage != null) 191 if (handlerUndeliveredMessage != null)
192 { 192 {
193 handlerUndeliveredMessage(im); 193 handlerUndeliveredMessage(im);
194 result(true); 194 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
195 result(true);
196 else
197 result(false);
195 return; 198 return;
196 } 199 }
197 200
@@ -504,14 +507,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
504 // 507 //
505 if (upd.RegionID == prevRegionID) 508 if (upd.RegionID == prevRegionID)
506 { 509 {
507 m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); 510 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
508 HandleUndeliveredMessage(im, result); 511 HandleUndeliveredMessage(im, result);
509 return; 512 return;
510 } 513 }
511 } 514 }
512 else 515 else
513 { 516 {
514 m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); 517 // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
515 HandleUndeliveredMessage(im, result); 518 HandleUndeliveredMessage(im, result);
516 return; 519 return;
517 } 520 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index f130b3e..7683288 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -100,37 +100,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
100 /// </returns> 100 /// </returns>
101 public HashSet<InventoryNodeBase> Execute() 101 public HashSet<InventoryNodeBase> Execute()
102 { 102 {
103 string filePath = "ERROR";
104 int successfulAssetRestores = 0;
105 int failedAssetRestores = 0;
106 int successfulItemRestores = 0;
107
108 HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();
109
110 List<InventoryFolderBase> folderCandidates
111 = InventoryArchiveUtils.FindFolderByPath(
112 m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath);
113
114 if (folderCandidates.Count == 0)
115 {
116 // Possibly provide an option later on to automatically create this folder if it does not exist
117 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath);
118
119 return loadedNodes;
120 }
121
122 InventoryFolderBase rootDestinationFolder = folderCandidates[0];
123 archive = new TarArchiveReader(m_loadStream);
124
125 // In order to load identically named folders, we need to keep track of the folders that we have already
126 // resolved
127 Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>();
128
129 byte[] data;
130 TarArchiveReader.TarEntryType entryType;
131
132 try 103 try
133 { 104 {
105 string filePath = "ERROR";
106 int successfulAssetRestores = 0;
107 int failedAssetRestores = 0;
108 int successfulItemRestores = 0;
109
110 HashSet<InventoryNodeBase> loadedNodes = new HashSet<InventoryNodeBase>();
111
112 List<InventoryFolderBase> folderCandidates
113 = InventoryArchiveUtils.FindFolderByPath(
114 m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath);
115
116 if (folderCandidates.Count == 0)
117 {
118 // Possibly provide an option later on to automatically create this folder if it does not exist
119 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath);
120
121 return loadedNodes;
122 }
123
124 InventoryFolderBase rootDestinationFolder = folderCandidates[0];
125 archive = new TarArchiveReader(m_loadStream);
126
127 // In order to load identically named folders, we need to keep track of the folders that we have already
128 // resolved
129 Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>();
130
131 byte[] data;
132 TarArchiveReader.TarEntryType entryType;
133
134 while ((data = archive.ReadEntry(out filePath, out entryType)) != null) 134 while ((data = archive.ReadEntry(out filePath, out entryType)) != null)
135 { 135 {
136 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) 136 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
@@ -173,18 +173,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
173 } 173 }
174 } 174 }
175 } 175 }
176
177 archive.Close();
178
179 m_log.DebugFormat(
180 "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
181 successfulAssetRestores, failedAssetRestores);
182 m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores);
183
184 return loadedNodes;
176 } 185 }
177 finally 186 finally
178 { 187 {
179 archive.Close(); 188 m_loadStream.Close();
180 } 189 }
181
182 m_log.DebugFormat(
183 "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
184 successfulAssetRestores, failedAssetRestores);
185 m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores);
186
187 return loadedNodes;
188 } 190 }
189 191
190 public void Close() 192 public void Close()
@@ -220,9 +222,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
220 InventoryFolderBase destFolder 222 InventoryFolderBase destFolder
221 = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders); 223 = ResolveDestinationFolder(rootDestFolder, ref iarPathExisting, resolvedFolders);
222 224
223 m_log.DebugFormat( 225// m_log.DebugFormat(
224 "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", 226// "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]",
225 iarPath, iarPathExisting); 227// iarPath, iarPathExisting);
226 228
227 string iarPathToCreate = iarPath.Substring(iarPathExisting.Length); 229 string iarPathToCreate = iarPath.Substring(iarPathExisting.Length);
228 CreateFoldersForPath(destFolder, iarPathExisting, iarPathToCreate, resolvedFolders, loadedNodes); 230 CreateFoldersForPath(destFolder, iarPathExisting, iarPathToCreate, resolvedFolders, loadedNodes);
@@ -255,7 +257,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
255 ref string archivePath, 257 ref string archivePath,
256 Dictionary <string, InventoryFolderBase> resolvedFolders) 258 Dictionary <string, InventoryFolderBase> resolvedFolders)
257 { 259 {
258 string originalArchivePath = archivePath; 260// string originalArchivePath = archivePath;
259 261
260 while (archivePath.Length > 0) 262 while (archivePath.Length > 0)
261 { 263 {
@@ -263,8 +265,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
263 265
264 if (resolvedFolders.ContainsKey(archivePath)) 266 if (resolvedFolders.ContainsKey(archivePath))
265 { 267 {
266 m_log.DebugFormat( 268// m_log.DebugFormat(
267 "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); 269// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
268 return resolvedFolders[archivePath]; 270 return resolvedFolders[archivePath];
269 } 271 }
270 else 272 else
@@ -296,9 +298,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
296 } 298 }
297 else 299 else
298 { 300 {
299 m_log.DebugFormat( 301// m_log.DebugFormat(
300 "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}", 302// "[INVENTORY ARCHIVER]: Found no previously created folder for archive path {0}",
301 originalArchivePath); 303// originalArchivePath);
302 archivePath = string.Empty; 304 archivePath = string.Empty;
303 return rootDestFolder; 305 return rootDestFolder;
304 } 306 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index ca33968..84afb40 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -206,11 +206,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
206 206
207 if (components.Length == 1) 207 if (components.Length == 1)
208 { 208 {
209// m_log.DebugFormat("FOUND SINGLE COMPONENT [{0}]", components[0]); 209// m_log.DebugFormat(
210// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
211// components[0], startFolder.Name, startFolder.ID);
210 212
211 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); 213 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
214
215// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
216
212 foreach (InventoryItemBase item in items) 217 foreach (InventoryItemBase item in items)
213 { 218 {
219// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
220
214 if (item.Name == components[0]) 221 if (item.Name == components[0])
215 return item; 222 return item;
216 } 223 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 2c2724e..25a78ff 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -119,22 +119,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
119 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) 119 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
120 { 120 {
121 Exception reportedException = null; 121 Exception reportedException = null;
122 bool succeeded = true; 122 bool succeeded = true;
123 123
124 try 124 try
125 { 125 {
126 // We're almost done. Just need to write out the control file now 126 // We're almost done. Just need to write out the control file now
127 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p1ControlFile()); 127 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p1ControlFile());
128 m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); 128 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
129
130 m_archiveWriter.Close(); 129 m_archiveWriter.Close();
131 } 130 }
132 catch (Exception e) 131 catch (Exception e)
133 { 132 {
134 m_saveStream.Close();
135 reportedException = e; 133 reportedException = e;
136 succeeded = false; 134 succeeded = false;
137 } 135 }
136 finally
137 {
138 m_saveStream.Close();
139 }
138 140
139 m_module.TriggerInventoryArchiveSaved( 141 m_module.TriggerInventoryArchiveSaved(
140 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); 142 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
@@ -213,70 +215,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
213 /// </summary> 215 /// </summary>
214 public void Execute() 216 public void Execute()
215 { 217 {
216 InventoryFolderBase inventoryFolder = null; 218 try
217 InventoryItemBase inventoryItem = null;
218 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);
219
220 bool foundStar = false;
221
222 // Eliminate double slashes and any leading / on the path.
223 string[] components
224 = m_invPath.Split(
225 new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);
226
227 int maxComponentIndex = components.Length - 1;
228
229 // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the
230 // folder itself. This may get more sophisicated later on
231 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
232 {
233 foundStar = true;
234 maxComponentIndex--;
235 }
236
237 m_invPath = String.Empty;
238 for (int i = 0; i <= maxComponentIndex; i++)
239 {
240 m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
241 }
242
243 // Annoyingly Split actually returns the original string if the input string consists only of delimiters
244 // Therefore if we still start with a / after the split, then we need the root folder
245 if (m_invPath.Length == 0)
246 {
247 inventoryFolder = rootFolder;
248 }
249 else
250 {
251 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
252 List<InventoryFolderBase> candidateFolders
253 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath);
254 if (candidateFolders.Count > 0)
255 inventoryFolder = candidateFolders[0];
256 }
257
258 // The path may point to an item instead
259 if (inventoryFolder == null)
260 {
261 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
262 //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
263 }
264
265 if (null == inventoryFolder && null == inventoryItem)
266 { 219 {
267 // We couldn't find the path indicated 220 InventoryFolderBase inventoryFolder = null;
268 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); 221 InventoryItemBase inventoryItem = null;
269 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", errorMessage); 222 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);
270 m_module.TriggerInventoryArchiveSaved( 223
271 m_id, false, m_userInfo, m_invPath, m_saveStream, 224 bool foundStar = false;
272 new Exception(errorMessage)); 225
273 return; 226 // Eliminate double slashes and any leading / on the path.
274 } 227 string[] components
228 = m_invPath.Split(
229 new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);
230
231 int maxComponentIndex = components.Length - 1;
232
233 // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the
234 // folder itself. This may get more sophisicated later on
235 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
236 {
237 foundStar = true;
238 maxComponentIndex--;
239 }
240
241 m_invPath = String.Empty;
242 for (int i = 0; i <= maxComponentIndex; i++)
243 {
244 m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
245 }
246
247 // Annoyingly Split actually returns the original string if the input string consists only of delimiters
248 // Therefore if we still start with a / after the split, then we need the root folder
249 if (m_invPath.Length == 0)
250 {
251 inventoryFolder = rootFolder;
252 }
253 else
254 {
255 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
256 List<InventoryFolderBase> candidateFolders
257 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath);
258 if (candidateFolders.Count > 0)
259 inventoryFolder = candidateFolders[0];
260 }
261
262 // The path may point to an item instead
263 if (inventoryFolder == null)
264 {
265 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
266 //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
267 }
268
269 if (null == inventoryFolder && null == inventoryItem)
270 {
271 // We couldn't find the path indicated
272 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
273 Exception e = new InventoryArchiverException(errorMessage);
274 m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e);
275 throw e;
276 }
275 277
276 m_archiveWriter = new TarArchiveWriter(m_saveStream); 278 m_archiveWriter = new TarArchiveWriter(m_saveStream);
277 279
278 try
279 {
280 if (inventoryFolder != null) 280 if (inventoryFolder != null)
281 { 281 {
282 m_log.DebugFormat( 282 m_log.DebugFormat(
@@ -297,16 +297,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
297 297
298 // Don't put all this profile information into the archive right now. 298 // Don't put all this profile information into the archive right now.
299 //SaveUsers(); 299 //SaveUsers();
300
301 new AssetsRequest(
302 new AssetsArchiver(m_archiveWriter), m_assetUuids, m_scene.AssetService, ReceivedAllAssets).Execute();
300 } 303 }
301 catch (Exception) 304 catch (Exception)
302 { 305 {
303 m_archiveWriter.Close(); 306 m_saveStream.Close();
304 throw; 307 throw;
305 } 308 }
306
307 new AssetsRequest(
308 new AssetsArchiver(m_archiveWriter), m_assetUuids,
309 m_scene.AssetService, ReceivedAllAssets).Execute();
310 } 309 }
311 310
312 /// <summary> 311 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs
new file mode 100644
index 0000000..e07e2ca
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs
@@ -0,0 +1,40 @@
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
28using System;
29
30namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
31{
32 /// <summary>
33 /// Signals an inventory archiving problem
34 /// </summary>
35 public class InventoryArchiverException : Exception
36 {
37 public InventoryArchiverException(string message) : base(message) {}
38 public InventoryArchiverException(string message, Exception e) : base(message, e) {}
39 }
40} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 668c344..f03f2a1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -324,34 +324,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
324 /// <param name="cmdparams"></param> 324 /// <param name="cmdparams"></param>
325 protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams) 325 protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams)
326 { 326 {
327 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); 327 try
328 328 {
329 Dictionary<string, object> options = new Dictionary<string, object>(); 329 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
330 OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); 330
331 331 Dictionary<string, object> options = new Dictionary<string, object>();
332 List<string> mainParams = optionSet.Parse(cmdparams); 332 OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
333 333
334 if (mainParams.Count < 6) 334 List<string> mainParams = optionSet.Parse(cmdparams);
335 { 335
336 m_log.Error( 336 if (mainParams.Count < 6)
337 "[INVENTORY ARCHIVER]: usage is load iar <first name> <last name> <inventory path> <user password> [<load file path>]"); 337 {
338 return; 338 m_log.Error(
339 } 339 "[INVENTORY ARCHIVER]: usage is load iar [--merge] <first name> <last name> <inventory path> <user password> [<load file path>]");
340 340 return;
341 string firstName = mainParams[2]; 341 }
342 string lastName = mainParams[3]; 342
343 string invPath = mainParams[4]; 343 string firstName = mainParams[2];
344 string pass = mainParams[5]; 344 string lastName = mainParams[3];
345 string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); 345 string invPath = mainParams[4];
346 346 string pass = mainParams[5];
347 m_log.InfoFormat( 347 string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
348 "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", 348
349 loadPath, invPath, firstName, lastName);
350
351 if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
352 m_log.InfoFormat( 349 m_log.InfoFormat(
353 "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", 350 "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}",
354 loadPath, firstName, lastName); 351 loadPath, invPath, firstName, lastName);
352
353 if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
354 m_log.InfoFormat(
355 "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}",
356 loadPath, firstName, lastName);
357 }
358 catch (InventoryArchiverException e)
359 {
360 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
361 }
355 } 362 }
356 363
357 /// <summary> 364 /// <summary>
@@ -360,30 +367,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
360 /// <param name="cmdparams"></param> 367 /// <param name="cmdparams"></param>
361 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) 368 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
362 { 369 {
363 if (cmdparams.Length < 6) 370 Guid id = Guid.NewGuid();
371
372 try
364 { 373 {
365 m_log.Error( 374 if (cmdparams.Length < 6)
366 "[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]"); 375 {
367 return; 376 m_log.Error(
377 "[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]");
378 return;
379 }
380
381 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
382
383 string firstName = cmdparams[2];
384 string lastName = cmdparams[3];
385 string invPath = cmdparams[4];
386 string pass = cmdparams[5];
387 string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME);
388
389 m_log.InfoFormat(
390 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
391 savePath, invPath, firstName, lastName);
392
393 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary<string, object>());
368 } 394 }
369 395 catch (InventoryArchiverException e)
370 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); 396 {
371 397 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
372 string firstName = cmdparams[2]; 398 }
373 string lastName = cmdparams[3]; 399
374 string invPath = cmdparams[4];
375 string pass = cmdparams[5];
376 string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME);
377
378 m_log.InfoFormat(
379 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
380 savePath, invPath, firstName, lastName);
381
382 Guid id = Guid.NewGuid();
383 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary<string, object>());
384
385 lock (m_pendingConsoleSaves) 400 lock (m_pendingConsoleSaves)
386 m_pendingConsoleSaves.Add(id); 401 m_pendingConsoleSaves.Add(id);
387 } 402 }
388 403
389 private void SaveInvConsoleCommandCompleted( 404 private void SaveInvConsoleCommandCompleted(
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 5fad0a9..2d80382 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -63,13 +63,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
63 } 63 }
64 64
65 /// <summary> 65 /// <summary>
66 /// Test saving a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet). 66 /// Test saving an inventory path to a V0.1 OpenSim Inventory Archive
67 /// (subject to change since there is no fixed format yet).
67 /// </summary> 68 /// </summary>
68 // Commenting for now! The mock inventory service needs more beef, at least for
69 // GetFolderForType
70 // REFACTORING PROBLEM. This needs to be rewritten.
71 [Test] 69 [Test]
72 public void TestSaveIarV0_1() 70 public void TestSavePathToIarV0_1()
73 { 71 {
74 TestHelper.InMethod(); 72 TestHelper.InMethod();
75// log4net.Config.XmlConfigurator.Configure(); 73// log4net.Config.XmlConfigurator.Configure();
@@ -182,6 +180,123 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
182 } 180 }
183 181
184 /// <summary> 182 /// <summary>
183 /// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive
184 /// (subject to change since there is no fixed format yet).
185 /// </summary>
186 [Test]
187 public void TestSaveItemToIarV0_1()
188 {
189 TestHelper.InMethod();
190// log4net.Config.XmlConfigurator.Configure();
191
192 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
193
194 Scene scene = SceneSetupHelpers.SetupScene("Inventory");
195 SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
196
197 // Create user
198 string userFirstName = "Jock";
199 string userLastName = "Stirrup";
200 string userPassword = "troll";
201 UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
202 UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword);
203
204 // Create asset
205 SceneObjectGroup object1;
206 SceneObjectPart part1;
207 {
208 string partName = "My Little Dog Object";
209 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
210 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
211 Vector3 groupPosition = new Vector3(10, 20, 30);
212 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
213 Vector3 offsetPosition = new Vector3(5, 10, 15);
214
215 part1
216 = new SceneObjectPart(
217 ownerId, shape, groupPosition, rotationOffset, offsetPosition);
218 part1.Name = partName;
219
220 object1 = new SceneObjectGroup(part1);
221 scene.AddNewSceneObject(object1, false);
222 }
223
224 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
225 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
226 scene.AssetService.Store(asset1);
227
228 // Create item
229 UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
230 string item1Name = "My Little Dog";
231 InventoryItemBase item1 = new InventoryItemBase();
232 item1.Name = item1Name;
233 item1.AssetID = asset1.FullID;
234 item1.ID = item1Id;
235 InventoryFolderBase objsFolder
236 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0];
237 item1.Folder = objsFolder.ID;
238 scene.AddInventoryItem(userId, item1);
239
240 MemoryStream archiveWriteStream = new MemoryStream();
241 archiverModule.OnInventoryArchiveSaved += SaveCompleted;
242
243 mre.Reset();
244 archiverModule.ArchiveInventory(
245 Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream);
246 mre.WaitOne(60000, false);
247
248 byte[] archive = archiveWriteStream.ToArray();
249 MemoryStream archiveReadStream = new MemoryStream(archive);
250 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
251
252 //bool gotControlFile = false;
253 bool gotObject1File = false;
254 //bool gotObject2File = false;
255 string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1);
256 string expectedObject1FilePath = string.Format(
257 "{0}{1}",
258 ArchiveConstants.INVENTORY_PATH,
259 expectedObject1FileName);
260
261 string filePath;
262 TarArchiveReader.TarEntryType tarEntryType;
263
264// Console.WriteLine("Reading archive");
265
266 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
267 {
268 Console.WriteLine("Got {0}", filePath);
269
270// if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
271// {
272// gotControlFile = true;
273// }
274
275 if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
276 {
277// string fileName = filePath.Remove(0, "Objects/".Length);
278//
279// if (fileName.StartsWith(part1.Name))
280// {
281 Assert.That(expectedObject1FilePath, Is.EqualTo(filePath));
282 gotObject1File = true;
283// }
284// else if (fileName.StartsWith(part2.Name))
285// {
286// Assert.That(fileName, Is.EqualTo(expectedObject2FileName));
287// gotObject2File = true;
288// }
289 }
290 }
291
292// Assert.That(gotControlFile, Is.True, "No control file in archive");
293 Assert.That(gotObject1File, Is.True, "No item1 file in archive");
294// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
295
296 // TODO: Test presence of more files and contents of files.
297 }
298
299 /// <summary>
185 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 300 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
186 /// an account exists with the creator name. 301 /// an account exists with the creator name.
187 /// </summary> 302 /// </summary>