diff options
9 files changed, 226 insertions, 116 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index b255415..2979e29 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -268,7 +268,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
268 | 268 | ||
269 | if (m_Friends.ContainsKey(agentID)) | 269 | if (m_Friends.ContainsKey(agentID)) |
270 | { | 270 | { |
271 | if (m_Friends[agentID].RegionID == UUID.Zero && m_Friends[agentID].Friends == null) | 271 | if (m_Friends[agentID].RegionID == UUID.Zero) |
272 | { | 272 | { |
273 | m_Friends[agentID].Friends = | 273 | m_Friends[agentID].Friends = |
274 | m_FriendsService.GetFriends(agentID); | 274 | m_FriendsService.GetFriends(agentID); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 806aa4f..60d1720 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -97,9 +97,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
97 | int successfulAssetRestores = 0; | 97 | int successfulAssetRestores = 0; |
98 | int failedAssetRestores = 0; | 98 | int failedAssetRestores = 0; |
99 | int successfulItemRestores = 0; | 99 | int successfulItemRestores = 0; |
100 | List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>(); | 100 | |
101 | List<InventoryNodeBase> loadedNodes = new List<InventoryNodeBase>(); | ||
101 | 102 | ||
102 | //InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath); | ||
103 | InventoryFolderBase rootDestinationFolder | 103 | InventoryFolderBase rootDestinationFolder |
104 | = InventoryArchiveUtils.FindFolderByPath( | 104 | = InventoryArchiveUtils.FindFolderByPath( |
105 | m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); | 105 | m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); |
@@ -109,14 +109,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
109 | // Possibly provide an option later on to automatically create this folder if it does not exist | 109 | // Possibly provide an option later on to automatically create this folder if it does not exist |
110 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); | 110 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); |
111 | 111 | ||
112 | return nodesLoaded; | 112 | return loadedNodes; |
113 | } | 113 | } |
114 | 114 | ||
115 | archive = new TarArchiveReader(m_loadStream); | 115 | archive = new TarArchiveReader(m_loadStream); |
116 | 116 | ||
117 | // In order to load identically named folders, we need to keep track of the folders that we have already | 117 | // In order to load identically named folders, we need to keep track of the folders that we have already |
118 | // created | 118 | // resolved |
119 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); | 119 | Dictionary <string, InventoryFolderBase> resolvedFolders = new Dictionary<string, InventoryFolderBase>(); |
120 | 120 | ||
121 | byte[] data; | 121 | byte[] data; |
122 | TarArchiveReader.TarEntryType entryType; | 122 | TarArchiveReader.TarEntryType entryType; |
@@ -139,10 +139,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
139 | } | 139 | } |
140 | else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH)) | 140 | else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH)) |
141 | { | 141 | { |
142 | filePath = filePath.Substring(ArchiveConstants.INVENTORY_PATH.Length); | ||
143 | |||
144 | // Trim off the file portion if we aren't already dealing with a directory path | ||
145 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) | ||
146 | filePath = filePath.Remove(filePath.LastIndexOf("/") + 1); | ||
147 | |||
142 | InventoryFolderBase foundFolder | 148 | InventoryFolderBase foundFolder |
143 | = ReplicateArchivePathToUserInventory( | 149 | = ReplicateArchivePathToUserInventory( |
144 | filePath, TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType, | 150 | filePath, rootDestinationFolder, resolvedFolders, loadedNodes); |
145 | rootDestinationFolder, foldersCreated, nodesLoaded); | ||
146 | 151 | ||
147 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) | 152 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) |
148 | { | 153 | { |
@@ -155,7 +160,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
155 | // If we're loading an item directly into the given destination folder then we need to record | 160 | // If we're loading an item directly into the given destination folder then we need to record |
156 | // it separately from any loaded root folders | 161 | // it separately from any loaded root folders |
157 | if (rootDestinationFolder == foundFolder) | 162 | if (rootDestinationFolder == foundFolder) |
158 | nodesLoaded.Add(item); | 163 | loadedNodes.Add(item); |
159 | } | 164 | } |
160 | } | 165 | } |
161 | } | 166 | } |
@@ -171,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
171 | successfulAssetRestores, failedAssetRestores); | 176 | successfulAssetRestores, failedAssetRestores); |
172 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); | 177 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); |
173 | 178 | ||
174 | return nodesLoaded; | 179 | return loadedNodes; |
175 | } | 180 | } |
176 | 181 | ||
177 | public void Close() | 182 | public void Close() |
@@ -184,54 +189,119 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
184 | /// Replicate the inventory paths in the archive to the user's inventory as necessary. | 189 | /// Replicate the inventory paths in the archive to the user's inventory as necessary. |
185 | /// </summary> | 190 | /// </summary> |
186 | /// <param name="archivePath">The item archive path to replicate</param> | 191 | /// <param name="archivePath">The item archive path to replicate</param> |
187 | /// <param name="isDir">Is the path we're dealing with a directory?</param> | ||
188 | /// <param name="rootDestinationFolder">The root folder for the inventory load</param> | 192 | /// <param name="rootDestinationFolder">The root folder for the inventory load</param> |
189 | /// <param name="foldersCreated"> | 193 | /// <param name="resolvedFolders"> |
190 | /// The folders created so far. This method will add more folders if necessary | 194 | /// The folders that we have resolved so far for a given archive path. |
195 | /// This method will add more folders if necessary | ||
191 | /// </param> | 196 | /// </param> |
192 | /// <param name="nodesLoaded"> | 197 | /// <param name="loadedNodes"> |
193 | /// Track the inventory nodes created. This is distinct from the folders created since for a particular folder | 198 | /// Track the inventory nodes created. |
194 | /// chain, only the root node needs to be recorded | ||
195 | /// </param> | 199 | /// </param> |
196 | /// <returns>The last user inventory folder created or found for the archive path</returns> | 200 | /// <returns>The last user inventory folder created or found for the archive path</returns> |
197 | public InventoryFolderBase ReplicateArchivePathToUserInventory( | 201 | public InventoryFolderBase ReplicateArchivePathToUserInventory( |
198 | string archivePath, | 202 | string archivePath, |
199 | bool isDir, | ||
200 | InventoryFolderBase rootDestFolder, | 203 | InventoryFolderBase rootDestFolder, |
201 | Dictionary <string, InventoryFolderBase> foldersCreated, | 204 | Dictionary <string, InventoryFolderBase> resolvedFolders, |
202 | List<InventoryNodeBase> nodesLoaded) | 205 | List<InventoryNodeBase> loadedNodes) |
203 | { | 206 | { |
204 | archivePath = archivePath.Substring(ArchiveConstants.INVENTORY_PATH.Length); | ||
205 | |||
206 | // Remove the file portion if we aren't already dealing with a directory path | ||
207 | if (!isDir) | ||
208 | archivePath = archivePath.Remove(archivePath.LastIndexOf("/") + 1); | ||
209 | |||
210 | string originalArchivePath = archivePath; | 207 | string originalArchivePath = archivePath; |
211 | 208 | ||
212 | // m_log.DebugFormat( | 209 | // m_log.DebugFormat( |
213 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); | 210 | // "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); |
211 | |||
212 | InventoryFolderBase destFolder = ResolveDestinationFolder(rootDestFolder, ref archivePath, resolvedFolders); | ||
213 | |||
214 | // m_log.DebugFormat( | ||
215 | // "[INVENTORY ARCHIVER]: originalArchivePath [{0}], section already loaded [{1}]", | ||
216 | // originalArchivePath, archivePath); | ||
217 | |||
218 | string archivePathSectionToCreate = originalArchivePath.Substring(archivePath.Length); | ||
219 | CreateFoldersForPath(destFolder, archivePathSectionToCreate, resolvedFolders, loadedNodes); | ||
220 | |||
221 | return destFolder; | ||
222 | |||
223 | /* | ||
224 | string[] rawFolders = filePath.Split(new char[] { '/' }); | ||
225 | |||
226 | // Find the folders that do exist along the path given | ||
227 | int i = 0; | ||
228 | bool noFolder = false; | ||
229 | InventoryFolderImpl foundFolder = rootDestinationFolder; | ||
230 | while (!noFolder && i < rawFolders.Length) | ||
231 | { | ||
232 | InventoryFolderImpl folder = foundFolder.FindFolderByPath(rawFolders[i]); | ||
233 | if (null != folder) | ||
234 | { | ||
235 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Found folder {0}", folder.Name); | ||
236 | foundFolder = folder; | ||
237 | i++; | ||
238 | } | ||
239 | else | ||
240 | { | ||
241 | noFolder = true; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | // Create any folders that did not previously exist | ||
246 | while (i < rawFolders.Length) | ||
247 | { | ||
248 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawFolders[i]); | ||
249 | |||
250 | UUID newFolderId = UUID.Random(); | ||
251 | m_userInfo.CreateFolder( | ||
252 | rawFolders[i++], newFolderId, (ushort)AssetType.Folder, foundFolder.ID); | ||
253 | foundFolder = foundFolder.GetChildFolder(newFolderId); | ||
254 | } | ||
255 | */ | ||
256 | } | ||
257 | |||
258 | /// <summary> | ||
259 | /// Resolve a destination folder | ||
260 | /// </summary> | ||
261 | /// | ||
262 | /// We require here a root destination folder (usually the root of the user's inventory) and the archive | ||
263 | /// path. We also pass in a list of previously resolved folders in case we've found this one previously. | ||
264 | /// | ||
265 | /// <param name="archivePath"> | ||
266 | /// The item archive path to resolve. The portion of the path passed back is that | ||
267 | /// which corresponds to the resolved desintation folder. | ||
268 | /// <param name="rootDestinationFolder"> | ||
269 | /// The root folder for the inventory load | ||
270 | /// </param> | ||
271 | /// <param name="resolvedFolders"> | ||
272 | /// The folders that we have resolved so far for a given archive path. | ||
273 | /// </param> | ||
274 | /// <returns> | ||
275 | /// The folder in the user's inventory that matches best the archive path given. If no such folder was found | ||
276 | /// then the passed in root destination folder is returned. | ||
277 | /// </returns> | ||
278 | protected InventoryFolderBase ResolveDestinationFolder( | ||
279 | InventoryFolderBase rootDestFolder, | ||
280 | ref string archivePath, | ||
281 | Dictionary <string, InventoryFolderBase> resolvedFolders) | ||
282 | { | ||
283 | string originalArchivePath = archivePath; | ||
214 | 284 | ||
215 | InventoryFolderBase destFolder = null; | 285 | InventoryFolderBase destFolder = null; |
216 | 286 | ||
217 | // XXX: Nasty way of dealing with a path that has no directory component | ||
218 | if (archivePath.Length > 0) | 287 | if (archivePath.Length > 0) |
219 | { | 288 | { |
220 | while (null == destFolder && archivePath.Length > 0) | 289 | while (null == destFolder && archivePath.Length > 0) |
221 | { | 290 | { |
222 | if (foldersCreated.ContainsKey(archivePath)) | 291 | if (resolvedFolders.ContainsKey(archivePath)) |
223 | { | 292 | { |
224 | // m_log.DebugFormat( | 293 | // m_log.DebugFormat( |
225 | // "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); | 294 | // "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); |
226 | destFolder = foldersCreated[archivePath]; | 295 | destFolder = resolvedFolders[archivePath]; |
227 | } | 296 | } |
228 | else | 297 | else |
229 | { | 298 | { |
230 | // Don't include the last slash | 299 | // Don't include the last slash so find the penultimate one |
231 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); | 300 | int penultimateSlashIndex = archivePath.LastIndexOf("/", archivePath.Length - 2); |
232 | 301 | ||
233 | if (penultimateSlashIndex >= 0) | 302 | if (penultimateSlashIndex >= 0) |
234 | { | 303 | { |
304 | // Remove the last section of path so that we can see if we've already resolved the parent | ||
235 | archivePath = archivePath.Remove(penultimateSlashIndex + 1); | 305 | archivePath = archivePath.Remove(penultimateSlashIndex + 1); |
236 | } | 306 | } |
237 | else | 307 | else |
@@ -245,19 +315,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
245 | } | 315 | } |
246 | } | 316 | } |
247 | } | 317 | } |
248 | else | 318 | |
249 | { | 319 | if (null == destFolder) |
250 | destFolder = rootDestFolder; | 320 | destFolder = rootDestFolder; |
251 | } | 321 | |
252 | 322 | return destFolder; | |
253 | string archivePathSectionToCreate = originalArchivePath.Substring(archivePath.Length); | 323 | } |
254 | string[] rawDirsToCreate | 324 | |
255 | = archivePathSectionToCreate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); | 325 | /// <summary> |
326 | /// Create a set of folders for the given path. | ||
327 | /// </summary> | ||
328 | /// <param name="destFolder"> | ||
329 | /// The root folder from which the creation will take place. | ||
330 | /// </param> | ||
331 | /// <param name="path"> | ||
332 | /// The path to create | ||
333 | /// </param> | ||
334 | /// <param name="resolvedFolders"> | ||
335 | /// The folders that we have resolved so far for a given archive path. | ||
336 | /// </param> | ||
337 | /// <param name="loadedNodes"> | ||
338 | /// Track the inventory nodes created. | ||
339 | /// </param> | ||
340 | protected void CreateFoldersForPath( | ||
341 | InventoryFolderBase destFolder, string path, Dictionary <string, InventoryFolderBase> resolvedFolders, | ||
342 | List<InventoryNodeBase> loadedNodes) | ||
343 | { | ||
344 | string pathCreated = ""; | ||
345 | string[] rawDirsToCreate = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); | ||
256 | int i = 0; | 346 | int i = 0; |
257 | 347 | ||
258 | while (i < rawDirsToCreate.Length) | 348 | while (i < rawDirsToCreate.Length) |
259 | { | 349 | { |
260 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Loading archived folder {0}", rawDirsToCreate[i]); | 350 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0} from IAR", rawDirsToCreate[i]); |
261 | 351 | ||
262 | int identicalNameIdentifierIndex | 352 | int identicalNameIdentifierIndex |
263 | = rawDirsToCreate[i].LastIndexOf( | 353 | = rawDirsToCreate[i].LastIndexOf( |
@@ -282,66 +372,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
282 | newFolderId, newFolderName, m_userInfo.PrincipalID, | 372 | newFolderId, newFolderName, m_userInfo.PrincipalID, |
283 | (short)AssetType.Unknown, destFolder.ID, 1); | 373 | (short)AssetType.Unknown, destFolder.ID, 1); |
284 | m_scene.InventoryService.AddFolder(destFolder); | 374 | m_scene.InventoryService.AddFolder(destFolder); |
285 | |||
286 | // UUID newFolderId = UUID.Random(); | ||
287 | // m_scene.InventoryService.AddFolder( | ||
288 | // m_userInfo.CreateFolder( | ||
289 | // folderName, newFolderId, (ushort)AssetType.Folder, foundFolder.ID); | ||
290 | |||
291 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Retrieving newly created folder {0}", folderName); | ||
292 | // foundFolder = foundFolder.GetChildFolder(newFolderId); | ||
293 | // m_log.DebugFormat( | ||
294 | // "[INVENTORY ARCHIVER]: Retrieved newly created folder {0} with ID {1}", | ||
295 | // foundFolder.Name, foundFolder.ID); | ||
296 | 375 | ||
297 | // Record that we have now created this folder | 376 | // Record that we have now created this folder |
298 | archivePath += rawDirsToCreate[i] + "/"; | 377 | pathCreated += rawDirsToCreate[i] + "/"; |
299 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Loaded archive path {0}", archivePath); | 378 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Created folder {0} from IAR", pathCreated); |
300 | foldersCreated[archivePath] = destFolder; | 379 | resolvedFolders[pathCreated] = destFolder; |
301 | 380 | ||
302 | if (0 == i) | 381 | if (0 == i) |
303 | nodesLoaded.Add(destFolder); | 382 | loadedNodes.Add(destFolder); |
304 | 383 | ||
305 | i++; | 384 | i++; |
306 | } | 385 | } |
307 | |||
308 | return destFolder; | ||
309 | |||
310 | /* | ||
311 | string[] rawFolders = filePath.Split(new char[] { '/' }); | ||
312 | |||
313 | // Find the folders that do exist along the path given | ||
314 | int i = 0; | ||
315 | bool noFolder = false; | ||
316 | InventoryFolderImpl foundFolder = rootDestinationFolder; | ||
317 | while (!noFolder && i < rawFolders.Length) | ||
318 | { | ||
319 | InventoryFolderImpl folder = foundFolder.FindFolderByPath(rawFolders[i]); | ||
320 | if (null != folder) | ||
321 | { | ||
322 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Found folder {0}", folder.Name); | ||
323 | foundFolder = folder; | ||
324 | i++; | ||
325 | } | ||
326 | else | ||
327 | { | ||
328 | noFolder = true; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | // Create any folders that did not previously exist | ||
333 | while (i < rawFolders.Length) | ||
334 | { | ||
335 | m_log.DebugFormat("[INVENTORY ARCHIVER]: Creating folder {0}", rawFolders[i]); | ||
336 | |||
337 | UUID newFolderId = UUID.Random(); | ||
338 | m_userInfo.CreateFolder( | ||
339 | rawFolders[i++], newFolderId, (ushort)AssetType.Folder, foundFolder.ID); | ||
340 | foundFolder = foundFolder.GetChildFolder(newFolderId); | ||
341 | } | ||
342 | */ | ||
343 | } | 386 | } |
344 | 387 | ||
345 | /// <summary> | 388 | /// <summary> |
346 | /// Load an item from the archive | 389 | /// Load an item from the archive |
347 | /// </summary> | 390 | /// </summary> |
@@ -432,4 +475,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
432 | } | 475 | } |
433 | } | 476 | } |
434 | } | 477 | } |
435 | } | 478 | } \ 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 ab5f485..cfefbe9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -30,11 +30,11 @@ using System.Collections.Generic; | |||
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using log4net; | 32 | using log4net; |
33 | using NDesk.Options; | ||
33 | using Nini.Config; | 34 | using Nini.Config; |
34 | using OpenMetaverse; | 35 | using OpenMetaverse; |
35 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Communications; | 37 | using OpenSim.Framework.Communications; |
37 | |||
38 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
39 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
@@ -91,9 +91,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
91 | 91 | ||
92 | scene.AddCommand( | 92 | scene.AddCommand( |
93 | this, "load iar", | 93 | this, "load iar", |
94 | "load iar <first> <last> <inventory path> <password> [<IAR path>]", | 94 | "load iar <first> <last> <inventory path> <password> [<IAR path>]", |
95 | //"load iar [--merge] <first> <last> <inventory path> <password> [<IAR path>]", | ||
95 | "Load user inventory archive (IAR).", | 96 | "Load user inventory archive (IAR).", |
96 | "<first> is user's first name." + Environment.NewLine | 97 | //"--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" |
98 | //+ "<first> is user's first name." + Environment.NewLine | ||
99 | "<first> is user's first name." + Environment.NewLine | ||
97 | + "<last> is user's last name." + Environment.NewLine | 100 | + "<last> is user's last name." + Environment.NewLine |
98 | + "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine | 101 | + "<inventory path> is the path inside the user's inventory where the IAR should be loaded." + Environment.NewLine |
99 | + "<password> is the user's password." + Environment.NewLine | 102 | + "<password> is the user's password." + Environment.NewLine |
@@ -133,8 +136,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
133 | if (handlerInventoryArchiveSaved != null) | 136 | if (handlerInventoryArchiveSaved != null) |
134 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); | 137 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); |
135 | } | 138 | } |
136 | 139 | ||
137 | public bool ArchiveInventory(Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) | 140 | public bool ArchiveInventory( |
141 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) | ||
142 | { | ||
143 | return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>()); | ||
144 | } | ||
145 | |||
146 | public bool ArchiveInventory( | ||
147 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, | ||
148 | Dictionary<string, object> options) | ||
138 | { | 149 | { |
139 | if (m_scenes.Count > 0) | 150 | if (m_scenes.Count > 0) |
140 | { | 151 | { |
@@ -172,7 +183,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
172 | return false; | 183 | return false; |
173 | } | 184 | } |
174 | 185 | ||
175 | public bool ArchiveInventory(Guid id, string firstName, string lastName, string invPath, string pass, string savePath) | 186 | public bool ArchiveInventory( |
187 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, | ||
188 | Dictionary<string, object> options) | ||
176 | { | 189 | { |
177 | if (m_scenes.Count > 0) | 190 | if (m_scenes.Count > 0) |
178 | { | 191 | { |
@@ -209,8 +222,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
209 | 222 | ||
210 | return false; | 223 | return false; |
211 | } | 224 | } |
212 | 225 | ||
213 | public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream) | 226 | public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream) |
227 | { | ||
228 | return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); | ||
229 | } | ||
230 | |||
231 | public bool DearchiveInventory( | ||
232 | string firstName, string lastName, string invPath, string pass, Stream loadStream, | ||
233 | Dictionary<string, object> options) | ||
214 | { | 234 | { |
215 | if (m_scenes.Count > 0) | 235 | if (m_scenes.Count > 0) |
216 | { | 236 | { |
@@ -252,7 +272,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
252 | return false; | 272 | return false; |
253 | } | 273 | } |
254 | 274 | ||
255 | public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, string loadPath) | 275 | public bool DearchiveInventory( |
276 | string firstName, string lastName, string invPath, string pass, string loadPath, | ||
277 | Dictionary<string, object> options) | ||
256 | { | 278 | { |
257 | if (m_scenes.Count > 0) | 279 | if (m_scenes.Count > 0) |
258 | { | 280 | { |
@@ -300,29 +322,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
300 | /// <param name="cmdparams"></param> | 322 | /// <param name="cmdparams"></param> |
301 | protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams) | 323 | protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams) |
302 | { | 324 | { |
303 | if (cmdparams.Length < 6) | 325 | m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); |
326 | |||
327 | Dictionary<string, object> options = new Dictionary<string, object>(); | ||
328 | OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); | ||
329 | |||
330 | List<string> mainParams = optionSet.Parse(cmdparams); | ||
331 | |||
332 | if (mainParams.Count < 6) | ||
304 | { | 333 | { |
305 | m_log.Error( | 334 | m_log.Error( |
306 | "[INVENTORY ARCHIVER]: usage is load iar <first name> <last name> <inventory path> <user password> [<load file path>]"); | 335 | "[INVENTORY ARCHIVER]: usage is load iar <first name> <last name> <inventory path> <user password> [<load file path>]"); |
307 | return; | 336 | return; |
308 | } | 337 | } |
309 | 338 | ||
310 | m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); | 339 | string firstName = mainParams[2]; |
311 | 340 | string lastName = mainParams[3]; | |
312 | string firstName = cmdparams[2]; | 341 | string invPath = mainParams[4]; |
313 | string lastName = cmdparams[3]; | 342 | string pass = mainParams[5]; |
314 | string invPath = cmdparams[4]; | 343 | string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); |
315 | string pass = cmdparams[5]; | ||
316 | string loadPath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME); | ||
317 | 344 | ||
318 | m_log.InfoFormat( | 345 | m_log.InfoFormat( |
319 | "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", | 346 | "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", |
320 | loadPath, invPath, firstName, lastName); | 347 | loadPath, invPath, firstName, lastName); |
321 | 348 | ||
322 | if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath)) | 349 | if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) |
323 | m_log.InfoFormat( | 350 | m_log.InfoFormat( |
324 | "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", | 351 | "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", |
325 | loadPath, firstName, lastName); | 352 | loadPath, firstName, lastName); |
326 | } | 353 | } |
327 | 354 | ||
328 | /// <summary> | 355 | /// <summary> |
@@ -351,7 +378,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
351 | savePath, invPath, firstName, lastName); | 378 | savePath, invPath, firstName, lastName); |
352 | 379 | ||
353 | Guid id = Guid.NewGuid(); | 380 | Guid id = Guid.NewGuid(); |
354 | ArchiveInventory(id, firstName, lastName, invPath, pass, savePath); | 381 | ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary<string, object>()); |
355 | 382 | ||
356 | lock (m_pendingConsoleSaves) | 383 | lock (m_pendingConsoleSaves) |
357 | m_pendingConsoleSaves.Add(id); | 384 | m_pendingConsoleSaves.Add(id); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 507662f..59cd386 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs | |||
@@ -279,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
279 | public void TestIarV0_1WithEscapedChars() | 279 | public void TestIarV0_1WithEscapedChars() |
280 | { | 280 | { |
281 | TestHelper.InMethod(); | 281 | TestHelper.InMethod(); |
282 | // log4net.Config.XmlConfigurator.Configure(); | 282 | log4net.Config.XmlConfigurator.Configure(); |
283 | 283 | ||
284 | string itemName = "You & you are a mean/man/"; | 284 | string itemName = "You & you are a mean/man/"; |
285 | string humanEscapedItemName = @"You & you are a mean\/man\/"; | 285 | string humanEscapedItemName = @"You & you are a mean\/man\/"; |
@@ -531,7 +531,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
531 | 531 | ||
532 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) | 532 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null) |
533 | .ReplicateArchivePathToUserInventory( | 533 | .ReplicateArchivePathToUserInventory( |
534 | itemArchivePath, false, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 534 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
535 | foldersCreated, nodesLoaded); | 535 | foldersCreated, nodesLoaded); |
536 | 536 | ||
537 | InventoryFolderBase folder1 | 537 | InventoryFolderBase folder1 |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index dc1025d..66c5a72 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -410,6 +410,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
410 | teleportFlags, capsPath); | 410 | teleportFlags, capsPath); |
411 | } | 411 | } |
412 | 412 | ||
413 | // Let's set this to true tentatively. This does not trigger OnChildAgent | ||
414 | sp.IsChildAgent = true; | ||
415 | |||
413 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 416 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which |
414 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | 417 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation |
415 | // that the client contacted the destination before we send the attachments and close things here. | 418 | // that the client contacted the destination before we send the attachments and close things here. |
@@ -418,6 +421,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
418 | // Client never contacted destination. Let's restore everything back | 421 | // Client never contacted destination. Let's restore everything back |
419 | sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); | 422 | sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); |
420 | 423 | ||
424 | // Fail. Reset it back | ||
425 | sp.IsChildAgent = false; | ||
426 | |||
421 | ResetFromTransit(sp.UUID); | 427 | ResetFromTransit(sp.UUID); |
422 | 428 | ||
423 | // Yikes! We should just have a ref to scene here. | 429 | // Yikes! We should just have a ref to scene here. |
@@ -436,7 +442,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
436 | 442 | ||
437 | KillEntity(sp.Scene, sp.LocalId); | 443 | KillEntity(sp.Scene, sp.LocalId); |
438 | 444 | ||
445 | // Now let's make it officially a child agent | ||
439 | sp.MakeChildAgent(); | 446 | sp.MakeChildAgent(); |
447 | |||
440 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 448 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
441 | 449 | ||
442 | if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 450 | if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
@@ -538,6 +546,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
538 | client.SendTeleportFailed("Your home region could not be found."); | 546 | client.SendTeleportFailed("Your home region could not be found."); |
539 | return; | 547 | return; |
540 | } | 548 | } |
549 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: User's home region is {0} {1} ({2}-{3})", | ||
550 | regionInfo.RegionName, regionInfo.RegionID, regionInfo.RegionLocX / Constants.RegionSize, regionInfo.RegionLocY / Constants.RegionSize); | ||
551 | |||
541 | // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point... | 552 | // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point... |
542 | ((Scene)(client.Scene)).RequestTeleportLocation( | 553 | ((Scene)(client.Scene)).RequestTeleportLocation( |
543 | client, regionInfo.RegionHandle, uinfo.HomePosition, uinfo.HomeLookAt, | 554 | client, regionInfo.RegionHandle, uinfo.HomePosition, uinfo.HomeLookAt, |
diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryArchiverModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryArchiverModule.cs index fbadd91..01066e6 100644 --- a/OpenSim/Region/Framework/Interfaces/IInventoryArchiverModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IInventoryArchiverModule.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using System.IO; | 30 | using System.IO; |
30 | using OpenSim.Services.Interfaces; | 31 | using OpenSim.Services.Interfaces; |
31 | 32 | ||
@@ -59,6 +60,20 @@ namespace OpenSim.Region.Framework.Interfaces | |||
59 | /// <param name="loadStream">The stream from which the inventory archive will be loaded</param> | 60 | /// <param name="loadStream">The stream from which the inventory archive will be loaded</param> |
60 | /// <returns>true if the first stage of the operation succeeded, false otherwise</returns> | 61 | /// <returns>true if the first stage of the operation succeeded, false otherwise</returns> |
61 | bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream); | 62 | bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream); |
63 | |||
64 | /// <summary> | ||
65 | /// Dearchive a user's inventory folder from the given stream | ||
66 | /// </summary> | ||
67 | /// <param name="firstName"></param> | ||
68 | /// <param name="lastName"></param> | ||
69 | /// <param name="invPath">The inventory path in which to place the loaded folders and items</param> | ||
70 | /// <param name="loadStream">The stream from which the inventory archive will be loaded</param> | ||
71 | /// <param name="options">Dearchiving options. At the moment, the only option is ("merge", true). This merges | ||
72 | /// the loaded IAR with existing folders where possible.</param> | ||
73 | /// <returns>true if the first stage of the operation succeeded, false otherwise</returns> | ||
74 | bool DearchiveInventory( | ||
75 | string firstName, string lastName, string invPath, string pass, Stream loadStream, | ||
76 | Dictionary<string, object> options); | ||
62 | 77 | ||
63 | /// <summary> | 78 | /// <summary> |
64 | /// Archive a user's inventory folder to the given stream | 79 | /// Archive a user's inventory folder to the given stream |
@@ -70,5 +85,19 @@ namespace OpenSim.Region.Framework.Interfaces | |||
70 | /// <param name="saveStream">The stream to which the inventory archive will be saved</param> | 85 | /// <param name="saveStream">The stream to which the inventory archive will be saved</param> |
71 | /// <returns>true if the first stage of the operation succeeded, false otherwise</returns> | 86 | /// <returns>true if the first stage of the operation succeeded, false otherwise</returns> |
72 | bool ArchiveInventory(Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream); | 87 | bool ArchiveInventory(Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream); |
88 | |||
89 | /// <summary> | ||
90 | /// Archive a user's inventory folder to the given stream | ||
91 | /// </summary> | ||
92 | /// <param name="id">ID representing this request. This will later be returned in the save event</param> | ||
93 | /// <param name="firstName"></param> | ||
94 | /// <param name="lastName"></param> | ||
95 | /// <param name="invPath">The inventory path from which the inventory should be saved.</param> | ||
96 | /// <param name="saveStream">The stream to which the inventory archive will be saved</param> | ||
97 | /// <param name="options">Archiving options. Currently, there are none.</param> | ||
98 | /// <returns>true if the first stage of the operation succeeded, false otherwise</returns> | ||
99 | bool ArchiveInventory( | ||
100 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, | ||
101 | Dictionary<string, object> options); | ||
73 | } | 102 | } |
74 | } | 103 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 19329a8..756b81e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -4039,7 +4039,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
4039 | // bordercross if position is outside of region | 4039 | // bordercross if position is outside of region |
4040 | 4040 | ||
4041 | if (!result) | 4041 | if (!result) |
4042 | { | ||
4042 | regionHandle = m_regInfo.RegionHandle; | 4043 | regionHandle = m_regInfo.RegionHandle; |
4044 | } | ||
4043 | else | 4045 | else |
4044 | { | 4046 | { |
4045 | // not in this region, undo the shift! | 4047 | // not in this region, undo the shift! |
diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs index 600ddfd..935ebb1 100644 --- a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs +++ b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs | |||
@@ -206,9 +206,7 @@ namespace OpenSim.Services.Connectors | |||
206 | if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) | 206 | if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) |
207 | { | 207 | { |
208 | if (replyData["result"] is Dictionary<string, object>) | 208 | if (replyData["result"] is Dictionary<string, object>) |
209 | { | ||
210 | guinfo = new GridUserInfo((Dictionary<string, object>)replyData["result"]); | 209 | guinfo = new GridUserInfo((Dictionary<string, object>)replyData["result"]); |
211 | } | ||
212 | } | 210 | } |
213 | 211 | ||
214 | return guinfo; | 212 | return guinfo; |
diff --git a/OpenSim/Services/Interfaces/IGridUserService.cs b/OpenSim/Services/Interfaces/IGridUserService.cs index e629dff..95ce5e8 100644 --- a/OpenSim/Services/Interfaces/IGridUserService.cs +++ b/OpenSim/Services/Interfaces/IGridUserService.cs | |||
@@ -65,7 +65,7 @@ namespace OpenSim.Services.Interfaces | |||
65 | Vector3.TryParse(kvp["HomeLookAt"].ToString(), out HomeLookAt); | 65 | Vector3.TryParse(kvp["HomeLookAt"].ToString(), out HomeLookAt); |
66 | 66 | ||
67 | if (kvp.ContainsKey("LastRegionID")) | 67 | if (kvp.ContainsKey("LastRegionID")) |
68 | UUID.TryParse(kvp["LastRegionID"].ToString(), out HomeRegionID); | 68 | UUID.TryParse(kvp["LastRegionID"].ToString(), out LastRegionID); |
69 | if (kvp.ContainsKey("LastPosition")) | 69 | if (kvp.ContainsKey("LastPosition")) |
70 | Vector3.TryParse(kvp["LastPosition"].ToString(), out LastPosition); | 70 | Vector3.TryParse(kvp["LastPosition"].ToString(), out LastPosition); |
71 | if (kvp.ContainsKey("LastLookAt")) | 71 | if (kvp.ContainsKey("LastLookAt")) |