29 using System.Collections.Generic;
31 using System.IO.Compression;
32 using System.Reflection;
33 using System.Text.RegularExpressions;
34 using System.Threading;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Monitoring;
40 using OpenSim.Framework.Serialization;
41 using OpenSim.Region.CoreModules.World.Terrain;
42 using OpenSim.Region.Framework.Interfaces;
43 using OpenSim.Region.Framework.Scenes;
48 using OpenSim.Framework.Serialization.External;
58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63 public static int MIN_MAJOR_VERSION = 0;
68 public static int MAX_MAJOR_VERSION = 1;
73 public bool MultiRegionFormat {
get; set; }
78 public bool SaveAssets {
get; set; }
84 public string FilterContent {
get; set; }
107 catch (EntryPointNotFoundException e)
110 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
111 +
"If you've manually installed Mono, have you appropriately updated zlib1g as well?");
112 m_log.ErrorFormat(
"{0} {1}", e.Message, e.StackTrace);
124 m_saveStream = saveStream;
130 m_requestId = requestId;
131 m_archiveWriter = null;
133 MultiRegionFormat =
false;
135 FilterContent = null;
146 if (options.ContainsKey(
"all") && (bool)options[
"all"])
147 MultiRegionFormat =
true;
149 if (options.ContainsKey(
"noassets") && (bool)options[
"noassets"])
153 if (options.TryGetValue(
"checkPermissions", out temp))
154 FilterContent = (
string)temp;
159 if (MultiRegionFormat)
161 m_log.InfoFormat(
"[ARCHIVER]: Saving {0} regions", SceneManager.Instance.Scenes.Count);
162 SceneManager.Instance.ForEachScene(delegate(
Scene scene)
164 scenesGroup.AddScene(scene);
169 scenesGroup.AddScene(m_rootScene);
171 scenesGroup.CalcSceneLocations();
178 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(scenesGroup));
179 m_log.InfoFormat(
"[ARCHIVER]: Added control file to archive.");
183 Dictionary<UUID, sbyte> assetUuids =
new Dictionary<UUID, sbyte>();
185 scenesGroup.ForEachScene(delegate(
Scene scene)
187 string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) :
"";
188 ArchiveOneRegion(scene, regionDir, assetUuids);
195 m_log.DebugFormat(
"[ARCHIVER]: Saving {0} assets", assetUuids.Count);
201 m_rootScene.AssetService, m_rootScene.UserAccountService,
202 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets);
204 WorkManager.RunInThread(o => ar.Execute(), null,
"Archive Assets Request");
210 m_log.DebugFormat(
"[ARCHIVER]: Not saving assets since --noassets was specified");
211 CloseArchive(
string.Empty);
216 CloseArchive(e.Message);
221 private void ArchiveOneRegion(
Scene scene,
string regionDir, Dictionary<UUID, sbyte> assetUuids)
223 m_log.InfoFormat(
"[ARCHIVER]: Writing region {0}", scene.Name);
226 List<SceneObjectGroup> sceneObjects =
new List<SceneObjectGroup>();
228 int numObjectsSkippedPermissions = 0;
238 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
245 ++numObjectsSkippedPermissions;
249 sceneObjects.Add(sceneObject);
258 int prevAssets = assetUuids.Count;
260 foreach (SceneObjectGroup sceneObject
in sceneObjects)
261 assetGatherer.AddForInspection(sceneObject);
263 assetGatherer.GatherAll();
266 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
267 sceneObjects.Count, assetUuids.Count - prevAssets);
270 if (numObjectsSkippedPermissions > 0)
273 "[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
274 numObjectsSkippedPermissions);
281 assetUuids[regionSettings.TerrainTexture1] = (sbyte)AssetType.Texture;
284 assetUuids[regionSettings.TerrainTexture2] = (sbyte)AssetType.Texture;
287 assetUuids[regionSettings.TerrainTexture3] = (sbyte)AssetType.Texture;
290 assetUuids[regionSettings.TerrainTexture4] = (sbyte)AssetType.Texture;
292 Save(scene, sceneObjects, regionDir);
303 private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup,
string filterContent,
IPermissionsModule permissionsModule)
305 if (filterContent == null)
308 if (permissionsModule == null)
314 bool permitted =
true;
320 PermissionClass permissionClass = permissionsModule.GetPermissionClass(user, obj);
321 switch (permissionClass)
323 case PermissionClass.Owner:
326 case PermissionClass.Group:
327 perm = obj.GroupMask | obj.EveryoneMask;
329 case PermissionClass.Everyone:
331 perm = obj.EveryoneMask;
344 canTransfer |= (obj.EveryoneMask & (uint)
PermissionMask.Copy) != 0;
346 bool partPermitted =
true;
347 if (filterContent.Contains(
"C") && !canCopy)
348 partPermitted =
false;
349 if (filterContent.Contains(
"T") && !canTransfer)
350 partPermitted =
false;
353 bool creator = (obj.CreatorID.Guid == user.Guid);
355 partPermitted =
true;
383 if (MultiRegionFormat)
385 majorVersion = MAX_MAJOR_VERSION;
426 m_log.InfoFormat(
"[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
427 if (majorVersion == 1)
429 m_log.WarnFormat(
"[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim versions prior to 0.7.4. Do not use the --all option if you want to produce a compatible OAR");
434 using (StringWriter sw =
new StringWriter())
436 using (XmlTextWriter xtw =
new XmlTextWriter(sw))
438 xtw.Formatting = Formatting.Indented;
439 xtw.WriteStartDocument();
440 xtw.WriteStartElement(
"archive");
441 xtw.WriteAttributeString(
"major_version", majorVersion.ToString());
442 xtw.WriteAttributeString(
"minor_version", minorVersion.ToString());
444 xtw.WriteStartElement(
"creation_info");
445 DateTime now = DateTime.UtcNow;
446 TimeSpan t = now -
new DateTime(1970, 1, 1);
447 xtw.WriteElementString(
"datetime", ((int)t.TotalSeconds).ToString());
448 if (!MultiRegionFormat)
449 xtw.WriteElementString(
"id", m_rootScene.RegionInfo.RegionID.ToString());
450 xtw.WriteEndElement();
452 xtw.WriteElementString(
"assets_included", SaveAssets.ToString());
454 if (MultiRegionFormat)
456 WriteRegionsManifest(scenesGroup, xtw);
460 xtw.WriteStartElement(
"region_info");
461 WriteRegionInfo(m_rootScene, xtw);
462 xtw.WriteEndElement();
465 xtw.WriteEndElement();
479 private static void WriteRegionsManifest(
ArchiveScenesGroup scenesGroup, XmlTextWriter xtw)
481 xtw.WriteStartElement(
"regions");
486 for (uint y = (uint)scenesGroup.Rect.Top; y < scenesGroup.Rect.Bottom; ++y)
488 SortedDictionary<uint, Scene> row;
489 if (scenesGroup.
Regions.TryGetValue(y, out row))
491 xtw.WriteStartElement(
"row");
493 for (uint x = (uint)scenesGroup.Rect.Left; x < scenesGroup.Rect.Right; ++x)
496 if (row.TryGetValue(x, out scene))
498 xtw.WriteStartElement(
"region");
499 xtw.WriteElementString(
"id", scene.RegionInfo.RegionID.ToString());
500 xtw.WriteElementString(
"dir", scenesGroup.GetRegionDir(scene.RegionInfo.RegionID));
501 WriteRegionInfo(scene, xtw);
502 xtw.WriteEndElement();
507 xtw.WriteElementString(
"region",
"");
511 xtw.WriteEndElement();
516 xtw.WriteElementString(
"row",
"");
520 xtw.WriteEndElement();
531 isMegaregion = rcMod.IsRootForMegaregion(scene.RegionInfo.RegionID);
533 isMegaregion =
false;
536 size = rcMod.GetSizeOfMegaregion(scene.RegionInfo.RegionID);
540 xtw.WriteElementString(
"is_megaregion", isMegaregion.ToString());
541 xtw.WriteElementString(
"size_in_meters", string.Format(
"{0},{1}", size.X, size.Y));
544 protected void Save(
Scene scene, List<SceneObjectGroup> sceneObjects,
string regionDir)
546 if (regionDir !=
string.Empty)
547 regionDir = ArchiveConstants.REGIONS_PATH + regionDir +
"/";
549 m_log.InfoFormat(
"[ARCHIVER]: Adding region settings to archive.");
552 string settingsPath = String.Format(
"{0}{1}{2}.xml",
553 regionDir, ArchiveConstants.SETTINGS_PATH, scene.RegionInfo.RegionName);
556 m_log.InfoFormat(
"[ARCHIVER]: Adding parcel settings to archive.");
559 List<ILandObject> landObjects = scene.LandChannel.AllParcels();
564 = String.Format(
"{0}{1}", regionDir, ArchiveConstants.CreateOarLandDataPath(landData));
565 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
568 m_log.InfoFormat(
"[ARCHIVER]: Adding terrain information to archive.");
571 string terrainPath = String.Format(
"{0}{1}{2}.r32",
572 regionDir, ArchiveConstants.TERRAINS_PATH, scene.RegionInfo.RegionName);
574 using (MemoryStream ms =
new MemoryStream())
576 scene.RequestModuleInterface<
ITerrainModule>().SaveToStream(terrainPath, ms);
577 m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
580 m_log.InfoFormat(
"[ARCHIVER]: Adding scene objects to archive.");
584 foreach (SceneObjectGroup sceneObject
in sceneObjects)
588 string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options);
589 string objectPath = string.Format(
"{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject));
590 m_archiveWriter.WriteFile(objectPath, serializedObject);
594 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids,
bool timedOut)
600 errorMessage =
"Loading assets timed out";
604 foreach (
UUID uuid
in assetsNotFoundUuids)
606 m_log.DebugFormat(
"[ARCHIVER]: Could not find asset {0}", uuid);
613 errorMessage = String.Empty;
616 CloseArchive(errorMessage);
627 if (m_archiveWriter != null)
628 m_archiveWriter.Close();
629 m_saveStream.Close();
633 m_log.Error(string.Format(
"[ARCHIVER]: Error closing archive: {0} ", e.Message), e);
634 if (errorMessage ==
string.Empty)
635 errorMessage = e.Message;
638 m_log.InfoFormat(
"[ARCHIVER]: Finished writing out OAR for {0}", m_rootScene.RegionInfo.RegionName);
640 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage);
Ionic.Zlib.CompressionMode CompressionMode
Gather uuids for a given entity.
EstateSettings EstateSettings
Ionic.Zlib.GZipStream GZipStream
void Save(Scene scene, List< SceneObjectGroup > sceneObjects, string regionDir)
A group of regions arranged in a rectangle, possibly with holes.
IAssetService AssetService
uint RegionSizeX
X dimension of the region.
uint RegionSizeY
X dimension of the region.
OpenSim.Framework.RegionSettings RegionSettings
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
OpenSim.Framework.PermissionMask PermissionMask
Ionic.Zlib.GZipStream GZipStream
Temporary code to produce a tar archive in tar v7 format
Dictionary< string, object > m_options
static readonly UUID DEFAULT_TERRAIN_TEXTURE_2
bool IsDeleted
Signals whether this entity was in a scene but has since been removed from it.
Encapsulate the asynchronous requests for the assets required for an archive operation ...
static readonly UUID DEFAULT_TERRAIN_TEXTURE_1
Details of a Parcel of land
ArchiveWriteRequest(Scene scene, Guid requestId)
SortedDictionary< uint, SortedDictionary< uint, Scene > > Regions
All the regions. The outer dictionary contains rows (key: Y coordinate). The inner dictionaries conta...
void ReceivedAllAssets(ICollection< UUID > assetsFoundUuids, ICollection< UUID > assetsNotFoundUuids, bool timedOut)
Ionic.Zlib.CompressionLevel CompressionLevel
static void WriteRegionInfo(Scene scene, XmlTextWriter xtw)
ArchiveWriteRequest(Scene scene, Stream saveStream, Guid requestId)
Constructor.
Ionic.Zlib.CompressionLevel CompressionLevel
Ionic.Zlib.CompressionMode CompressionMode
Prepare to write out an archive.
void CloseArchive(string errorMessage)
Closes the archive and notifies that we're done.
ArchiveWriteRequest(Scene scene, string savePath, Guid requestId)
Constructor
virtual RegionInfo RegionInfo
OpenSim.Framework.Serialization.TarArchiveWriter TarArchiveWriter
string CreateControlFile(ArchiveScenesGroup scenesGroup)
Create the control file.
void ArchiveRegion(Dictionary< string, object > options)
Archive the region requested.
static readonly UUID DEFAULT_TERRAIN_TEXTURE_4
bool IsAttachment
Is this scene object acting as an attachment?
static readonly UUID DEFAULT_TERRAIN_TEXTURE_3
TarArchiveWriter m_archiveWriter