diff options
author | Melanie | 2009-09-16 17:52:16 +0100 |
---|---|---|
committer | Melanie | 2009-09-16 17:52:16 +0100 |
commit | 90a4d4f9f93eda3d707292c9619aecc765edada8 (patch) | |
tree | 78c93f214407011909fda2f6e6527bad72ad8089 /OpenSim/Data/MySQL/MySQLRegionData.cs | |
parent | Database interface tot the new region store (diff) | |
download | opensim-SC-90a4d4f9f93eda3d707292c9619aecc765edada8.zip opensim-SC-90a4d4f9f93eda3d707292c9619aecc765edada8.tar.gz opensim-SC-90a4d4f9f93eda3d707292c9619aecc765edada8.tar.bz2 opensim-SC-90a4d4f9f93eda3d707292c9619aecc765edada8.tar.xz |
Adding the MySQL RegionData service.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Data/MySQL/MySQLRegionData.cs | 1615 |
1 files changed, 144 insertions, 1471 deletions
diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 4a16a70..ced26a4 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs | |||
@@ -26,1569 +26,242 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
30 | using System.Data; | 31 | using System.Data; |
31 | using System.Drawing; | ||
32 | using System.IO; | ||
33 | using System.Reflection; | ||
34 | using System.Threading; | ||
35 | using log4net; | ||
36 | using MySql.Data.MySqlClient; | ||
37 | using OpenMetaverse; | 32 | using OpenMetaverse; |
38 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
39 | using OpenSim.Region.Framework.Interfaces; | 34 | using MySql.Data.MySqlClient; |
40 | using OpenSim.Region.Framework.Scenes; | ||
41 | 35 | ||
42 | namespace OpenSim.Data.MySQL | 36 | namespace OpenSim.Data.MySQL |
43 | { | 37 | { |
44 | /// <summary> | 38 | public class MySqlRegionData : MySqlFramework, IRegionData |
45 | /// A MySQL Interface for the Region Server | ||
46 | /// </summary> | ||
47 | public class MySQLDataStore : IRegionDataStore | ||
48 | { | 39 | { |
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 40 | private string m_Realm; |
50 | 41 | private List<string> m_ColumnNames = null; | |
51 | private string m_ConnectionString; | 42 | private int m_LastExpire = 0; |
52 | 43 | ||
53 | private MySqlConnection m_Connection = null; | 44 | public MySqlRegionData(string connectionString, string realm) |
54 | 45 | : base(connectionString) | |
55 | public void Initialise(string connectionString) | ||
56 | { | 46 | { |
57 | m_ConnectionString = connectionString; | 47 | m_Realm = realm; |
58 | |||
59 | m_Connection = new MySqlConnection(m_ConnectionString); | ||
60 | 48 | ||
61 | m_Connection.Open(); | 49 | Migration m = new Migration(m_Connection, GetType().Assembly, "GridStore"); |
62 | |||
63 | // Apply new Migrations | ||
64 | // | ||
65 | Assembly assem = GetType().Assembly; | ||
66 | Migration m = new Migration(m_Connection, assem, "RegionStore"); | ||
67 | m.Update(); | 50 | m.Update(); |
68 | |||
69 | // Clean dropped attachments | ||
70 | // | ||
71 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
72 | cmd.CommandText = "delete from prims, primshapes using prims " + | ||
73 | "left join primshapes on prims.uuid = primshapes.uuid " + | ||
74 | "where PCode = 9 and State <> 0"; | ||
75 | ExecuteNonQuery(cmd); | ||
76 | cmd.Dispose(); | ||
77 | } | 51 | } |
78 | 52 | ||
79 | private IDataReader ExecuteReader(MySqlCommand c) | 53 | public List<RegionData> Get(string regionName, UUID scopeID) |
80 | { | 54 | { |
81 | IDataReader r = null; | 55 | string command = "select * from `"+m_Realm+"` where regionName like ?regionName"; |
82 | bool errorSeen = false; | 56 | if (scopeID != UUID.Zero) |
57 | command += " and ScopeID = ?scopeID"; | ||
83 | 58 | ||
84 | while (true) | 59 | MySqlCommand cmd = new MySqlCommand(command); |
85 | { | ||
86 | try | ||
87 | { | ||
88 | r = c.ExecuteReader(); | ||
89 | } | ||
90 | catch (Exception) | ||
91 | { | ||
92 | Thread.Sleep(500); | ||
93 | |||
94 | m_Connection.Close(); | ||
95 | m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); | ||
96 | m_Connection.Open(); | ||
97 | c.Connection = m_Connection; | ||
98 | 60 | ||
99 | if (!errorSeen) | 61 | cmd.Parameters.AddWithValue("?regionName", regionName); |
100 | { | 62 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); |
101 | errorSeen = true; | ||
102 | continue; | ||
103 | } | ||
104 | throw; | ||
105 | } | ||
106 | 63 | ||
107 | break; | 64 | return RunCommand(cmd); |
108 | } | ||
109 | |||
110 | return r; | ||
111 | } | 65 | } |
112 | 66 | ||
113 | private void ExecuteNonQuery(MySqlCommand c) | 67 | public RegionData Get(int posX, int posY, UUID scopeID) |
114 | { | 68 | { |
115 | bool errorSeen = false; | 69 | string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY"; |
70 | if (scopeID != UUID.Zero) | ||
71 | command += " and ScopeID = ?scopeID"; | ||
116 | 72 | ||
117 | while (true) | 73 | MySqlCommand cmd = new MySqlCommand(command); |
118 | { | ||
119 | try | ||
120 | { | ||
121 | c.ExecuteNonQuery(); | ||
122 | } | ||
123 | catch (Exception) | ||
124 | { | ||
125 | Thread.Sleep(500); | ||
126 | 74 | ||
127 | m_Connection.Close(); | 75 | cmd.Parameters.AddWithValue("?posX", posX.ToString()); |
128 | m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone(); | 76 | cmd.Parameters.AddWithValue("?posY", posY.ToString()); |
129 | m_Connection.Open(); | 77 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); |
130 | c.Connection = m_Connection; | ||
131 | 78 | ||
132 | if (!errorSeen) | 79 | List<RegionData> ret = RunCommand(cmd); |
133 | { | 80 | if (ret == null) |
134 | errorSeen = true; | 81 | return null; |
135 | continue; | ||
136 | } | ||
137 | throw; | ||
138 | } | ||
139 | 82 | ||
140 | break; | 83 | return ret[0]; |
141 | } | ||
142 | } | 84 | } |
143 | 85 | ||
144 | public void Dispose() {} | 86 | public RegionData Get(UUID regionID, UUID scopeID) |
145 | |||
146 | public void StoreObject(SceneObjectGroup obj, UUID regionUUID) | ||
147 | { | 87 | { |
148 | uint flags = obj.RootPart.GetEffectiveObjectFlags(); | 88 | string command = "select * from `"+m_Realm+"` where uuid = ?regionID"; |
149 | 89 | if (scopeID != UUID.Zero) | |
150 | // Eligibility check | 90 | command += " and ScopeID = ?scopeID"; |
151 | // | ||
152 | if ((flags & (uint)PrimFlags.Temporary) != 0) | ||
153 | return; | ||
154 | if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) | ||
155 | return; | ||
156 | |||
157 | lock (m_Connection) | ||
158 | { | ||
159 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
160 | 91 | ||
161 | foreach (SceneObjectPart prim in obj.Children.Values) | 92 | MySqlCommand cmd = new MySqlCommand(command); |
162 | { | ||
163 | cmd.Parameters.Clear(); | ||
164 | |||
165 | cmd.CommandText = "replace into prims ("+ | ||
166 | "UUID, CreationDate, "+ | ||
167 | "Name, Text, Description, "+ | ||
168 | "SitName, TouchName, ObjectFlags, "+ | ||
169 | "OwnerMask, NextOwnerMask, GroupMask, "+ | ||
170 | "EveryoneMask, BaseMask, PositionX, "+ | ||
171 | "PositionY, PositionZ, GroupPositionX, "+ | ||
172 | "GroupPositionY, GroupPositionZ, VelocityX, "+ | ||
173 | "VelocityY, VelocityZ, AngularVelocityX, "+ | ||
174 | "AngularVelocityY, AngularVelocityZ, "+ | ||
175 | "AccelerationX, AccelerationY, "+ | ||
176 | "AccelerationZ, RotationX, "+ | ||
177 | "RotationY, RotationZ, "+ | ||
178 | "RotationW, SitTargetOffsetX, "+ | ||
179 | "SitTargetOffsetY, SitTargetOffsetZ, "+ | ||
180 | "SitTargetOrientW, SitTargetOrientX, "+ | ||
181 | "SitTargetOrientY, SitTargetOrientZ, "+ | ||
182 | "RegionUUID, CreatorID, "+ | ||
183 | "OwnerID, GroupID, "+ | ||
184 | "LastOwnerID, SceneGroupID, "+ | ||
185 | "PayPrice, PayButton1, "+ | ||
186 | "PayButton2, PayButton3, "+ | ||
187 | "PayButton4, LoopedSound, "+ | ||
188 | "LoopedSoundGain, TextureAnimation, "+ | ||
189 | "OmegaX, OmegaY, OmegaZ, "+ | ||
190 | "CameraEyeOffsetX, CameraEyeOffsetY, "+ | ||
191 | "CameraEyeOffsetZ, CameraAtOffsetX, "+ | ||
192 | "CameraAtOffsetY, CameraAtOffsetZ, "+ | ||
193 | "ForceMouselook, ScriptAccessPin, "+ | ||
194 | "AllowedDrop, DieAtEdge, "+ | ||
195 | "SalePrice, SaleType, "+ | ||
196 | "ColorR, ColorG, ColorB, ColorA, "+ | ||
197 | "ParticleSystem, ClickAction, Material, "+ | ||
198 | "CollisionSound, CollisionSoundVolume, "+ | ||
199 | "PassTouches, "+ | ||
200 | "LinkNumber) values (" + "?UUID, "+ | ||
201 | "?CreationDate, ?Name, ?Text, "+ | ||
202 | "?Description, ?SitName, ?TouchName, "+ | ||
203 | "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, "+ | ||
204 | "?GroupMask, ?EveryoneMask, ?BaseMask, "+ | ||
205 | "?PositionX, ?PositionY, ?PositionZ, "+ | ||
206 | "?GroupPositionX, ?GroupPositionY, "+ | ||
207 | "?GroupPositionZ, ?VelocityX, "+ | ||
208 | "?VelocityY, ?VelocityZ, ?AngularVelocityX, "+ | ||
209 | "?AngularVelocityY, ?AngularVelocityZ, "+ | ||
210 | "?AccelerationX, ?AccelerationY, "+ | ||
211 | "?AccelerationZ, ?RotationX, "+ | ||
212 | "?RotationY, ?RotationZ, "+ | ||
213 | "?RotationW, ?SitTargetOffsetX, "+ | ||
214 | "?SitTargetOffsetY, ?SitTargetOffsetZ, "+ | ||
215 | "?SitTargetOrientW, ?SitTargetOrientX, "+ | ||
216 | "?SitTargetOrientY, ?SitTargetOrientZ, "+ | ||
217 | "?RegionUUID, ?CreatorID, ?OwnerID, "+ | ||
218 | "?GroupID, ?LastOwnerID, ?SceneGroupID, "+ | ||
219 | "?PayPrice, ?PayButton1, ?PayButton2, "+ | ||
220 | "?PayButton3, ?PayButton4, ?LoopedSound, "+ | ||
221 | "?LoopedSoundGain, ?TextureAnimation, "+ | ||
222 | "?OmegaX, ?OmegaY, ?OmegaZ, "+ | ||
223 | "?CameraEyeOffsetX, ?CameraEyeOffsetY, "+ | ||
224 | "?CameraEyeOffsetZ, ?CameraAtOffsetX, "+ | ||
225 | "?CameraAtOffsetY, ?CameraAtOffsetZ, "+ | ||
226 | "?ForceMouselook, ?ScriptAccessPin, "+ | ||
227 | "?AllowedDrop, ?DieAtEdge, ?SalePrice, "+ | ||
228 | "?SaleType, ?ColorR, ?ColorG, "+ | ||
229 | "?ColorB, ?ColorA, ?ParticleSystem, "+ | ||
230 | "?ClickAction, ?Material, ?CollisionSound, "+ | ||
231 | "?CollisionSoundVolume, ?PassTouches, ?LinkNumber)"; | ||
232 | |||
233 | FillPrimCommand(cmd, prim, obj.UUID, regionUUID); | ||
234 | |||
235 | ExecuteNonQuery(cmd); | ||
236 | |||
237 | cmd.Parameters.Clear(); | ||
238 | 93 | ||
239 | cmd.CommandText = "replace into primshapes ("+ | 94 | cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); |
240 | "UUID, Shape, ScaleX, ScaleY, "+ | 95 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); |
241 | "ScaleZ, PCode, PathBegin, PathEnd, "+ | ||
242 | "PathScaleX, PathScaleY, PathShearX, "+ | ||
243 | "PathShearY, PathSkew, PathCurve, "+ | ||
244 | "PathRadiusOffset, PathRevolutions, "+ | ||
245 | "PathTaperX, PathTaperY, PathTwist, "+ | ||
246 | "PathTwistBegin, ProfileBegin, ProfileEnd, "+ | ||
247 | "ProfileCurve, ProfileHollow, Texture, "+ | ||
248 | "ExtraParams, State) values (?UUID, "+ | ||
249 | "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, "+ | ||
250 | "?PCode, ?PathBegin, ?PathEnd, "+ | ||
251 | "?PathScaleX, ?PathScaleY, "+ | ||
252 | "?PathShearX, ?PathShearY, "+ | ||
253 | "?PathSkew, ?PathCurve, ?PathRadiusOffset, "+ | ||
254 | "?PathRevolutions, ?PathTaperX, "+ | ||
255 | "?PathTaperY, ?PathTwist, "+ | ||
256 | "?PathTwistBegin, ?ProfileBegin, "+ | ||
257 | "?ProfileEnd, ?ProfileCurve, "+ | ||
258 | "?ProfileHollow, ?Texture, ?ExtraParams, "+ | ||
259 | "?State)"; | ||
260 | 96 | ||
261 | FillShapeCommand(cmd, prim); | 97 | List<RegionData> ret = RunCommand(cmd); |
98 | if (ret == null) | ||
99 | return null; | ||
262 | 100 | ||
263 | ExecuteNonQuery(cmd); | 101 | return ret[0]; |
264 | } | ||
265 | cmd.Dispose(); | ||
266 | } | ||
267 | } | 102 | } |
268 | 103 | ||
269 | public void RemoveObject(UUID obj, UUID regionUUID) | 104 | public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID) |
270 | { | 105 | { |
271 | // Formerly, this used to check the region UUID. | 106 | string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY"; |
272 | // That makes no sense, as we remove the contents of a prim | 107 | if (scopeID != UUID.Zero) |
273 | // unconditionally, but the prim dependent on the region ID. | 108 | command += " and ScopeID = ?scopeID"; |
274 | // So, we would destroy an object and cause hard to detect | ||
275 | // issues if we delete the contents only. Deleting it all may | ||
276 | // cause the loss of a prim, but is cleaner. | ||
277 | // It's also faster because it uses the primary key. | ||
278 | // | ||
279 | lock (m_Connection) | ||
280 | { | ||
281 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
282 | |||
283 | cmd.CommandText = "select UUID from prims where "+ | ||
284 | "SceneGroupID= ?UUID"; | ||
285 | 109 | ||
286 | cmd.Parameters.AddWithValue("UUID", obj.ToString()); | 110 | MySqlCommand cmd = new MySqlCommand(command); |
287 | 111 | ||
288 | List<UUID> uuids = new List<UUID>(); | 112 | cmd.Parameters.AddWithValue("?startX", startX.ToString()); |
113 | cmd.Parameters.AddWithValue("?startY", startY.ToString()); | ||
114 | cmd.Parameters.AddWithValue("?endX", endX.ToString()); | ||
115 | cmd.Parameters.AddWithValue("?endY", endY.ToString()); | ||
116 | cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString()); | ||
289 | 117 | ||
290 | IDataReader reader = ExecuteReader(cmd); | 118 | return RunCommand(cmd); |
291 | |||
292 | try | ||
293 | { | ||
294 | while (reader.Read()) | ||
295 | { | ||
296 | uuids.Add(new UUID(reader["UUID"].ToString())); | ||
297 | } | ||
298 | } | ||
299 | finally | ||
300 | { | ||
301 | reader.Close(); | ||
302 | } | ||
303 | |||
304 | // delete the main prims | ||
305 | cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; | ||
306 | ExecuteNonQuery(cmd); | ||
307 | cmd.Dispose(); | ||
308 | |||
309 | // there is no way this should be < 1 unless there is | ||
310 | // a very corrupt database, but in that case be extra | ||
311 | // safe anyway. | ||
312 | if (uuids.Count > 0) | ||
313 | { | ||
314 | RemoveShapes(uuids); | ||
315 | RemoveItems(uuids); | ||
316 | } | ||
317 | } | ||
318 | } | 119 | } |
319 | 120 | ||
320 | /// <summary> | 121 | public List<RegionData> RunCommand(MySqlCommand cmd) |
321 | /// Remove all persisted items of the given prim. | ||
322 | /// The caller must acquire the necessrary synchronization locks | ||
323 | /// </summary> | ||
324 | /// <param name="uuid">the Item UUID</param> | ||
325 | private void RemoveItems(UUID uuid) | ||
326 | { | 122 | { |
327 | lock (m_Connection) | 123 | List<RegionData> retList = new List<RegionData>(); |
328 | { | ||
329 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
330 | |||
331 | cmd.CommandText = "delete from primitems where " + | ||
332 | "PrimID = ?PrimID"; | ||
333 | |||
334 | cmd.Parameters.AddWithValue("PrimID", uuid.ToString()); | ||
335 | 124 | ||
336 | ExecuteNonQuery(cmd); | 125 | IDataReader result = ExecuteReader(cmd); |
337 | cmd.Dispose(); | ||
338 | } | ||
339 | } | ||
340 | 126 | ||
341 | 127 | while (result.Read()) | |
342 | /// <summary> | ||
343 | /// Remove all persisted shapes for a list of prims | ||
344 | /// The caller must acquire the necessrary synchronization locks | ||
345 | /// </summary> | ||
346 | /// <param name="uuids">the list of UUIDs</param> | ||
347 | private void RemoveShapes(List<UUID> uuids) | ||
348 | { | ||
349 | lock (m_Connection) | ||
350 | { | 128 | { |
351 | string sql = "delete from primshapes where "; | 129 | RegionData ret = new RegionData(); |
352 | MySqlCommand cmd = m_Connection.CreateCommand(); | 130 | ret.Data = new Dictionary<string, object>(); |
353 | 131 | ||
354 | for (int i = 0; i < uuids.Count; i++) | 132 | UUID regionID; |
133 | UUID.TryParse(result["uuid"].ToString(), out regionID); | ||
134 | ret.RegionID = regionID; | ||
135 | UUID scope; | ||
136 | UUID.TryParse(result["ScopeID"].ToString(), out scope); | ||
137 | ret.ScopeID = scope; | ||
138 | ret.RegionName = result["regionName"].ToString(); | ||
139 | ret.posX = Convert.ToInt32(result["locX"]); | ||
140 | ret.posY = Convert.ToInt32(result["locY"]); | ||
141 | |||
142 | if (m_ColumnNames == null) | ||
355 | { | 143 | { |
356 | if ((i + 1) == uuids.Count) | 144 | m_ColumnNames = new List<string>(); |
357 | {// end of the list | ||
358 | sql += "(UUID = ?UUID" + i + ")"; | ||
359 | } | ||
360 | else | ||
361 | { | ||
362 | sql += "(UUID = ?UUID" + i + ") or "; | ||
363 | } | ||
364 | } | ||
365 | cmd.CommandText = sql; | ||
366 | 145 | ||
367 | for (int i = 0; i < uuids.Count; i++) | 146 | DataTable schemaTable = result.GetSchemaTable(); |
368 | { | 147 | foreach (DataRow row in schemaTable.Rows) |
369 | cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString()); | 148 | m_ColumnNames.Add(row["ColumnName"].ToString()); |
370 | } | 149 | } |
371 | 150 | ||
372 | ExecuteNonQuery(cmd); | 151 | foreach (string s in m_ColumnNames) |
373 | cmd.Dispose(); | ||
374 | } | ||
375 | } | ||
376 | |||
377 | /// <summary> | ||
378 | /// Remove all persisted items for a list of prims | ||
379 | /// The caller must acquire the necessrary synchronization locks | ||
380 | /// </summary> | ||
381 | /// <param name="uuids">the list of UUIDs</param> | ||
382 | private void RemoveItems(List<UUID> uuids) | ||
383 | { | ||
384 | lock (m_Connection) | ||
385 | { | ||
386 | string sql = "delete from primitems where "; | ||
387 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
388 | |||
389 | for (int i = 0; i < uuids.Count; i++) | ||
390 | { | 152 | { |
391 | if ((i + 1) == uuids.Count) | 153 | if (s == "uuid") |
392 | {// end of the list | 154 | continue; |
393 | sql += "(PrimID = ?PrimID" + i + ")"; | 155 | if (s == "ScopeID") |
394 | } | 156 | continue; |
395 | else | 157 | if (s == "regionName") |
396 | { | 158 | continue; |
397 | sql += "(PrimID = ?PrimID" + i + ") or "; | 159 | if (s == "locX") |
398 | } | 160 | continue; |
399 | } | 161 | if (s == "locY") |
400 | cmd.CommandText = sql; | 162 | continue; |
401 | |||
402 | for (int i = 0; i < uuids.Count; i++) | ||
403 | { | ||
404 | cmd.Parameters.AddWithValue("PrimID" + i, uuids[i].ToString()); | ||
405 | } | ||
406 | |||
407 | ExecuteNonQuery(cmd); | ||
408 | cmd.Dispose(); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | public List<SceneObjectGroup> LoadObjects(UUID regionUUID) | ||
413 | { | ||
414 | UUID lastGroupID = UUID.Zero; | ||
415 | Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>(); | ||
416 | Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>(); | ||
417 | SceneObjectGroup grp = null; | ||
418 | |||
419 | lock (m_Connection) | ||
420 | { | ||
421 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
422 | |||
423 | cmd.CommandText = "select *, " + | ||
424 | "case when prims.UUID = SceneGroupID " + | ||
425 | "then 0 else 1 end as sort from prims " + | ||
426 | "left join primshapes on prims.UUID = primshapes.UUID "+ | ||
427 | "where RegionUUID = ?RegionUUID " + | ||
428 | "order by SceneGroupID asc, sort asc, LinkNumber asc"; | ||
429 | |||
430 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
431 | |||
432 | IDataReader reader = ExecuteReader(cmd); | ||
433 | |||
434 | try | ||
435 | { | ||
436 | while (reader.Read()) | ||
437 | { | ||
438 | SceneObjectPart prim = BuildPrim(reader); | ||
439 | if (reader["Shape"] is DBNull) | ||
440 | prim.Shape = PrimitiveBaseShape.Default; | ||
441 | else | ||
442 | prim.Shape = BuildShape(reader); | ||
443 | |||
444 | prims[prim.UUID] = prim; | ||
445 | |||
446 | UUID groupID = new UUID(reader["SceneGroupID"].ToString()); | ||
447 | |||
448 | if (groupID != lastGroupID) // New SOG | ||
449 | { | ||
450 | if (grp != null) | ||
451 | objects[grp.UUID] = grp; | ||
452 | |||
453 | lastGroupID = groupID; | ||
454 | |||
455 | // There sometimes exist OpenSim bugs that 'orphan groups' so that none of the prims are | ||
456 | // recorded as the root prim (for which the UUID must equal the persisted group UUID). In | ||
457 | // this case, force the UUID to be the same as the group UUID so that at least these can be | ||
458 | // deleted (we need to change the UUID so that any other prims in the linkset can also be | ||
459 | // deleted). | ||
460 | if (prim.UUID != groupID && groupID != UUID.Zero) | ||
461 | { | ||
462 | m_log.WarnFormat( | ||
463 | "[REGION DB]: Found root prim {0} {1} at {2} where group was actually {3}. Forcing UUID to group UUID", | ||
464 | prim.Name, prim.UUID, prim.GroupPosition, groupID); | ||
465 | |||
466 | prim.UUID = groupID; | ||
467 | } | ||
468 | |||
469 | grp = new SceneObjectGroup(prim); | ||
470 | } | ||
471 | else | ||
472 | { | ||
473 | // Black magic to preserve link numbers | ||
474 | // | ||
475 | int link = prim.LinkNum; | ||
476 | |||
477 | grp.AddPart(prim); | ||
478 | 163 | ||
479 | if (link != 0) | 164 | ret.Data[s] = result[s].ToString(); |
480 | prim.LinkNum = link; | ||
481 | } | ||
482 | } | ||
483 | } | ||
484 | finally | ||
485 | { | ||
486 | reader.Close(); | ||
487 | } | 165 | } |
488 | 166 | ||
489 | if (grp != null) | 167 | retList.Add(ret); |
490 | objects[grp.UUID] = grp; | ||
491 | cmd.Dispose(); | ||
492 | } | 168 | } |
493 | 169 | ||
494 | // Instead of attempting to LoadItems on every prim, | 170 | result.Close(); |
495 | // most of which probably have no items... get a | 171 | CloseReaderCommand(cmd); |
496 | // list from DB of all prims which have items and | ||
497 | // LoadItems only on those | ||
498 | List<SceneObjectPart> primsWithInventory = new List<SceneObjectPart>(); | ||
499 | lock (m_Connection) | ||
500 | { | ||
501 | MySqlCommand itemCmd = m_Connection.CreateCommand(); | ||
502 | itemCmd.CommandText = "select distinct primID from primitems"; | ||
503 | IDataReader itemReader = ExecuteReader(itemCmd); | ||
504 | try | ||
505 | { | ||
506 | while (itemReader.Read()) | ||
507 | { | ||
508 | if (!(itemReader["primID"] is DBNull)) | ||
509 | { | ||
510 | UUID primID = new UUID(itemReader["primID"].ToString()); | ||
511 | if (prims.ContainsKey(primID)) | ||
512 | { | ||
513 | primsWithInventory.Add(prims[primID]); | ||
514 | } | ||
515 | } | ||
516 | } | ||
517 | } | ||
518 | finally | ||
519 | { | ||
520 | itemReader.Close(); | ||
521 | } | ||
522 | itemCmd.Dispose(); | ||
523 | } | ||
524 | |||
525 | foreach (SceneObjectPart prim in primsWithInventory) | ||
526 | { | ||
527 | LoadItems(prim); | ||
528 | } | ||
529 | m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count); | ||
530 | return new List<SceneObjectGroup>(objects.Values); | ||
531 | } | ||
532 | |||
533 | /// <summary> | ||
534 | /// Load in a prim's persisted inventory. | ||
535 | /// </summary> | ||
536 | /// <param name="prim">The prim</param> | ||
537 | private void LoadItems(SceneObjectPart prim) | ||
538 | { | ||
539 | lock (m_Connection) | ||
540 | { | ||
541 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
542 | 172 | ||
543 | cmd.CommandText = "select * from primitems where "+ | 173 | if (retList.Count > 0) |
544 | "PrimID = ?PrimID"; | 174 | return retList; |
545 | 175 | ||
546 | cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString()); | 176 | return null; |
547 | |||
548 | IDataReader reader = ExecuteReader(cmd); | ||
549 | List<TaskInventoryItem> inventory = | ||
550 | new List<TaskInventoryItem>(); | ||
551 | |||
552 | try | ||
553 | { | ||
554 | while (reader.Read()) | ||
555 | { | ||
556 | TaskInventoryItem item = BuildItem(reader); | ||
557 | |||
558 | item.ParentID = prim.UUID; // Values in database are | ||
559 | // often wrong | ||
560 | inventory.Add(item); | ||
561 | } | ||
562 | } | ||
563 | finally | ||
564 | { | ||
565 | reader.Close(); | ||
566 | } | ||
567 | |||
568 | cmd.Dispose(); | ||
569 | prim.Inventory.RestoreInventoryItems(inventory); | ||
570 | } | ||
571 | } | 177 | } |
572 | 178 | ||
573 | public void StoreTerrain(double[,] ter, UUID regionID) | 179 | public bool Store(RegionData data) |
574 | { | 180 | { |
575 | m_log.Info("[REGION DB]: Storing terrain"); | 181 | if (data.Data.ContainsKey("uuid")) |
182 | data.Data.Remove("uuid"); | ||
183 | if (data.Data.ContainsKey("ScopeID")) | ||
184 | data.Data.Remove("ScopeID"); | ||
185 | if (data.Data.ContainsKey("regionName")) | ||
186 | data.Data.Remove("regionName"); | ||
187 | if (data.Data.ContainsKey("posX")) | ||
188 | data.Data.Remove("posX"); | ||
189 | if (data.Data.ContainsKey("posY")) | ||
190 | data.Data.Remove("posY"); | ||
576 | 191 | ||
577 | lock (m_Connection) | 192 | string[] fields = new List<string>(data.Data.Keys).ToArray(); |
578 | { | ||
579 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
580 | |||
581 | cmd.CommandText = "delete from terrain where " + | ||
582 | "RegionUUID = ?RegionUUID"; | ||
583 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
584 | |||
585 | ExecuteNonQuery(cmd); | ||
586 | |||
587 | cmd.CommandText = "insert into terrain (RegionUUID, " + | ||
588 | "Revision, Heightfield) values (?RegionUUID, " + | ||
589 | "1, ?Heightfield)"; | ||
590 | 193 | ||
591 | cmd.Parameters.AddWithValue("Heightfield", | 194 | MySqlCommand cmd = new MySqlCommand(); |
592 | SerializeTerrain(ter)); | ||
593 | |||
594 | ExecuteNonQuery(cmd); | ||
595 | cmd.Dispose(); | ||
596 | } | ||
597 | } | ||
598 | 195 | ||
599 | public double[,] LoadTerrain(UUID regionID) | 196 | string update = "update `"+m_Realm+"` set "; |
600 | { | 197 | bool first = true; |
601 | double[,] terrain = null; | 198 | foreach (string field in fields) |
602 | |||
603 | lock (m_Connection) | ||
604 | { | 199 | { |
605 | MySqlCommand cmd = m_Connection.CreateCommand(); | 200 | if (!first) |
606 | cmd.CommandText = "select RegionUUID, Revision, Heightfield " + | 201 | update += ", "; |
607 | "from terrain where RegionUUID = ?RegionUUID "+ | 202 | update += "`" + field + "` = ?"+field; |
608 | "order by Revision desc limit 1"; | ||
609 | cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); | ||
610 | |||
611 | IDataReader reader = ExecuteReader(cmd); | ||
612 | |||
613 | try | ||
614 | { | ||
615 | while (reader.Read()) | ||
616 | { | ||
617 | terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize]; | ||
618 | terrain.Initialize(); | ||
619 | 203 | ||
620 | MemoryStream mstr = new MemoryStream((byte[]) reader["Heightfield"]); | 204 | first = false; |
621 | int rev = 0; | ||
622 | 205 | ||
623 | BinaryReader br = new BinaryReader(mstr); | 206 | cmd.Parameters.AddWithValue("?"+field, data.Data[field]); |
624 | for (int x = 0; x < (int)Constants.RegionSize; x++) | ||
625 | { | ||
626 | for (int y = 0; y < (int)Constants.RegionSize; y++) | ||
627 | { | ||
628 | terrain[x, y] = br.ReadDouble(); | ||
629 | } | ||
630 | rev = Convert.ToInt32(reader["Revision"]); | ||
631 | } | ||
632 | m_log.InfoFormat("[REGION DB]: Loaded terrain " + | ||
633 | "revision r{0}", rev); | ||
634 | } | ||
635 | } | ||
636 | finally | ||
637 | { | ||
638 | reader.Close(); | ||
639 | } | ||
640 | cmd.Dispose(); | ||
641 | } | 207 | } |
642 | 208 | ||
643 | return terrain; | 209 | update += " where uuid = ?regionID"; |
644 | } | ||
645 | |||
646 | public void RemoveLandObject(UUID globalID) | ||
647 | { | ||
648 | lock (m_Connection) | ||
649 | { | ||
650 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
651 | |||
652 | cmd.CommandText = "delete from land where UUID = ?UUID"; | ||
653 | 210 | ||
654 | cmd.Parameters.AddWithValue("UUID", globalID.ToString()); | 211 | if (data.ScopeID != UUID.Zero) |
212 | update += " and ScopeID = ?scopeID"; | ||
655 | 213 | ||
656 | ExecuteNonQuery(cmd); | 214 | cmd.CommandText = update; |
657 | cmd.Dispose(); | 215 | cmd.Parameters.AddWithValue("?regionID", data.RegionID.ToString()); |
658 | } | 216 | cmd.Parameters.AddWithValue("?scopeID", data.ScopeID.ToString()); |
659 | } | ||
660 | 217 | ||
661 | public void StoreLandObject(ILandObject parcel) | 218 | if (ExecuteNonQuery(cmd) < 1) |
662 | { | ||
663 | lock (m_Connection) | ||
664 | { | 219 | { |
665 | MySqlCommand cmd = m_Connection.CreateCommand(); | 220 | string insert = "insert into `" + m_Realm + "` (`uuid`, `ScopeID`, `" + |
666 | 221 | String.Join("`, `", fields) + | |
667 | cmd.CommandText = "replace into land (UUID, RegionUUID, " + | 222 | "`) values ( ?regionID, ?scopeID, ?" + String.Join(", ?", fields) + ")"; |
668 | "LocalLandID, Bitmap, Name, Description, " + | ||
669 | "OwnerUUID, IsGroupOwned, Area, AuctionID, " + | ||
670 | "Category, ClaimDate, ClaimPrice, GroupUUID, " + | ||
671 | "SalePrice, LandStatus, LandFlags, LandingType, " + | ||
672 | "MediaAutoScale, MediaTextureUUID, MediaURL, " + | ||
673 | "MusicURL, PassHours, PassPrice, SnapshotUUID, " + | ||
674 | "UserLocationX, UserLocationY, UserLocationZ, " + | ||
675 | "UserLookAtX, UserLookAtY, UserLookAtZ, " + | ||
676 | "AuthbuyerID, OtherCleanTime, Dwell) values (" + | ||
677 | "?UUID, ?RegionUUID, " + | ||
678 | "?LocalLandID, ?Bitmap, ?Name, ?Description, " + | ||
679 | "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " + | ||
680 | "?Category, ?ClaimDate, ?ClaimPrice, ?GroupUUID, " + | ||
681 | "?SalePrice, ?LandStatus, ?LandFlags, ?LandingType, " + | ||
682 | "?MediaAutoScale, ?MediaTextureUUID, ?MediaURL, " + | ||
683 | "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " + | ||
684 | "?UserLocationX, ?UserLocationY, ?UserLocationZ, " + | ||
685 | "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + | ||
686 | "?AuthbuyerID, ?OtherCleanTime, ?Dwell)"; | ||
687 | |||
688 | FillLandCommand(cmd, parcel.landData, parcel.regionUUID); | ||
689 | 223 | ||
690 | ExecuteNonQuery(cmd); | 224 | cmd.CommandText = insert; |
691 | 225 | ||
692 | cmd.CommandText = "delete from landaccesslist where " + | 226 | if (ExecuteNonQuery(cmd) < 1) |
693 | "LandUUID = ?UUID"; | ||
694 | |||
695 | ExecuteNonQuery(cmd); | ||
696 | |||
697 | cmd.Parameters.Clear(); | ||
698 | cmd.CommandText = "insert into landaccesslist (LandUUID, " + | ||
699 | "AccessUUID, Flags) values (?LandUUID, ?AccessUUID, " + | ||
700 | "?Flags)"; | ||
701 | |||
702 | foreach (ParcelManager.ParcelAccessEntry entry in | ||
703 | parcel.landData.ParcelAccessList) | ||
704 | { | 227 | { |
705 | FillLandAccessCommand(cmd, entry, parcel.landData.GlobalID); | 228 | cmd.Dispose(); |
706 | ExecuteNonQuery(cmd); | 229 | return false; |
707 | cmd.Parameters.Clear(); | ||
708 | } | 230 | } |
709 | cmd.Dispose(); | ||
710 | } | 231 | } |
711 | } | ||
712 | 232 | ||
713 | public RegionSettings LoadRegionSettings(UUID regionUUID) | 233 | cmd.Dispose(); |
714 | { | ||
715 | RegionSettings rs = null; | ||
716 | |||
717 | lock (m_Connection) | ||
718 | { | ||
719 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
720 | |||
721 | cmd.CommandText = "select * from regionsettings where " + | ||
722 | "regionUUID = ?RegionUUID"; | ||
723 | cmd.Parameters.AddWithValue("regionUUID", regionUUID); | ||
724 | |||
725 | IDataReader reader = ExecuteReader(cmd); | ||
726 | |||
727 | try | ||
728 | { | ||
729 | if (reader.Read()) | ||
730 | { | ||
731 | rs = BuildRegionSettings(reader); | ||
732 | rs.OnSave += StoreRegionSettings; | ||
733 | } | ||
734 | else | ||
735 | { | ||
736 | rs = new RegionSettings(); | ||
737 | rs.RegionUUID = regionUUID; | ||
738 | rs.OnSave += StoreRegionSettings; | ||
739 | |||
740 | StoreRegionSettings(rs); | ||
741 | } | ||
742 | } | ||
743 | finally | ||
744 | { | ||
745 | reader.Close(); | ||
746 | } | ||
747 | cmd.Dispose(); | ||
748 | } | ||
749 | |||
750 | return rs; | ||
751 | } | ||
752 | |||
753 | public void StoreRegionSettings(RegionSettings rs) | ||
754 | { | ||
755 | lock (m_Connection) | ||
756 | { | ||
757 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
758 | |||
759 | cmd.CommandText = "replace into regionsettings (regionUUID, " + | ||
760 | "block_terraform, block_fly, allow_damage, " + | ||
761 | "restrict_pushing, allow_land_resell, " + | ||
762 | "allow_land_join_divide, block_show_in_search, " + | ||
763 | "agent_limit, object_bonus, maturity, " + | ||
764 | "disable_scripts, disable_collisions, " + | ||
765 | "disable_physics, terrain_texture_1, " + | ||
766 | "terrain_texture_2, terrain_texture_3, " + | ||
767 | "terrain_texture_4, elevation_1_nw, " + | ||
768 | "elevation_2_nw, elevation_1_ne, " + | ||
769 | "elevation_2_ne, elevation_1_se, "+ | ||
770 | "elevation_2_se, elevation_1_sw, "+ | ||
771 | "elevation_2_sw, water_height, " + | ||
772 | "terrain_raise_limit, terrain_lower_limit, " + | ||
773 | "use_estate_sun, fixed_sun, sun_position, " + | ||
774 | "covenant, Sandbox, sunvectorx, sunvectory, " + | ||
775 | "sunvectorz, loaded_creation_datetime, " + | ||
776 | "loaded_creation_id) values ( ?RegionUUID, ?BlockTerraform, " + | ||
777 | "?BlockFly, ?AllowDamage, ?RestrictPushing, " + | ||
778 | "?AllowLandResell, ?AllowLandJoinDivide, " + | ||
779 | "?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " + | ||
780 | "?Maturity, ?DisableScripts, ?DisableCollisions, " + | ||
781 | "?DisablePhysics, ?TerrainTexture1, " + | ||
782 | "?TerrainTexture2, ?TerrainTexture3, " + | ||
783 | "?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " + | ||
784 | "?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " + | ||
785 | "?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " + | ||
786 | "?WaterHeight, ?TerrainRaiseLimit, " + | ||
787 | "?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " + | ||
788 | "?SunPosition, ?Covenant, ?Sandbox, " + | ||
789 | "?SunVectorX, ?SunVectorY, ?SunVectorZ, " + | ||
790 | "?LoadedCreationDateTime, ?LoadedCreationID)"; | ||
791 | |||
792 | FillRegionSettingsCommand(cmd, rs); | ||
793 | |||
794 | ExecuteNonQuery(cmd); | ||
795 | cmd.Dispose(); | ||
796 | |||
797 | } | ||
798 | } | ||
799 | |||
800 | public List<LandData> LoadLandObjects(UUID regionUUID) | ||
801 | { | ||
802 | List<LandData> landData = new List<LandData>(); | ||
803 | |||
804 | lock (m_Connection) | ||
805 | { | ||
806 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
807 | |||
808 | cmd.CommandText = "select * from land where " + | ||
809 | "RegionUUID = ?RegionUUID"; | ||
810 | |||
811 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
812 | |||
813 | IDataReader reader = ExecuteReader(cmd); | ||
814 | |||
815 | try | ||
816 | { | ||
817 | while (reader.Read()) | ||
818 | { | ||
819 | LandData newLand = BuildLandData(reader); | ||
820 | landData.Add(newLand); | ||
821 | } | ||
822 | } | ||
823 | finally | ||
824 | { | ||
825 | reader.Close(); | ||
826 | } | ||
827 | |||
828 | foreach (LandData land in landData) | ||
829 | { | ||
830 | cmd.Parameters.Clear(); | ||
831 | |||
832 | cmd.CommandText = "select * from landaccesslist " + | ||
833 | "where LandUUID = ?LandUUID"; | ||
834 | |||
835 | cmd.Parameters.AddWithValue("LandUUID", land.GlobalID.ToString()); | ||
836 | |||
837 | reader = ExecuteReader(cmd); | ||
838 | |||
839 | try | ||
840 | { | ||
841 | while (reader.Read()) | ||
842 | { | ||
843 | land.ParcelAccessList.Add(BuildLandAccessData(reader)); | ||
844 | } | ||
845 | } | ||
846 | finally | ||
847 | { | ||
848 | reader.Close(); | ||
849 | } | ||
850 | } | ||
851 | cmd.Dispose(); | ||
852 | } | ||
853 | |||
854 | return landData; | ||
855 | } | ||
856 | |||
857 | public void Shutdown() | ||
858 | { | ||
859 | } | ||
860 | |||
861 | private SceneObjectPart BuildPrim(IDataReader row) | ||
862 | { | ||
863 | SceneObjectPart prim = new SceneObjectPart(); | ||
864 | prim.UUID = new UUID((String) row["UUID"]); | ||
865 | // explicit conversion of integers is required, which sort | ||
866 | // of sucks. No idea if there is a shortcut here or not. | ||
867 | prim.CreationDate = Convert.ToInt32(row["CreationDate"]); | ||
868 | if (row["Name"] != DBNull.Value) | ||
869 | prim.Name = (String)row["Name"]; | ||
870 | else | ||
871 | prim.Name = string.Empty; | ||
872 | // various text fields | ||
873 | prim.Text = (String) row["Text"]; | ||
874 | prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]), | ||
875 | Convert.ToInt32(row["ColorR"]), | ||
876 | Convert.ToInt32(row["ColorG"]), | ||
877 | Convert.ToInt32(row["ColorB"])); | ||
878 | prim.Description = (String) row["Description"]; | ||
879 | prim.SitName = (String) row["SitName"]; | ||
880 | prim.TouchName = (String) row["TouchName"]; | ||
881 | // permissions | ||
882 | prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]); | ||
883 | prim.CreatorID = new UUID((String) row["CreatorID"]); | ||
884 | prim.OwnerID = new UUID((String) row["OwnerID"]); | ||
885 | prim.GroupID = new UUID((String) row["GroupID"]); | ||
886 | prim.LastOwnerID = new UUID((String) row["LastOwnerID"]); | ||
887 | prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); | ||
888 | prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); | ||
889 | prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); | ||
890 | prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); | ||
891 | prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); | ||
892 | // vectors | ||
893 | prim.OffsetPosition = new Vector3( | ||
894 | Convert.ToSingle(row["PositionX"]), | ||
895 | Convert.ToSingle(row["PositionY"]), | ||
896 | Convert.ToSingle(row["PositionZ"]) | ||
897 | ); | ||
898 | prim.GroupPosition = new Vector3( | ||
899 | Convert.ToSingle(row["GroupPositionX"]), | ||
900 | Convert.ToSingle(row["GroupPositionY"]), | ||
901 | Convert.ToSingle(row["GroupPositionZ"]) | ||
902 | ); | ||
903 | prim.Velocity = new Vector3( | ||
904 | Convert.ToSingle(row["VelocityX"]), | ||
905 | Convert.ToSingle(row["VelocityY"]), | ||
906 | Convert.ToSingle(row["VelocityZ"]) | ||
907 | ); | ||
908 | prim.AngularVelocity = new Vector3( | ||
909 | Convert.ToSingle(row["AngularVelocityX"]), | ||
910 | Convert.ToSingle(row["AngularVelocityY"]), | ||
911 | Convert.ToSingle(row["AngularVelocityZ"]) | ||
912 | ); | ||
913 | prim.Acceleration = new Vector3( | ||
914 | Convert.ToSingle(row["AccelerationX"]), | ||
915 | Convert.ToSingle(row["AccelerationY"]), | ||
916 | Convert.ToSingle(row["AccelerationZ"]) | ||
917 | ); | ||
918 | // quaternions | ||
919 | prim.RotationOffset = new Quaternion( | ||
920 | Convert.ToSingle(row["RotationX"]), | ||
921 | Convert.ToSingle(row["RotationY"]), | ||
922 | Convert.ToSingle(row["RotationZ"]), | ||
923 | Convert.ToSingle(row["RotationW"]) | ||
924 | ); | ||
925 | prim.SitTargetPositionLL = new Vector3( | ||
926 | Convert.ToSingle(row["SitTargetOffsetX"]), | ||
927 | Convert.ToSingle(row["SitTargetOffsetY"]), | ||
928 | Convert.ToSingle(row["SitTargetOffsetZ"]) | ||
929 | ); | ||
930 | prim.SitTargetOrientationLL = new Quaternion( | ||
931 | Convert.ToSingle(row["SitTargetOrientX"]), | ||
932 | Convert.ToSingle(row["SitTargetOrientY"]), | ||
933 | Convert.ToSingle(row["SitTargetOrientZ"]), | ||
934 | Convert.ToSingle(row["SitTargetOrientW"]) | ||
935 | ); | ||
936 | |||
937 | prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]); | ||
938 | prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]); | ||
939 | prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]); | ||
940 | prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]); | ||
941 | prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]); | ||
942 | |||
943 | prim.Sound = new UUID(row["LoopedSound"].ToString()); | ||
944 | prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); | ||
945 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | ||
946 | |||
947 | if (!(row["TextureAnimation"] is DBNull)) | ||
948 | prim.TextureAnimation = (Byte[])row["TextureAnimation"]; | ||
949 | if (!(row["ParticleSystem"] is DBNull)) | ||
950 | prim.ParticleSystem = (Byte[])row["ParticleSystem"]; | ||
951 | |||
952 | prim.RotationalVelocity = new Vector3( | ||
953 | Convert.ToSingle(row["OmegaX"]), | ||
954 | Convert.ToSingle(row["OmegaY"]), | ||
955 | Convert.ToSingle(row["OmegaZ"]) | ||
956 | ); | ||
957 | |||
958 | prim.SetCameraEyeOffset(new Vector3( | ||
959 | Convert.ToSingle(row["CameraEyeOffsetX"]), | ||
960 | Convert.ToSingle(row["CameraEyeOffsetY"]), | ||
961 | Convert.ToSingle(row["CameraEyeOffsetZ"]) | ||
962 | )); | ||
963 | |||
964 | prim.SetCameraAtOffset(new Vector3( | ||
965 | Convert.ToSingle(row["CameraAtOffsetX"]), | ||
966 | Convert.ToSingle(row["CameraAtOffsetY"]), | ||
967 | Convert.ToSingle(row["CameraAtOffsetZ"]) | ||
968 | )); | ||
969 | |||
970 | if (Convert.ToInt16(row["ForceMouselook"]) != 0) | ||
971 | prim.SetForceMouselook(true); | ||
972 | |||
973 | prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]); | ||
974 | |||
975 | if (Convert.ToInt16(row["AllowedDrop"]) != 0) | ||
976 | prim.AllowedDrop = true; | ||
977 | |||
978 | if (Convert.ToInt16(row["DieAtEdge"]) != 0) | ||
979 | prim.DIE_AT_EDGE = true; | ||
980 | |||
981 | prim.SalePrice = Convert.ToInt32(row["SalePrice"]); | ||
982 | prim.ObjectSaleType = unchecked((byte)Convert.ToSByte(row["SaleType"])); | ||
983 | |||
984 | prim.Material = unchecked((byte)Convert.ToSByte(row["Material"])); | ||
985 | |||
986 | if (!(row["ClickAction"] is DBNull)) | ||
987 | prim.ClickAction = unchecked((byte)Convert.ToSByte(row["ClickAction"])); | ||
988 | |||
989 | prim.CollisionSound = new UUID(row["CollisionSound"].ToString()); | ||
990 | prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]); | ||
991 | |||
992 | if (Convert.ToInt16(row["PassTouches"]) != 0) | ||
993 | prim.PassTouches = true; | ||
994 | prim.LinkNum = Convert.ToInt32(row["LinkNumber"]); | ||
995 | |||
996 | return prim; | ||
997 | } | ||
998 | |||
999 | |||
1000 | /// <summary> | ||
1001 | /// Build a prim inventory item from the persisted data. | ||
1002 | /// </summary> | ||
1003 | /// <param name="row"></param> | ||
1004 | /// <returns></returns> | ||
1005 | private static TaskInventoryItem BuildItem(IDataReader row) | ||
1006 | { | ||
1007 | TaskInventoryItem taskItem = new TaskInventoryItem(); | ||
1008 | |||
1009 | taskItem.ItemID = new UUID((String)row["itemID"]); | ||
1010 | taskItem.ParentPartID = new UUID((String)row["primID"]); | ||
1011 | taskItem.AssetID = new UUID((String)row["assetID"]); | ||
1012 | taskItem.ParentID = new UUID((String)row["parentFolderID"]); | ||
1013 | |||
1014 | taskItem.InvType = Convert.ToInt32(row["invType"]); | ||
1015 | taskItem.Type = Convert.ToInt32(row["assetType"]); | ||
1016 | |||
1017 | taskItem.Name = (String)row["name"]; | ||
1018 | taskItem.Description = (String)row["description"]; | ||
1019 | taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); | ||
1020 | taskItem.CreatorID = new UUID((String)row["creatorID"]); | ||
1021 | taskItem.OwnerID = new UUID((String)row["ownerID"]); | ||
1022 | taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]); | ||
1023 | taskItem.GroupID = new UUID((String)row["groupID"]); | ||
1024 | |||
1025 | taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); | ||
1026 | taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); | ||
1027 | taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); | ||
1028 | taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); | ||
1029 | taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); | ||
1030 | taskItem.Flags = Convert.ToUInt32(row["flags"]); | ||
1031 | |||
1032 | return taskItem; | ||
1033 | } | ||
1034 | |||
1035 | private static RegionSettings BuildRegionSettings(IDataReader row) | ||
1036 | { | ||
1037 | RegionSettings newSettings = new RegionSettings(); | ||
1038 | |||
1039 | newSettings.RegionUUID = new UUID((string) row["regionUUID"]); | ||
1040 | newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); | ||
1041 | newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); | ||
1042 | newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); | ||
1043 | newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); | ||
1044 | newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); | ||
1045 | newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); | ||
1046 | newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); | ||
1047 | newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); | ||
1048 | newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); | ||
1049 | newSettings.Maturity = Convert.ToInt32(row["maturity"]); | ||
1050 | newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); | ||
1051 | newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); | ||
1052 | newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); | ||
1053 | newSettings.TerrainTexture1 = new UUID((String) row["terrain_texture_1"]); | ||
1054 | newSettings.TerrainTexture2 = new UUID((String) row["terrain_texture_2"]); | ||
1055 | newSettings.TerrainTexture3 = new UUID((String) row["terrain_texture_3"]); | ||
1056 | newSettings.TerrainTexture4 = new UUID((String) row["terrain_texture_4"]); | ||
1057 | newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); | ||
1058 | newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); | ||
1059 | newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); | ||
1060 | newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); | ||
1061 | newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); | ||
1062 | newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); | ||
1063 | newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); | ||
1064 | newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); | ||
1065 | newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); | ||
1066 | newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); | ||
1067 | newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); | ||
1068 | newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); | ||
1069 | newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]); | ||
1070 | newSettings.SunVector = new Vector3 ( | ||
1071 | Convert.ToSingle(row["sunvectorx"]), | ||
1072 | Convert.ToSingle(row["sunvectory"]), | ||
1073 | Convert.ToSingle(row["sunvectorz"]) | ||
1074 | ); | ||
1075 | newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); | ||
1076 | newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); | ||
1077 | newSettings.Covenant = new UUID((String) row["covenant"]); | ||
1078 | |||
1079 | newSettings.LoadedCreationDateTime = Convert.ToInt32(row["loaded_creation_datetime"]); | ||
1080 | |||
1081 | if (row["loaded_creation_id"] is DBNull) | ||
1082 | newSettings.LoadedCreationID = ""; | ||
1083 | else | ||
1084 | newSettings.LoadedCreationID = (String) row["loaded_creation_id"]; | ||
1085 | |||
1086 | return newSettings; | ||
1087 | } | ||
1088 | |||
1089 | /// <summary> | ||
1090 | /// | ||
1091 | /// </summary> | ||
1092 | /// <param name="row"></param> | ||
1093 | /// <returns></returns> | ||
1094 | private static LandData BuildLandData(IDataReader row) | ||
1095 | { | ||
1096 | LandData newData = new LandData(); | ||
1097 | |||
1098 | newData.GlobalID = new UUID((String) row["UUID"]); | ||
1099 | newData.LocalID = Convert.ToInt32(row["LocalLandID"]); | ||
1100 | |||
1101 | // Bitmap is a byte[512] | ||
1102 | newData.Bitmap = (Byte[]) row["Bitmap"]; | ||
1103 | |||
1104 | newData.Name = (String) row["Name"]; | ||
1105 | newData.Description = (String) row["Description"]; | ||
1106 | newData.OwnerID = new UUID((String)row["OwnerUUID"]); | ||
1107 | newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); | ||
1108 | newData.Area = Convert.ToInt32(row["Area"]); | ||
1109 | newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unimplemented | ||
1110 | newData.Category = (ParcelCategory) Convert.ToInt32(row["Category"]); | ||
1111 | //Enum libsecondlife.Parcel.ParcelCategory | ||
1112 | newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); | ||
1113 | newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); | ||
1114 | newData.GroupID = new UUID((String) row["GroupUUID"]); | ||
1115 | newData.SalePrice = Convert.ToInt32(row["SalePrice"]); | ||
1116 | newData.Status = (ParcelStatus) Convert.ToInt32(row["LandStatus"]); | ||
1117 | //Enum. libsecondlife.Parcel.ParcelStatus | ||
1118 | newData.Flags = Convert.ToUInt32(row["LandFlags"]); | ||
1119 | newData.LandingType = Convert.ToByte(row["LandingType"]); | ||
1120 | newData.MediaAutoScale = Convert.ToByte(row["MediaAutoScale"]); | ||
1121 | newData.MediaID = new UUID((String) row["MediaTextureUUID"]); | ||
1122 | newData.MediaURL = (String) row["MediaURL"]; | ||
1123 | newData.MusicURL = (String) row["MusicURL"]; | ||
1124 | newData.PassHours = Convert.ToSingle(row["PassHours"]); | ||
1125 | newData.PassPrice = Convert.ToInt32(row["PassPrice"]); | ||
1126 | UUID authedbuyer = UUID.Zero; | ||
1127 | UUID snapshotID = UUID.Zero; | ||
1128 | |||
1129 | UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer); | ||
1130 | UUID.TryParse((string)row["SnapshotUUID"], out snapshotID); | ||
1131 | newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); | ||
1132 | newData.Dwell = Convert.ToInt32(row["Dwell"]); | ||
1133 | |||
1134 | newData.AuthBuyerID = authedbuyer; | ||
1135 | newData.SnapshotID = snapshotID; | ||
1136 | try | ||
1137 | { | ||
1138 | newData.UserLocation = | ||
1139 | new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), | ||
1140 | Convert.ToSingle(row["UserLocationZ"])); | ||
1141 | newData.UserLookAt = | ||
1142 | new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), | ||
1143 | Convert.ToSingle(row["UserLookAtZ"])); | ||
1144 | } | ||
1145 | catch (InvalidCastException) | ||
1146 | { | ||
1147 | newData.UserLocation = Vector3.Zero; | ||
1148 | newData.UserLookAt = Vector3.Zero; | ||
1149 | m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); | ||
1150 | } | ||
1151 | |||
1152 | newData.ParcelAccessList = new List<ParcelManager.ParcelAccessEntry>(); | ||
1153 | |||
1154 | return newData; | ||
1155 | } | ||
1156 | |||
1157 | /// <summary> | ||
1158 | /// | ||
1159 | /// </summary> | ||
1160 | /// <param name="row"></param> | ||
1161 | /// <returns></returns> | ||
1162 | private static ParcelManager.ParcelAccessEntry BuildLandAccessData(IDataReader row) | ||
1163 | { | ||
1164 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); | ||
1165 | entry.AgentID = new UUID((string) row["AccessUUID"]); | ||
1166 | entry.Flags = (AccessList) Convert.ToInt32(row["Flags"]); | ||
1167 | entry.Time = new DateTime(); | ||
1168 | return entry; | ||
1169 | } | ||
1170 | |||
1171 | /// <summary> | ||
1172 | /// | ||
1173 | /// </summary> | ||
1174 | /// <param name="val"></param> | ||
1175 | /// <returns></returns> | ||
1176 | private static Array SerializeTerrain(double[,] val) | ||
1177 | { | ||
1178 | MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double)); | ||
1179 | BinaryWriter bw = new BinaryWriter(str); | ||
1180 | |||
1181 | // TODO: COMPATIBILITY - Add byte-order conversions | ||
1182 | for (int x = 0; x < (int)Constants.RegionSize; x++) | ||
1183 | for (int y = 0; y < (int)Constants.RegionSize; y++) | ||
1184 | { | ||
1185 | double height = val[x, y]; | ||
1186 | if (height == 0.0) | ||
1187 | height = double.Epsilon; | ||
1188 | |||
1189 | bw.Write(height); | ||
1190 | } | ||
1191 | |||
1192 | return str.ToArray(); | ||
1193 | } | ||
1194 | |||
1195 | /// <summary> | ||
1196 | /// Fill the prim command with prim values | ||
1197 | /// </summary> | ||
1198 | /// <param name="row"></param> | ||
1199 | /// <param name="prim"></param> | ||
1200 | /// <param name="sceneGroupID"></param> | ||
1201 | /// <param name="regionUUID"></param> | ||
1202 | private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) | ||
1203 | { | ||
1204 | cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); | ||
1205 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
1206 | cmd.Parameters.AddWithValue("CreationDate", prim.CreationDate); | ||
1207 | cmd.Parameters.AddWithValue("Name", prim.Name); | ||
1208 | cmd.Parameters.AddWithValue("SceneGroupID", sceneGroupID.ToString()); | ||
1209 | // the UUID of the root part for this SceneObjectGroup | ||
1210 | // various text fields | ||
1211 | cmd.Parameters.AddWithValue("Text", prim.Text); | ||
1212 | cmd.Parameters.AddWithValue("ColorR", prim.Color.R); | ||
1213 | cmd.Parameters.AddWithValue("ColorG", prim.Color.G); | ||
1214 | cmd.Parameters.AddWithValue("ColorB", prim.Color.B); | ||
1215 | cmd.Parameters.AddWithValue("ColorA", prim.Color.A); | ||
1216 | cmd.Parameters.AddWithValue("Description", prim.Description); | ||
1217 | cmd.Parameters.AddWithValue("SitName", prim.SitName); | ||
1218 | cmd.Parameters.AddWithValue("TouchName", prim.TouchName); | ||
1219 | // permissions | ||
1220 | cmd.Parameters.AddWithValue("ObjectFlags", prim.ObjectFlags); | ||
1221 | cmd.Parameters.AddWithValue("CreatorID", prim.CreatorID.ToString()); | ||
1222 | cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString()); | ||
1223 | cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString()); | ||
1224 | cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString()); | ||
1225 | cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask); | ||
1226 | cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask); | ||
1227 | cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask); | ||
1228 | cmd.Parameters.AddWithValue("EveryoneMask", prim.EveryoneMask); | ||
1229 | cmd.Parameters.AddWithValue("BaseMask", prim.BaseMask); | ||
1230 | // vectors | ||
1231 | cmd.Parameters.AddWithValue("PositionX", (double)prim.OffsetPosition.X); | ||
1232 | cmd.Parameters.AddWithValue("PositionY", (double)prim.OffsetPosition.Y); | ||
1233 | cmd.Parameters.AddWithValue("PositionZ", (double)prim.OffsetPosition.Z); | ||
1234 | cmd.Parameters.AddWithValue("GroupPositionX", (double)prim.GroupPosition.X); | ||
1235 | cmd.Parameters.AddWithValue("GroupPositionY", (double)prim.GroupPosition.Y); | ||
1236 | cmd.Parameters.AddWithValue("GroupPositionZ", (double)prim.GroupPosition.Z); | ||
1237 | cmd.Parameters.AddWithValue("VelocityX", (double)prim.Velocity.X); | ||
1238 | cmd.Parameters.AddWithValue("VelocityY", (double)prim.Velocity.Y); | ||
1239 | cmd.Parameters.AddWithValue("VelocityZ", (double)prim.Velocity.Z); | ||
1240 | cmd.Parameters.AddWithValue("AngularVelocityX", (double)prim.AngularVelocity.X); | ||
1241 | cmd.Parameters.AddWithValue("AngularVelocityY", (double)prim.AngularVelocity.Y); | ||
1242 | cmd.Parameters.AddWithValue("AngularVelocityZ", (double)prim.AngularVelocity.Z); | ||
1243 | cmd.Parameters.AddWithValue("AccelerationX", (double)prim.Acceleration.X); | ||
1244 | cmd.Parameters.AddWithValue("AccelerationY", (double)prim.Acceleration.Y); | ||
1245 | cmd.Parameters.AddWithValue("AccelerationZ", (double)prim.Acceleration.Z); | ||
1246 | // quaternions | ||
1247 | cmd.Parameters.AddWithValue("RotationX", (double)prim.RotationOffset.X); | ||
1248 | cmd.Parameters.AddWithValue("RotationY", (double)prim.RotationOffset.Y); | ||
1249 | cmd.Parameters.AddWithValue("RotationZ", (double)prim.RotationOffset.Z); | ||
1250 | cmd.Parameters.AddWithValue("RotationW", (double)prim.RotationOffset.W); | ||
1251 | |||
1252 | // Sit target | ||
1253 | Vector3 sitTargetPos = prim.SitTargetPositionLL; | ||
1254 | cmd.Parameters.AddWithValue("SitTargetOffsetX", (double)sitTargetPos.X); | ||
1255 | cmd.Parameters.AddWithValue("SitTargetOffsetY", (double)sitTargetPos.Y); | ||
1256 | cmd.Parameters.AddWithValue("SitTargetOffsetZ", (double)sitTargetPos.Z); | ||
1257 | |||
1258 | Quaternion sitTargetOrient = prim.SitTargetOrientationLL; | ||
1259 | cmd.Parameters.AddWithValue("SitTargetOrientW", (double)sitTargetOrient.W); | ||
1260 | cmd.Parameters.AddWithValue("SitTargetOrientX", (double)sitTargetOrient.X); | ||
1261 | cmd.Parameters.AddWithValue("SitTargetOrientY", (double)sitTargetOrient.Y); | ||
1262 | cmd.Parameters.AddWithValue("SitTargetOrientZ", (double)sitTargetOrient.Z); | ||
1263 | |||
1264 | cmd.Parameters.AddWithValue("PayPrice", prim.PayPrice[0]); | ||
1265 | cmd.Parameters.AddWithValue("PayButton1", prim.PayPrice[1]); | ||
1266 | cmd.Parameters.AddWithValue("PayButton2", prim.PayPrice[2]); | ||
1267 | cmd.Parameters.AddWithValue("PayButton3", prim.PayPrice[3]); | ||
1268 | cmd.Parameters.AddWithValue("PayButton4", prim.PayPrice[4]); | ||
1269 | |||
1270 | if ((prim.SoundFlags & 1) != 0) // Looped | ||
1271 | { | ||
1272 | cmd.Parameters.AddWithValue("LoopedSound", prim.Sound.ToString()); | ||
1273 | cmd.Parameters.AddWithValue("LoopedSoundGain", prim.SoundGain); | ||
1274 | } | ||
1275 | else | ||
1276 | { | ||
1277 | cmd.Parameters.AddWithValue("LoopedSound", UUID.Zero); | ||
1278 | cmd.Parameters.AddWithValue("LoopedSoundGain", 0.0f); | ||
1279 | } | ||
1280 | |||
1281 | cmd.Parameters.AddWithValue("TextureAnimation", prim.TextureAnimation); | ||
1282 | cmd.Parameters.AddWithValue("ParticleSystem", prim.ParticleSystem); | ||
1283 | |||
1284 | cmd.Parameters.AddWithValue("OmegaX", (double)prim.RotationalVelocity.X); | ||
1285 | cmd.Parameters.AddWithValue("OmegaY", (double)prim.RotationalVelocity.Y); | ||
1286 | cmd.Parameters.AddWithValue("OmegaZ", (double)prim.RotationalVelocity.Z); | ||
1287 | |||
1288 | cmd.Parameters.AddWithValue("CameraEyeOffsetX", (double)prim.GetCameraEyeOffset().X); | ||
1289 | cmd.Parameters.AddWithValue("CameraEyeOffsetY", (double)prim.GetCameraEyeOffset().Y); | ||
1290 | cmd.Parameters.AddWithValue("CameraEyeOffsetZ", (double)prim.GetCameraEyeOffset().Z); | ||
1291 | |||
1292 | cmd.Parameters.AddWithValue("CameraAtOffsetX", (double)prim.GetCameraAtOffset().X); | ||
1293 | cmd.Parameters.AddWithValue("CameraAtOffsetY", (double)prim.GetCameraAtOffset().Y); | ||
1294 | cmd.Parameters.AddWithValue("CameraAtOffsetZ", (double)prim.GetCameraAtOffset().Z); | ||
1295 | |||
1296 | if (prim.GetForceMouselook()) | ||
1297 | cmd.Parameters.AddWithValue("ForceMouselook", 1); | ||
1298 | else | ||
1299 | cmd.Parameters.AddWithValue("ForceMouselook", 0); | ||
1300 | |||
1301 | cmd.Parameters.AddWithValue("ScriptAccessPin", prim.ScriptAccessPin); | ||
1302 | |||
1303 | if (prim.AllowedDrop) | ||
1304 | cmd.Parameters.AddWithValue("AllowedDrop", 1); | ||
1305 | else | ||
1306 | cmd.Parameters.AddWithValue("AllowedDrop", 0); | ||
1307 | |||
1308 | if (prim.DIE_AT_EDGE) | ||
1309 | cmd.Parameters.AddWithValue("DieAtEdge", 1); | ||
1310 | else | ||
1311 | cmd.Parameters.AddWithValue("DieAtEdge", 0); | ||
1312 | |||
1313 | cmd.Parameters.AddWithValue("SalePrice", prim.SalePrice); | ||
1314 | cmd.Parameters.AddWithValue("SaleType", unchecked((sbyte)(prim.ObjectSaleType))); | ||
1315 | |||
1316 | byte clickAction = prim.ClickAction; | ||
1317 | cmd.Parameters.AddWithValue("ClickAction", unchecked((sbyte)(clickAction))); | ||
1318 | |||
1319 | cmd.Parameters.AddWithValue("Material", unchecked((sbyte)(prim.Material))); | ||
1320 | |||
1321 | cmd.Parameters.AddWithValue("CollisionSound", prim.CollisionSound.ToString()); | ||
1322 | cmd.Parameters.AddWithValue("CollisionSoundVolume", prim.CollisionSoundVolume); | ||
1323 | |||
1324 | if (prim.PassTouches) | ||
1325 | cmd.Parameters.AddWithValue("PassTouches", 1); | ||
1326 | else | ||
1327 | cmd.Parameters.AddWithValue("PassTouches", 0); | ||
1328 | |||
1329 | cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); | ||
1330 | } | ||
1331 | |||
1332 | /// <summary> | ||
1333 | /// | ||
1334 | /// </summary> | ||
1335 | /// <param name="row"></param> | ||
1336 | /// <param name="taskItem"></param> | ||
1337 | private static void FillItemCommand(MySqlCommand cmd, TaskInventoryItem taskItem) | ||
1338 | { | ||
1339 | cmd.Parameters.AddWithValue("itemID", taskItem.ItemID); | ||
1340 | cmd.Parameters.AddWithValue("primID", taskItem.ParentPartID); | ||
1341 | cmd.Parameters.AddWithValue("assetID", taskItem.AssetID); | ||
1342 | cmd.Parameters.AddWithValue("parentFolderID", taskItem.ParentID); | ||
1343 | |||
1344 | cmd.Parameters.AddWithValue("invType", taskItem.InvType); | ||
1345 | cmd.Parameters.AddWithValue("assetType", taskItem.Type); | ||
1346 | |||
1347 | cmd.Parameters.AddWithValue("name", taskItem.Name); | ||
1348 | cmd.Parameters.AddWithValue("description", taskItem.Description); | ||
1349 | cmd.Parameters.AddWithValue("creationDate", taskItem.CreationDate); | ||
1350 | cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorID); | ||
1351 | cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID); | ||
1352 | cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID); | ||
1353 | cmd.Parameters.AddWithValue("groupID", taskItem.GroupID); | ||
1354 | cmd.Parameters.AddWithValue("nextPermissions", taskItem.NextPermissions); | ||
1355 | cmd.Parameters.AddWithValue("currentPermissions", taskItem.CurrentPermissions); | ||
1356 | cmd.Parameters.AddWithValue("basePermissions", taskItem.BasePermissions); | ||
1357 | cmd.Parameters.AddWithValue("everyonePermissions", taskItem.EveryonePermissions); | ||
1358 | cmd.Parameters.AddWithValue("groupPermissions", taskItem.GroupPermissions); | ||
1359 | cmd.Parameters.AddWithValue("flags", taskItem.Flags); | ||
1360 | } | ||
1361 | |||
1362 | /// <summary> | ||
1363 | /// | ||
1364 | /// </summary> | ||
1365 | private static void FillRegionSettingsCommand(MySqlCommand cmd, RegionSettings settings) | ||
1366 | { | ||
1367 | cmd.Parameters.AddWithValue("RegionUUID", settings.RegionUUID.ToString()); | ||
1368 | cmd.Parameters.AddWithValue("BlockTerraform", settings.BlockTerraform); | ||
1369 | cmd.Parameters.AddWithValue("BlockFly", settings.BlockFly); | ||
1370 | cmd.Parameters.AddWithValue("AllowDamage", settings.AllowDamage); | ||
1371 | cmd.Parameters.AddWithValue("RestrictPushing", settings.RestrictPushing); | ||
1372 | cmd.Parameters.AddWithValue("AllowLandResell", settings.AllowLandResell); | ||
1373 | cmd.Parameters.AddWithValue("AllowLandJoinDivide", settings.AllowLandJoinDivide); | ||
1374 | cmd.Parameters.AddWithValue("BlockShowInSearch", settings.BlockShowInSearch); | ||
1375 | cmd.Parameters.AddWithValue("AgentLimit", settings.AgentLimit); | ||
1376 | cmd.Parameters.AddWithValue("ObjectBonus", settings.ObjectBonus); | ||
1377 | cmd.Parameters.AddWithValue("Maturity", settings.Maturity); | ||
1378 | cmd.Parameters.AddWithValue("DisableScripts", settings.DisableScripts); | ||
1379 | cmd.Parameters.AddWithValue("DisableCollisions", settings.DisableCollisions); | ||
1380 | cmd.Parameters.AddWithValue("DisablePhysics", settings.DisablePhysics); | ||
1381 | cmd.Parameters.AddWithValue("TerrainTexture1", settings.TerrainTexture1.ToString()); | ||
1382 | cmd.Parameters.AddWithValue("TerrainTexture2", settings.TerrainTexture2.ToString()); | ||
1383 | cmd.Parameters.AddWithValue("TerrainTexture3", settings.TerrainTexture3.ToString()); | ||
1384 | cmd.Parameters.AddWithValue("TerrainTexture4", settings.TerrainTexture4.ToString()); | ||
1385 | cmd.Parameters.AddWithValue("Elevation1NW", settings.Elevation1NW); | ||
1386 | cmd.Parameters.AddWithValue("Elevation2NW", settings.Elevation2NW); | ||
1387 | cmd.Parameters.AddWithValue("Elevation1NE", settings.Elevation1NE); | ||
1388 | cmd.Parameters.AddWithValue("Elevation2NE", settings.Elevation2NE); | ||
1389 | cmd.Parameters.AddWithValue("Elevation1SE", settings.Elevation1SE); | ||
1390 | cmd.Parameters.AddWithValue("Elevation2SE", settings.Elevation2SE); | ||
1391 | cmd.Parameters.AddWithValue("Elevation1SW", settings.Elevation1SW); | ||
1392 | cmd.Parameters.AddWithValue("Elevation2SW", settings.Elevation2SW); | ||
1393 | cmd.Parameters.AddWithValue("WaterHeight", settings.WaterHeight); | ||
1394 | cmd.Parameters.AddWithValue("TerrainRaiseLimit", settings.TerrainRaiseLimit); | ||
1395 | cmd.Parameters.AddWithValue("TerrainLowerLimit", settings.TerrainLowerLimit); | ||
1396 | cmd.Parameters.AddWithValue("UseEstateSun", settings.UseEstateSun); | ||
1397 | cmd.Parameters.AddWithValue("Sandbox", settings.Sandbox); | ||
1398 | cmd.Parameters.AddWithValue("SunVectorX", settings.SunVector.X); | ||
1399 | cmd.Parameters.AddWithValue("SunVectorY", settings.SunVector.Y); | ||
1400 | cmd.Parameters.AddWithValue("SunVectorZ", settings.SunVector.Z); | ||
1401 | cmd.Parameters.AddWithValue("FixedSun", settings.FixedSun); | ||
1402 | cmd.Parameters.AddWithValue("SunPosition", settings.SunPosition); | ||
1403 | cmd.Parameters.AddWithValue("Covenant", settings.Covenant.ToString()); | ||
1404 | cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime); | ||
1405 | cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID); | ||
1406 | |||
1407 | } | ||
1408 | |||
1409 | /// <summary> | ||
1410 | /// | ||
1411 | /// </summary> | ||
1412 | /// <param name="row"></param> | ||
1413 | /// <param name="land"></param> | ||
1414 | /// <param name="regionUUID"></param> | ||
1415 | private static void FillLandCommand(MySqlCommand cmd, LandData land, UUID regionUUID) | ||
1416 | { | ||
1417 | cmd.Parameters.AddWithValue("UUID", land.GlobalID.ToString()); | ||
1418 | cmd.Parameters.AddWithValue("RegionUUID", regionUUID.ToString()); | ||
1419 | cmd.Parameters.AddWithValue("LocalLandID", land.LocalID); | ||
1420 | |||
1421 | // Bitmap is a byte[512] | ||
1422 | cmd.Parameters.AddWithValue("Bitmap", land.Bitmap); | ||
1423 | |||
1424 | cmd.Parameters.AddWithValue("Name", land.Name); | ||
1425 | cmd.Parameters.AddWithValue("Description", land.Description); | ||
1426 | cmd.Parameters.AddWithValue("OwnerUUID", land.OwnerID.ToString()); | ||
1427 | cmd.Parameters.AddWithValue("IsGroupOwned", land.IsGroupOwned); | ||
1428 | cmd.Parameters.AddWithValue("Area", land.Area); | ||
1429 | cmd.Parameters.AddWithValue("AuctionID", land.AuctionID); //Unemplemented | ||
1430 | cmd.Parameters.AddWithValue("Category", land.Category); //Enum libsecondlife.Parcel.ParcelCategory | ||
1431 | cmd.Parameters.AddWithValue("ClaimDate", land.ClaimDate); | ||
1432 | cmd.Parameters.AddWithValue("ClaimPrice", land.ClaimPrice); | ||
1433 | cmd.Parameters.AddWithValue("GroupUUID", land.GroupID.ToString()); | ||
1434 | cmd.Parameters.AddWithValue("SalePrice", land.SalePrice); | ||
1435 | cmd.Parameters.AddWithValue("LandStatus", land.Status); //Enum. libsecondlife.Parcel.ParcelStatus | ||
1436 | cmd.Parameters.AddWithValue("LandFlags", land.Flags); | ||
1437 | cmd.Parameters.AddWithValue("LandingType", land.LandingType); | ||
1438 | cmd.Parameters.AddWithValue("MediaAutoScale", land.MediaAutoScale); | ||
1439 | cmd.Parameters.AddWithValue("MediaTextureUUID", land.MediaID.ToString()); | ||
1440 | cmd.Parameters.AddWithValue("MediaURL", land.MediaURL); | ||
1441 | cmd.Parameters.AddWithValue("MusicURL", land.MusicURL); | ||
1442 | cmd.Parameters.AddWithValue("PassHours", land.PassHours); | ||
1443 | cmd.Parameters.AddWithValue("PassPrice", land.PassPrice); | ||
1444 | cmd.Parameters.AddWithValue("SnapshotUUID", land.SnapshotID.ToString()); | ||
1445 | cmd.Parameters.AddWithValue("UserLocationX", land.UserLocation.X); | ||
1446 | cmd.Parameters.AddWithValue("UserLocationY", land.UserLocation.Y); | ||
1447 | cmd.Parameters.AddWithValue("UserLocationZ", land.UserLocation.Z); | ||
1448 | cmd.Parameters.AddWithValue("UserLookAtX", land.UserLookAt.X); | ||
1449 | cmd.Parameters.AddWithValue("UserLookAtY", land.UserLookAt.Y); | ||
1450 | cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z); | ||
1451 | cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID); | ||
1452 | cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime); | ||
1453 | cmd.Parameters.AddWithValue("Dwell", land.Dwell); | ||
1454 | } | ||
1455 | 234 | ||
1456 | /// <summary> | 235 | return true; |
1457 | /// | ||
1458 | /// </summary> | ||
1459 | /// <param name="row"></param> | ||
1460 | /// <param name="entry"></param> | ||
1461 | /// <param name="parcelID"></param> | ||
1462 | private static void FillLandAccessCommand(MySqlCommand cmd, ParcelManager.ParcelAccessEntry entry, UUID parcelID) | ||
1463 | { | ||
1464 | cmd.Parameters.AddWithValue("LandUUID", parcelID.ToString()); | ||
1465 | cmd.Parameters.AddWithValue("AccessUUID", entry.AgentID.ToString()); | ||
1466 | cmd.Parameters.AddWithValue("Flags", entry.Flags); | ||
1467 | } | 236 | } |
1468 | 237 | ||
1469 | /// <summary> | 238 | public bool SetDataItem(UUID regionID, string item, string value) |
1470 | /// | ||
1471 | /// </summary> | ||
1472 | /// <param name="row"></param> | ||
1473 | /// <returns></returns> | ||
1474 | private PrimitiveBaseShape BuildShape(IDataReader row) | ||
1475 | { | 239 | { |
1476 | PrimitiveBaseShape s = new PrimitiveBaseShape(); | 240 | MySqlCommand cmd = new MySqlCommand("update `" + m_Realm + |
1477 | s.Scale = new Vector3( | 241 | "` set `" + item + "` = ?" + item + " where uuid = ?UUID"); |
1478 | Convert.ToSingle(row["ScaleX"]), | ||
1479 | Convert.ToSingle(row["ScaleY"]), | ||
1480 | Convert.ToSingle(row["ScaleZ"]) | ||
1481 | ); | ||
1482 | // paths | ||
1483 | s.PCode = Convert.ToByte(row["PCode"]); | ||
1484 | s.PathBegin = Convert.ToUInt16(row["PathBegin"]); | ||
1485 | s.PathEnd = Convert.ToUInt16(row["PathEnd"]); | ||
1486 | s.PathScaleX = Convert.ToByte(row["PathScaleX"]); | ||
1487 | s.PathScaleY = Convert.ToByte(row["PathScaleY"]); | ||
1488 | s.PathShearX = Convert.ToByte(row["PathShearX"]); | ||
1489 | s.PathShearY = Convert.ToByte(row["PathShearY"]); | ||
1490 | s.PathSkew = Convert.ToSByte(row["PathSkew"]); | ||
1491 | s.PathCurve = Convert.ToByte(row["PathCurve"]); | ||
1492 | s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]); | ||
1493 | s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]); | ||
1494 | s.PathTaperX = Convert.ToSByte(row["PathTaperX"]); | ||
1495 | s.PathTaperY = Convert.ToSByte(row["PathTaperY"]); | ||
1496 | s.PathTwist = Convert.ToSByte(row["PathTwist"]); | ||
1497 | s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]); | ||
1498 | // profile | ||
1499 | s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]); | ||
1500 | s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); | ||
1501 | s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); | ||
1502 | s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); | ||
1503 | byte[] textureEntry = (byte[]) row["Texture"]; | ||
1504 | s.TextureEntry = textureEntry; | ||
1505 | 242 | ||
1506 | s.ExtraParams = (byte[]) row["ExtraParams"]; | ||
1507 | 243 | ||
1508 | s.State = Convert.ToByte(row["State"]); | 244 | cmd.Parameters.AddWithValue("?"+item, value); |
245 | cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); | ||
1509 | 246 | ||
1510 | return s; | 247 | if (ExecuteNonQuery(cmd) > 0) |
1511 | } | 248 | return true; |
1512 | 249 | ||
1513 | /// <summary> | 250 | return false; |
1514 | /// | ||
1515 | /// </summary> | ||
1516 | /// <param name="row"></param> | ||
1517 | /// <param name="prim"></param> | ||
1518 | private void FillShapeCommand(MySqlCommand cmd, SceneObjectPart prim) | ||
1519 | { | ||
1520 | PrimitiveBaseShape s = prim.Shape; | ||
1521 | cmd.Parameters.AddWithValue("UUID", prim.UUID.ToString()); | ||
1522 | // shape is an enum | ||
1523 | cmd.Parameters.AddWithValue("Shape", 0); | ||
1524 | // vectors | ||
1525 | cmd.Parameters.AddWithValue("ScaleX", (double)s.Scale.X); | ||
1526 | cmd.Parameters.AddWithValue("ScaleY", (double)s.Scale.Y); | ||
1527 | cmd.Parameters.AddWithValue("ScaleZ", (double)s.Scale.Z); | ||
1528 | // paths | ||
1529 | cmd.Parameters.AddWithValue("PCode", s.PCode); | ||
1530 | cmd.Parameters.AddWithValue("PathBegin", s.PathBegin); | ||
1531 | cmd.Parameters.AddWithValue("PathEnd", s.PathEnd); | ||
1532 | cmd.Parameters.AddWithValue("PathScaleX", s.PathScaleX); | ||
1533 | cmd.Parameters.AddWithValue("PathScaleY", s.PathScaleY); | ||
1534 | cmd.Parameters.AddWithValue("PathShearX", s.PathShearX); | ||
1535 | cmd.Parameters.AddWithValue("PathShearY", s.PathShearY); | ||
1536 | cmd.Parameters.AddWithValue("PathSkew", s.PathSkew); | ||
1537 | cmd.Parameters.AddWithValue("PathCurve", s.PathCurve); | ||
1538 | cmd.Parameters.AddWithValue("PathRadiusOffset", s.PathRadiusOffset); | ||
1539 | cmd.Parameters.AddWithValue("PathRevolutions", s.PathRevolutions); | ||
1540 | cmd.Parameters.AddWithValue("PathTaperX", s.PathTaperX); | ||
1541 | cmd.Parameters.AddWithValue("PathTaperY", s.PathTaperY); | ||
1542 | cmd.Parameters.AddWithValue("PathTwist", s.PathTwist); | ||
1543 | cmd.Parameters.AddWithValue("PathTwistBegin", s.PathTwistBegin); | ||
1544 | // profile | ||
1545 | cmd.Parameters.AddWithValue("ProfileBegin", s.ProfileBegin); | ||
1546 | cmd.Parameters.AddWithValue("ProfileEnd", s.ProfileEnd); | ||
1547 | cmd.Parameters.AddWithValue("ProfileCurve", s.ProfileCurve); | ||
1548 | cmd.Parameters.AddWithValue("ProfileHollow", s.ProfileHollow); | ||
1549 | cmd.Parameters.AddWithValue("Texture", s.TextureEntry); | ||
1550 | cmd.Parameters.AddWithValue("ExtraParams", s.ExtraParams); | ||
1551 | cmd.Parameters.AddWithValue("State", s.State); | ||
1552 | } | 251 | } |
1553 | 252 | ||
1554 | public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items) | 253 | public bool Delete(UUID regionID) |
1555 | { | 254 | { |
1556 | lock (m_Connection) | 255 | MySqlCommand cmd = new MySqlCommand("delete from `" + m_Realm + |
1557 | { | 256 | "` where uuid = ?UUID"); |
1558 | RemoveItems(primID); | ||
1559 | 257 | ||
1560 | MySqlCommand cmd = m_Connection.CreateCommand(); | ||
1561 | 258 | ||
1562 | if (items.Count == 0) | 259 | cmd.Parameters.AddWithValue("?UUID", regionID.ToString()); |
1563 | return; | ||
1564 | 260 | ||
1565 | cmd.CommandText = "insert into primitems ("+ | 261 | if (ExecuteNonQuery(cmd) > 0) |
1566 | "invType, assetType, name, "+ | 262 | return true; |
1567 | "description, creationDate, nextPermissions, "+ | ||
1568 | "currentPermissions, basePermissions, "+ | ||
1569 | "everyonePermissions, groupPermissions, "+ | ||
1570 | "flags, itemID, primID, assetID, "+ | ||
1571 | "parentFolderID, creatorID, ownerID, "+ | ||
1572 | "groupID, lastOwnerID) values (?invType, "+ | ||
1573 | "?assetType, ?name, ?description, "+ | ||
1574 | "?creationDate, ?nextPermissions, "+ | ||
1575 | "?currentPermissions, ?basePermissions, "+ | ||
1576 | "?everyonePermissions, ?groupPermissions, "+ | ||
1577 | "?flags, ?itemID, ?primID, ?assetID, "+ | ||
1578 | "?parentFolderID, ?creatorID, ?ownerID, "+ | ||
1579 | "?groupID, ?lastOwnerID)"; | ||
1580 | 263 | ||
1581 | foreach (TaskInventoryItem item in items) | 264 | return false; |
1582 | { | ||
1583 | cmd.Parameters.Clear(); | ||
1584 | |||
1585 | FillItemCommand(cmd, item); | ||
1586 | |||
1587 | ExecuteNonQuery(cmd); | ||
1588 | } | ||
1589 | |||
1590 | cmd.Dispose(); | ||
1591 | } | ||
1592 | } | 265 | } |
1593 | } | 266 | } |
1594 | } | 267 | } |