aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Application/OpenSim.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs202
2 files changed, 121 insertions, 85 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 2c920f6..dd2e859 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -265,9 +265,9 @@ namespace OpenSim
265 LoadOar); 265 LoadOar);
266 266
267 m_console.Commands.AddCommand("region", false, "save oar", 267 m_console.Commands.AddCommand("region", false, "save oar",
268 "save oar [-v|version=N] [<OAR path>]", 268 "save oar [-v|--version=N] [<OAR path>]",
269 "Save a region's data to an OAR archive.", 269 "Save a region's data to an OAR archive.",
270 "-v|version=N generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine 270 "-v|--version=N generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
271 + "The OAR path must be a filesystem path." 271 + "The OAR path must be a filesystem path."
272 + " If this is not given then the oar is saved to region.oar in the current directory.", 272 + " If this is not given then the oar is saved to region.oar in the current directory.",
273 SaveOar); 273 SaveOar);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index 0567a82..3eb797b 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -49,7 +49,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
49 public class ArchiveWriteRequestPreparation 49 public class ArchiveWriteRequestPreparation
50 { 50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 /// <summary>
54 /// The minimum major version of OAR that we can write.
55 /// </summary>
56 public static int MIN_MAJOR_VERSION = 0;
57
58 /// <summary>
59 /// The maximum major version of OAR that we can write.
60 /// </summary>
61 public static int MAX_MAJOR_VERSION = 1;
62
53 protected Scene m_scene; 63 protected Scene m_scene;
54 protected Stream m_saveStream; 64 protected Stream m_saveStream;
55 protected Guid m_requestId; 65 protected Guid m_requestId;
@@ -101,110 +111,136 @@ namespace OpenSim.Region.CoreModules.World.Archiver
101 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> 111 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
102 public void ArchiveRegion(Dictionary<string, object> options) 112 public void ArchiveRegion(Dictionary<string, object> options)
103 { 113 {
104 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); 114 try
105 115 {
106 EntityBase[] entities = m_scene.GetEntities(); 116 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
107 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 117
108 118 EntityBase[] entities = m_scene.GetEntities();
109 /* 119 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
110 foreach (ILandObject lo in m_scene.LandChannel.AllParcels()) 120
121 /*
122 foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
123 {
124 if (name == lo.LandData.Name)
125 {
126 // This is the parcel we want
127 }
128 }
129 */
130
131 // Filter entities so that we only have scene objects.
132 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
133 // end up having to do this
134 foreach (EntityBase entity in entities)
111 { 135 {
112 if (name == lo.LandData.Name) 136 if (entity is SceneObjectGroup)
113 { 137 {
114 // This is the parcel we want 138 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
139
140 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
141 sceneObjects.Add((SceneObjectGroup)entity);
115 } 142 }
116 } 143 }
117 */ 144
118 145 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
119 // Filter entities so that we only have scene objects. 146
120 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods 147 foreach (SceneObjectGroup sceneObject in sceneObjects)
121 // end up having to do this
122 foreach (EntityBase entity in entities)
123 {
124 if (entity is SceneObjectGroup)
125 { 148 {
126 SceneObjectGroup sceneObject = (SceneObjectGroup)entity; 149 assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
127
128 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
129 sceneObjects.Add((SceneObjectGroup)entity);
130 } 150 }
151
152 m_log.DebugFormat(
153 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
154 sceneObjects.Count, assetUuids.Count);
155
156 // Make sure that we also request terrain texture assets
157 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
158
159 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
160 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
161
162 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
163 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
164
165 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
166 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
167
168 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
169 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
170
171 TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);
172
173 // Asynchronously request all the assets required to perform this archive operation
174 ArchiveWriteRequestExecution awre
175 = new ArchiveWriteRequestExecution(
176 sceneObjects,
177 m_scene.RequestModuleInterface<ITerrainModule>(),
178 m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
179 m_scene,
180 archiveWriter,
181 m_requestId,
182 options);
183
184 m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
185
186 // Write out control file. This has to be done first so that subsequent loaders will see this file first
187 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
188 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
189 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
190
191 new AssetsRequest(
192 new AssetsArchiver(archiveWriter), assetUuids,
193 m_scene.AssetService, awre.ReceivedAllAssets).Execute();
131 } 194 }
132 195 finally
133 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
134
135 foreach (SceneObjectGroup sceneObject in sceneObjects)
136 { 196 {
137 assetGatherer.GatherAssetUuids(sceneObject, assetUuids); 197 m_saveStream.Close();
138 } 198 }
139
140 m_log.DebugFormat(
141 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
142 sceneObjects.Count, assetUuids.Count);
143
144 // Make sure that we also request terrain texture assets
145 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
146
147 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
148 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
149
150 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
151 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
152
153 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
154 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
155
156 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
157 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
158
159 TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);
160
161 // Asynchronously request all the assets required to perform this archive operation
162 ArchiveWriteRequestExecution awre
163 = new ArchiveWriteRequestExecution(
164 sceneObjects,
165 m_scene.RequestModuleInterface<ITerrainModule>(),
166 m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
167 m_scene,
168 archiveWriter,
169 m_requestId,
170 options);
171
172 m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
173
174 // Write out control file. This has to be done first so that subsequent loaders will see this file first
175 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
176 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile(options));
177 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
178
179 new AssetsRequest(
180 new AssetsArchiver(archiveWriter), assetUuids,
181 m_scene.AssetService, awre.ReceivedAllAssets).Execute();
182 } 199 }
183 200
184 /// <summary> 201 /// <summary>
185 /// Create the control file for the most up to date archive 202 /// Create the control file for the most up to date archive
186 /// </summary> 203 /// </summary>
187 /// <returns></returns> 204 /// <returns></returns>
188 public static string Create0p2ControlFile(Dictionary<string, object> options) 205 public static string CreateControlFile(Dictionary<string, object> options)
189 { 206 {
190 int majorVersion = 0, minorVersion = 5; 207 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 0;
191 208
192 if (options.ContainsKey("version")) 209 if (options.ContainsKey("version"))
193 { 210 {
194 minorVersion = 0;
195 string[] parts = options["version"].ToString().Split('.'); 211 string[] parts = options["version"].ToString().Split('.');
196 if (parts.Length >= 1) 212 if (parts.Length >= 1)
197 majorVersion = Int32.Parse(parts[0]); 213 {
198 if (parts.Length >= 2) 214 majorVersion = Int32.Parse(parts[0]);
199 minorVersion = Int32.Parse(parts[1]); 215
216 if (parts.Length >= 2)
217 minorVersion = Int32.Parse(parts[1]);
218 }
200 } 219 }
201 220
202 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion); 221 if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION)
203// if (majorVersion == 1) 222 {
204// { 223 throw new Exception(
205// m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); 224 string.Format(
206// } 225 "OAR version number for save must be between {0} and {1}",
226 MIN_MAJOR_VERSION, MAX_MAJOR_VERSION));
227 }
228 else if (majorVersion == MAX_MAJOR_VERSION)
229 {
230 // Force 1.0
231 minorVersion = 0;
232 }
233 else if (majorVersion == MIN_MAJOR_VERSION)
234 {
235 // Force 0.4
236 minorVersion = 4;
237 }
207 238
239 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
240 if (majorVersion == 1)
241 {
242 m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
243 }
208 244
209 StringWriter sw = new StringWriter(); 245 StringWriter sw = new StringWriter();
210 XmlTextWriter xtw = new XmlTextWriter(sw); 246 XmlTextWriter xtw = new XmlTextWriter(sw);