public GatherAssetUuids ( |
||
sceneObject | The scene object for which to gather assets | |
assetUuids | AssetType>.IDictionary | The assets gathered |
return | void |
public void SaveModuleToArchive(TarArchiveWriter writer, IScene scene) { m_isArchiving = true; m_log.Info("[Archive]: Writing parcels to archive"); writer.WriteDir("parcels"); IParcelManagementModule module = scene.RequestModuleInterface<IParcelManagementModule>(); if (module != null) { List<ILandObject> landObject = module.AllParcels(); foreach (ILandObject parcel in landObject) { OSDMap parcelMap = parcel.LandData.ToOSD(); writer.WriteFile("parcels/" + parcel.LandData.GlobalID.ToString(), OSDParser.SerializeLLSDBinary(parcelMap)); } } m_log.Info("[Archive]: Finished writing parcels to archive"); m_log.Info("[Archive]: Writing terrain to archive"); writer.WriteDir("terrain"); ITerrainModule tModule = scene.RequestModuleInterface<ITerrainModule>(); if (tModule != null) { MemoryStream s = new MemoryStream(); tModule.SaveToStream(scene.RegionInfo.RegionID.ToString() + ".r32", s); writer.WriteFile("terrain/" + scene.RegionInfo.RegionID.ToString() + ".r32", s.ToArray()); s.Close(); } m_log.Info("[Archive]: Finished writing terrain to archive"); m_log.Info("[Archive]: Writing entities to archive"); ISceneEntity[] entities = scene.Entities.GetEntities(); //Get all entities, then start writing them to the database writer.WriteDir("entities"); IDictionary<UUID, AssetType> assets = new Dictionary<UUID, AssetType>(); UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); foreach (ISceneEntity entity in entities) { //Write all entities writer.WriteFile("entities/" + entity.UUID.ToString(), ((ISceneObject)entity).ToXml2()); //Get all the assets too assetGatherer.GatherAssetUuids(entity, assets, scene); } m_log.Info("[Archive]: Finished writing entities to archive"); m_log.Info("[Archive]: Writing assets for entities to archive"); bool foundAllAssets = true; foreach (UUID assetID in new List<UUID>(assets.Keys)) { AssetBase asset = m_scene.AssetService.GetCached(assetID.ToString()); if (asset != null) WriteAsset(asset, writer); //Write it syncronously since we havn't else { foundAllAssets = false; //Not all are cached m_missingAssets.Add(assetID); m_scene.AssetService.Get(assetID.ToString(), writer, RetrievedAsset); } } if (foundAllAssets) m_isArchiving = false; //We're done if all the assets were found m_log.Info("[Archive]: Finished writing assets for entities to archive"); }
/// <summary> /// Archive the region requested. /// </summary> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> public void ArchiveRegion() { Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); ISceneEntity[] entities = m_scene.Entities.GetEntities (); List<ISceneEntity> sceneObjects = new List<ISceneEntity>(); int numObjectsSkippedPermissions = 0; // Filter entities so that we only have scene objects. // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods // end up having to do this foreach (ISceneEntity entity in entities) { if (!entity.IsDeleted && !entity.IsAttachment) if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, entity, m_checkPermissions)) // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR. ++numObjectsSkippedPermissions; else sceneObjects.Add(entity); } UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); foreach (ISceneEntity sceneObject in sceneObjects) { assetGatherer.GatherAssetUuids(sceneObject, assetUuids, m_scene); } m_log.DebugFormat( "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", sceneObjects.Count, assetUuids.Count); if (numObjectsSkippedPermissions > 0) { m_log.DebugFormat( "[ARCHIVER]: {0} scene objects skipped due to lack of permissions", numObjectsSkippedPermissions); } // Make sure that we also request terrain texture assets RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture; if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture; if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture; if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture; TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream); // Asynchronously request all the assets required to perform this archive operation ArchiveWriteRequestExecution awre = new ArchiveWriteRequestExecution( sceneObjects, m_scene.RequestModuleInterface<ITerrainModule>(), m_scene.RequestModuleInterface<IRegionSerialiserModule>(), m_scene, archiveWriter, m_requestId); new AssetsRequest( new AssetsArchiver(archiveWriter), assetUuids, m_scene.AssetService, awre.ReceivedAllAssets).Execute(); }
/// <summary> /// Archive the region requested. /// </summary> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> public void ArchiveRegion() { Dictionary<UUID, int> assetUuids = new Dictionary<UUID, int>(); List<EntityBase> entities = m_scene.GetEntities(); List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); /* foreach (ILandObject lo in m_scene.LandChannel.AllParcels()) { if (name == lo.LandData.Name) { // This is the parcel we want } } */ // Filter entities so that we only have scene objects. // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods // end up having to do this foreach (EntityBase entity in entities) { if (entity is SceneObjectGroup) { SceneObjectGroup sceneObject = (SceneObjectGroup)entity; if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) sceneObjects.Add((SceneObjectGroup)entity); } } UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); foreach (SceneObjectGroup sceneObject in sceneObjects) { assetGatherer.GatherAssetUuids(sceneObject, assetUuids); } m_log.DebugFormat( "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", sceneObjects.Count, assetUuids.Count); // Make sure that we also request terrain texture assets RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) assetUuids[regionSettings.TerrainTexture1] = 1; if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) assetUuids[regionSettings.TerrainTexture2] = 1; if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) assetUuids[regionSettings.TerrainTexture3] = 1; if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) assetUuids[regionSettings.TerrainTexture4] = 1; TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream); // Asynchronously request all the assets required to perform this archive operation ArchiveWriteRequestExecution awre = new ArchiveWriteRequestExecution( sceneObjects, m_scene.RequestModuleInterface<ITerrainModule>(), m_scene.RequestModuleInterface<IRegionSerialiserModule>(), m_scene, archiveWriter, m_requestId); new AssetsRequest( new AssetsArchiver(archiveWriter), assetUuids.Keys, m_scene.AssetService, awre.ReceivedAllAssets).Execute(); }
/// <summary> /// Save a backup of the sim /// </summary> /// <param name = "appendedFilePath">The file path where the backup will be saved</param> protected virtual void SaveBackup(string appendedFilePath, bool saveAssets) { if (appendedFilePath == "/") appendedFilePath = ""; if (m_scene.RegionInfo.HasBeenDeleted) return; IBackupModule backupModule = m_scene.RequestModuleInterface<IBackupModule>(); if (backupModule != null && backupModule.LoadingPrims) //Something is changing lots of prims { MainConsole.Instance.Info("[Backup]: Not saving backup because the backup module is loading prims"); return; } //Save any script state saves that might be around IScriptModule[] engines = m_scene.RequestModuleInterfaces<IScriptModule>(); try { if (engines != null) { #if (!ISWIN) foreach (IScriptModule engine in engines) { if (engine != null) { engine.SaveStateSaves(); } } #else foreach (IScriptModule engine in engines.Where(engine => engine != null)) { engine.SaveStateSaves(); } #endif } } catch (Exception ex) { MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex); } MainConsole.Instance.Info("[FileBasedSimulationData]: Saving backup for region " + m_scene.RegionInfo.RegionName); string fileName = appendedFilePath + m_scene.RegionInfo.RegionName + m_saveAppendedFileName + ".abackup"; if (File.Exists(fileName)) { //Do new style saving here! GZipStream m_saveStream = new GZipStream(new FileStream(fileName + ".tmp", FileMode.Create), CompressionMode.Compress); TarArchiveWriter writer = new TarArchiveWriter(m_saveStream); GZipStream m_loadStream = new GZipStream(new FileStream(fileName, FileMode.Open), CompressionMode.Decompress); TarArchiveReader reader = new TarArchiveReader(m_loadStream); writer.WriteDir("parcels"); IParcelManagementModule module = m_scene.RequestModuleInterface<IParcelManagementModule>(); if (module != null) { List<ILandObject> landObject = module.AllParcels(); foreach (ILandObject parcel in landObject) { OSDMap parcelMap = parcel.LandData.ToOSD(); var binary = OSDParser.SerializeLLSDBinary(parcelMap); writer.WriteFile("parcels/" + parcel.LandData.GlobalID.ToString(), binary); binary = null; parcelMap = null; } } writer.WriteDir("newstyleterrain"); writer.WriteDir("newstylerevertterrain"); writer.WriteDir("newstylewater"); writer.WriteDir("newstylerevertwater"); ITerrainModule tModule = m_scene.RequestModuleInterface<ITerrainModule>(); if (tModule != null) { try { byte[] sdata = WriteTerrainToStream(tModule.TerrainMap); writer.WriteFile("newstyleterrain/" + m_scene.RegionInfo.RegionID.ToString() + ".terrain", sdata); sdata = null; sdata = WriteTerrainToStream(tModule.TerrainRevertMap); writer.WriteFile( "newstylerevertterrain/" + m_scene.RegionInfo.RegionID.ToString() + ".terrain", sdata); sdata = null; if (tModule.TerrainWaterMap != null) { sdata = WriteTerrainToStream(tModule.TerrainWaterMap); writer.WriteFile("newstylewater/" + m_scene.RegionInfo.RegionID.ToString() + ".terrain", sdata); sdata = null; sdata = WriteTerrainToStream(tModule.TerrainWaterRevertMap); writer.WriteFile( "newstylerevertwater/" + m_scene.RegionInfo.RegionID.ToString() + ".terrain", sdata); sdata = null; } } catch (Exception ex) { MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex); } } IDictionary<UUID, AssetType> assets = new Dictionary<UUID, AssetType>(); UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); ISceneEntity[] saveentities = m_scene.Entities.GetEntities(); List<UUID> entitiesToSave = new List<UUID>(); foreach (ISceneEntity entity in saveentities) { try { if (entity.IsAttachment || ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) || ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez)) continue; if (entity.HasGroupChanged) { entity.HasGroupChanged = false; //Write all entities byte[] xml = ((ISceneObject) entity).ToBinaryXml2(); writer.WriteFile("entities/" + entity.UUID.ToString(), xml); xml = null; } else entitiesToSave.Add(entity.UUID); if (saveAssets) assetGatherer.GatherAssetUuids(entity, assets, m_scene); } catch (Exception ex) { MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex); entitiesToSave.Add(entity.UUID); } } byte[] data; string filePath; TarArchiveReader.TarEntryType entryType; //Load the archive data that we need try { while ((data = reader.ReadEntry(out filePath, out entryType)) != null) { if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) continue; if (filePath.StartsWith("entities/")) { UUID entityID = UUID.Parse(filePath.Remove(0, 9)); if (entitiesToSave.Contains(entityID)) { writer.WriteFile(filePath, data); entitiesToSave.Remove(entityID); } } data = null; } } catch (Exception ex) { MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex); } if (entitiesToSave.Count > 0) { MainConsole.Instance.Fatal(entitiesToSave.Count + " PRIMS WERE NOT GOING TO BE SAVED! FORCE SAVING NOW! "); foreach (ISceneEntity entity in saveentities) { if (entitiesToSave.Contains(entity.UUID)) { if (entity.IsAttachment || ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) || ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez)) continue; //Write all entities byte[] xml = ((ISceneObject) entity).ToBinaryXml2(); writer.WriteFile("entities/" + entity.UUID.ToString(), xml); xml = null; } } } if (saveAssets) { foreach (UUID assetID in new List<UUID>(assets.Keys)) { try { WriteAsset(assetID.ToString(), m_scene.AssetService.Get(assetID.ToString()), writer); } catch (Exception ex) { MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex); } } } reader.Close(); writer.Close(); m_loadStream.Close(); m_saveStream.Close(); GC.Collect(); if (m_keepOldSave && !m_oldSaveHasBeenSaved) { //Havn't moved it yet, so make sure the directory exists, then move it m_oldSaveHasBeenSaved = true; if (!Directory.Exists(m_oldSaveDirectory)) Directory.CreateDirectory(m_oldSaveDirectory); File.Copy(fileName + ".tmp", Path.Combine(m_oldSaveDirectory, m_scene.RegionInfo.RegionName + SerializeDateTime() + m_saveAppendedFileName + ".abackup")); } //Just remove the file File.Delete(fileName); } else { //Add the .temp since we might need to make a backup and so that if something goes wrong, we don't corrupt the main backup GZipStream m_saveStream = new GZipStream(new FileStream(fileName + ".tmp", FileMode.Create), CompressionMode.Compress); TarArchiveWriter writer = new TarArchiveWriter(m_saveStream); IAuroraBackupArchiver archiver = m_scene.RequestModuleInterface<IAuroraBackupArchiver>(); //Turn off prompting so that we don't ask the user questions every time we need to save the backup archiver.AllowPrompting = false; archiver.SaveRegionBackup(writer, m_scene); archiver.AllowPrompting = true; m_saveStream.Close(); writer.Close(); GC.Collect(); } File.Move(fileName + ".tmp", fileName); ISceneEntity[] entities = m_scene.Entities.GetEntities(); try { #if (!ISWIN) foreach (ISceneEntity entity in entities) { if (entity.HasGroupChanged) { entity.HasGroupChanged = false; } } #else foreach (ISceneEntity entity in entities.Where(entity => entity.HasGroupChanged)) { entity.HasGroupChanged = false; } #endif } catch (Exception ex) { MainConsole.Instance.WarnFormat("[Backup]: Exception caught: {0}", ex); } //Now make it the full file again MapTileNeedsGenerated = true; MainConsole.Instance.Info("[FileBasedSimulationData]: Saved Backup for region " + m_scene.RegionInfo.RegionName); }
private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids) { m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); EntityBase[] entities = scene.GetEntities(); List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); int numObjectsSkippedPermissions = 0; // Filter entities so that we only have scene objects. // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods // end up having to do this IPermissionsModule permissionsModule = scene.RequestModuleInterface<IPermissionsModule>(); foreach (EntityBase entity in entities) { if (entity is SceneObjectGroup) { SceneObjectGroup sceneObject = (SceneObjectGroup)entity; if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) { if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, CheckPermissions, permissionsModule)) { // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR. ++numObjectsSkippedPermissions; } else { sceneObjects.Add(sceneObject); } } } } if (SaveAssets) { UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService); int prevAssets = assetUuids.Count; foreach (SceneObjectGroup sceneObject in sceneObjects) { assetGatherer.GatherAssetUuids(sceneObject, assetUuids); } m_log.DebugFormat( "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", sceneObjects.Count, assetUuids.Count - prevAssets); } if (numObjectsSkippedPermissions > 0) { m_log.DebugFormat( "[ARCHIVER]: {0} scene objects skipped due to lack of permissions", numObjectsSkippedPermissions); } // Make sure that we also request terrain texture assets RegionSettings regionSettings = scene.RegionInfo.RegionSettings; if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) assetUuids[regionSettings.TerrainTexture1] = (sbyte)AssetType.Texture; if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) assetUuids[regionSettings.TerrainTexture2] = (sbyte)AssetType.Texture; if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) assetUuids[regionSettings.TerrainTexture3] = (sbyte)AssetType.Texture; if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) assetUuids[regionSettings.TerrainTexture4] = (sbyte)AssetType.Texture; Save(scene, sceneObjects, regionDir); }
/// <summary> /// Archive the region requested. /// </summary> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> public void ArchiveRegion(Dictionary<string, object> options) { if (options.ContainsKey("noassets") && (bool)options["noassets"]) SaveAssets = false; try { Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); EntityBase[] entities = m_scene.GetEntities(); List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); string checkPermissions = null; int numObjectsSkippedPermissions = 0; Object temp; if (options.TryGetValue("checkPermissions", out temp)) checkPermissions = (string)temp; // Filter entities so that we only have scene objects. // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods // end up having to do this foreach (EntityBase entity in entities) { if (entity is SceneObjectGroup) { SceneObjectGroup sceneObject = (SceneObjectGroup)entity; if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) { if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions)) { // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR. ++numObjectsSkippedPermissions; } else { sceneObjects.Add(sceneObject); } } } } if (SaveAssets) { UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); foreach (SceneObjectGroup sceneObject in sceneObjects) { assetGatherer.GatherAssetUuids(sceneObject, assetUuids); } m_log.DebugFormat( "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", sceneObjects.Count, assetUuids.Count); } else { m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); } if (numObjectsSkippedPermissions > 0) { m_log.DebugFormat( "[ARCHIVER]: {0} scene objects skipped due to lack of permissions", numObjectsSkippedPermissions); } // Make sure that we also request terrain texture assets RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture; if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture; if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture; if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture; TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream); // Asynchronously request all the assets required to perform this archive operation ArchiveWriteRequestExecution awre = new ArchiveWriteRequestExecution( sceneObjects, m_scene.RequestModuleInterface<ITerrainModule>(), m_scene.RequestModuleInterface<IRegionSerialiserModule>(), m_scene, archiveWriter, m_requestId, options); m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time."); // Write out control file. This has to be done first so that subsequent loaders will see this file first // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); if (SaveAssets) new AssetsRequest( new AssetsArchiver(archiveWriter), assetUuids, m_scene.AssetService, m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute(); else awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>()); } catch (Exception) { m_saveStream.Close(); throw; } }
/// <summary> /// Archive the region requested. /// </summary> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> public void ArchiveRegion(Dictionary<string, object> options) { Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); EntityBase[] entities = m_scene.GetEntities(); List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); /* foreach (ILandObject lo in m_scene.LandChannel.AllParcels()) { if (name == lo.LandData.Name) { // This is the parcel we want } } */ // Filter entities so that we only have scene objects. // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods // end up having to do this foreach (EntityBase entity in entities) { if (entity is SceneObjectGroup) { SceneObjectGroup sceneObject = (SceneObjectGroup)entity; if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) sceneObjects.Add((SceneObjectGroup)entity); } } UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); foreach (SceneObjectGroup sceneObject in sceneObjects) { assetGatherer.GatherAssetUuids(sceneObject, assetUuids); } m_log.DebugFormat( "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", sceneObjects.Count, assetUuids.Count); // Make sure that we also request terrain texture assets RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture; if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture; if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture; if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture; TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream); // Asynchronously request all the assets required to perform this archive operation ArchiveWriteRequestExecution awre = new ArchiveWriteRequestExecution( sceneObjects, m_scene.RequestModuleInterface<ITerrainModule>(), m_scene.RequestModuleInterface<IRegionSerialiserModule>(), m_scene, archiveWriter, m_requestId, options); m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time."); // Write out control file. This has to be done first so that subsequent loaders will see this file first // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile(options)); m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); new AssetsRequest( new AssetsArchiver(archiveWriter), assetUuids, m_scene.AssetService, awre.ReceivedAllAssets).Execute(); }
public void SaveModuleToArchive(TarArchiveWriter writer, IScene scene) { m_isArchiving = true; m_log.Info("[Archive]: Writing parcels to archive"); writer.WriteDir("parcels"); IParcelManagementModule module = scene.RequestModuleInterface<IParcelManagementModule>(); if (module != null) { List<ILandObject> landObject = module.AllParcels(); foreach (ILandObject parcel in landObject) { OSDMap parcelMap = parcel.LandData.ToOSD(); writer.WriteFile("parcels/" + parcel.LandData.GlobalID.ToString(), OSDParser.SerializeLLSDBinary(parcelMap)); parcelMap = null; } } m_log.Info("[Archive]: Finished writing parcels to archive"); m_log.Info ("[Archive]: Writing terrain to archive"); writer.WriteDir ("newstyleterrain"); writer.WriteDir ("newstylerevertterrain"); writer.WriteDir ("newstylewater"); writer.WriteDir ("newstylerevertwater"); ITerrainModule tModule = scene.RequestModuleInterface<ITerrainModule> (); if (tModule != null) { try { byte[] sdata = WriteTerrainToStream (tModule.TerrainMap); writer.WriteFile ("newstyleterrain/" + scene.RegionInfo.RegionID.ToString () + ".terrain", sdata); sdata = null; sdata = WriteTerrainToStream (tModule.TerrainRevertMap); writer.WriteFile ("newstylerevertterrain/" + scene.RegionInfo.RegionID.ToString () + ".terrain", sdata); sdata = null; if (tModule.TerrainWaterMap != null) { sdata = WriteTerrainToStream (tModule.TerrainWaterMap); writer.WriteFile ("newstylewater/" + scene.RegionInfo.RegionID.ToString () + ".terrain", sdata); sdata = null; sdata = WriteTerrainToStream (tModule.TerrainWaterRevertMap); writer.WriteFile ("newstylerevertwater/" + scene.RegionInfo.RegionID.ToString () + ".terrain", sdata); sdata = null; } } catch (Exception ex) { m_log.WarnFormat ("[Backup]: Exception caught: {0}", ex.ToString ()); } } m_log.Info("[Archive]: Finished writing terrain to archive"); m_log.Info("[Archive]: Writing entities to archive"); ISceneEntity[] entities = scene.Entities.GetEntities(); //Get all entities, then start writing them to the database writer.WriteDir("entities"); IDictionary<UUID, AssetType> assets = new Dictionary<UUID, AssetType>(); UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); IAuroraBackupArchiver archiver = m_scene.RequestModuleInterface<IAuroraBackupArchiver> (); bool saveAssets = false; if(archiver.AllowPrompting) saveAssets = MainConsole.Instance.CmdPrompt ("Save assets? (Will not be able to load on other grids)", "false").Equals ("true", StringComparison.CurrentCultureIgnoreCase); int count = 0; foreach (ISceneEntity entity in entities) { try { if (entity.IsAttachment || ((entity.RootChild.Flags & PrimFlags.Temporary) == PrimFlags.Temporary) || ((entity.RootChild.Flags & PrimFlags.TemporaryOnRez) == PrimFlags.TemporaryOnRez)) continue; //Write all entities byte[] xml = ((ISceneObject)entity).ToBinaryXml2 (); writer.WriteFile ("entities/" + entity.UUID.ToString (), xml); xml = null; count++; if (count % 5 == 0) Thread.Sleep (1); //Get all the assets too if (saveAssets) assetGatherer.GatherAssetUuids (entity, assets, scene); } catch (Exception ex) { m_log.WarnFormat ("[Backup]: Exception caught: {0}", ex.ToString ()); } } entities = null; m_log.Info("[Archive]: Finished writing entities to archive"); m_log.Info("[Archive]: Writing assets for entities to archive"); bool foundAllAssets = true; foreach (UUID assetID in new List<UUID> (assets.Keys)) { try { AssetBase asset = m_scene.AssetService.GetCached (assetID.ToString ()); if (asset != null) WriteAsset (assetID.ToString (), asset, writer); //Write it syncronously since we havn't else { foundAllAssets = false; //Not all are cached m_missingAssets.Add (assetID); m_scene.AssetService.Get (assetID.ToString (), writer, RetrievedAsset); } } catch (Exception ex) { m_log.WarnFormat ("[Backup]: Exception caught: {0}", ex.ToString ()); } } if (foundAllAssets) m_isArchiving = false; //We're done if all the assets were found m_log.Info("[Archive]: Finished writing assets for entities to archive"); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public ResponseBase GetDependentAssetsHandler(RequestBase irequest) { if (irequest.GetType() != typeof(GetDependentAssetsRequest)) return OperationFailed("wrong type"); GetDependentAssetsRequest request = (GetDependentAssetsRequest)irequest; AssetBase asset = m_cache.Get(request.AssetID.ToString()); if (asset == null) return OperationFailed("no such asset"); UuidGatherer gatherer = new UuidGatherer(m_scene.AssetService); Dictionary<UUID,sbyte> assetids = new Dictionary<UUID,sbyte>(); //gatherer.GatherAssetUuids(request.AssetID, (AssetType)asset.Type, assetids); gatherer.GatherAssetUuids(request.AssetID, (sbyte)asset.Type, assetids); List<UUID> assets = new List<UUID>(assetids.Keys); return new GetDependentAssetsResponse(assets); }
/// <summary> /// Iterates through all Scenes, doing a deep scan through assets /// to update the access time of all assets present in the scene or referenced by assets /// in the scene. /// </summary> /// <param name="storeUncached"> /// If true, then assets scanned which are not found in cache are added to the cache. /// </param> /// <returns>Number of distinct asset references found in the scene.</returns> private int TouchAllSceneAssets(bool storeUncached) { UuidGatherer gatherer = new UuidGatherer(m_AssetService); HashSet<UUID> uniqueUuids = new HashSet<UUID>(); Dictionary<UUID, sbyte> assets = new Dictionary<UUID, sbyte>(); m_Scenes.ForEach(delegate(Scene s) { StampRegionStatusFile(s.RegionInfo.RegionID); s.ForEachSOG(delegate(SceneObjectGroup e) { gatherer.GatherAssetUuids(e, assets); foreach (UUID assetID in assets.Keys) { string filename = GetFileName(assetID.ToString()); if (File.Exists(filename)) { if (!uniqueUuids.Contains(assetID)) { File.SetLastAccessTime(filename, DateTime.Now); } } else if (storeUncached) { AssetBase cachedAsset = null; if (!uniqueUuids.Contains(assetID)) { cachedAsset = m_AssetService.Get(assetID.ToString()); } if (cachedAsset == null && assets[assetID] != (sbyte)AssetType.Unknown) m_log.DebugFormat( "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets", assetID, assets[assetID], e.Name, e.AbsolutePosition, s.Name); } uniqueUuids.Add(assetID); } assets.Clear(); }); }); return uniqueUuids.Count; }
/// <summary> /// Archive the region requested. /// </summary> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> public void ArchiveRegion() { Dictionary<UUID, int> assetUuids = new Dictionary<UUID, int>(); List<EntityBase> entities = m_scene.GetEntities(); List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); // Filter entities so that we only have scene objects. // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods // end up having to do this foreach (EntityBase entity in entities) { if (entity is SceneObjectGroup) { SceneObjectGroup sceneObject = (SceneObjectGroup)entity; if (MustCheckCreatorIds) { bool failedCreatorCheck = false; foreach (SceneObjectPart part in sceneObject.GetParts()) { if (!ExportIsAllowed(part.CreatorID)) { failedCreatorCheck = true; break; } } if (failedCreatorCheck) { continue; } } if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) sceneObjects.Add(sceneObject); } } if (m_storeAssets) { UuidGatherer assetGatherer = new UuidGatherer(m_scene.CommsManager.AssetCache); foreach (SceneObjectGroup sceneObject in sceneObjects) { assetGatherer.GatherAssetUuids(sceneObject, assetUuids); } } // Make sure that we also request terrain texture assets RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; if (m_storeAssets) { if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) assetUuids[regionSettings.TerrainTexture1] = 1; if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) assetUuids[regionSettings.TerrainTexture2] = 1; if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) assetUuids[regionSettings.TerrainTexture3] = 1; if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) assetUuids[regionSettings.TerrainTexture4] = 1; } if (MustCheckCreatorIds) { int originalCount = assetUuids.Count; m_log.DebugFormat( "[ARCHIVER]: Filtering {0} asset IDs for {1} allowed creators", originalCount, m_allowedCreatorIds.Count); C5.HashSet<UUID> assetsCreatedByAllowedUsers = this.CollectCreatedAssetIdsFromUserInventories(); IEnumerable<UUID> uuids = new List<UUID>(assetUuids.Keys); assetUuids.Clear(); foreach (UUID assetId in uuids) { if (assetsCreatedByAllowedUsers.Contains(assetId)) { assetUuids.Add(assetId, 1); } } m_log.DebugFormat( "[ARCHIVER]: Allowing export of {0} of {1} assets", assetUuids.Count, originalCount); } m_log.DebugFormat( "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", sceneObjects.Count, assetUuids.Count); TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream); // Asynchronously request all the assets required to perform this archive operation ArchiveWriteRequestExecution awre = new ArchiveWriteRequestExecution( sceneObjects, m_scene.RequestModuleInterface<ITerrainModule>(), m_scene.RequestModuleInterface<IRegionSerializerModule>(), m_scene, archiveWriter, m_requestId); new AssetsRequest( new AssetsArchiver(archiveWriter), assetUuids.Keys, m_scene.CommsManager.AssetCache, awre.ReceivedAllAssets).Execute(); }
/// <summary> /// Gets list of assets /// </summary> /// <param name="scene">The scene where to get the assets</param> /// <param name="assetType">Type of the assets to get</param> /// <returns>Dictinary of assets found</returns> public static Dictionary<UUID, AssetBase> GetAssetList(Scene scene, int assetType) { Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); List<EntityBase> entities = scene.GetEntities(); List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); Dictionary<UUID, AssetBase> foundObjects = new Dictionary<UUID, AssetBase>(); foreach (EntityBase entity in entities) { if (entity is SceneObjectGroup) { SceneObjectGroup sceneObject = (SceneObjectGroup)entity; if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) sceneObjects.Add((SceneObjectGroup)entity); } } UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService); if (assetType == 0 || assetType == 1) //do this only for textures and sounds { foreach (SceneObjectGroup sceneObject in sceneObjects) { assetGatherer.GatherAssetUuids(sceneObject, assetUuids); } } ModrexObjects module = scene.RequestModuleInterface<ModrexObjects>(); if (module != null) { foreach (SceneObjectGroup sceneObject in sceneObjects) { RexObjectProperties rop = module.GetObject(sceneObject.RootPart.UUID); AssetBase asset; switch (assetType) { case 1: //sound if (rop.RexSoundUUID != UUID.Zero) { asset = scene.AssetService.Get(rop.RexSoundUUID.ToString()); if (asset != null && !foundObjects.ContainsKey(asset.FullID)) { foundObjects.Add(asset.FullID, asset); } } break; case 6: //3d if (rop.RexMeshUUID != UUID.Zero) { asset = scene.AssetService.Get(rop.RexMeshUUID.ToString()); if (asset != null && !foundObjects.ContainsKey(asset.FullID)) { foundObjects.Add(asset.FullID, asset); } } if (rop.RexCollisionMeshUUID != UUID.Zero) { asset = scene.AssetService.Get(rop.RexCollisionMeshUUID.ToString()); if (asset != null && !foundObjects.ContainsKey(asset.FullID)) { foundObjects.Add(asset.FullID, asset); } } break; case 0: //texture foreach (KeyValuePair<uint, RexMaterialsDictionaryItem> kvp in rop.GetRexMaterials()) { asset = scene.AssetService.Get(kvp.Value.AssetID.ToString()); if (asset != null && (int)asset.Type == assetType && !foundObjects.ContainsKey(asset.FullID)) { foundObjects.Add(asset.FullID, asset); } } break; case 41: //Particle if (rop.RexParticleScriptUUID != UUID.Zero) { asset = scene.AssetService.Get(rop.RexParticleScriptUUID.ToString()); if (asset != null && !foundObjects.ContainsKey(asset.FullID)) { foundObjects.Add(asset.FullID, asset); } } break; case 45: //Material foreach (KeyValuePair<uint, RexMaterialsDictionaryItem> kvp in rop.GetRexMaterials()) { asset = scene.AssetService.Get(kvp.Value.AssetID.ToString()); if (asset != null && (int)asset.Type == assetType && !foundObjects.ContainsKey(asset.FullID)) { foundObjects.Add(asset.FullID, asset); } } break; case 19: //3d anim if (rop.RexAnimationPackageUUID != UUID.Zero) { asset = scene.AssetService.Get(rop.RexAnimationPackageUUID.ToString()); if (asset != null && !foundObjects.ContainsKey(asset.FullID)) { foundObjects.Add(asset.FullID, asset); } } break; case 42: //flash //No way to fetch flash animation from scene, since no reference to it is kept in scene break; default: m_log.Warn("[ASSETS]: Requested list of unknown asset type"); break; } } } foreach (KeyValuePair<UUID, AssetType> kvp in assetUuids) { if (kvp.Value == (AssetType)assetType) { AssetBase asset = scene.AssetService.Get(kvp.Key.ToString()); if (asset != null && !foundObjects.ContainsKey(asset.FullID)) { foundObjects.Add(asset.FullID, asset); } } } return foundObjects; }