diff options
Diffstat (limited to 'OpenSim/Region/DataSnapshot/LandSnapshot.cs')
-rw-r--r-- | OpenSim/Region/DataSnapshot/LandSnapshot.cs | 267 |
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 | |||
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 | } | ||