diff options
-rw-r--r-- | OpenSim/Region/DataSnapshot/DataRequestHandler.cs | 75 | ||||
-rw-r--r-- | OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | 524 | ||||
-rw-r--r-- | OpenSim/Region/DataSnapshot/EstateSnapshot.cs | 68 | ||||
-rw-r--r-- | OpenSim/Region/DataSnapshot/Interfaces/IDataSnapshotProvider.cs | 48 | ||||
-rw-r--r-- | OpenSim/Region/DataSnapshot/LandSnapshot.cs | 267 | ||||
-rw-r--r-- | OpenSim/Region/DataSnapshot/ObjectSnapshot.cs | 83 | ||||
-rw-r--r-- | bin/OpenSim.ini.example | 18 | ||||
-rw-r--r-- | prebuild.xml | 29 |
8 files changed, 1111 insertions, 1 deletions
diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs new file mode 100644 index 0000000..512ad55 --- /dev/null +++ b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Collections; | ||
32 | using System.Text; | ||
33 | using System.Xml; | ||
34 | using OpenSim.Region.Environment.Scenes; | ||
35 | using OpenSim.Framework.Servers; | ||
36 | using OpenSim.Framework.Console; | ||
37 | |||
38 | namespace OpenSim.Region.DataSnapshot | ||
39 | { | ||
40 | public class DataRequestHandler | ||
41 | { | ||
42 | private Scene m_scene = null; | ||
43 | private DataSnapshotManager m_externalData = null; | ||
44 | private log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
45 | |||
46 | public DataRequestHandler(Scene scene, DataSnapshotManager externalData) | ||
47 | { | ||
48 | m_scene = scene; | ||
49 | m_externalData = externalData; | ||
50 | |||
51 | if (m_scene.AddHTTPHandler("collector", OnGetSnapshot)) | ||
52 | { | ||
53 | m_log.Info("[DATASNAPSHOT]: Set up snapshot service"); | ||
54 | } | ||
55 | //harbl | ||
56 | } | ||
57 | |||
58 | public Hashtable OnGetSnapshot(Hashtable keysvals) | ||
59 | { | ||
60 | m_log.Info("[DATASNAPSHOT] Received collection request"); | ||
61 | Hashtable reply = new Hashtable(); | ||
62 | int statuscode = 200; | ||
63 | |||
64 | string snapObj = (string)keysvals["region"]; | ||
65 | |||
66 | XmlDocument response = m_externalData.GetSnapshot(snapObj); | ||
67 | |||
68 | reply["str_response_string"] = response.OuterXml; | ||
69 | reply["int_response_code"] = statuscode; | ||
70 | reply["content_type"] = "text/xml"; | ||
71 | |||
72 | return reply; | ||
73 | } | ||
74 | } | ||
75 | } | ||
diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs new file mode 100644 index 0000000..1831f0a --- /dev/null +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | |||
@@ -0,0 +1,524 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using System.Xml; | ||
33 | using System.IO; | ||
34 | using System.Text; | ||
35 | using System.Timers; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Communications; | ||
38 | using OpenSim.Region.Environment.Interfaces; | ||
39 | using OpenSim.Region.Environment.Scenes; | ||
40 | using Nini.Config; | ||
41 | using libsecondlife; | ||
42 | using libsecondlife.Packets; | ||
43 | |||
44 | namespace OpenSim.Region.DataSnapshot | ||
45 | { | ||
46 | public class DataSnapshotManager : IRegionModule | ||
47 | { | ||
48 | #region Class members | ||
49 | private List<Scene> m_scenes = new List<Scene>(); | ||
50 | private log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
51 | private bool m_enabled = false; | ||
52 | private bool m_configLoaded = false; | ||
53 | internal object m_syncInit = new object(); | ||
54 | private DataRequestHandler m_requests = null; | ||
55 | private Dictionary<Scene, List<IDataSnapshotProvider>> m_dataproviders = new Dictionary<Scene, List<IDataSnapshotProvider>>(); | ||
56 | private Dictionary<String, String> m_gridinfo = new Dictionary<String, String>(); | ||
57 | //private int m_oldestSnapshot = 0; | ||
58 | private int m_maxSnapshots = 500; | ||
59 | private int m_lastSnapshot = 0; | ||
60 | private string m_snapsDir = "DataSnapshot"; | ||
61 | private string m_dataServices = "noservices"; | ||
62 | private string m_listener_port = "9000"; //TODO: Set default port over 9000 | ||
63 | private string m_hostname = "127.0.0.1"; | ||
64 | private Timer m_periodic = null; | ||
65 | private int m_period = 60; // in seconds | ||
66 | private List<String> m_disabledModules = new List<String>(); | ||
67 | #endregion | ||
68 | |||
69 | #region IRegionModule | ||
70 | public void Close() | ||
71 | { | ||
72 | |||
73 | } | ||
74 | |||
75 | public void Initialise(Scene scene, Nini.Config.IConfigSource config) | ||
76 | { | ||
77 | if (!m_scenes.Contains(scene)) | ||
78 | m_scenes.Add(scene); | ||
79 | |||
80 | if (!m_configLoaded) { | ||
81 | m_configLoaded = true; | ||
82 | m_log.Info("[DATASNAPSHOT]: Loading configuration"); | ||
83 | //Read from the config for options | ||
84 | lock (m_syncInit) { | ||
85 | try { | ||
86 | m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); | ||
87 | if (config.Configs["Startup"].GetBoolean("gridmode", true)) | ||
88 | { | ||
89 | m_gridinfo.Add("gridserverURL", config.Configs["Network"].GetString("grid_server_url", "harbl")); | ||
90 | m_gridinfo.Add("userserverURL", config.Configs["Network"].GetString("user_server_url", "harbl")); | ||
91 | m_gridinfo.Add("assetserverURL", config.Configs["Network"].GetString("asset_server_url", "harbl")); | ||
92 | } | ||
93 | else | ||
94 | { | ||
95 | //Non gridmode stuff | ||
96 | } | ||
97 | |||
98 | m_gridinfo.Add("Name", config.Configs["DataSnapshot"].GetString("gridname", "harbl")); | ||
99 | m_maxSnapshots = config.Configs["DataSnapshot"].GetInt("max_snapshots", m_maxSnapshots); | ||
100 | m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); | ||
101 | m_snapsDir = config.Configs["DataSnapshot"].GetString("snapshot_cache_directory", m_snapsDir); | ||
102 | m_dataServices = config.Configs["DataSnapshot"].GetString("data_services", m_dataServices); | ||
103 | m_listener_port = config.Configs["Network"].GetString("http_listener_port", m_listener_port); | ||
104 | //BUG: Naming a search data module "DESUDESUDESU" will cause it to not get loaded by default. | ||
105 | //RESOLUTION: Wontfix, there are no Suiseiseki-loving developers | ||
106 | String[] annoying_string_array = config.Configs["DataSnapshot"].GetString("disable_modules", "DESUDESUDESU").Split(".".ToCharArray()); | ||
107 | foreach (String bloody_wanker in annoying_string_array) { | ||
108 | m_disabledModules.Add(bloody_wanker); | ||
109 | } | ||
110 | |||
111 | } catch (Exception) { | ||
112 | m_log.Info("[DATASNAPSHOT]: Could not load configuration. DataSnapshot will be disabled."); | ||
113 | m_enabled = false; | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | } | ||
118 | } | ||
119 | if (Directory.Exists(m_snapsDir)) | ||
120 | { | ||
121 | m_log.Info("[DATASNAPSHOT] DataSnapshot directory already exists."); | ||
122 | } | ||
123 | else | ||
124 | { | ||
125 | // Try to create the directory. | ||
126 | m_log.Info("[DATASNAPSHOT] Creating " + m_snapsDir + " directory."); | ||
127 | try | ||
128 | { | ||
129 | Directory.CreateDirectory(m_snapsDir); | ||
130 | } | ||
131 | catch (Exception) | ||
132 | { | ||
133 | m_log.Error("[DATASNAPSHOT] Failed to create " + m_snapsDir + " directory."); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | |||
138 | if (m_enabled) | ||
139 | { | ||
140 | m_log.Info("[DATASNAPSHOT]: Scene added to module."); | ||
141 | } | ||
142 | else | ||
143 | { | ||
144 | m_log.Warn("[DATASNAPSHOT]: Data snapshot disabled, not adding scene to module (or anything else)."); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | public bool IsSharedModule | ||
149 | { | ||
150 | get { return true; } | ||
151 | } | ||
152 | |||
153 | public string Name | ||
154 | { | ||
155 | get { return "External Data Generator"; } | ||
156 | } | ||
157 | |||
158 | public void PostInitialise() | ||
159 | { | ||
160 | if (m_enabled) | ||
161 | { | ||
162 | //Right now, only load ISearchData objects in the current assembly. | ||
163 | //Eventually allow it to load ISearchData objects from all assemblies. | ||
164 | Assembly currentasm = Assembly.GetExecutingAssembly(); | ||
165 | |||
166 | //Stolen from ModuleLoader.cs | ||
167 | foreach (Type pluginType in currentasm.GetTypes()) | ||
168 | { | ||
169 | if (pluginType.IsPublic) | ||
170 | { | ||
171 | if (!pluginType.IsAbstract) | ||
172 | { | ||
173 | if (pluginType.GetInterface("IDataSnapshotProvider") != null) | ||
174 | { | ||
175 | foreach (Scene scene in m_scenes) | ||
176 | { | ||
177 | IDataSnapshotProvider module = (IDataSnapshotProvider)Activator.CreateInstance(pluginType); | ||
178 | module.Initialize(scene, this); | ||
179 | //module.PrepareData(); | ||
180 | List<IDataSnapshotProvider> providerlist = null; | ||
181 | m_dataproviders.TryGetValue(scene, out providerlist); | ||
182 | if (providerlist == null) | ||
183 | { | ||
184 | providerlist = new List<IDataSnapshotProvider>(); | ||
185 | m_dataproviders.Add(scene, providerlist); | ||
186 | } | ||
187 | providerlist.Add(module); | ||
188 | |||
189 | } | ||
190 | m_log.Info("[DATASNAPSHOT]: Added new data provider type: " + pluginType.Name); | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
196 | //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer | ||
197 | m_requests = new DataRequestHandler(m_scenes[0], this); | ||
198 | |||
199 | //Create timer | ||
200 | m_periodic = new Timer(); | ||
201 | m_periodic.Interval = m_period * 1000; | ||
202 | m_periodic.Elapsed += SnapshotTimerCallback; | ||
203 | m_periodic.Enabled = true; | ||
204 | |||
205 | m_hostname = m_scenes[0].RegionInfo.ExternalHostName; | ||
206 | |||
207 | MakeNewSnapshot(); //Make the initial snapshot | ||
208 | |||
209 | if (m_dataServices != "noservices") | ||
210 | NotifyDataServices(m_dataServices); | ||
211 | } | ||
212 | } | ||
213 | #endregion | ||
214 | |||
215 | #region Associated helper functions | ||
216 | |||
217 | string DataFileName(Scene scene) | ||
218 | { | ||
219 | return Path.Combine(m_snapsDir, Path.ChangeExtension(scene.RegionInfo.RegionName, "xml")); | ||
220 | //return (m_snapsDir + Path.DirectorySeparatorChar + scene.RegionInfo.RegionName + ".xml"); | ||
221 | } | ||
222 | |||
223 | Scene SceneForName(string name) | ||
224 | { | ||
225 | foreach (Scene scene in m_scenes) | ||
226 | if (scene.RegionInfo.RegionName == name) | ||
227 | return scene; | ||
228 | |||
229 | return null; | ||
230 | } | ||
231 | |||
232 | #endregion | ||
233 | |||
234 | #region [Private] XML snapshot generator | ||
235 | |||
236 | private XmlDocument Snapshot(Scene scene) | ||
237 | { | ||
238 | XmlDocument basedoc = new XmlDocument(); | ||
239 | XmlNode regionElement = MakeRegionNode(scene, basedoc); | ||
240 | |||
241 | regionElement.AppendChild(GetGridSnapshotData(basedoc)); | ||
242 | XmlNode regionData = basedoc.CreateNode(XmlNodeType.Element, "data", ""); | ||
243 | |||
244 | foreach (KeyValuePair<Scene, List<IDataSnapshotProvider>> dataprovider in m_dataproviders) | ||
245 | { | ||
246 | if (dataprovider.Key == scene) | ||
247 | { | ||
248 | foreach (IDataSnapshotProvider provider in dataprovider.Value) | ||
249 | { | ||
250 | XmlNode data = provider.RequestSnapshotData(basedoc); | ||
251 | regionData.AppendChild(data); | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | |||
256 | regionElement.AppendChild(regionData); | ||
257 | |||
258 | basedoc.AppendChild(regionElement); | ||
259 | |||
260 | return basedoc; | ||
261 | } | ||
262 | |||
263 | private XmlNode MakeRegionNode(Scene scene, XmlDocument basedoc) | ||
264 | { | ||
265 | XmlNode docElement = basedoc.CreateNode(XmlNodeType.Element, "region", ""); | ||
266 | |||
267 | XmlAttribute attr = basedoc.CreateAttribute("category"); | ||
268 | attr.Value = GetRegionCategory(scene); | ||
269 | docElement.Attributes.Append(attr); | ||
270 | |||
271 | attr = basedoc.CreateAttribute("entities"); | ||
272 | attr.Value = scene.Entities.Count.ToString(); | ||
273 | docElement.Attributes.Append(attr); | ||
274 | |||
275 | //attr = basedoc.CreateAttribute("parcels"); | ||
276 | //attr.Value = scene.LandManager.landList.Count.ToString(); | ||
277 | //docElement.Attributes.Append(attr); | ||
278 | |||
279 | |||
280 | XmlNode infoblock = basedoc.CreateNode(XmlNodeType.Element, "info", ""); | ||
281 | |||
282 | XmlNode infopiece = basedoc.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
283 | infopiece.InnerText = scene.RegionInfo.RegionID.ToString(); | ||
284 | infoblock.AppendChild(infopiece); | ||
285 | |||
286 | infopiece = basedoc.CreateNode(XmlNodeType.Element, "url", ""); | ||
287 | infopiece.InnerText = "http://" + m_hostname + ":" + m_listener_port; | ||
288 | infoblock.AppendChild(infopiece); | ||
289 | |||
290 | infopiece = basedoc.CreateNode(XmlNodeType.Element, "name", ""); | ||
291 | infopiece.InnerText = scene.RegionInfo.RegionName; | ||
292 | infoblock.AppendChild(infopiece); | ||
293 | |||
294 | docElement.AppendChild(infoblock); | ||
295 | |||
296 | return docElement; | ||
297 | } | ||
298 | |||
299 | private XmlNode GetGridSnapshotData(XmlDocument factory) | ||
300 | { | ||
301 | XmlNode griddata = factory.CreateNode(XmlNodeType.Element, "grid", ""); | ||
302 | |||
303 | foreach (KeyValuePair<String, String> GridData in m_gridinfo) | ||
304 | { | ||
305 | //TODO: make it lowercase tag names for diva | ||
306 | XmlNode childnode = factory.CreateNode(XmlNodeType.Element, GridData.Key, ""); | ||
307 | childnode.InnerText = GridData.Value; | ||
308 | griddata.AppendChild(childnode); | ||
309 | } | ||
310 | |||
311 | return griddata; | ||
312 | } | ||
313 | |||
314 | private String GetRegionCategory(Scene scene) | ||
315 | { | ||
316 | |||
317 | //Boolean choice between: | ||
318 | // "PG" - Mormontown | ||
319 | // "Mature" - Sodom and Gomorrah | ||
320 | // (Depreciated) "Patriotic Nigra Testing Sandbox" - Abandon Hope All Ye Who Enter Here | ||
321 | if ((scene.RegionInfo.EstateSettings.simAccess & Simulator.SimAccess.Mature) == Simulator.SimAccess.Mature) | ||
322 | { | ||
323 | return "Mature"; | ||
324 | } | ||
325 | else if ((scene.RegionInfo.EstateSettings.simAccess & Simulator.SimAccess.PG) == Simulator.SimAccess.PG) | ||
326 | { | ||
327 | return "PG"; | ||
328 | } | ||
329 | else | ||
330 | { | ||
331 | return "Unknown"; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | /* Code's closed due to AIDS, See EstateSnapshot.cs for CURE | ||
336 | private XmlNode GetEstateSnapshotData(Scene scene, XmlDocument factory) | ||
337 | { | ||
338 | //Estate data section - contains who owns a set of sims and the name of the set. | ||
339 | //In Opensim all the estate names are the same as the Master Avatar (owner of the sim) | ||
340 | XmlNode estatedata = factory.CreateNode(XmlNodeType.Element, "estate", ""); | ||
341 | |||
342 | LLUUID ownerid = scene.RegionInfo.MasterAvatarAssignedUUID; | ||
343 | String firstname = scene.RegionInfo.MasterAvatarFirstName; | ||
344 | String lastname = scene.RegionInfo.MasterAvatarLastName; | ||
345 | String hostname = scene.RegionInfo.ExternalHostName; | ||
346 | |||
347 | XmlNode user = factory.CreateNode(XmlNodeType.Element, "owner", ""); | ||
348 | |||
349 | XmlNode username = factory.CreateNode(XmlNodeType.Element, "name", ""); | ||
350 | username.InnerText = firstname + " " + lastname; | ||
351 | user.AppendChild(username); | ||
352 | |||
353 | XmlNode useruuid = factory.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
354 | useruuid.InnerText = ownerid.ToString(); | ||
355 | user.AppendChild(useruuid); | ||
356 | |||
357 | estatedata.AppendChild(user); | ||
358 | |||
359 | return estatedata; | ||
360 | } */ | ||
361 | |||
362 | #endregion | ||
363 | |||
364 | #region [Public] Snapshot storage functions | ||
365 | |||
366 | public void MakeNewSnapshot() | ||
367 | { | ||
368 | foreach (Scene scene in m_scenes) | ||
369 | { | ||
370 | XmlDocument snapshot = Snapshot(scene); | ||
371 | |||
372 | string path = DataFileName(scene); | ||
373 | |||
374 | try | ||
375 | { | ||
376 | using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default)) | ||
377 | { | ||
378 | snapXWriter.Formatting = Formatting.Indented; | ||
379 | snapXWriter.WriteStartDocument(); | ||
380 | snapshot.WriteTo(snapXWriter); | ||
381 | snapXWriter.WriteEndDocument(); | ||
382 | |||
383 | m_lastSnapshot++; | ||
384 | } | ||
385 | } | ||
386 | catch (Exception e) | ||
387 | { | ||
388 | m_log.Warn("[DATASNAPSHOT]: Caught unknown exception while trying to save snapshot: " + path + "\n" + e.ToString()); | ||
389 | } | ||
390 | m_log.Info("[DATASNAPSHOT]: Made external data snapshot " + path); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | /** | ||
395 | * Reply to the http request | ||
396 | */ | ||
397 | public XmlDocument GetSnapshot(string regionName) | ||
398 | { | ||
399 | XmlDocument requestedSnap = new XmlDocument(); | ||
400 | requestedSnap.AppendChild(requestedSnap.CreateXmlDeclaration("1.0", null, null)); | ||
401 | requestedSnap.AppendChild(requestedSnap.CreateWhitespace("\r\n")); | ||
402 | XmlNode regiondata = requestedSnap.CreateNode(XmlNodeType.Element, "regiondata", ""); | ||
403 | try | ||
404 | { | ||
405 | if (regionName == null || regionName == "") | ||
406 | { | ||
407 | foreach (Scene scene in m_scenes) | ||
408 | { | ||
409 | string path = DataFileName(scene); | ||
410 | XmlDocument regionSnap = new XmlDocument(); | ||
411 | regionSnap.PreserveWhitespace = true; | ||
412 | |||
413 | regionSnap.Load(path); | ||
414 | XmlNode nodeOrig = regionSnap["region"]; | ||
415 | XmlNode nodeDest = requestedSnap.ImportNode(nodeOrig, true); | ||
416 | //requestedSnap.AppendChild(nodeDest); | ||
417 | |||
418 | regiondata.AppendChild(requestedSnap.CreateWhitespace("\r\n")); | ||
419 | regiondata.AppendChild(nodeDest); | ||
420 | } | ||
421 | } | ||
422 | else | ||
423 | { | ||
424 | Scene scene = SceneForName(regionName); | ||
425 | requestedSnap.Load(DataFileName(scene)); | ||
426 | } | ||
427 | // requestedSnap.InsertBefore(requestedSnap.CreateXmlDeclaration("1.0", null, null), | ||
428 | // requestedSnap.DocumentElement); | ||
429 | requestedSnap.AppendChild(regiondata); | ||
430 | regiondata.AppendChild(requestedSnap.CreateWhitespace("\r\n")); | ||
431 | |||
432 | |||
433 | } | ||
434 | catch (XmlException e) | ||
435 | { | ||
436 | m_log.Warn("[DATASNAPSHOT]: XmlException while trying to load snapshot: " + e.ToString()); | ||
437 | requestedSnap = GetErrorMessage(regionName, e); | ||
438 | } | ||
439 | catch (Exception e) | ||
440 | { | ||
441 | m_log.Warn("[DATASNAPSHOT]: Caught unknown exception while trying to load snapshot: " + e.StackTrace); | ||
442 | requestedSnap = GetErrorMessage(regionName, e); | ||
443 | } | ||
444 | |||
445 | |||
446 | return requestedSnap; | ||
447 | } | ||
448 | |||
449 | private XmlDocument GetErrorMessage(string regionName, Exception e) | ||
450 | { | ||
451 | XmlDocument errorMessage = new XmlDocument(); | ||
452 | XmlNode error = errorMessage.CreateNode(XmlNodeType.Element, "error", ""); | ||
453 | XmlNode region = errorMessage.CreateNode(XmlNodeType.Element, "region", ""); | ||
454 | region.InnerText = regionName; | ||
455 | |||
456 | XmlNode exception = errorMessage.CreateNode(XmlNodeType.Element, "exception", ""); | ||
457 | exception.InnerText = e.ToString(); | ||
458 | |||
459 | error.AppendChild(region); | ||
460 | error.AppendChild(exception); | ||
461 | errorMessage.AppendChild(error); | ||
462 | |||
463 | return errorMessage; | ||
464 | } | ||
465 | |||
466 | #endregion | ||
467 | |||
468 | #region Event callbacks | ||
469 | |||
470 | private void SnapshotTimerCallback(object timer, ElapsedEventArgs args) | ||
471 | { | ||
472 | MakeNewSnapshot(); | ||
473 | //Add extra calls here | ||
474 | } | ||
475 | |||
476 | #endregion | ||
477 | |||
478 | #region External data services | ||
479 | private void NotifyDataServices(string servicesStr) | ||
480 | { | ||
481 | Stream reply = null; | ||
482 | string delimStr = ";"; | ||
483 | char [] delimiter = delimStr.ToCharArray(); | ||
484 | |||
485 | string[] services = servicesStr.Split(delimiter); | ||
486 | |||
487 | for (int i = 0; i < services.Length; i++) | ||
488 | { | ||
489 | string url = services[i].Trim(); | ||
490 | RestClient cli = new RestClient(url); | ||
491 | cli.AddQueryParameter("host", m_hostname); | ||
492 | cli.AddQueryParameter("port", m_listener_port); | ||
493 | cli.RequestMethod = "GET"; | ||
494 | try | ||
495 | { | ||
496 | reply = cli.Request(); | ||
497 | } | ||
498 | catch (System.Net.WebException) | ||
499 | { | ||
500 | m_log.Warn("[DATASNAPSHOT] Unable to notify " + url); | ||
501 | } | ||
502 | catch (Exception e) | ||
503 | { | ||
504 | m_log.Warn("[DATASNAPSHOT] Ignoring unknown exception " + e.ToString()); | ||
505 | } | ||
506 | byte[] response = new byte[1024]; | ||
507 | int n = 0; | ||
508 | try | ||
509 | { | ||
510 | n = reply.Read(response, 0, 1024); | ||
511 | } | ||
512 | catch (Exception e) | ||
513 | { | ||
514 | m_log.Warn("[DATASNAPSHOT] Unable to decode reply from data service. Ignoring. " + e.StackTrace); | ||
515 | } | ||
516 | // This is not quite working, so... | ||
517 | string responseStr = System.Text.ASCIIEncoding.UTF8.GetString(response); | ||
518 | m_log.Info("[DATASNAPSHOT] data service notified: " + url); | ||
519 | } | ||
520 | |||
521 | } | ||
522 | #endregion | ||
523 | } | ||
524 | } | ||
diff --git a/OpenSim/Region/DataSnapshot/EstateSnapshot.cs b/OpenSim/Region/DataSnapshot/EstateSnapshot.cs new file mode 100644 index 0000000..76fed59 --- /dev/null +++ b/OpenSim/Region/DataSnapshot/EstateSnapshot.cs | |||
@@ -0,0 +1,68 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.Xml; | ||
5 | using OpenSim.Region.Environment.Scenes; | ||
6 | using OpenSim.Region.Environment.Modules.LandManagement; | ||
7 | using OpenSim.Framework; | ||
8 | using OpenSim.Framework.Console; | ||
9 | using OpenSim.Framework.Communications; | ||
10 | using libsecondlife; | ||
11 | using libsecondlife.Packets; | ||
12 | |||
13 | namespace OpenSim.Region.DataSnapshot | ||
14 | { | ||
15 | public class EstateSnapshot : IDataSnapshotProvider | ||
16 | { | ||
17 | private Scene m_scene = null; | ||
18 | private DataSnapshotManager m_parent = null; | ||
19 | |||
20 | #region IDataSnapshotProvider Members | ||
21 | |||
22 | public XmlNode RequestSnapshotData(XmlDocument factory) | ||
23 | { | ||
24 | //Estate data section - contains who owns a set of sims and the name of the set. | ||
25 | //In Opensim all the estate names are the same as the Master Avatar (owner of the sim) | ||
26 | //Now in DataSnapshotProvider module form! | ||
27 | XmlNode estatedata = factory.CreateNode(XmlNodeType.Element, "estate", ""); | ||
28 | |||
29 | LLUUID ownerid = m_scene.RegionInfo.MasterAvatarAssignedUUID; | ||
30 | |||
31 | //TODO: Change to query userserver about the master avatar UUID ? | ||
32 | String firstname = m_scene.RegionInfo.MasterAvatarFirstName; | ||
33 | String lastname = m_scene.RegionInfo.MasterAvatarLastName; | ||
34 | |||
35 | //TODO: Fix the marshalling system to have less copypasta gruntwork | ||
36 | XmlNode user = factory.CreateNode(XmlNodeType.Element, "user", ""); | ||
37 | XmlAttribute type = (XmlAttribute)factory.CreateNode(XmlNodeType.Attribute, "type", ""); | ||
38 | type.Value = "owner"; | ||
39 | user.Attributes.Append(type); | ||
40 | |||
41 | //TODO: Create more TODOs | ||
42 | XmlNode username = factory.CreateNode(XmlNodeType.Element, "name", ""); | ||
43 | username.InnerText = firstname + " " + lastname; | ||
44 | user.AppendChild(username); | ||
45 | |||
46 | XmlNode useruuid = factory.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
47 | useruuid.InnerText = ownerid.ToString(); | ||
48 | user.AppendChild(useruuid); | ||
49 | |||
50 | estatedata.AppendChild(user); | ||
51 | |||
52 | return estatedata; | ||
53 | } | ||
54 | |||
55 | public void Initialize(Scene scene, DataSnapshotManager parent) | ||
56 | { | ||
57 | m_scene = scene; | ||
58 | m_parent = parent; | ||
59 | } | ||
60 | |||
61 | public Scene GetParentScene | ||
62 | { | ||
63 | get { return m_scene; } | ||
64 | } | ||
65 | |||
66 | #endregion | ||
67 | } | ||
68 | } | ||
diff --git a/OpenSim/Region/DataSnapshot/Interfaces/IDataSnapshotProvider.cs b/OpenSim/Region/DataSnapshot/Interfaces/IDataSnapshotProvider.cs new file mode 100644 index 0000000..42b6818 --- /dev/null +++ b/OpenSim/Region/DataSnapshot/Interfaces/IDataSnapshotProvider.cs | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Text; | ||
32 | using System.Xml; | ||
33 | using OpenSim.Region.Environment.Scenes; | ||
34 | using libsecondlife; | ||
35 | |||
36 | namespace OpenSim.Region.DataSnapshot | ||
37 | { | ||
38 | public interface IDataSnapshotProvider | ||
39 | { | ||
40 | XmlNode RequestSnapshotData(XmlDocument document); | ||
41 | |||
42 | //void PrepareData(); | ||
43 | |||
44 | void Initialize(Scene scene, DataSnapshotManager parent); | ||
45 | |||
46 | Scene GetParentScene { get; } | ||
47 | } | ||
48 | } | ||
diff --git a/OpenSim/Region/DataSnapshot/LandSnapshot.cs b/OpenSim/Region/DataSnapshot/LandSnapshot.cs new file mode 100644 index 0000000..47dea43 --- /dev/null +++ b/OpenSim/Region/DataSnapshot/LandSnapshot.cs | |||
@@ -0,0 +1,267 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Text; | ||
32 | using System.Xml; | ||
33 | using System.Reflection; | ||
34 | |||
35 | using OpenSim.Region.Environment.Scenes; | ||
36 | using OpenSim.Region.Environment.Modules.LandManagement; | ||
37 | using OpenSim.Region.Environment.Interfaces; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Console; | ||
40 | using OpenSim.Framework.Communications; | ||
41 | using libsecondlife; | ||
42 | using libsecondlife.Packets; | ||
43 | |||
44 | namespace OpenSim.Region.DataSnapshot | ||
45 | { | ||
46 | public class LandSnapshot : IDataSnapshotProvider | ||
47 | { | ||
48 | private Scene m_scene = null; | ||
49 | private DataSnapshotManager m_parent = null; | ||
50 | //private Dictionary<int, Land> m_landIndexed = new Dictionary<int, Land>(); | ||
51 | private log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
52 | |||
53 | #region Dead code | ||
54 | |||
55 | /* | ||
56 | * David, I don't think we need this at all. When we do the snapshot, we can | ||
57 | * simply look into the parcels that are marked for ShowDirectory -- see | ||
58 | * conditional in RequestSnapshotData | ||
59 | * | ||
60 | //Revise this, look for more direct way of checking for change in land | ||
61 | #region Client hooks | ||
62 | |||
63 | public void OnNewClient(IClientAPI client) | ||
64 | { | ||
65 | //Land hooks | ||
66 | client.OnParcelDivideRequest += ParcelSplitHook; | ||
67 | client.OnParcelJoinRequest += ParcelSplitHook; | ||
68 | client.OnParcelPropertiesUpdateRequest += ParcelPropsHook; | ||
69 | } | ||
70 | |||
71 | public void ParcelSplitHook(int west, int south, int east, int north, IClientAPI remote_client) | ||
72 | { | ||
73 | PrepareData(); | ||
74 | } | ||
75 | |||
76 | public void ParcelPropsHook(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) | ||
77 | { | ||
78 | PrepareData(); | ||
79 | } | ||
80 | |||
81 | #endregion | ||
82 | |||
83 | public void PrepareData() | ||
84 | { | ||
85 | m_log.Info("[EXTERNALDATA]: Generating land data."); | ||
86 | |||
87 | m_landIndexed.Clear(); | ||
88 | |||
89 | //Index sim land | ||
90 | foreach (KeyValuePair<int, Land> curLand in m_scene.LandManager.landList) | ||
91 | { | ||
92 | //if ((curLand.Value.landData.landFlags & (uint)Parcel.ParcelFlags.ShowDirectory) == (uint)Parcel.ParcelFlags.ShowDirectory) | ||
93 | //{ | ||
94 | m_landIndexed.Add(curLand.Key, curLand.Value.Copy()); | ||
95 | //} | ||
96 | } | ||
97 | } | ||
98 | |||
99 | public Dictionary<int,Land> IndexedLand { | ||
100 | get { return m_landIndexed; } | ||
101 | } | ||
102 | */ | ||
103 | |||
104 | #endregion | ||
105 | |||
106 | #region IDataSnapshotProvider members | ||
107 | |||
108 | public void Initialize(Scene scene, DataSnapshotManager parent) | ||
109 | { | ||
110 | m_scene = scene; | ||
111 | m_parent = parent; | ||
112 | //m_scene.EventManager.OnNewClient += OnNewClient; | ||
113 | } | ||
114 | |||
115 | public Scene GetParentScene | ||
116 | { | ||
117 | get { return m_scene; } | ||
118 | } | ||
119 | |||
120 | public XmlNode RequestSnapshotData(XmlDocument nodeFactory) | ||
121 | { | ||
122 | ILandChannel landChannel = (LandChannel)m_scene.LandChannel; | ||
123 | Dictionary<int, ILandObject> landList = null; | ||
124 | try | ||
125 | { | ||
126 | Type landChannelType = typeof(LandChannel); | ||
127 | FieldInfo landListField = landChannelType.GetField("landList", BindingFlags.NonPublic | BindingFlags.Instance); | ||
128 | if (landListField != null) | ||
129 | { | ||
130 | landList = (Dictionary<int, ILandObject>)landListField.GetValue(landChannel); | ||
131 | } | ||
132 | } | ||
133 | catch (Exception e) | ||
134 | { | ||
135 | Console.WriteLine("[DATASNAPSHOT] couldn't access field reflectively\n" + e.ToString()); | ||
136 | } | ||
137 | XmlNode parent = nodeFactory.CreateNode(XmlNodeType.Element, "parceldata", ""); | ||
138 | if (landList != null) | ||
139 | { | ||
140 | |||
141 | //foreach (KeyValuePair<int, Land> curParcel in m_landIndexed) | ||
142 | foreach (LandObject land in landList.Values) | ||
143 | { | ||
144 | LandData parcel = land.landData; | ||
145 | if ((parcel.landFlags & (uint)Parcel.ParcelFlags.ShowDirectory) == (uint)Parcel.ParcelFlags.ShowDirectory) | ||
146 | { | ||
147 | |||
148 | //TODO: make better method of marshalling data from LandData to XmlNode | ||
149 | XmlNode xmlparcel = nodeFactory.CreateNode(XmlNodeType.Element, "parcel", ""); | ||
150 | |||
151 | // Attributes of the parcel node | ||
152 | XmlAttribute scripts_attr = nodeFactory.CreateAttribute("scripts"); | ||
153 | scripts_attr.Value = GetScriptsPermissions(parcel); | ||
154 | XmlAttribute category_attr = nodeFactory.CreateAttribute("category"); | ||
155 | category_attr.Value = parcel.category.ToString(); | ||
156 | //XmlAttribute entities_attr = nodeFactory.CreateAttribute("entities"); | ||
157 | //entities_attr.Value = land.primsOverMe.Count.ToString(); | ||
158 | xmlparcel.Attributes.Append(scripts_attr); | ||
159 | xmlparcel.Attributes.Append(category_attr); | ||
160 | //xmlparcel.Attributes.Append(entities_attr); | ||
161 | |||
162 | |||
163 | //name, description, area, and UUID | ||
164 | XmlNode name = nodeFactory.CreateNode(XmlNodeType.Element, "name", ""); | ||
165 | name.InnerText = parcel.landName; | ||
166 | xmlparcel.AppendChild(name); | ||
167 | |||
168 | XmlNode desc = nodeFactory.CreateNode(XmlNodeType.Element, "description", ""); | ||
169 | desc.InnerText = parcel.landDesc; | ||
170 | xmlparcel.AppendChild(desc); | ||
171 | |||
172 | XmlNode uuid = nodeFactory.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
173 | uuid.InnerText = parcel.globalID.ToString(); | ||
174 | xmlparcel.AppendChild(uuid); | ||
175 | |||
176 | XmlNode area = nodeFactory.CreateNode(XmlNodeType.Element, "area", ""); | ||
177 | area.InnerText = parcel.area.ToString(); | ||
178 | xmlparcel.AppendChild(area); | ||
179 | |||
180 | //default location | ||
181 | XmlNode tpLocation = nodeFactory.CreateNode(XmlNodeType.Element, "location", ""); | ||
182 | LLVector3 loc = parcel.userLocation; | ||
183 | if (loc.Equals(LLVector3.Zero)) // This test is mute at this point: the location is wrong by default | ||
184 | loc = new LLVector3((parcel.AABBMax.X - parcel.AABBMin.X) / 2, (parcel.AABBMax.Y - parcel.AABBMin.Y) / 2, (parcel.AABBMax.Y - parcel.AABBMin.Y) / 2); | ||
185 | tpLocation.InnerText = loc.X.ToString() + "/" + loc.Y.ToString() + "/" + loc.Z.ToString(); | ||
186 | xmlparcel.AppendChild(tpLocation); | ||
187 | |||
188 | //TODO: figure how to figure out teleport system landData.landingType | ||
189 | |||
190 | //land texture snapshot uuid | ||
191 | if (parcel.snapshotID != LLUUID.Zero) | ||
192 | { | ||
193 | XmlNode textureuuid = nodeFactory.CreateNode(XmlNodeType.Element, "image", ""); | ||
194 | textureuuid.InnerText = parcel.snapshotID.ToString(); | ||
195 | xmlparcel.AppendChild(textureuuid); | ||
196 | } | ||
197 | |||
198 | //attached user and group | ||
199 | if (parcel.groupID != LLUUID.Zero) | ||
200 | { | ||
201 | XmlNode groupblock = nodeFactory.CreateNode(XmlNodeType.Element, "group", ""); | ||
202 | XmlNode groupuuid = nodeFactory.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
203 | groupuuid.InnerText = parcel.groupID.ToString(); | ||
204 | groupblock.AppendChild(groupuuid); | ||
205 | |||
206 | //No name yet, there's no way to get a group name since they don't exist yet. | ||
207 | //TODO: When groups are supported, add the group handling code. | ||
208 | |||
209 | xmlparcel.AppendChild(groupblock); | ||
210 | } | ||
211 | |||
212 | if (!parcel.isGroupOwned) | ||
213 | { | ||
214 | XmlNode userblock = nodeFactory.CreateNode(XmlNodeType.Element, "owner", ""); | ||
215 | |||
216 | LLUUID userOwnerUUID = parcel.ownerID; | ||
217 | |||
218 | XmlNode useruuid = nodeFactory.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
219 | useruuid.InnerText = userOwnerUUID.ToString(); | ||
220 | userblock.AppendChild(useruuid); | ||
221 | |||
222 | try | ||
223 | { | ||
224 | XmlNode username = nodeFactory.CreateNode(XmlNodeType.Element, "name", ""); | ||
225 | UserProfileData userProfile = m_scene.CommsManager.UserService.GetUserProfile(userOwnerUUID); | ||
226 | username.InnerText = userProfile.username + " " + userProfile.surname; | ||
227 | userblock.AppendChild(username); | ||
228 | } | ||
229 | catch (Exception) | ||
230 | { | ||
231 | m_log.Info("[DATASNAPSHOT]: Cannot find owner name; ignoring this parcel"); | ||
232 | } | ||
233 | |||
234 | xmlparcel.AppendChild(userblock); | ||
235 | } | ||
236 | //else | ||
237 | //{ | ||
238 | // XmlAttribute type = (XmlAttribute)nodeFactory.CreateNode(XmlNodeType.Attribute, "type", ""); | ||
239 | // type.InnerText = "owner"; | ||
240 | // groupblock.Attributes.Append(type); | ||
241 | //} | ||
242 | |||
243 | parent.AppendChild(xmlparcel); | ||
244 | } | ||
245 | } | ||
246 | //snap.AppendChild(parent); | ||
247 | } | ||
248 | |||
249 | return parent; | ||
250 | } | ||
251 | |||
252 | #endregion | ||
253 | |||
254 | #region Helper functions | ||
255 | |||
256 | private string GetScriptsPermissions(LandData parcel) | ||
257 | { | ||
258 | if ((parcel.landFlags & (uint)Parcel.ParcelFlags.AllowOtherScripts) == (uint)Parcel.ParcelFlags.AllowOtherScripts) | ||
259 | return "yes"; | ||
260 | else | ||
261 | return "no"; | ||
262 | |||
263 | } | ||
264 | |||
265 | #endregion | ||
266 | } | ||
267 | } | ||
diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs new file mode 100644 index 0000000..9222b48 --- /dev/null +++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs | |||
@@ -0,0 +1,83 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.Xml; | ||
5 | using System.Reflection; | ||
6 | using OpenSim.Region.Environment.Scenes; | ||
7 | using OpenSim.Framework; | ||
8 | using libsecondlife; | ||
9 | |||
10 | namespace OpenSim.Region.DataSnapshot | ||
11 | { | ||
12 | public class ObjectSnapshot : IDataSnapshotProvider | ||
13 | { | ||
14 | private Scene m_scene = null; | ||
15 | private DataSnapshotManager m_parent = null; | ||
16 | private log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
17 | |||
18 | public void Initialize(Scene scene, DataSnapshotManager parent) | ||
19 | { | ||
20 | m_scene = scene; | ||
21 | m_parent = parent; | ||
22 | } | ||
23 | |||
24 | public Scene GetParentScene | ||
25 | { | ||
26 | get { return m_scene; } | ||
27 | } | ||
28 | |||
29 | public XmlNode RequestSnapshotData(XmlDocument nodeFactory) | ||
30 | { | ||
31 | XmlNode parent = nodeFactory.CreateNode(XmlNodeType.Element, "objectdata", ""); | ||
32 | XmlNode node; | ||
33 | #if LIBSL_IS_FIXED | ||
34 | foreach (EntityBase entity in m_scene.Entities.Values) | ||
35 | { | ||
36 | // only objects, not avatars | ||
37 | if (entity is SceneObjectGroup) | ||
38 | { | ||
39 | SceneObjectGroup obj = (SceneObjectGroup)entity; | ||
40 | |||
41 | XmlNode xmlobject = nodeFactory.CreateNode(XmlNodeType.Element, "object", ""); | ||
42 | |||
43 | node = nodeFactory.CreateNode(XmlNodeType.Element, "uuid", ""); | ||
44 | node.InnerText = obj.UUID.ToString(); | ||
45 | xmlobject.AppendChild(node); | ||
46 | |||
47 | SceneObjectPart m_rootPart = null; | ||
48 | try | ||
49 | { | ||
50 | Type sog = typeof(SceneObjectGroup); | ||
51 | FieldInfo rootField = sog.GetField("m_rootPart", BindingFlags.NonPublic | BindingFlags.Instance); | ||
52 | if (rootField != null) | ||
53 | { | ||
54 | m_rootPart = (SceneObjectPart)rootField.GetValue(obj); | ||
55 | } | ||
56 | } | ||
57 | catch (Exception e) | ||
58 | { | ||
59 | Console.WriteLine("[DATASNAPSHOT] couldn't access field reflectively\n" + e.ToString()); | ||
60 | } | ||
61 | if (m_rootPart != null) | ||
62 | { | ||
63 | node = nodeFactory.CreateNode(XmlNodeType.Element, "title", ""); | ||
64 | node.InnerText = m_rootPart.Name; | ||
65 | xmlobject.AppendChild(node); | ||
66 | |||
67 | node = nodeFactory.CreateNode(XmlNodeType.Element, "description", ""); | ||
68 | node.InnerText = m_rootPart.Description; | ||
69 | xmlobject.AppendChild(node); | ||
70 | |||
71 | node = nodeFactory.CreateNode(XmlNodeType.Element, "flags", ""); | ||
72 | node.InnerText = String.Format("{0:x}", m_rootPart.ObjectFlags); | ||
73 | xmlobject.AppendChild(node); | ||
74 | } | ||
75 | parent.AppendChild(xmlobject); | ||
76 | } | ||
77 | } | ||
78 | #endif | ||
79 | return parent; | ||
80 | |||
81 | } | ||
82 | } | ||
83 | } | ||
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 9a49359..6d89b3e 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -7,7 +7,7 @@ gridmode = false | |||
7 | 7 | ||
8 | ; *** Prim Storage - only leave one storage_plugin uncommented *** | 8 | ; *** Prim Storage - only leave one storage_plugin uncommented *** |
9 | ; --- The NullStorage stores nothing - effectively disabling persistence: | 9 | ; --- The NullStorage stores nothing - effectively disabling persistence: |
10 | storage_plugin = "OpenSim.Data.Null.dll" | 10 | storage_plugin = "OpenSim.DataStore.NullStorage.dll" |
11 | 11 | ||
12 | ; --- To use sqlite as region storage: | 12 | ; --- To use sqlite as region storage: |
13 | ;storage_plugin = "OpenSim.Data.SQLite.dll" | 13 | ;storage_plugin = "OpenSim.Data.SQLite.dll" |
@@ -285,3 +285,19 @@ CleanUpOldScriptsOnStartup=true | |||
285 | [LL-Functions] | 285 | [LL-Functions] |
286 | ; Set the following to true to allow administrator owned scripts to execute console commands | 286 | ; Set the following to true to allow administrator owned scripts to execute console commands |
287 | AllowosConsoleCommand=false | 287 | AllowosConsoleCommand=false |
288 | |||
289 | [DataSnapshot] | ||
290 | ; The following set of configs pertains to search. | ||
291 | ; Set index_sims to true to enable search engines to index your searchable data | ||
292 | ; If false, no data will be exposed, DataSnapshot module will be off, and you can ignore the rest of these search-related configs | ||
293 | index_sims = false | ||
294 | ; If search is on, change this to your grid name; will be ignored for standalones | ||
295 | gridname = "OSGrid" | ||
296 | ; Period between data snapshots, in seconds. 20 minutes, for starters, so that you see the initial changes fast. | ||
297 | ; Later, you may want to increase this to 3600 (1 hour) or more | ||
298 | default_snapshot_period = 1200 | ||
299 | ; This will be created in bin, if it doesn't exist already. It will hold the data snapshots. | ||
300 | snapshot_cache_directory = "DataSnapshot" | ||
301 | ; This semicolon-separated string serves to notify specific data services | ||
302 | ; about the existence of this sim. | ||
303 | data_services="http://metaverseink.com/cgi-bin/register.py" | ||
diff --git a/prebuild.xml b/prebuild.xml index dedbadc..c8238f9 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -1073,6 +1073,35 @@ | |||
1073 | 1073 | ||
1074 | <!-- Scene Server API Example Apps --> | 1074 | <!-- Scene Server API Example Apps --> |
1075 | 1075 | ||
1076 | <Project name="OpenSim.Region.DataSnapshot" path="OpenSim/Region/DataSnapshot" type="Library"> | ||
1077 | <Configuration name="Debug"> | ||
1078 | <Options> | ||
1079 | <OutputPath>../../../bin/</OutputPath> | ||
1080 | </Options> | ||
1081 | </Configuration> | ||
1082 | <Configuration name="Release"> | ||
1083 | <Options> | ||
1084 | <OutputPath>../../../bin/</OutputPath> | ||
1085 | </Options> | ||
1086 | </Configuration> | ||
1087 | |||
1088 | <ReferencePath>../../../bin/</ReferencePath> | ||
1089 | <Reference name="System" localCopy="false"/> | ||
1090 | <Reference name="System.Xml"/> | ||
1091 | <Reference name="System.Data"/> | ||
1092 | <Reference name="OpenSim.Framework"/> | ||
1093 | <Reference name="OpenSim.Framework.Communications"/> | ||
1094 | <Reference name="OpenSim.Framework.Console"/> | ||
1095 | <Reference name="OpenSim.Framework.Servers"/> | ||
1096 | <Reference name="OpenSim.Region.Environment"/> | ||
1097 | <Reference name="libsecondlife.dll"/> | ||
1098 | <Reference name="Nini.dll" /> | ||
1099 | <Reference name="log4net.dll" /> | ||
1100 | <Files> | ||
1101 | <Match pattern="*.cs" recurse="true"/> | ||
1102 | </Files> | ||
1103 | </Project> | ||
1104 | |||
1076 | <Project name="OpenSim.Region.Examples.SimpleModule" path="OpenSim/Region/Examples/SimpleModule" type="Library"> | 1105 | <Project name="OpenSim.Region.Examples.SimpleModule" path="OpenSim/Region/Examples/SimpleModule" type="Library"> |
1077 | <Configuration name="Debug"> | 1106 | <Configuration name="Debug"> |
1078 | <Options> | 1107 | <Options> |