aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/MySQL/MySQLLegacyRegionData.cs')
-rw-r--r--OpenSim/Data/MySQL/MySQLLegacyRegionData.cs1594
1 files changed, 1594 insertions, 0 deletions
diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
new file mode 100644
index 0000000..4a16a70
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs
@@ -0,0 +1,1594 @@
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 OpenSimulator 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
28using System;
29using System.Collections.Generic;
30using System.Data;
31using System.Drawing;
32using System.IO;
33using System.Reflection;
34using System.Threading;
35using log4net;
36using MySql.Data.MySqlClient;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41
42namespace OpenSim.Data.MySQL
43{
44 /// <summary>
45 /// A MySQL Interface for the Region Server
46 /// </summary>
47 public class MySQLDataStore : IRegionDataStore
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private string m_ConnectionString;
52
53 private MySqlConnection m_Connection = null;
54
55 public void Initialise(string connectionString)
56 {
57 m_ConnectionString = connectionString;
58
59 m_Connection = new MySqlConnection(m_ConnectionString);
60
61 m_Connection.Open();
62
63 // Apply new Migrations
64 //
65 Assembly assem = GetType().Assembly;
66 Migration m = new Migration(m_Connection, assem, "RegionStore");
67 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 }
78
79 private IDataReader ExecuteReader(MySqlCommand c)
80 {
81 IDataReader r = null;
82 bool errorSeen = false;
83
84 while (true)
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
99 if (!errorSeen)
100 {
101 errorSeen = true;
102 continue;
103 }
104 throw;
105 }
106
107 break;
108 }
109
110 return r;
111 }
112
113 private void ExecuteNonQuery(MySqlCommand c)
114 {
115 bool errorSeen = false;
116
117 while (true)
118 {
119 try
120 {
121 c.ExecuteNonQuery();
122 }
123 catch (Exception)
124 {
125 Thread.Sleep(500);
126
127 m_Connection.Close();
128 m_Connection = (MySqlConnection) ((ICloneable)m_Connection).Clone();
129 m_Connection.Open();
130 c.Connection = m_Connection;
131
132 if (!errorSeen)
133 {
134 errorSeen = true;
135 continue;
136 }
137 throw;
138 }
139
140 break;
141 }
142 }
143
144 public void Dispose() {}
145
146 public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
147 {
148 uint flags = obj.RootPart.GetEffectiveObjectFlags();
149
150 // Eligibility check
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
161 foreach (SceneObjectPart prim in obj.Children.Values)
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
239 cmd.CommandText = "replace into primshapes ("+
240 "UUID, Shape, ScaleX, ScaleY, "+
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
261 FillShapeCommand(cmd, prim);
262
263 ExecuteNonQuery(cmd);
264 }
265 cmd.Dispose();
266 }
267 }
268
269 public void RemoveObject(UUID obj, UUID regionUUID)
270 {
271 // Formerly, this used to check the region UUID.
272 // That makes no sense, as we remove the contents of a prim
273 // unconditionally, but the prim dependent on the region ID.
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
286 cmd.Parameters.AddWithValue("UUID", obj.ToString());
287
288 List<UUID> uuids = new List<UUID>();
289
290 IDataReader reader = ExecuteReader(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 }
319
320 /// <summary>
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 {
327 lock (m_Connection)
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
336 ExecuteNonQuery(cmd);
337 cmd.Dispose();
338 }
339 }
340
341
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 {
351 string sql = "delete from primshapes where ";
352 MySqlCommand cmd = m_Connection.CreateCommand();
353
354 for (int i = 0; i < uuids.Count; i++)
355 {
356 if ((i + 1) == uuids.Count)
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
367 for (int i = 0; i < uuids.Count; i++)
368 {
369 cmd.Parameters.AddWithValue("UUID" + i, uuids[i].ToString());
370 }
371
372 ExecuteNonQuery(cmd);
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 {
391 if ((i + 1) == uuids.Count)
392 {// end of the list
393 sql += "(PrimID = ?PrimID" + i + ")";
394 }
395 else
396 {
397 sql += "(PrimID = ?PrimID" + i + ") or ";
398 }
399 }
400 cmd.CommandText = sql;
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
479 if (link != 0)
480 prim.LinkNum = link;
481 }
482 }
483 }
484 finally
485 {
486 reader.Close();
487 }
488
489 if (grp != null)
490 objects[grp.UUID] = grp;
491 cmd.Dispose();
492 }
493
494 // Instead of attempting to LoadItems on every prim,
495 // most of which probably have no items... get a
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
543 cmd.CommandText = "select * from primitems where "+
544 "PrimID = ?PrimID";
545
546 cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString());
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 }
572
573 public void StoreTerrain(double[,] ter, UUID regionID)
574 {
575 m_log.Info("[REGION DB]: Storing terrain");
576
577 lock (m_Connection)
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
591 cmd.Parameters.AddWithValue("Heightfield",
592 SerializeTerrain(ter));
593
594 ExecuteNonQuery(cmd);
595 cmd.Dispose();
596 }
597 }
598
599 public double[,] LoadTerrain(UUID regionID)
600 {
601 double[,] terrain = null;
602
603 lock (m_Connection)
604 {
605 MySqlCommand cmd = m_Connection.CreateCommand();
606 cmd.CommandText = "select RegionUUID, Revision, Heightfield " +
607 "from terrain where RegionUUID = ?RegionUUID "+
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
620 MemoryStream mstr = new MemoryStream((byte[]) reader["Heightfield"]);
621 int rev = 0;
622
623 BinaryReader br = new BinaryReader(mstr);
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 }
642
643 return terrain;
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
654 cmd.Parameters.AddWithValue("UUID", globalID.ToString());
655
656 ExecuteNonQuery(cmd);
657 cmd.Dispose();
658 }
659 }
660
661 public void StoreLandObject(ILandObject parcel)
662 {
663 lock (m_Connection)
664 {
665 MySqlCommand cmd = m_Connection.CreateCommand();
666
667 cmd.CommandText = "replace into land (UUID, RegionUUID, " +
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
690 ExecuteNonQuery(cmd);
691
692 cmd.CommandText = "delete from landaccesslist where " +
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 {
705 FillLandAccessCommand(cmd, entry, parcel.landData.GlobalID);
706 ExecuteNonQuery(cmd);
707 cmd.Parameters.Clear();
708 }
709 cmd.Dispose();
710 }
711 }
712
713 public RegionSettings LoadRegionSettings(UUID regionUUID)
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
1456 /// <summary>
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 }
1468
1469 /// <summary>
1470 ///
1471 /// </summary>
1472 /// <param name="row"></param>
1473 /// <returns></returns>
1474 private PrimitiveBaseShape BuildShape(IDataReader row)
1475 {
1476 PrimitiveBaseShape s = new PrimitiveBaseShape();
1477 s.Scale = new Vector3(
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
1506 s.ExtraParams = (byte[]) row["ExtraParams"];
1507
1508 s.State = Convert.ToByte(row["State"]);
1509
1510 return s;
1511 }
1512
1513 /// <summary>
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 }
1553
1554 public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
1555 {
1556 lock (m_Connection)
1557 {
1558 RemoveItems(primID);
1559
1560 MySqlCommand cmd = m_Connection.CreateCommand();
1561
1562 if (items.Count == 0)
1563 return;
1564
1565 cmd.CommandText = "insert into primitems ("+
1566 "invType, assetType, name, "+
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
1581 foreach (TaskInventoryItem item in items)
1582 {
1583 cmd.Parameters.Clear();
1584
1585 FillItemCommand(cmd, item);
1586
1587 ExecuteNonQuery(cmd);
1588 }
1589
1590 cmd.Dispose();
1591 }
1592 }
1593 }
1594}