aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/DataSnapshot/LandSnapshot.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/DataSnapshot/LandSnapshot.cs')
-rw-r--r--OpenSim/Region/DataSnapshot/LandSnapshot.cs267
1 files changed, 267 insertions, 0 deletions
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
29using System;
30using System.Collections.Generic;
31using System.Text;
32using System.Xml;
33using System.Reflection;
34
35using OpenSim.Region.Environment.Scenes;
36using OpenSim.Region.Environment.Modules.LandManagement;
37using OpenSim.Region.Environment.Interfaces;
38using OpenSim.Framework;
39using OpenSim.Framework.Console;
40using OpenSim.Framework.Communications;
41using libsecondlife;
42using libsecondlife.Packets;
43
44namespace 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}