aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/IRegionData.cs2
-rw-r--r--OpenSim/Data/MySQL/MySQLLegacyRegionData.cs1594
-rw-r--r--OpenSim/Data/MySQL/MySQLRegionData.cs1615
-rw-r--r--OpenSim/Data/MySQL/Resources/003_GridStore.sql7
-rw-r--r--OpenSim/Data/NHibernate/NHibernateRegionData.cs32
-rw-r--r--OpenSim/Data/Null/NullRegionData.cs136
-rw-r--r--OpenSim/Data/SQLite/SQLiteRegionData.cs3
-rw-r--r--OpenSim/Data/Tests/BasicRegionTest.cs6
-rw-r--r--OpenSim/Framework/Servers/BaseGetAssetStreamHandler.cs205
-rw-r--r--OpenSim/Framework/Servers/PostAssetStreamHandler.cs72
-rw-r--r--OpenSim/Framework/Servers/Tests/GetAssetStreamHandlerTests.cs135
-rw-r--r--OpenSim/Framework/Servers/VersionInfo.cs2
-rw-r--r--OpenSim/Grid/AssetServer/Main.cs146
-rw-r--r--OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs63
-rw-r--r--OpenSim/Grid/InventoryServer/AuthedSessionCache.cs133
-rw-r--r--OpenSim/Grid/InventoryServer/GridInventoryService.cs256
-rw-r--r--OpenSim/Grid/InventoryServer/InventoryServiceBase.cs519
-rw-r--r--OpenSim/Grid/InventoryServer/Main.cs182
-rw-r--r--OpenSim/Region/Examples/SimpleModule/ComplexObject.cs4
-rw-r--r--OpenSim/Region/Framework/Interfaces/IVoiceModule.cs (renamed from OpenSim/Framework/Servers/GetAssetStreamHandler.cs)38
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs110
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs265
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs53
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs3
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs55
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs102
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs42
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs3
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs132
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs5
-rw-r--r--OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs36
-rw-r--r--OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs12
-rw-r--r--OpenSim/Tests/Common/Setup/GetAssetStreamHandlerTestHelpers.cs122
37 files changed, 2385 insertions, 3741 deletions
diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs
index 988bdf8..71dd525 100644
--- a/OpenSim/Data/IRegionData.cs
+++ b/OpenSim/Data/IRegionData.cs
@@ -48,7 +48,7 @@ namespace OpenSim.Data
48 public interface IRegionData 48 public interface IRegionData
49 { 49 {
50 RegionData Get(UUID regionID, UUID ScopeID); 50 RegionData Get(UUID regionID, UUID ScopeID);
51 RegionData Get(string regionName, UUID ScopeID); 51 List<RegionData> Get(string regionName, UUID ScopeID);
52 RegionData Get(int x, int y, UUID ScopeID); 52 RegionData Get(int x, int y, UUID ScopeID);
53 List<RegionData> Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID); 53 List<RegionData> Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID);
54 54
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}
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
28using System; 28using System;
29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Data; 31using System.Data;
31using System.Drawing;
32using System.IO;
33using System.Reflection;
34using System.Threading;
35using log4net;
36using MySql.Data.MySqlClient;
37using OpenMetaverse; 32using OpenMetaverse;
38using OpenSim.Framework; 33using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces; 34using MySql.Data.MySqlClient;
40using OpenSim.Region.Framework.Scenes;
41 35
42namespace OpenSim.Data.MySQL 36namespace 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}
diff --git a/OpenSim/Data/MySQL/Resources/003_GridStore.sql b/OpenSim/Data/MySQL/Resources/003_GridStore.sql
new file mode 100644
index 0000000..bc3fe7d
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/003_GridStore.sql
@@ -0,0 +1,7 @@
1BEGIN;
2
3ALTER TABLE regions add column ScopeID char(36) not null default '00000000-0000-0000-0000-000000000000';
4
5create index ScopeID on regions(ScopeID);
6
7COMMIT;
diff --git a/OpenSim/Data/NHibernate/NHibernateRegionData.cs b/OpenSim/Data/NHibernate/NHibernateRegionData.cs
index 26ec500..673ca6f 100644
--- a/OpenSim/Data/NHibernate/NHibernateRegionData.cs
+++ b/OpenSim/Data/NHibernate/NHibernateRegionData.cs
@@ -178,25 +178,38 @@ namespace OpenSim.Data.NHibernate
178 178
179 private SceneObjectGroup LoadObject(UUID uuid, UUID region) 179 private SceneObjectGroup LoadObject(UUID uuid, UUID region)
180 { 180 {
181 SceneObjectGroup group = new SceneObjectGroup();
182
183 ICriteria criteria = manager.GetSession().CreateCriteria(typeof(SceneObjectPart)); 181 ICriteria criteria = manager.GetSession().CreateCriteria(typeof(SceneObjectPart));
184 criteria.Add(Expression.Eq("RegionID", region)); 182 criteria.Add(Expression.Eq("RegionID", region));
185 criteria.Add(Expression.Eq("ParentUUID", uuid)); 183 criteria.Add(Expression.Eq("ParentUUID", uuid));
186 criteria.AddOrder(Order.Asc("ParentID")); 184 criteria.AddOrder(Order.Asc("ParentID"));
187 185
188 foreach (SceneObjectPart p in criteria.List()) 186 IList<SceneObjectPart> parts = criteria.List<SceneObjectPart>();
187
188 SceneObjectGroup group = null;
189
190 // Find the root part
191 for (int i = 0; i < parts.Count; i++)
189 { 192 {
190 // root part 193 if (parts[i].UUID == uuid)
191 if (p.UUID == uuid)
192 { 194 {
193 group.SetRootPart(p); 195 group = new SceneObjectGroup(parts[i]);
196 break;
194 } 197 }
195 else 198 }
199
200 // Add the children parts
201 if (group != null)
202 {
203 for (int i = 0; i < parts.Count; i++)
196 { 204 {
197 group.AddPart(p); 205 if (parts[i].UUID != uuid)
206 group.AddPart(parts[i]);
198 } 207 }
199 } 208 }
209 else
210 {
211 m_log.Error("[NHIBERNATE]: LoadObject() Attempted to load a SceneObjectGroup with no root SceneObjectPart ");
212 }
200 213
201 return group; 214 return group;
202 } 215 }
@@ -237,8 +250,7 @@ namespace OpenSim.Data.NHibernate
237 // root part 250 // root part
238 if (p.UUID == p.ParentUUID) 251 if (p.UUID == p.ParentUUID)
239 { 252 {
240 SceneObjectGroup group = new SceneObjectGroup(); 253 SceneObjectGroup group = new SceneObjectGroup(p);
241 group.SetRootPart(p);
242 SOG.Add(p.ParentUUID, group); 254 SOG.Add(p.ParentUUID, group);
243 } 255 }
244 else 256 else
diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs
new file mode 100644
index 0000000..588b8ac
--- /dev/null
+++ b/OpenSim/Data/Null/NullRegionData.cs
@@ -0,0 +1,136 @@
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;
30using System.Collections.Generic;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Data;
34
35namespace OpenSim.Data.Null
36{
37 public class NullRegionData : IRegionData
38 {
39 Dictionary<UUID, RegionData> m_regionData = new Dictionary<UUID, RegionData>();
40
41 public NullRegionData(string connectionString, string realm)
42 {
43 }
44
45 public List<RegionData> Get(string regionName, UUID scopeID)
46 {
47 List<RegionData> ret = new List<RegionData>();
48
49 foreach(RegionData r in m_regionData.Values)
50 {
51 if (regionName.Contains("%"))
52 {
53 if (r.RegionName.Contains(regionName.Replace("%", "")))
54 ret.Add(r);
55 }
56 else
57 {
58 if (r.RegionName == regionName)
59 ret.Add(r);
60 }
61 }
62
63 if (ret.Count > 0)
64 return ret;
65
66 return null;
67 }
68
69 public RegionData Get(int posX, int posY, UUID scopeID)
70 {
71 List<RegionData> ret = new List<RegionData>();
72
73 foreach(RegionData r in m_regionData.Values)
74 {
75 if (r.posX == posX && r.posY == posY)
76 ret.Add(r);
77 }
78
79 if (ret.Count > 0)
80 return ret[0];
81
82 return null;
83 }
84
85 public RegionData Get(UUID regionID, UUID scopeID)
86 {
87 if (m_regionData.ContainsKey(regionID))
88 return m_regionData[regionID];
89
90 return null;
91 }
92
93 public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
94 {
95 List<RegionData> ret = new List<RegionData>();
96
97 foreach(RegionData r in m_regionData.Values)
98 {
99 if (r.posX >= startX && r.posX <= endX && r.posY >= startY && r.posY <= endY)
100 ret.Add(r);
101 }
102
103 if (ret.Count > 0)
104 return ret;
105
106 return null;
107 }
108
109 public bool Store(RegionData data)
110 {
111 m_regionData[data.RegionID] = data;
112
113 return true;
114 }
115
116 public bool SetDataItem(UUID regionID, string item, string value)
117 {
118 if (!m_regionData.ContainsKey(regionID))
119 return false;
120
121 m_regionData[regionID].Data[item] = value;
122
123 return true;
124 }
125
126 public bool Delete(UUID regionID)
127 {
128 if (!m_regionData.ContainsKey(regionID))
129 return false;
130
131 m_regionData.Remove(regionID);
132
133 return true;
134 }
135 }
136}
diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs
index 0259ac5..ea076fe 100644
--- a/OpenSim/Data/SQLite/SQLiteRegionData.cs
+++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs
@@ -416,7 +416,6 @@ namespace OpenSim.Data.SQLite
416 416
417 if (uuid == objID) //is new SceneObjectGroup ? 417 if (uuid == objID) //is new SceneObjectGroup ?
418 { 418 {
419 SceneObjectGroup group = new SceneObjectGroup();
420 prim = buildPrim(primRow); 419 prim = buildPrim(primRow);
421 DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); 420 DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
422 if (shapeRow != null) 421 if (shapeRow != null)
@@ -430,7 +429,7 @@ namespace OpenSim.Data.SQLite
430 prim.Shape = PrimitiveBaseShape.Default; 429 prim.Shape = PrimitiveBaseShape.Default;
431 } 430 }
432 431
433 group.SetRootPart(prim); 432 SceneObjectGroup group = new SceneObjectGroup(prim);
434 createdObjects.Add(group.UUID, group); 433 createdObjects.Add(group.UUID, group);
435 retvals.Add(group); 434 retvals.Add(group);
436 LoadItems(prim); 435 LoadItems(prim);
diff --git a/OpenSim/Data/Tests/BasicRegionTest.cs b/OpenSim/Data/Tests/BasicRegionTest.cs
index 8474921..c66ab7c 100644
--- a/OpenSim/Data/Tests/BasicRegionTest.cs
+++ b/OpenSim/Data/Tests/BasicRegionTest.cs
@@ -322,9 +322,8 @@ namespace OpenSim.Data.Tests
322 // This is necessary or object will not be inserted in DB 322 // This is necessary or object will not be inserted in DB
323 sop.ObjectFlags = 0; 323 sop.ObjectFlags = 0;
324 324
325 SceneObjectGroup sog = new SceneObjectGroup(); 325 SceneObjectGroup sog = new SceneObjectGroup(sop);
326 sog.SetScene(scene); // Reguired by nhibernate database module. 326 sog.SetScene(scene); // Reguired by nhibernate database module.
327 sog.SetRootPart(sop);
328 327
329 // Inserts group in DB 328 // Inserts group in DB
330 db.StoreObject(sog,region3); 329 db.StoreObject(sog,region3);
@@ -1003,9 +1002,8 @@ namespace OpenSim.Data.Tests
1003 sop.UUID = uuid; 1002 sop.UUID = uuid;
1004 sop.Shape = PrimitiveBaseShape.Default; 1003 sop.Shape = PrimitiveBaseShape.Default;
1005 1004
1006 SceneObjectGroup sog = new SceneObjectGroup(); 1005 SceneObjectGroup sog = new SceneObjectGroup(sop);
1007 sog.SetScene(scene); 1006 sog.SetScene(scene);
1008 sog.SetRootPart(sop);
1009 1007
1010 return sog; 1008 return sog;
1011 } 1009 }
diff --git a/OpenSim/Framework/Servers/BaseGetAssetStreamHandler.cs b/OpenSim/Framework/Servers/BaseGetAssetStreamHandler.cs
deleted file mode 100644
index 8372ae7..0000000
--- a/OpenSim/Framework/Servers/BaseGetAssetStreamHandler.cs
+++ /dev/null
@@ -1,205 +0,0 @@
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.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34using System.Text.RegularExpressions;
35using System.Xml;
36using System.Xml.Serialization;
37using log4net;
38using OpenMetaverse;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Framework.Statistics;
41
42namespace OpenSim.Framework.Servers
43{
44 public abstract class BaseGetAssetStreamHandler : BaseStreamHandler
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 protected BaseGetAssetStreamHandler(string httpMethod, string path) : base(httpMethod, path)
49 {
50 }
51
52 protected abstract AssetBase GetAsset(UUID assetID);
53
54 public override byte[] Handle(string path, Stream request,
55 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
56 {
57 byte[] result = new byte[] { };
58
59 string[] p = SplitParams(path);
60
61 if (p.Length > 0)
62 {
63 UUID assetID;
64
65 if (!UUID.TryParse(p[0], out assetID))
66 {
67 m_log.DebugFormat(
68 "[REST]: GET:/asset ignoring request with malformed UUID {0}", p[0]);
69 return result;
70 }
71
72 if (StatsManager.AssetStats != null)
73 {
74 StatsManager.AssetStats.AddRequest();
75 }
76
77 AssetBase asset = GetAsset(assetID);
78
79 if (asset != null)
80 {
81 if (p.Length > 1 && p[1] == "data")
82 {
83 httpResponse.StatusCode = (int)HttpStatusCode.OK;
84 httpResponse.ContentType = SLAssetTypeToContentType(asset.Type);
85 result = asset.Data;
86 }
87 else
88 {
89 result = GetXml(asset);
90 }
91 }
92 else
93 {
94 m_log.DebugFormat("[REST]: GET:/asset failed to find {0}", assetID);
95
96 httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
97
98 if (StatsManager.AssetStats != null)
99 {
100 StatsManager.AssetStats.AddNotFoundRequest();
101 }
102 }
103 }
104
105 return result;
106 }
107
108 public static byte[] GetXml(AssetBase asset)
109 {
110 byte[] result;
111 XmlSerializer xs = new XmlSerializer(typeof(AssetBase));
112 MemoryStream ms = new MemoryStream();
113 XmlTextWriter xw = new XmlTextWriter(ms, Encoding.UTF8);
114 xw.Formatting = Formatting.Indented;
115 xs.Serialize(xw, asset);
116 xw.Flush();
117
118 ms.Seek(0, SeekOrigin.Begin);
119 //StreamReader sr = new StreamReader(ms);
120
121 result = ms.GetBuffer();
122
123 Array.Resize<byte>(ref result, (int)ms.Length);
124 return result;
125 }
126
127 public string ProcessAssetDataString(string data)
128 {
129 Regex regex = new Regex("(creator_id|owner_id)\\s+(\\S+)");
130
131 // IUserService userService = null;
132
133 data = regex.Replace(data, delegate(Match m)
134 {
135 string result = String.Empty;
136
137// string key = m.Groups[1].Captures[0].Value;
138//
139// string value = m.Groups[2].Captures[0].Value;
140//
141// Guid userUri;
142//
143// switch (key)
144// {
145// case "creator_id":
146// userUri = new Guid(value);
147// // result = "creator_url " + userService(userService, userUri);
148// break;
149//
150// case "owner_id":
151// userUri = new Guid(value);
152// // result = "owner_url " + ResolveUserUri(userService, userUri);
153// break;
154// }
155
156 return result;
157 });
158
159 return data;
160 }
161
162 private string SLAssetTypeToContentType(int assetType)
163 {
164 switch (assetType)
165 {
166 case 0:
167 return "image/jp2";
168 case 1:
169 return "application/ogg";
170 case 2:
171 return "application/x-metaverse-callingcard";
172 case 3:
173 return "application/x-metaverse-landmark";
174 case 5:
175 return "application/x-metaverse-clothing";
176 case 6:
177 return "application/x-metaverse-primitive";
178 case 7:
179 return "application/x-metaverse-notecard";
180 case 8:
181 return "application/x-metaverse-folder";
182 case 10:
183 return "application/x-metaverse-lsl";
184 case 11:
185 return "application/x-metaverse-lso";
186 case 12:
187 return "image/tga";
188 case 13:
189 return "application/x-metaverse-bodypart";
190 case 17:
191 return "audio/x-wav";
192 case 19:
193 return "image/jpeg";
194 case 20:
195 return "application/x-metaverse-animation";
196 case 21:
197 return "application/x-metaverse-gesture";
198 case 22:
199 return "application/x-metaverse-simstate";
200 default:
201 return "application/octet-stream";
202 }
203 }
204 }
205}
diff --git a/OpenSim/Framework/Servers/PostAssetStreamHandler.cs b/OpenSim/Framework/Servers/PostAssetStreamHandler.cs
deleted file mode 100644
index 8bf406c..0000000
--- a/OpenSim/Framework/Servers/PostAssetStreamHandler.cs
+++ /dev/null
@@ -1,72 +0,0 @@
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.IO;
29using System.Reflection;
30using System.Xml.Serialization;
31using log4net;
32using OpenMetaverse;
33using OpenSim.Data;
34using OpenSim.Framework;
35using OpenSim.Framework.Servers.HttpServer;
36
37namespace OpenSim.Framework.Servers
38{
39 public class PostAssetStreamHandler : BaseStreamHandler
40 {
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42
43 // private OpenAsset_Main m_assetManager;
44 private IAssetDataPlugin m_assetProvider;
45
46 public override byte[] Handle(string path, Stream request,
47 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
48 {
49 string param = GetParam(path);
50
51 UUID assetId;
52 if (param.Length > 0)
53 UUID.TryParse(param, out assetId);
54 // byte[] txBuffer = new byte[4096];
55
56 XmlSerializer xs = new XmlSerializer(typeof (AssetBase));
57 AssetBase asset = (AssetBase) xs.Deserialize(request);
58
59 m_log.InfoFormat("[REST]: Creating asset {0}", asset.FullID);
60 m_assetProvider.StoreAsset(asset);
61
62 return new byte[] {};
63 }
64
65 public PostAssetStreamHandler(IAssetDataPlugin assetProvider)
66 : base("POST", "/assets")
67 {
68 // m_assetManager = assetManager;
69 m_assetProvider = assetProvider;
70 }
71 }
72}
diff --git a/OpenSim/Framework/Servers/Tests/GetAssetStreamHandlerTests.cs b/OpenSim/Framework/Servers/Tests/GetAssetStreamHandlerTests.cs
deleted file mode 100644
index be3f518..0000000
--- a/OpenSim/Framework/Servers/Tests/GetAssetStreamHandlerTests.cs
+++ /dev/null
@@ -1,135 +0,0 @@
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.Net;
31using System.Text;
32using HttpServer;
33using NUnit.Framework;
34using OpenSim.Data;
35using OpenSim.Framework.Servers.HttpServer;
36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38using OpenSim.Tests.Common.Setup;
39
40namespace OpenSim.Framework.Servers.Tests
41{
42 [TestFixture]
43 public class GetAssetStreamHandlerTests
44 {
45 private const string ASSETS_PATH = "/assets";
46
47 [Test]
48 public void TestConstructor()
49 {
50 TestHelper.InMethod();
51
52 // GetAssetStreamHandler handler =
53 new GetAssetStreamHandler(null);
54 }
55
56 [Test]
57 public void TestGetParams()
58 {
59 TestHelper.InMethod();
60
61 GetAssetStreamHandler handler = new GetAssetStreamHandler(null);
62 BaseRequestHandlerTestHelper.BaseTestGetParams(handler, ASSETS_PATH);
63 }
64
65 [Test]
66 public void TestSplitParams()
67 {
68 TestHelper.InMethod();
69
70 GetAssetStreamHandler handler = new GetAssetStreamHandler(null);
71 BaseRequestHandlerTestHelper.BaseTestSplitParams(handler, ASSETS_PATH);
72 }
73
74 [Test]
75 public void TestHandleNoParams()
76 {
77 TestHelper.InMethod();
78
79 GetAssetStreamHandler handler = new GetAssetStreamHandler(null);
80
81 BaseRequestHandlerTestHelper.BaseTestHandleNoParams(handler, ASSETS_PATH);
82 }
83
84 [Test]
85 public void TestHandleMalformedGuid()
86 {
87 TestHelper.InMethod();
88
89 GetAssetStreamHandler handler = new GetAssetStreamHandler(null);
90
91 BaseRequestHandlerTestHelper.BaseTestHandleMalformedGuid(handler, ASSETS_PATH);
92 }
93
94 [Test]
95 public void TestHandleFetchMissingAsset()
96 {
97 GetAssetStreamHandler handler;
98 OSHttpResponse response;
99 CreateTestEnvironment(out handler, out response);
100
101 GetAssetStreamHandlerTestHelpers.BaseFetchMissingAsset(handler, response);
102 }
103
104 [Test]
105 public void TestHandleFetchExistingAssetData()
106 {
107 GetAssetStreamHandler handler;
108 OSHttpResponse response;
109 AssetBase asset = CreateTestEnvironment(out handler, out response);
110
111 GetAssetStreamHandlerTestHelpers.BaseFetchExistingAssetDataTest(asset, handler, response);
112 }
113
114 [Test]
115 public void TestHandleFetchExistingAssetXml()
116 {
117 GetAssetStreamHandler handler;
118 OSHttpResponse response;
119 AssetBase asset = CreateTestEnvironment(out handler, out response);
120
121 GetAssetStreamHandlerTestHelpers.BaseFetchExistingAssetXmlTest(asset, handler, response);
122 }
123
124 private static AssetBase CreateTestEnvironment(out GetAssetStreamHandler handler, out OSHttpResponse response)
125 {
126 AssetBase asset = GetAssetStreamHandlerTestHelpers.CreateCommonTestResources(out response);
127
128 IAssetDataPlugin assetDataPlugin = new TestAssetDataPlugin();
129 handler = new GetAssetStreamHandler(assetDataPlugin);
130
131 assetDataPlugin.StoreAsset(asset);
132 return asset;
133 }
134 }
135}
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs
index 743ca69..6f9b00c 100644
--- a/OpenSim/Framework/Servers/VersionInfo.cs
+++ b/OpenSim/Framework/Servers/VersionInfo.cs
@@ -69,6 +69,6 @@ namespace OpenSim
69 /// of the code that is too old. 69 /// of the code that is too old.
70 /// 70 ///
71 /// </value> 71 /// </value>
72 public readonly static int MajorInterfaceVersion = 5; 72 public readonly static int MajorInterfaceVersion = 6;
73 } 73 }
74} 74}
diff --git a/OpenSim/Grid/AssetServer/Main.cs b/OpenSim/Grid/AssetServer/Main.cs
deleted file mode 100644
index ac8f888..0000000
--- a/OpenSim/Grid/AssetServer/Main.cs
+++ /dev/null
@@ -1,146 +0,0 @@
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.IO;
30using System.Reflection;
31using log4net;
32using log4net.Config;
33using OpenMetaverse;
34using OpenSim.Data;
35using OpenSim.Framework;
36using OpenSim.Framework.AssetLoader.Filesystem;
37using OpenSim.Framework.Console;
38using OpenSim.Framework.Servers;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Framework.Statistics;
41
42namespace OpenSim.Grid.AssetServer
43{
44 /// <summary>
45 /// An asset server
46 /// </summary>
47 public class OpenAsset_Main : BaseOpenSimServer
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 public static OpenAsset_Main assetserver;
52
53 // Temporarily hardcoded - should be a plugin
54 protected IAssetLoader assetLoader = new AssetLoaderFileSystem();
55
56 private IAssetDataPlugin m_assetProvider;
57
58 public static void Main(string[] args)
59 {
60 XmlConfigurator.Configure();
61
62 assetserver = new OpenAsset_Main();
63 assetserver.Startup();
64
65 assetserver.Work();
66 }
67
68 private void Work()
69 {
70 m_console.Output("Enter help for a list of commands");
71
72 while (true)
73 {
74 m_console.Prompt();
75 }
76 }
77
78 public OpenAsset_Main()
79 {
80 m_console = new LocalConsole("Asset");
81
82 MainConsole.Instance = m_console;
83 }
84
85 protected override void StartupSpecific()
86 {
87 AssetConfig config = new AssetConfig("ASSET SERVER", (Path.Combine(Util.configDir(), "AssetServer_Config.xml")));
88
89 m_log.Info("[ASSET]: Setting up asset DB");
90 setupDB(config);
91
92 m_log.Info("[ASSET]: Loading default asset set from '" + config.AssetSetsLocation + "'");
93 LoadDefaultAssets(config.AssetSetsLocation);
94
95 m_log.Info("[ASSET]: Starting HTTP process");
96 m_httpServer = new BaseHttpServer(config.HttpPort);
97
98 m_stats = StatsManager.StartCollectingAssetStats();
99
100 AddHttpHandlers();
101
102 m_httpServer.Start();
103
104 base.StartupSpecific();
105 }
106
107 protected void AddHttpHandlers()
108 {
109 m_httpServer.AddStreamHandler(new GetAssetStreamHandler(m_assetProvider));
110 m_httpServer.AddStreamHandler(new PostAssetStreamHandler(m_assetProvider));
111 }
112
113 public byte[] GetAssetData(UUID assetID, bool isTexture)
114 {
115 return null;
116 }
117
118 public void setupDB(AssetConfig config)
119 {
120 try
121 {
122 m_assetProvider = DataPluginFactory.LoadDataPlugin<IAssetDataPlugin>(config.DatabaseProvider, config.DatabaseConnect);
123 if (m_assetProvider == null)
124 {
125 m_log.Error("[ASSET]: Failed to load a database plugin, server halting");
126 Environment.Exit(-1);
127 }
128 }
129 catch (Exception e)
130 {
131 m_log.Warn("[ASSET]: setupDB() - Exception occured");
132 m_log.Warn("[ASSET]: " + e.ToString());
133 }
134 }
135
136 public void LoadDefaultAssets(string pAssetSetsLocation)
137 {
138 assetLoader.ForEachDefaultXmlAsset(pAssetSetsLocation, StoreAsset);
139 }
140
141 protected void StoreAsset(AssetBase asset)
142 {
143 m_assetProvider.StoreAsset(asset);
144 }
145 }
146}
diff --git a/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs b/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs
deleted file mode 100644
index 5d67e3f..0000000
--- a/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,63 +0,0 @@
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.Reflection;
29using System.Runtime.InteropServices;
30
31// General information about an assembly is controlled through the following
32// set of attributes. Change these attribute values to modify the information
33// associated with an assembly.
34
35[assembly : AssemblyTitle("OGS-AssetServer")]
36[assembly : AssemblyDescription("")]
37[assembly : AssemblyConfiguration("")]
38[assembly : AssemblyCompany("http://opensimulator.org")]
39[assembly : AssemblyProduct("OGS-AssetServer")]
40[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
41[assembly : AssemblyTrademark("")]
42[assembly : AssemblyCulture("")]
43
44// Setting ComVisible to false makes the types in this assembly not visible
45// to COM components. If you need to access a type in this assembly from
46// COM, set the ComVisible attribute to true on that type.
47
48[assembly : ComVisible(false)]
49
50// The following GUID is for the ID of the typelib if this project is exposed to COM
51
52[assembly : Guid("b541b244-3d1d-4625-9003-bc2a3a6a39a4")]
53
54// Version information for an assembly consists of the following four values:
55//
56// Major Version
57// Minor Version
58// Build Number
59// Revision
60//
61
62[assembly : AssemblyVersion("0.6.5.*")]
63[assembly : AssemblyFileVersion("0.6.5.0")]
diff --git a/OpenSim/Grid/InventoryServer/AuthedSessionCache.cs b/OpenSim/Grid/InventoryServer/AuthedSessionCache.cs
deleted file mode 100644
index dadf34a..0000000
--- a/OpenSim/Grid/InventoryServer/AuthedSessionCache.cs
+++ /dev/null
@@ -1,133 +0,0 @@
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;
30
31namespace OpenSim.Grid.InventoryServer
32{
33 public class AuthedSessionCache
34 {
35 public class CacheData
36 {
37 private static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1);
38 private string m_session_id;
39 private string m_agent_id;
40 private int m_expire;
41
42 private int get_current_unix_time()
43 {
44 return (int)(DateTime.UtcNow - UNIX_EPOCH).TotalSeconds;
45 }
46
47 public CacheData(string sid, string aid)
48 {
49 m_session_id = sid;
50 m_agent_id = aid;
51 m_expire = get_current_unix_time() + DEFAULT_LIFETIME;
52 }
53
54 public CacheData(string sid, string aid, int time_now)
55 {
56 m_session_id = sid;
57 m_agent_id = aid;
58 m_expire = time_now + DEFAULT_LIFETIME;
59 }
60
61 public string SessionID
62 {
63 get { return m_session_id; }
64 set { m_session_id = value; }
65 }
66
67 public string AgentID
68 {
69 get { return m_agent_id; }
70 set { m_agent_id = value; }
71 }
72
73 public bool isExpired
74 {
75 get { return m_expire < get_current_unix_time(); }
76 }
77
78 public void Renew()
79 {
80 m_expire = get_current_unix_time() + DEFAULT_LIFETIME;
81 }
82 }
83
84 private static readonly int DEFAULT_LIFETIME = 30;
85 private Dictionary<string, CacheData> m_authed_sessions = new Dictionary<string,CacheData>();
86 // private int m_session_lifetime = DEFAULT_LIFETIME;
87
88 public AuthedSessionCache()
89 {
90 // m_session_lifetime = DEFAULT_LIFETIME;
91 }
92
93 public AuthedSessionCache(int timeout)
94 {
95 // m_session_lifetime = timeout;
96 }
97
98 public CacheData getCachedSession(string session_id, string agent_id)
99 {
100 CacheData ret = null;
101 lock (m_authed_sessions)
102 {
103 if (m_authed_sessions.ContainsKey(session_id))
104 {
105 CacheData cached_session = m_authed_sessions[session_id];
106 if (!cached_session.isExpired && cached_session.AgentID == agent_id)
107 {
108 ret = m_authed_sessions[session_id];
109 // auto renew
110 m_authed_sessions[session_id].Renew();
111 }
112 }
113 }
114 return ret;
115 }
116
117 public void Add(string session_id, string agent_id)
118 {
119 CacheData data = new CacheData(session_id, agent_id);
120 lock (m_authed_sessions)
121 {
122 if (m_authed_sessions.ContainsKey(session_id))
123 {
124 m_authed_sessions[session_id] = data;
125 }
126 else
127 {
128 m_authed_sessions.Add(session_id, data);
129 }
130 }
131 }
132 }
133}
diff --git a/OpenSim/Grid/InventoryServer/GridInventoryService.cs b/OpenSim/Grid/InventoryServer/GridInventoryService.cs
deleted file mode 100644
index 0704faa..0000000
--- a/OpenSim/Grid/InventoryServer/GridInventoryService.cs
+++ /dev/null
@@ -1,256 +0,0 @@
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;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33using log4net;
34using Nwc.XmlRpc;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Communications;
38using OpenSim.Framework.Communications.Cache;
39
40namespace OpenSim.Grid.InventoryServer
41{
42 /// <summary>
43 /// Used on a grid server to satisfy external inventory requests
44 /// </summary>
45 public class GridInventoryService : InventoryServiceBase
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private bool m_doLookup = false;
50
51 public bool DoLookup
52 {
53 get { return m_doLookup; }
54 set { m_doLookup = value; }
55 }
56
57 private static readonly int INVENTORY_DEFAULT_SESSION_TIME = 30; // secs
58
59 private string m_userserver_url;
60 private AuthedSessionCache m_session_cache = new AuthedSessionCache(INVENTORY_DEFAULT_SESSION_TIME);
61
62 public GridInventoryService(string userserver_url)
63 {
64 m_userserver_url = userserver_url;
65 }
66
67 /// <summary>
68 /// Check that the source of an inventory request is one that we trust.
69 /// </summary>
70 /// <param name="peer"></param>
71 /// <returns></returns>
72 public bool CheckTrustSource(IPEndPoint peer)
73 {
74 if (m_doLookup)
75 {
76 m_log.InfoFormat("[GRID AGENT INVENTORY]: Checking trusted source {0}", peer);
77 UriBuilder ub = new UriBuilder(m_userserver_url);
78 IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host);
79 foreach (IPAddress uaddr in uaddrs)
80 {
81 if (uaddr.Equals(peer.Address))
82 {
83 return true;
84 }
85 }
86
87 m_log.WarnFormat(
88 "[GRID AGENT INVENTORY]: Rejecting request since source {0} was not in the list of trusted sources",
89 peer);
90
91 return false;
92 }
93 else
94 {
95 return true;
96 }
97 }
98
99 /// <summary>
100 /// Check that the source of an inventory request for a particular agent is a current session belonging to
101 /// that agent.
102 /// </summary>
103 /// <param name="session_id"></param>
104 /// <param name="avatar_id"></param>
105 /// <returns></returns>
106 public bool CheckAuthSession(string session_id, string avatar_id)
107 {
108 if (m_doLookup)
109 {
110 m_log.InfoFormat("[GRID AGENT INVENTORY]: checking authed session {0} {1}", session_id, avatar_id);
111
112 if (m_session_cache.getCachedSession(session_id, avatar_id) == null)
113 {
114 // cache miss, ask userserver
115 Hashtable requestData = new Hashtable();
116 requestData["avatar_uuid"] = avatar_id;
117 requestData["session_id"] = session_id;
118 ArrayList SendParams = new ArrayList();
119 SendParams.Add(requestData);
120 XmlRpcRequest UserReq = new XmlRpcRequest("check_auth_session", SendParams);
121 XmlRpcResponse UserResp = UserReq.Send(m_userserver_url, 3000);
122
123 Hashtable responseData = (Hashtable)UserResp.Value;
124 if (responseData.ContainsKey("auth_session") && responseData["auth_session"].ToString() == "TRUE")
125 {
126 m_log.Info("[GRID AGENT INVENTORY]: got authed session from userserver");
127 // add to cache; the session time will be automatically renewed
128 m_session_cache.Add(session_id, avatar_id);
129 return true;
130 }
131 }
132 else
133 {
134 // cache hits
135 m_log.Info("[GRID AGENT INVENTORY]: got authed session from cache");
136 return true;
137 }
138
139 m_log.Warn("[GRID AGENT INVENTORY]: unknown session_id, request rejected");
140 return false;
141 }
142 else
143 {
144 return true;
145 }
146 }
147
148 /// <summary>
149 /// Return a user's entire inventory
150 /// </summary>
151 /// <param name="rawUserID"></param>
152 /// <returns>The user's inventory. If an inventory cannot be found then an empty collection is returned.</returns>
153 public InventoryCollection GetUserInventory(Guid rawUserID)
154 {
155 UUID userID = new UUID(rawUserID);
156
157 m_log.InfoFormat("[GRID AGENT INVENTORY]: Processing request for inventory of {0}", userID);
158
159 // Uncomment me to simulate a slow responding inventory server
160 //Thread.Sleep(16000);
161
162 InventoryCollection invCollection = new InventoryCollection();
163
164 List<InventoryFolderBase> allFolders = GetInventorySkeleton(userID);
165
166 if (null == allFolders)
167 {
168 m_log.WarnFormat("[GRID AGENT INVENTORY]: No inventory found for user {0}", rawUserID);
169
170 return invCollection;
171 }
172
173 List<InventoryItemBase> allItems = new List<InventoryItemBase>();
174
175 foreach (InventoryFolderBase folder in allFolders)
176 {
177 List<InventoryItemBase> items = RequestFolderItems(folder.ID);
178
179 if (items != null)
180 {
181 allItems.InsertRange(0, items);
182 }
183 }
184
185 invCollection.UserID = userID;
186 invCollection.Folders = allFolders;
187 invCollection.Items = allItems;
188
189 // foreach (InventoryFolderBase folder in invCollection.Folders)
190 // {
191 // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back folder {0} {1}", folder.Name, folder.ID);
192 // }
193 //
194 // foreach (InventoryItemBase item in invCollection.Items)
195 // {
196 // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back item {0} {1}, folder {2}", item.Name, item.ID, item.Folder);
197 // }
198
199 m_log.InfoFormat(
200 "[GRID AGENT INVENTORY]: Sending back inventory response to user {0} containing {1} folders and {2} items",
201 invCollection.UserID, invCollection.Folders.Count, invCollection.Items.Count);
202
203 return invCollection;
204 }
205
206 public List<InventoryItemBase> GetFolderItems(Guid folderID)
207 {
208 List<InventoryItemBase> allItems = new List<InventoryItemBase>();
209
210
211 List<InventoryItemBase> items = RequestFolderItems(new UUID(folderID));
212
213 if (items != null)
214 {
215 allItems.InsertRange(0, items);
216 }
217 m_log.InfoFormat(
218 "[GRID AGENT INVENTORY]: Sending back inventory response containing {0} items", allItems.Count.ToString());
219 return allItems;
220 }
221
222 /// <summary>
223 /// Guid to UUID wrapper for same name IInventoryServices method
224 /// </summary>
225 /// <param name="rawUserID"></param>
226 /// <returns></returns>
227 public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID)
228 {
229 UUID userID = new UUID(rawUserID);
230 return GetInventorySkeleton(userID);
231 }
232
233 /// <summary>
234 /// Create an inventory for the given user.
235 /// </summary>
236 /// <param name="rawUserID"></param>
237 /// <returns></returns>
238 public bool CreateUsersInventory(Guid rawUserID)
239 {
240 UUID userID = new UUID(rawUserID);
241
242 m_log.InfoFormat("[GRID AGENT INVENTORY]: Creating new set of inventory folders for user {0}", userID);
243
244 return CreateNewUserInventory(userID);
245 }
246
247 public List<InventoryItemBase> GetActiveGestures(Guid rawUserID)
248 {
249 UUID userID = new UUID(rawUserID);
250
251 m_log.InfoFormat("[GRID AGENT INVENTORY]: fetching active gestures for user {0}", userID);
252
253 return GetActiveGestures(userID);
254 }
255 }
256}
diff --git a/OpenSim/Grid/InventoryServer/InventoryServiceBase.cs b/OpenSim/Grid/InventoryServer/InventoryServiceBase.cs
deleted file mode 100644
index f8b4949..0000000
--- a/OpenSim/Grid/InventoryServer/InventoryServiceBase.cs
+++ /dev/null
@@ -1,519 +0,0 @@
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.Collections.Generic;
29using System.Reflection;
30using log4net;
31using OpenMetaverse;
32using OpenSim.Data;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications;
35
36namespace OpenSim.Grid.InventoryServer
37{
38 /// <summary>
39 /// Abstract base class used by local and grid implementations of an inventory service.
40 /// </summary>
41 public abstract class InventoryServiceBase : IInterServiceInventoryServices
42 {
43
44 private static readonly ILog m_log
45 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 protected List<IInventoryDataPlugin> m_plugins = new List<IInventoryDataPlugin>();
48
49 #region Plugin methods
50
51 /// <summary>
52 /// Add a new inventory data plugin - plugins will be requested in the order they were added.
53 /// </summary>
54 /// <param name="plugin">The plugin that will provide data</param>
55 public void AddPlugin(IInventoryDataPlugin plugin)
56 {
57 m_plugins.Add(plugin);
58 }
59
60 /// <summary>
61 /// Adds a list of inventory data plugins, as described by `provider'
62 /// and `connect', to `m_plugins'.
63 /// </summary>
64 /// <param name="provider">
65 /// The filename of the inventory server plugin DLL.
66 /// </param>
67 /// <param name="connect">
68 /// The connection string for the storage backend.
69 /// </param>
70 public void AddPlugin(string provider, string connect)
71 {
72 m_plugins.AddRange(DataPluginFactory.LoadDataPlugins<IInventoryDataPlugin>(provider, connect));
73 }
74
75 #endregion
76
77 #region IInventoryServices methods
78
79 public string Host
80 {
81 get { return "default"; }
82 }
83
84 public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
85 {
86// m_log.DebugFormat("[AGENT INVENTORY]: Getting inventory skeleton for {0}", userId);
87
88 InventoryFolderBase rootFolder = RequestRootFolder(userId);
89
90 // Agent has no inventory structure yet.
91 if (null == rootFolder)
92 {
93 return null;
94 }
95
96 List<InventoryFolderBase> userFolders = new List<InventoryFolderBase>();
97
98 userFolders.Add(rootFolder);
99
100 foreach (IInventoryDataPlugin plugin in m_plugins)
101 {
102 IList<InventoryFolderBase> folders = plugin.getFolderHierarchy(rootFolder.ID);
103 userFolders.AddRange(folders);
104 }
105
106// foreach (InventoryFolderBase folder in userFolders)
107// {
108// m_log.DebugFormat("[AGENT INVENTORY]: Got folder {0} {1}", folder.name, folder.folderID);
109// }
110
111 return userFolders;
112 }
113
114 // See IInventoryServices
115 public virtual bool HasInventoryForUser(UUID userID)
116 {
117 return false;
118 }
119
120 // See IInventoryServices
121 public virtual InventoryFolderBase RequestRootFolder(UUID userID)
122 {
123 // Retrieve the first root folder we get from the list of plugins.
124 foreach (IInventoryDataPlugin plugin in m_plugins)
125 {
126 InventoryFolderBase rootFolder = plugin.getUserRootFolder(userID);
127 if (rootFolder != null)
128 return rootFolder;
129 }
130
131 // Return nothing if no plugin was able to supply a root folder
132 return null;
133 }
134
135 // See IInventoryServices
136 public bool CreateNewUserInventory(UUID user)
137 {
138 InventoryFolderBase existingRootFolder = RequestRootFolder(user);
139
140 if (null != existingRootFolder)
141 {
142 m_log.WarnFormat(
143 "[AGENT INVENTORY]: Did not create a new inventory for user {0} since they already have "
144 + "a root inventory folder with id {1}",
145 user, existingRootFolder.ID);
146 }
147 else
148 {
149 UsersInventory inven = new UsersInventory();
150 inven.CreateNewInventorySet(user);
151 AddNewInventorySet(inven);
152
153 return true;
154 }
155
156 return false;
157 }
158
159 public List<InventoryItemBase> GetActiveGestures(UUID userId)
160 {
161 List<InventoryItemBase> activeGestures = new List<InventoryItemBase>();
162 foreach (IInventoryDataPlugin plugin in m_plugins)
163 {
164 activeGestures.AddRange(plugin.fetchActiveGestures(userId));
165 }
166
167 return activeGestures;
168 }
169
170 #endregion
171
172 #region Methods used by GridInventoryService
173
174 public List<InventoryFolderBase> RequestSubFolders(UUID parentFolderID)
175 {
176 List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>();
177
178 foreach (IInventoryDataPlugin plugin in m_plugins)
179 {
180 inventoryList.AddRange(plugin.getInventoryFolders(parentFolderID));
181 }
182
183 return inventoryList;
184 }
185
186 public List<InventoryItemBase> RequestFolderItems(UUID folderID)
187 {
188 List<InventoryItemBase> itemsList = new List<InventoryItemBase>();
189
190 foreach (IInventoryDataPlugin plugin in m_plugins)
191 {
192 itemsList.AddRange(plugin.getInventoryInFolder(folderID));
193 }
194
195 return itemsList;
196 }
197
198 #endregion
199
200 // See IInventoryServices
201 public virtual bool AddFolder(InventoryFolderBase folder)
202 {
203 m_log.DebugFormat(
204 "[AGENT INVENTORY]: Adding folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
205
206 foreach (IInventoryDataPlugin plugin in m_plugins)
207 {
208 plugin.addInventoryFolder(folder);
209 }
210
211 // FIXME: Should return false on failure
212 return true;
213 }
214
215 // See IInventoryServices
216 public virtual bool UpdateFolder(InventoryFolderBase folder)
217 {
218 m_log.DebugFormat(
219 "[AGENT INVENTORY]: Updating folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
220
221 foreach (IInventoryDataPlugin plugin in m_plugins)
222 {
223 plugin.updateInventoryFolder(folder);
224 }
225
226 // FIXME: Should return false on failure
227 return true;
228 }
229
230 // See IInventoryServices
231 public virtual bool MoveFolder(InventoryFolderBase folder)
232 {
233 m_log.DebugFormat(
234 "[AGENT INVENTORY]: Moving folder {0} {1} to folder {2}", folder.Name, folder.ID, folder.ParentID);
235
236 foreach (IInventoryDataPlugin plugin in m_plugins)
237 {
238 plugin.moveInventoryFolder(folder);
239 }
240
241 // FIXME: Should return false on failure
242 return true;
243 }
244
245 // See IInventoryServices
246 public virtual bool AddItem(InventoryItemBase item)
247 {
248 m_log.DebugFormat(
249 "[AGENT INVENTORY]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder);
250
251 foreach (IInventoryDataPlugin plugin in m_plugins)
252 {
253 plugin.addInventoryItem(item);
254 }
255
256 // FIXME: Should return false on failure
257 return true;
258 }
259
260 // See IInventoryServices
261 public virtual bool UpdateItem(InventoryItemBase item)
262 {
263 m_log.InfoFormat(
264 "[AGENT INVENTORY]: Updating item {0} {1} in folder {2}", item.Name, item.ID, item.Folder);
265
266 foreach (IInventoryDataPlugin plugin in m_plugins)
267 {
268 plugin.updateInventoryItem(item);
269 }
270
271 // FIXME: Should return false on failure
272 return true;
273 }
274
275 // See IInventoryServices
276 public virtual bool DeleteItem(InventoryItemBase item)
277 {
278 m_log.InfoFormat(
279 "[AGENT INVENTORY]: Deleting item {0} {1} from folder {2}", item.Name, item.ID, item.Folder);
280
281 foreach (IInventoryDataPlugin plugin in m_plugins)
282 {
283 plugin.deleteInventoryItem(item.ID);
284 }
285
286 // FIXME: Should return false on failure
287 return true;
288 }
289
290 public virtual InventoryItemBase QueryItem(InventoryItemBase item)
291 {
292 foreach (IInventoryDataPlugin plugin in m_plugins)
293 {
294 InventoryItemBase result = plugin.queryInventoryItem(item.ID);
295 if (result != null)
296 return result;
297 }
298
299 return null;
300 }
301
302 public virtual InventoryFolderBase QueryFolder(InventoryFolderBase item)
303 {
304 foreach (IInventoryDataPlugin plugin in m_plugins)
305 {
306 InventoryFolderBase result = plugin.queryInventoryFolder(item.ID);
307 if (result != null)
308 return result;
309 }
310
311 return null;
312 }
313
314 /// <summary>
315 /// Purge a folder of all items items and subfolders.
316 ///
317 /// FIXME: Really nasty in a sense, because we have to query the database to get information we may
318 /// already know... Needs heavy refactoring.
319 /// </summary>
320 /// <param name="folder"></param>
321 public virtual bool PurgeFolder(InventoryFolderBase folder)
322 {
323 m_log.DebugFormat(
324 "[AGENT INVENTORY]: Purging folder {0} {1} of its contents", folder.Name, folder.ID);
325
326 List<InventoryFolderBase> subFolders = RequestSubFolders(folder.ID);
327
328 foreach (InventoryFolderBase subFolder in subFolders)
329 {
330// m_log.DebugFormat("[AGENT INVENTORY]: Deleting folder {0} {1}", subFolder.Name, subFolder.ID);
331
332 foreach (IInventoryDataPlugin plugin in m_plugins)
333 {
334 plugin.deleteInventoryFolder(subFolder.ID);
335 }
336 }
337
338 List<InventoryItemBase> items = RequestFolderItems(folder.ID);
339
340 foreach (InventoryItemBase item in items)
341 {
342 DeleteItem(item);
343 }
344
345 // FIXME: Should return false on failure
346 return true;
347 }
348
349 private void AddNewInventorySet(UsersInventory inventory)
350 {
351 foreach (InventoryFolderBase folder in inventory.Folders.Values)
352 {
353 AddFolder(folder);
354 }
355 }
356
357 public InventoryItemBase GetInventoryItem(UUID itemID)
358 {
359 foreach (IInventoryDataPlugin plugin in m_plugins)
360 {
361 InventoryItemBase item = plugin.getInventoryItem(itemID);
362 if (item != null)
363 return item;
364 }
365
366 return null;
367 }
368
369 /// <summary>
370 /// Used to create a new user inventory.
371 /// </summary>
372 private class UsersInventory
373 {
374 public Dictionary<UUID, InventoryFolderBase> Folders = new Dictionary<UUID, InventoryFolderBase>();
375 public Dictionary<UUID, InventoryItemBase> Items = new Dictionary<UUID, InventoryItemBase>();
376
377 public virtual void CreateNewInventorySet(UUID user)
378 {
379 InventoryFolderBase folder = new InventoryFolderBase();
380
381 folder.ParentID = UUID.Zero;
382 folder.Owner = user;
383 folder.ID = UUID.Random();
384 folder.Name = "My Inventory";
385 folder.Type = (short)AssetType.Folder;
386 folder.Version = 1;
387 Folders.Add(folder.ID, folder);
388
389 UUID rootFolder = folder.ID;
390
391 folder = new InventoryFolderBase();
392 folder.ParentID = rootFolder;
393 folder.Owner = user;
394 folder.ID = UUID.Random();
395 folder.Name = "Animations";
396 folder.Type = (short)AssetType.Animation;
397 folder.Version = 1;
398 Folders.Add(folder.ID, folder);
399
400 folder = new InventoryFolderBase();
401 folder.ParentID = rootFolder;
402 folder.Owner = user;
403 folder.ID = UUID.Random();
404 folder.Name = "Body Parts";
405 folder.Type = (short)AssetType.Bodypart;
406 folder.Version = 1;
407 Folders.Add(folder.ID, folder);
408
409 folder = new InventoryFolderBase();
410 folder.ParentID = rootFolder;
411 folder.Owner = user;
412 folder.ID = UUID.Random();
413 folder.Name = "Calling Cards";
414 folder.Type = (short)AssetType.CallingCard;
415 folder.Version = 1;
416 Folders.Add(folder.ID, folder);
417
418 folder = new InventoryFolderBase();
419 folder.ParentID = rootFolder;
420 folder.Owner = user;
421 folder.ID = UUID.Random();
422 folder.Name = "Clothing";
423 folder.Type = (short)AssetType.Clothing;
424 folder.Version = 1;
425 Folders.Add(folder.ID, folder);
426
427 folder = new InventoryFolderBase();
428 folder.ParentID = rootFolder;
429 folder.Owner = user;
430 folder.ID = UUID.Random();
431 folder.Name = "Gestures";
432 folder.Type = (short)AssetType.Gesture;
433 folder.Version = 1;
434 Folders.Add(folder.ID, folder);
435
436 folder = new InventoryFolderBase();
437 folder.ParentID = rootFolder;
438 folder.Owner = user;
439 folder.ID = UUID.Random();
440 folder.Name = "Landmarks";
441 folder.Type = (short)AssetType.Landmark;
442 folder.Version = 1;
443 Folders.Add(folder.ID, folder);
444
445 folder = new InventoryFolderBase();
446 folder.ParentID = rootFolder;
447 folder.Owner = user;
448 folder.ID = UUID.Random();
449 folder.Name = "Lost And Found";
450 folder.Type = (short)AssetType.LostAndFoundFolder;
451 folder.Version = 1;
452 Folders.Add(folder.ID, folder);
453
454 folder = new InventoryFolderBase();
455 folder.ParentID = rootFolder;
456 folder.Owner = user;
457 folder.ID = UUID.Random();
458 folder.Name = "Notecards";
459 folder.Type = (short)AssetType.Notecard;
460 folder.Version = 1;
461 Folders.Add(folder.ID, folder);
462
463 folder = new InventoryFolderBase();
464 folder.ParentID = rootFolder;
465 folder.Owner = user;
466 folder.ID = UUID.Random();
467 folder.Name = "Objects";
468 folder.Type = (short)AssetType.Object;
469 folder.Version = 1;
470 Folders.Add(folder.ID, folder);
471
472 folder = new InventoryFolderBase();
473 folder.ParentID = rootFolder;
474 folder.Owner = user;
475 folder.ID = UUID.Random();
476 folder.Name = "Photo Album";
477 folder.Type = (short)AssetType.SnapshotFolder;
478 folder.Version = 1;
479 Folders.Add(folder.ID, folder);
480
481 folder = new InventoryFolderBase();
482 folder.ParentID = rootFolder;
483 folder.Owner = user;
484 folder.ID = UUID.Random();
485 folder.Name = "Scripts";
486 folder.Type = (short)AssetType.LSLText;
487 folder.Version = 1;
488 Folders.Add(folder.ID, folder);
489
490 folder = new InventoryFolderBase();
491 folder.ParentID = rootFolder;
492 folder.Owner = user;
493 folder.ID = UUID.Random();
494 folder.Name = "Sounds";
495 folder.Type = (short)AssetType.Sound;
496 folder.Version = 1;
497 Folders.Add(folder.ID, folder);
498
499 folder = new InventoryFolderBase();
500 folder.ParentID = rootFolder;
501 folder.Owner = user;
502 folder.ID = UUID.Random();
503 folder.Name = "Textures";
504 folder.Type = (short)AssetType.Texture;
505 folder.Version = 1;
506 Folders.Add(folder.ID, folder);
507
508 folder = new InventoryFolderBase();
509 folder.ParentID = rootFolder;
510 folder.Owner = user;
511 folder.ID = UUID.Random();
512 folder.Name = "Trash";
513 folder.Type = (short)AssetType.TrashFolder;
514 folder.Version = 1;
515 Folders.Add(folder.ID, folder);
516 }
517 }
518 }
519}
diff --git a/OpenSim/Grid/InventoryServer/Main.cs b/OpenSim/Grid/InventoryServer/Main.cs
deleted file mode 100644
index 6106d93..0000000
--- a/OpenSim/Grid/InventoryServer/Main.cs
+++ /dev/null
@@ -1,182 +0,0 @@
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.IO;
31using System.Reflection;
32using log4net;
33using log4net.Config;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Communications.Services;
37using OpenSim.Framework.Console;
38using OpenSim.Framework.Servers;
39using OpenSim.Framework.Servers.HttpServer;
40
41namespace OpenSim.Grid.InventoryServer
42{
43 public class OpenInventory_Main : BaseOpenSimServer
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 private GridInventoryService m_inventoryService;
48 //private HGInventoryService m_directInventoryService;
49
50 public const string LogName = "INVENTORY";
51
52 public static void Main(string[] args)
53 {
54 XmlConfigurator.Configure();
55
56 OpenInventory_Main theServer = new OpenInventory_Main();
57 theServer.Startup();
58
59 theServer.Work();
60 }
61
62 public OpenInventory_Main()
63 {
64 m_console = new LocalConsole("Inventory");
65 MainConsole.Instance = m_console;
66 }
67
68 protected override void StartupSpecific()
69 {
70 InventoryConfig config = new InventoryConfig(LogName, (Path.Combine(Util.configDir(), "InventoryServer_Config.xml")));
71
72 m_inventoryService = new GridInventoryService(config.UserServerURL);
73 m_inventoryService.DoLookup = config.SessionLookUp;
74 m_inventoryService.AddPlugin(config.DatabaseProvider, config.DatabaseConnect);
75
76
77 m_log.Info("[" + LogName + "]: Starting HTTP server ...");
78
79 m_httpServer = new BaseHttpServer(config.HttpPort);
80
81 AddHttpHandlers(config.RegionAccessToAgentsInventory);
82
83 m_httpServer.Start();
84
85 m_log.Info("[" + LogName + "]: Started HTTP server");
86
87 base.StartupSpecific();
88
89 m_console.Commands.AddCommand("inventoryserver", false, "add user",
90 "add user",
91 "Add a random user inventory", HandleAddUser);
92 }
93
94 protected void AddHttpHandlers(bool regionAccess)
95 {
96 if (regionAccess)
97 {
98 m_httpServer.AddStreamHandler(
99 new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
100 "POST", "/GetInventory/", m_inventoryService.GetUserInventory, m_inventoryService.CheckAuthSession));
101
102 m_httpServer.AddStreamHandler(
103 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
104 "POST", "/UpdateFolder/", m_inventoryService.UpdateFolder, m_inventoryService.CheckAuthSession));
105
106 m_httpServer.AddStreamHandler(
107 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
108 "POST", "/MoveFolder/", m_inventoryService.MoveFolder, m_inventoryService.CheckAuthSession));
109
110 m_httpServer.AddStreamHandler(
111 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
112 "POST", "/PurgeFolder/", m_inventoryService.PurgeFolder, m_inventoryService.CheckAuthSession));
113
114 m_httpServer.AddStreamHandler(
115 new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
116 "POST", "/DeleteItem/", m_inventoryService.DeleteItem, m_inventoryService.CheckAuthSession));
117
118 m_httpServer.AddStreamHandler(
119 new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
120 "POST", "/QueryItem/", m_inventoryService.QueryItem, m_inventoryService.CheckAuthSession));
121
122 m_httpServer.AddStreamHandler(
123 new RestDeserialiseSecureHandler<InventoryFolderBase, InventoryFolderBase>(
124 "POST", "/QueryFolder/", m_inventoryService.QueryFolder, m_inventoryService.CheckAuthSession));
125
126 }
127
128 m_httpServer.AddStreamHandler(
129 new RestDeserialiseTrustedHandler<Guid, bool>(
130 "POST", "/CreateInventory/", m_inventoryService.CreateUsersInventory, m_inventoryService.CheckTrustSource));
131
132 m_httpServer.AddStreamHandler(
133 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
134 "POST", "/NewFolder/", m_inventoryService.AddFolder, m_inventoryService.CheckAuthSession));
135
136 m_httpServer.AddStreamHandler(
137 new RestDeserialiseTrustedHandler<InventoryFolderBase, bool>(
138 "POST", "/CreateFolder/", m_inventoryService.AddFolder, m_inventoryService.CheckTrustSource));
139
140 m_httpServer.AddStreamHandler(
141 new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
142 "POST", "/NewItem/", m_inventoryService.AddItem, m_inventoryService.CheckAuthSession));
143
144 m_httpServer.AddStreamHandler(
145 new RestDeserialiseTrustedHandler<InventoryItemBase, bool>(
146 "POST", "/AddNewItem/", m_inventoryService.AddItem, m_inventoryService.CheckTrustSource));
147
148 m_httpServer.AddStreamHandler(
149 new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>>(
150 "POST", "/GetItems/", m_inventoryService.GetFolderItems, m_inventoryService.CheckTrustSource));
151
152 // for persistent active gestures
153 m_httpServer.AddStreamHandler(
154 new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>>
155 ("POST", "/ActiveGestures/", m_inventoryService.GetActiveGestures, m_inventoryService.CheckTrustSource));
156
157 // WARNING: Root folders no longer just delivers the root and immediate child folders (e.g
158 // system folders such as Objects, Textures), but it now returns the entire inventory skeleton.
159 // It would have been better to rename this request, but complexities in the BaseHttpServer
160 // (e.g. any http request not found is automatically treated as an xmlrpc request) make it easier
161 // to do this for now.
162 m_httpServer.AddStreamHandler(
163 new RestDeserialiseTrustedHandler<Guid, List<InventoryFolderBase>>
164 ("POST", "/RootFolders/", m_inventoryService.GetInventorySkeleton, m_inventoryService.CheckTrustSource));
165 }
166
167 private void Work()
168 {
169 m_console.Output("Enter help for a list of commands\n");
170
171 while (true)
172 {
173 m_console.Prompt();
174 }
175 }
176
177 private void HandleAddUser(string module, string[] args)
178 {
179 m_inventoryService.CreateUsersInventory(UUID.Random().Guid);
180 }
181 }
182}
diff --git a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs
index f9c3fa6..3809749 100644
--- a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs
+++ b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs
@@ -73,10 +73,6 @@ namespace OpenSim.Region.Examples.SimpleModule
73 base.UpdateMovement(); 73 base.UpdateMovement();
74 } 74 }
75 75
76 public ComplexObject()
77 {
78 }
79
80 public ComplexObject(Scene scene, ulong regionHandle, UUID ownerID, uint localID, Vector3 pos) 76 public ComplexObject(Scene scene, ulong regionHandle, UUID ownerID, uint localID, Vector3 pos)
81 : base(ownerID, pos, PrimitiveBaseShape.Default) 77 : base(ownerID, pos, PrimitiveBaseShape.Default)
82 { 78 {
diff --git a/OpenSim/Framework/Servers/GetAssetStreamHandler.cs b/OpenSim/Region/Framework/Interfaces/IVoiceModule.cs
index c6958de..2e555fa 100644
--- a/OpenSim/Framework/Servers/GetAssetStreamHandler.cs
+++ b/OpenSim/Region/Framework/Interfaces/IVoiceModule.cs
@@ -25,39 +25,21 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28
29using System.IO; 29using System.IO;
30using System.Reflection;
31using System.Text;
32using System.Text.RegularExpressions;
33using System.Xml;
34using System.Xml.Serialization;
35using log4net;
36using OpenMetaverse; 30using OpenMetaverse;
37using OpenSim.Data;
38using OpenSim.Framework;
39using OpenSim.Framework.Servers;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Framework.Statistics;
42using System.Net;
43 31
44namespace OpenSim.Framework.Servers 32namespace OpenSim.Region.Framework.Interfaces
45{ 33{
46 public class GetAssetStreamHandler : BaseGetAssetStreamHandler 34 public interface IVoiceModule
47 { 35 {
48 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 private readonly IAssetDataPlugin m_assetProvider;
51
52 public GetAssetStreamHandler(IAssetDataPlugin assetProvider)
53 : base("GET", "/assets")
54 {
55 m_assetProvider = assetProvider;
56 }
57 36
58 protected override AssetBase GetAsset(UUID assetID) 37 /// <summary>
59 { 38 /// Set the SIP url to be used by a parcel, this will allow manual setting of a SIP address
60 return m_assetProvider.GetAsset(assetID); 39 /// for a particular piece of land, allowing region owners to use preconfigured SIP conference channels.
61 } 40 /// This is used by osSetParcelSIPAddress
41 /// </summary>
42 void setLandSIPAddress(string SIPAddress,UUID GlobalID);
43
62 } 44 }
63} 45}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6ba7e41..3c17bbe 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -250,16 +250,7 @@ namespace OpenSim.Region.Framework.Scenes
250 /// </summary> 250 /// </summary>
251 public override Vector3 AbsolutePosition 251 public override Vector3 AbsolutePosition
252 { 252 {
253 get 253 get { return m_rootPart.GroupPosition; }
254 {
255 if (m_rootPart == null)
256 {
257 throw new NullReferenceException(
258 string.Format("[SCENE OBJECT GROUP]: Object {0} has no root part.", m_uuid));
259 }
260
261 return m_rootPart.GroupPosition;
262 }
263 set 254 set
264 { 255 {
265 Vector3 val = value; 256 Vector3 val = value;
@@ -291,41 +282,19 @@ namespace OpenSim.Region.Framework.Scenes
291 282
292 public override uint LocalId 283 public override uint LocalId
293 { 284 {
294 get 285 get { return m_rootPart.LocalId; }
295 {
296 if (m_rootPart == null)
297 {
298 m_log.Error("[SCENE OBJECT GROUP]: Unable to find the rootpart for a LocalId Request!");
299 return 0;
300 }
301
302 return m_rootPart.LocalId;
303 }
304 set { m_rootPart.LocalId = value; } 286 set { m_rootPart.LocalId = value; }
305 } 287 }
306 288
307 public override UUID UUID 289 public override UUID UUID
308 { 290 {
309 get { 291 get { return m_rootPart.UUID; }
310 if (m_rootPart == null)
311 {
312 m_log.Error("Got a null rootpart while requesting UUID. Called from: ", new Exception());
313 return UUID.Zero;
314 }
315 else return m_rootPart.UUID;
316 }
317 set { m_rootPart.UUID = value; } 292 set { m_rootPart.UUID = value; }
318 } 293 }
319 294
320 public UUID OwnerID 295 public UUID OwnerID
321 { 296 {
322 get 297 get { return m_rootPart.OwnerID; }
323 {
324 if (m_rootPart == null)
325 return UUID.Zero;
326
327 return m_rootPart.OwnerID;
328 }
329 set { m_rootPart.OwnerID = value; } 298 set { m_rootPart.OwnerID = value; }
330 } 299 }
331 300
@@ -366,7 +335,7 @@ namespace OpenSim.Region.Framework.Scenes
366 { 335 {
367 m_isSelected = value; 336 m_isSelected = value;
368 // Tell physics engine that group is selected 337 // Tell physics engine that group is selected
369 if (m_rootPart != null && m_rootPart.PhysActor != null) 338 if (m_rootPart.PhysActor != null)
370 { 339 {
371 m_rootPart.PhysActor.Selected = value; 340 m_rootPart.PhysActor.Selected = value;
372 // Pass it on to the children. 341 // Pass it on to the children.
@@ -399,13 +368,6 @@ namespace OpenSim.Region.Framework.Scenes
399 #region Constructors 368 #region Constructors
400 369
401 /// <summary> 370 /// <summary>
402 /// Constructor
403 /// </summary>
404 public SceneObjectGroup()
405 {
406 }
407
408 /// <summary>
409 /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart. 371 /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart.
410 /// The original SceneObjectPart will be used rather than a copy, preserving 372 /// The original SceneObjectPart will be used rather than a copy, preserving
411 /// its existing localID and UUID. 373 /// its existing localID and UUID.
@@ -419,9 +381,8 @@ namespace OpenSim.Region.Framework.Scenes
419 /// Constructor. This object is added to the scene later via AttachToScene() 381 /// Constructor. This object is added to the scene later via AttachToScene()
420 /// </summary> 382 /// </summary>
421 public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) 383 public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
422 { 384 {
423 Vector3 rootOffset = new Vector3(0, 0, 0); 385 SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero));
424 SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, rootOffset));
425 } 386 }
426 387
427 /// <summary> 388 /// <summary>
@@ -462,11 +423,7 @@ namespace OpenSim.Region.Framework.Scenes
462 423
463 public UUID GetFromItemID() 424 public UUID GetFromItemID()
464 { 425 {
465 if (m_rootPart != null) 426 return m_rootPart.FromItemID;
466 {
467 return m_rootPart.FromItemID;
468 }
469 return UUID.Zero;
470 } 427 }
471 428
472 /// <summary> 429 /// <summary>
@@ -958,11 +915,7 @@ namespace OpenSim.Region.Framework.Scenes
958 915
959 public byte GetAttachmentPoint() 916 public byte GetAttachmentPoint()
960 { 917 {
961 if (m_rootPart != null) 918 return m_rootPart.Shape.State;
962 {
963 return m_rootPart.Shape.State;
964 }
965 return (byte)0;
966 } 919 }
967 920
968 public void ClearPartAttachmentData() 921 public void ClearPartAttachmentData()
@@ -1071,7 +1024,10 @@ namespace OpenSim.Region.Framework.Scenes
1071 /// </summary> 1024 /// </summary>
1072 /// <param name="part"></param> 1025 /// <param name="part"></param>
1073 public void SetRootPart(SceneObjectPart part) 1026 public void SetRootPart(SceneObjectPart part)
1074 { 1027 {
1028 if (part == null)
1029 throw new ArgumentNullException("Cannot give SceneObjectGroup a null root SceneObjectPart");
1030
1075 part.SetParent(this); 1031 part.SetParent(this);
1076 m_rootPart = part; 1032 m_rootPart = part;
1077 if (!IsAttachment) 1033 if (!IsAttachment)
@@ -1224,7 +1180,7 @@ namespace OpenSim.Region.Framework.Scenes
1224 1180
1225 if (!silent) 1181 if (!silent)
1226 { 1182 {
1227 if (m_rootPart != null && part == m_rootPart) 1183 if (part == m_rootPart)
1228 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1184 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1229 } 1185 }
1230 } 1186 }
@@ -1447,7 +1403,7 @@ namespace OpenSim.Region.Framework.Scenes
1447 /// <param name="part"></param> 1403 /// <param name="part"></param>
1448 internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) 1404 internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags)
1449 { 1405 {
1450 if (m_rootPart != null && m_rootPart.UUID == part.UUID) 1406 if (m_rootPart.UUID == part.UUID)
1451 { 1407 {
1452 if (IsAttachment) 1408 if (IsAttachment)
1453 { 1409 {
@@ -1881,12 +1837,6 @@ namespace OpenSim.Region.Framework.Scenes
1881 if (m_isDeleted) 1837 if (m_isDeleted)
1882 return; 1838 return;
1883 1839
1884 // This is what happens when an orphanced link set child prim's
1885 // group was queued when it was linked
1886 //
1887 if (m_rootPart == null)
1888 return;
1889
1890 // Even temporary objects take part in physics (e.g. temp-on-rez bullets) 1840 // Even temporary objects take part in physics (e.g. temp-on-rez bullets)
1891 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 1841 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1892 // return; 1842 // return;
@@ -3129,26 +3079,22 @@ namespace OpenSim.Region.Framework.Scenes
3129 int yaxis = 4; 3079 int yaxis = 4;
3130 int zaxis = 8; 3080 int zaxis = 8;
3131 3081
3132 if (m_rootPart != null) 3082 setX = ((axis & xaxis) != 0) ? true : false;
3133 { 3083 setY = ((axis & yaxis) != 0) ? true : false;
3134 setX = ((axis & xaxis) != 0) ? true : false; 3084 setZ = ((axis & zaxis) != 0) ? true : false;
3135 setY = ((axis & yaxis) != 0) ? true : false;
3136 setZ = ((axis & zaxis) != 0) ? true : false;
3137 3085
3138 float setval = (rotate10 > 0) ? 1f : 0f; 3086 float setval = (rotate10 > 0) ? 1f : 0f;
3139 3087
3140 if (setX) 3088 if (setX)
3141 m_rootPart.RotationAxis.X = setval; 3089 m_rootPart.RotationAxis.X = setval;
3142 if (setY) 3090 if (setY)
3143 m_rootPart.RotationAxis.Y = setval; 3091 m_rootPart.RotationAxis.Y = setval;
3144 if (setZ) 3092 if (setZ)
3145 m_rootPart.RotationAxis.Z = setval; 3093 m_rootPart.RotationAxis.Z = setval;
3146
3147 if (setX || setY || setZ)
3148 {
3149 m_rootPart.SetPhysicsAxisRotation();
3150 }
3151 3094
3095 if (setX || setY || setZ)
3096 {
3097 m_rootPart.SetPhysicsAxisRotation();
3152 } 3098 }
3153 } 3099 }
3154 3100
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b0d279c..51bb114 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -415,9 +415,10 @@ namespace OpenSim.Region.Framework.Scenes
415 set 415 set
416 { 416 {
417 m_name = value; 417 m_name = value;
418 if (PhysActor != null) 418 PhysicsActor pa = PhysActor;
419 if (pa != null)
419 { 420 {
420 PhysActor.SOPName = value; 421 pa.SOPName = value;
421 } 422 }
422 } 423 }
423 } 424 }
@@ -427,10 +428,11 @@ namespace OpenSim.Region.Framework.Scenes
427 get { return (byte) m_material; } 428 get { return (byte) m_material; }
428 set 429 set
429 { 430 {
431 PhysicsActor pa = PhysActor;
430 m_material = (Material)value; 432 m_material = (Material)value;
431 if (PhysActor != null) 433 if (pa != null)
432 { 434 {
433 PhysActor.SetMaterial((int)value); 435 pa.SetMaterial((int)value);
434 } 436 }
435 } 437 }
436 } 438 }
@@ -501,11 +503,12 @@ namespace OpenSim.Region.Framework.Scenes
501 get 503 get
502 { 504 {
503 // If this is a linkset, we don't want the physics engine mucking up our group position here. 505 // If this is a linkset, we don't want the physics engine mucking up our group position here.
504 if (PhysActor != null && _parentID == 0) 506 PhysicsActor pa = PhysActor;
507 if (pa != null && _parentID == 0)
505 { 508 {
506 m_groupPosition.X = PhysActor.Position.X; 509 m_groupPosition.X = pa.Position.X;
507 m_groupPosition.Y = PhysActor.Position.Y; 510 m_groupPosition.Y = pa.Position.Y;
508 m_groupPosition.Z = PhysActor.Position.Z; 511 m_groupPosition.Z = pa.Position.Z;
509 } 512 }
510 513
511 if (IsAttachment) 514 if (IsAttachment)
@@ -525,26 +528,27 @@ namespace OpenSim.Region.Framework.Scenes
525 528
526 m_groupPosition = value; 529 m_groupPosition = value;
527 530
528 if (PhysActor != null) 531 PhysicsActor pa = PhysActor;
532 if (pa != null)
529 { 533 {
530 try 534 try
531 { 535 {
532 // Root prim actually goes at Position 536 // Root prim actually goes at Position
533 if (_parentID == 0) 537 if (_parentID == 0)
534 { 538 {
535 PhysActor.Position = new PhysicsVector(value.X, value.Y, value.Z); 539 pa.Position = new PhysicsVector(value.X, value.Y, value.Z);
536 } 540 }
537 else 541 else
538 { 542 {
539 // To move the child prim in respect to the group position and rotation we have to calculate 543 // To move the child prim in respect to the group position and rotation we have to calculate
540 Vector3 resultingposition = GetWorldPosition(); 544 Vector3 resultingposition = GetWorldPosition();
541 PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); 545 pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z);
542 Quaternion resultingrot = GetWorldRotation(); 546 Quaternion resultingrot = GetWorldRotation();
543 PhysActor.Orientation = resultingrot; 547 pa.Orientation = resultingrot;
544 } 548 }
545 549
546 // Tell the physics engines that this prim changed. 550 // Tell the physics engines that this prim changed.
547 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 551 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
548 } 552 }
549 catch (Exception e) 553 catch (Exception e)
550 { 554 {
@@ -577,15 +581,16 @@ namespace OpenSim.Region.Framework.Scenes
577 581
578 if (ParentGroup != null && !ParentGroup.IsDeleted) 582 if (ParentGroup != null && !ParentGroup.IsDeleted)
579 { 583 {
580 if (_parentID != 0 && PhysActor != null) 584 PhysicsActor pa = PhysActor;
585 if (_parentID != 0 && pa != null)
581 { 586 {
582 Vector3 resultingposition = GetWorldPosition(); 587 Vector3 resultingposition = GetWorldPosition();
583 PhysActor.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z); 588 pa.Position = new PhysicsVector(resultingposition.X, resultingposition.Y, resultingposition.Z);
584 Quaternion resultingrot = GetWorldRotation(); 589 Quaternion resultingrot = GetWorldRotation();
585 PhysActor.Orientation = resultingrot; 590 pa.Orientation = resultingrot;
586 591
587 // Tell the physics engines that this prim changed. 592 // Tell the physics engines that this prim changed.
588 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 593 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
589 } 594 }
590 } 595 }
591 } 596 }
@@ -595,13 +600,14 @@ namespace OpenSim.Region.Framework.Scenes
595 { 600 {
596 get 601 get
597 { 602 {
603 PhysicsActor pa = PhysActor;
598 // We don't want the physics engine mucking up the rotations in a linkset 604 // We don't want the physics engine mucking up the rotations in a linkset
599 if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (PhysActor != null)) 605 if ((_parentID == 0) && (Shape.PCode != 9 || Shape.State == 0) && (pa != null))
600 { 606 {
601 if (PhysActor.Orientation.X != 0 || PhysActor.Orientation.Y != 0 607 if (pa.Orientation.X != 0 || pa.Orientation.Y != 0
602 || PhysActor.Orientation.Z != 0 || PhysActor.Orientation.W != 0) 608 || pa.Orientation.Z != 0 || pa.Orientation.W != 0)
603 { 609 {
604 m_rotationOffset = PhysActor.Orientation; 610 m_rotationOffset = pa.Orientation;
605 } 611 }
606 } 612 }
607 613
@@ -610,27 +616,28 @@ namespace OpenSim.Region.Framework.Scenes
610 616
611 set 617 set
612 { 618 {
619 PhysicsActor pa = PhysActor;
613 StoreUndoState(); 620 StoreUndoState();
614 m_rotationOffset = value; 621 m_rotationOffset = value;
615 622
616 if (PhysActor != null) 623 if (pa != null)
617 { 624 {
618 try 625 try
619 { 626 {
620 // Root prim gets value directly 627 // Root prim gets value directly
621 if (_parentID == 0) 628 if (_parentID == 0)
622 { 629 {
623 PhysActor.Orientation = value; 630 pa.Orientation = value;
624 //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString()); 631 //m_log.Info("[PART]: RO1:" + PhysActor.Orientation.ToString());
625 } 632 }
626 else 633 else
627 { 634 {
628 // Child prim we have to calculate it's world rotationwel 635 // Child prim we have to calculate it's world rotationwel
629 Quaternion resultingrotation = GetWorldRotation(); 636 Quaternion resultingrotation = GetWorldRotation();
630 PhysActor.Orientation = resultingrotation; 637 pa.Orientation = resultingrotation;
631 //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString()); 638 //m_log.Info("[PART]: RO2:" + PhysActor.Orientation.ToString());
632 } 639 }
633 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 640 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
634 //} 641 //}
635 } 642 }
636 catch (Exception ex) 643 catch (Exception ex)
@@ -650,13 +657,14 @@ namespace OpenSim.Region.Framework.Scenes
650 //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0 657 //if (PhysActor.Velocity.X != 0 || PhysActor.Velocity.Y != 0
651 //|| PhysActor.Velocity.Z != 0) 658 //|| PhysActor.Velocity.Z != 0)
652 //{ 659 //{
653 if (PhysActor != null) 660 PhysicsActor pa = PhysActor;
661 if (pa != null)
654 { 662 {
655 if (PhysActor.IsPhysical) 663 if (pa.IsPhysical)
656 { 664 {
657 m_velocity.X = PhysActor.Velocity.X; 665 m_velocity.X = pa.Velocity.X;
658 m_velocity.Y = PhysActor.Velocity.Y; 666 m_velocity.Y = pa.Velocity.Y;
659 m_velocity.Z = PhysActor.Velocity.Z; 667 m_velocity.Z = pa.Velocity.Z;
660 } 668 }
661 } 669 }
662 670
@@ -666,12 +674,13 @@ namespace OpenSim.Region.Framework.Scenes
666 set 674 set
667 { 675 {
668 m_velocity = value; 676 m_velocity = value;
669 if (PhysActor != null) 677 PhysicsActor pa = PhysActor;
678 if (pa != null)
670 { 679 {
671 if (PhysActor.IsPhysical) 680 if (pa.IsPhysical)
672 { 681 {
673 PhysActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); 682 pa.Velocity = new PhysicsVector(value.X, value.Y, value.Z);
674 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 683 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
675 } 684 }
676 } 685 }
677 } 686 }
@@ -688,9 +697,10 @@ namespace OpenSim.Region.Framework.Scenes
688 { 697 {
689 get 698 get
690 { 699 {
691 if ((PhysActor != null) && PhysActor.IsPhysical) 700 PhysicsActor pa = PhysActor;
701 if ((pa != null) && pa.IsPhysical)
692 { 702 {
693 m_angularVelocity.FromBytes(PhysActor.RotationalVelocity.GetBytes(), 0); 703 m_angularVelocity.FromBytes(pa.RotationalVelocity.GetBytes(), 0);
694 } 704 }
695 return m_angularVelocity; 705 return m_angularVelocity;
696 } 706 }
@@ -709,10 +719,11 @@ namespace OpenSim.Region.Framework.Scenes
709 get { return m_description; } 719 get { return m_description; }
710 set 720 set
711 { 721 {
722 PhysicsActor pa = PhysActor;
712 m_description = value; 723 m_description = value;
713 if (PhysActor != null) 724 if (pa != null)
714 { 725 {
715 PhysActor.SOPDescription = value; 726 pa.SOPDescription = value;
716 } 727 }
717 } 728 }
718 } 729 }
@@ -806,14 +817,15 @@ namespace OpenSim.Region.Framework.Scenes
806if (m_shape != null) { 817if (m_shape != null) {
807 m_shape.Scale = value; 818 m_shape.Scale = value;
808 819
809 if (PhysActor != null && m_parentGroup != null) 820 PhysicsActor pa = PhysActor;
821 if (pa != null && m_parentGroup != null)
810 { 822 {
811 if (m_parentGroup.Scene != null) 823 if (m_parentGroup.Scene != null)
812 { 824 {
813 if (m_parentGroup.Scene.PhysicsScene != null) 825 if (m_parentGroup.Scene.PhysicsScene != null)
814 { 826 {
815 PhysActor.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z); 827 pa.Size = new PhysicsVector(m_shape.Scale.X, m_shape.Scale.Y, m_shape.Scale.Z);
816 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 828 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
817 } 829 }
818 } 830 }
819 } 831 }
@@ -1343,13 +1355,14 @@ if (m_shape != null) {
1343 RigidBody); 1355 RigidBody);
1344 1356
1345 // Basic Physics returns null.. joy joy joy. 1357 // Basic Physics returns null.. joy joy joy.
1346 if (PhysActor != null) 1358 PhysicsActor pa = PhysActor;
1359 if (pa != null)
1347 { 1360 {
1348 PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info 1361 pa.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
1349 PhysActor.SOPDescription = this.Description; 1362 pa.SOPDescription = this.Description;
1350 PhysActor.LocalID = LocalId; 1363 pa.LocalID = LocalId;
1351 DoPhysicsPropertyUpdate(RigidBody, true); 1364 DoPhysicsPropertyUpdate(RigidBody, true);
1352 PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); 1365 pa.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
1353 } 1366 }
1354 } 1367 }
1355 } 1368 }
@@ -1563,23 +1576,24 @@ if (m_shape != null) {
1563 } 1576 }
1564 else 1577 else
1565 { 1578 {
1566 if (PhysActor != null) 1579 PhysicsActor pa = PhysActor;
1580 if (pa != null)
1567 { 1581 {
1568 if (UsePhysics != PhysActor.IsPhysical || isNew) 1582 if (UsePhysics != pa.IsPhysical || isNew)
1569 { 1583 {
1570 if (PhysActor.IsPhysical) // implies UsePhysics==false for this block 1584 if (pa.IsPhysical) // implies UsePhysics==false for this block
1571 { 1585 {
1572 if (!isNew) 1586 if (!isNew)
1573 ParentGroup.Scene.RemovePhysicalPrim(1); 1587 ParentGroup.Scene.RemovePhysicalPrim(1);
1574 1588
1575 PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; 1589 pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
1576 PhysActor.OnOutOfBounds -= PhysicsOutOfBounds; 1590 pa.OnOutOfBounds -= PhysicsOutOfBounds;
1577 PhysActor.delink(); 1591 pa.delink();
1578 1592
1579 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew)) 1593 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints && (!isNew))
1580 { 1594 {
1581 // destroy all joints connected to this now deactivated body 1595 // destroy all joints connected to this now deactivated body
1582 m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor); 1596 m_parentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
1583 } 1597 }
1584 1598
1585 // stop client-side interpolation of all joint proxy objects that have just been deleted 1599 // stop client-side interpolation of all joint proxy objects that have just been deleted
@@ -1598,7 +1612,7 @@ if (m_shape != null) {
1598 //RotationalVelocity = new Vector3(0, 0, 0); 1612 //RotationalVelocity = new Vector3(0, 0, 0);
1599 } 1613 }
1600 1614
1601 PhysActor.IsPhysical = UsePhysics; 1615 pa.IsPhysical = UsePhysics;
1602 1616
1603 1617
1604 // If we're not what we're supposed to be in the physics scene, recreate ourselves. 1618 // If we're not what we're supposed to be in the physics scene, recreate ourselves.
@@ -1612,19 +1626,19 @@ if (m_shape != null) {
1612 { 1626 {
1613 ParentGroup.Scene.AddPhysicalPrim(1); 1627 ParentGroup.Scene.AddPhysicalPrim(1);
1614 1628
1615 PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 1629 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
1616 PhysActor.OnOutOfBounds += PhysicsOutOfBounds; 1630 pa.OnOutOfBounds += PhysicsOutOfBounds;
1617 if (_parentID != 0 && _parentID != LocalId) 1631 if (_parentID != 0 && _parentID != LocalId)
1618 { 1632 {
1619 if (ParentGroup.RootPart.PhysActor != null) 1633 if (ParentGroup.RootPart.PhysActor != null)
1620 { 1634 {
1621 PhysActor.link(ParentGroup.RootPart.PhysActor); 1635 pa.link(ParentGroup.RootPart.PhysActor);
1622 } 1636 }
1623 } 1637 }
1624 } 1638 }
1625 } 1639 }
1626 } 1640 }
1627 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 1641 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
1628 } 1642 }
1629 } 1643 }
1630 } 1644 }
@@ -1690,9 +1704,10 @@ if (m_shape != null) {
1690 1704
1691 public Vector3 GetGeometricCenter() 1705 public Vector3 GetGeometricCenter()
1692 { 1706 {
1693 if (PhysActor != null) 1707 PhysicsActor pa = PhysActor;
1708 if (pa != null)
1694 { 1709 {
1695 return new Vector3(PhysActor.CenterOfMass.X, PhysActor.CenterOfMass.Y, PhysActor.CenterOfMass.Z); 1710 return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z);
1696 } 1711 }
1697 else 1712 else
1698 { 1713 {
@@ -1702,9 +1717,10 @@ if (m_shape != null) {
1702 1717
1703 public float GetMass() 1718 public float GetMass()
1704 { 1719 {
1705 if (PhysActor != null) 1720 PhysicsActor pa = PhysActor;
1721 if (pa != null)
1706 { 1722 {
1707 return PhysActor.Mass; 1723 return pa.Mass;
1708 } 1724 }
1709 else 1725 else
1710 { 1726 {
@@ -1714,8 +1730,9 @@ if (m_shape != null) {
1714 1730
1715 public PhysicsVector GetForce() 1731 public PhysicsVector GetForce()
1716 { 1732 {
1717 if (PhysActor != null) 1733 PhysicsActor pa = PhysActor;
1718 return PhysActor.Force; 1734 if (pa != null)
1735 return pa.Force;
1719 else 1736 else
1720 return new PhysicsVector(); 1737 return new PhysicsVector();
1721 } 1738 }
@@ -2094,11 +2111,15 @@ if (m_shape != null) {
2094 2111
2095 public void PhysicsRequestingTerseUpdate() 2112 public void PhysicsRequestingTerseUpdate()
2096 { 2113 {
2097 if (PhysActor != null) 2114 PhysicsActor pa = PhysActor;
2115 if (pa != null)
2098 { 2116 {
2099 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); 2117 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0);
2100 2118
2101 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) 2119 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) |
2120 m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) |
2121 m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) |
2122 m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2102 { 2123 {
2103 m_parentGroup.AbsolutePosition = newpos; 2124 m_parentGroup.AbsolutePosition = newpos;
2104 return; 2125 return;
@@ -2294,14 +2315,15 @@ if (m_shape != null) {
2294 if (texture != null) 2315 if (texture != null)
2295 m_shape.SculptData = texture.Data; 2316 m_shape.SculptData = texture.Data;
2296 2317
2297 if (PhysActor != null) 2318 PhysicsActor pa = PhysActor;
2319 if (pa != null)
2298 { 2320 {
2299 // Tricks physics engine into thinking we've changed the part shape. 2321 // Tricks physics engine into thinking we've changed the part shape.
2300 PrimitiveBaseShape m_newshape = m_shape.Copy(); 2322 PrimitiveBaseShape m_newshape = m_shape.Copy();
2301 PhysActor.Shape = m_newshape; 2323 pa.Shape = m_newshape;
2302 m_shape = m_newshape; 2324 m_shape = m_newshape;
2303 2325
2304 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 2326 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
2305 } 2327 }
2306 } 2328 }
2307 } 2329 }
@@ -2520,9 +2542,10 @@ if (m_shape != null) {
2520 2542
2521 public void SetBuoyancy(float fvalue) 2543 public void SetBuoyancy(float fvalue)
2522 { 2544 {
2523 if (PhysActor != null) 2545 PhysicsActor pa = PhysActor;
2546 if (pa != null)
2524 { 2547 {
2525 PhysActor.Buoyancy = fvalue; 2548 pa.Buoyancy = fvalue;
2526 } 2549 }
2527 } 2550 }
2528 2551
@@ -2538,56 +2561,62 @@ if (m_shape != null) {
2538 2561
2539 public void SetFloatOnWater(int floatYN) 2562 public void SetFloatOnWater(int floatYN)
2540 { 2563 {
2541 if (PhysActor != null) 2564 PhysicsActor pa = PhysActor;
2565 if (pa != null)
2542 { 2566 {
2543 if (floatYN == 1) 2567 if (floatYN == 1)
2544 { 2568 {
2545 PhysActor.FloatOnWater = true; 2569 pa.FloatOnWater = true;
2546 } 2570 }
2547 else 2571 else
2548 { 2572 {
2549 PhysActor.FloatOnWater = false; 2573 pa.FloatOnWater = false;
2550 } 2574 }
2551 } 2575 }
2552 } 2576 }
2553 2577
2554 public void SetForce(PhysicsVector force) 2578 public void SetForce(PhysicsVector force)
2555 { 2579 {
2556 if (PhysActor != null) 2580 PhysicsActor pa = PhysActor;
2581 if (pa != null)
2557 { 2582 {
2558 PhysActor.Force = force; 2583 pa.Force = force;
2559 } 2584 }
2560 } 2585 }
2561 2586
2562 public void SetVehicleType(int type) 2587 public void SetVehicleType(int type)
2563 { 2588 {
2564 if (PhysActor != null) 2589 PhysicsActor pa = PhysActor;
2590 if (pa != null)
2565 { 2591 {
2566 PhysActor.VehicleType = type; 2592 pa.VehicleType = type;
2567 } 2593 }
2568 } 2594 }
2569 2595
2570 public void SetVehicleFloatParam(int param, float value) 2596 public void SetVehicleFloatParam(int param, float value)
2571 { 2597 {
2572 if (PhysActor != null) 2598 PhysicsActor pa = PhysActor;
2599 if (pa != null)
2573 { 2600 {
2574 PhysActor.VehicleFloatParam(param, value); 2601 pa.VehicleFloatParam(param, value);
2575 } 2602 }
2576 } 2603 }
2577 2604
2578 public void SetVehicleVectorParam(int param, PhysicsVector value) 2605 public void SetVehicleVectorParam(int param, PhysicsVector value)
2579 { 2606 {
2580 if (PhysActor != null) 2607 PhysicsActor pa = PhysActor;
2608 if (pa != null)
2581 { 2609 {
2582 PhysActor.VehicleVectorParam(param, value); 2610 pa.VehicleVectorParam(param, value);
2583 } 2611 }
2584 } 2612 }
2585 2613
2586 public void SetVehicleRotationParam(int param, Quaternion rotation) 2614 public void SetVehicleRotationParam(int param, Quaternion rotation)
2587 { 2615 {
2588 if (PhysActor != null) 2616 PhysicsActor pa = PhysActor;
2617 if (pa != null)
2589 { 2618 {
2590 PhysActor.VehicleRotationParam(param, rotation); 2619 pa.VehicleRotationParam(param, rotation);
2591 } 2620 }
2592 } 2621 }
2593 2622
@@ -2615,10 +2644,11 @@ if (m_shape != null) {
2615 2644
2616 public void SetPhysicsAxisRotation() 2645 public void SetPhysicsAxisRotation()
2617 { 2646 {
2618 if (PhysActor != null) 2647 PhysicsActor pa = PhysActor;
2648 if (pa != null)
2619 { 2649 {
2620 PhysActor.LockAngularMotion(RotationAxis); 2650 pa.LockAngularMotion(RotationAxis);
2621 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 2651 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
2622 } 2652 }
2623 } 2653 }
2624 2654
@@ -3350,8 +3380,9 @@ if (m_shape != null) {
3350 { 3380 {
3351 IsVD = false; // Switch it of for the course of this routine 3381 IsVD = false; // Switch it of for the course of this routine
3352 VolumeDetectActive = false; // and also permanently 3382 VolumeDetectActive = false; // and also permanently
3353 if (PhysActor != null) 3383 PhysicsActor pa = PhysActor;
3354 PhysActor.SetVolumeDetect(0); // Let physics know about it too 3384 if (pa != null)
3385 pa.SetVolumeDetect(0); // Let physics know about it too
3355 } 3386 }
3356 else 3387 else
3357 { 3388 {
@@ -3399,18 +3430,21 @@ if (m_shape != null) {
3399 if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints 3430 if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints
3400 { 3431 {
3401 AddFlag(PrimFlags.Phantom); 3432 AddFlag(PrimFlags.Phantom);
3402 if (PhysActor != null) 3433 PhysicsActor pa = PhysActor;
3434 if (pa != null)
3403 { 3435 {
3404 m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); 3436 m_parentGroup.Scene.PhysicsScene.RemovePrim(pa);
3405 /// that's not wholesome. Had to make Scene public 3437 /// that's not wholesome. Had to make Scene public
3406 PhysActor = null; 3438 pa = null;
3407 } 3439 }
3408 } 3440 }
3409 else // Not phantom 3441 else // Not phantom
3410 { 3442 {
3411 RemFlag(PrimFlags.Phantom); 3443 RemFlag(PrimFlags.Phantom);
3412 3444
3413 if (PhysActor == null) 3445 // This is NOT safe!!
3446 PhysicsActor pa = PhysActor;
3447 if (pa == null)
3414 { 3448 {
3415 // It's not phantom anymore. So make sure the physics engine get's knowledge of it 3449 // It's not phantom anymore. So make sure the physics engine get's knowledge of it
3416 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( 3450 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
@@ -3421,9 +3455,9 @@ if (m_shape != null) {
3421 RotationOffset, 3455 RotationOffset,
3422 UsePhysics); 3456 UsePhysics);
3423 3457
3424 if (PhysActor != null) 3458 if (pa != null)
3425 { 3459 {
3426 PhysActor.LocalID = LocalId; 3460 pa.LocalID = LocalId;
3427 DoPhysicsPropertyUpdate(UsePhysics, true); 3461 DoPhysicsPropertyUpdate(UsePhysics, true);
3428 if (m_parentGroup != null) 3462 if (m_parentGroup != null)
3429 { 3463 {
@@ -3442,14 +3476,14 @@ if (m_shape != null) {
3442 (CollisionSound != UUID.Zero) 3476 (CollisionSound != UUID.Zero)
3443 ) 3477 )
3444 { 3478 {
3445 PhysActor.OnCollisionUpdate += PhysicsCollision; 3479 pa.OnCollisionUpdate += PhysicsCollision;
3446 PhysActor.SubscribeEvents(1000); 3480 pa.SubscribeEvents(1000);
3447 } 3481 }
3448 } 3482 }
3449 } 3483 }
3450 else // it already has a physical representation 3484 else // it already has a physical representation
3451 { 3485 {
3452 PhysActor.IsPhysical = UsePhysics; 3486 pa.IsPhysical = UsePhysics;
3453 3487
3454 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim 3488 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
3455 if (m_parentGroup != null) 3489 if (m_parentGroup != null)
@@ -3472,9 +3506,10 @@ if (m_shape != null) {
3472 // Defensive programming calls for a check here. 3506 // Defensive programming calls for a check here.
3473 // Better would be throwing an exception that could be catched by a unit test as the internal 3507 // Better would be throwing an exception that could be catched by a unit test as the internal
3474 // logic should make sure, this Physactor is always here. 3508 // logic should make sure, this Physactor is always here.
3475 if (this.PhysActor != null) 3509 PhysicsActor pa = this.PhysActor;
3510 if (pa != null)
3476 { 3511 {
3477 PhysActor.SetVolumeDetect(1); 3512 pa.SetVolumeDetect(1);
3478 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active 3513 AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
3479 this.VolumeDetectActive = true; 3514 this.VolumeDetectActive = true;
3480 } 3515 }
@@ -3482,10 +3517,11 @@ if (m_shape != null) {
3482 } 3517 }
3483 else 3518 else
3484 { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like 3519 { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
3485 // (mumbles, well, at least if you have infinte CPU powers :-)) 3520 // (mumbles, well, at least if you have infinte CPU powers :-) )
3486 if (this.PhysActor != null) 3521 PhysicsActor pa = this.PhysActor;
3522 if (pa != null)
3487 { 3523 {
3488 PhysActor.SetVolumeDetect(0); 3524 pa.SetVolumeDetect(0);
3489 } 3525 }
3490 this.VolumeDetectActive = false; 3526 this.VolumeDetectActive = false;
3491 } 3527 }
@@ -3543,10 +3579,11 @@ if (m_shape != null) {
3543 m_shape.PathTaperY = shapeBlock.PathTaperY; 3579 m_shape.PathTaperY = shapeBlock.PathTaperY;
3544 m_shape.PathTwist = shapeBlock.PathTwist; 3580 m_shape.PathTwist = shapeBlock.PathTwist;
3545 m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; 3581 m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
3546 if (PhysActor != null) 3582 PhysicsActor pa = PhysActor;
3583 if (pa != null)
3547 { 3584 {
3548 PhysActor.Shape = m_shape; 3585 pa.Shape = m_shape;
3549 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 3586 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
3550 } 3587 }
3551 3588
3552 // This is what makes vehicle trailers work 3589 // This is what makes vehicle trailers work
@@ -3647,19 +3684,21 @@ if (m_shape != null) {
3647 ) 3684 )
3648 { 3685 {
3649 // subscribe to physics updates. 3686 // subscribe to physics updates.
3650 if (PhysActor != null) 3687 PhysicsActor pa = PhysActor;
3688 if (pa != null)
3651 { 3689 {
3652 PhysActor.OnCollisionUpdate += PhysicsCollision; 3690 pa.OnCollisionUpdate += PhysicsCollision;
3653 PhysActor.SubscribeEvents(1000); 3691 pa.SubscribeEvents(1000);
3654 3692
3655 } 3693 }
3656 } 3694 }
3657 else 3695 else
3658 { 3696 {
3659 if (PhysActor != null) 3697 PhysicsActor pa = PhysActor;
3698 if (pa != null)
3660 { 3699 {
3661 PhysActor.UnSubscribeEvents(); 3700 pa.UnSubscribeEvents();
3662 PhysActor.OnCollisionUpdate -= PhysicsCollision; 3701 pa.OnCollisionUpdate -= PhysicsCollision;
3663 } 3702 }
3664 } 3703 }
3665 3704
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 23fe2d3..6772f75 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2269,7 +2269,7 @@ namespace OpenSim.Region.Framework.Scenes
2269 { 2269 {
2270 //Record the time we enter this state so we know whether to "land" or not 2270 //Record the time we enter this state so we know whether to "land" or not
2271 m_animPersistUntil = DateTime.Now.Ticks; 2271 m_animPersistUntil = DateTime.Now.Ticks;
2272 return "FALLDOWN"; 2272 return "FALLDOWN"; // this falling animation is invoked too frequently when capsule tilt correction is used - why?
2273 } 2273 }
2274 } 2274 }
2275 } 2275 }
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 5ae81cd..fe74158 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -65,8 +65,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
65 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); 65 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
66 //int time = System.Environment.TickCount; 66 //int time = System.Environment.TickCount;
67 67
68 SceneObjectGroup sceneObject = new SceneObjectGroup();
69
70 // libomv.types changes UUID to Guid 68 // libomv.types changes UUID to Guid
71 xmlData = xmlData.Replace("<UUID>", "<Guid>"); 69 xmlData = xmlData.Replace("<UUID>", "<Guid>");
72 xmlData = xmlData.Replace("</UUID>", "</Guid>"); 70 xmlData = xmlData.Replace("</UUID>", "</Guid>");
@@ -88,17 +86,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
88 parts = doc.GetElementsByTagName("RootPart"); 86 parts = doc.GetElementsByTagName("RootPart");
89 87
90 if (parts.Count == 0) 88 if (parts.Count == 0)
91 {
92 throw new Exception("Invalid Xml format - no root part"); 89 throw new Exception("Invalid Xml format - no root part");
93 } 90
94 else 91 sr = new StringReader(parts[0].InnerXml);
95 { 92 reader = new XmlTextReader(sr);
96 sr = new StringReader(parts[0].InnerXml); 93 SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(fromUserInventoryItemID, reader));
97 reader = new XmlTextReader(sr); 94 reader.Close();
98 sceneObject.SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader)); 95 sr.Close();
99 reader.Close();
100 sr.Close();
101 }
102 96
103 parts = doc.GetElementsByTagName("Part"); 97 parts = doc.GetElementsByTagName("Part");
104 98
@@ -119,16 +113,15 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
119 // Script state may, or may not, exist. Not having any, is NOT 113 // Script state may, or may not, exist. Not having any, is NOT
120 // ever a problem. 114 // ever a problem.
121 sceneObject.LoadScriptState(doc); 115 sceneObject.LoadScriptState(doc);
116
117 return sceneObject;
122 } 118 }
123 catch (Exception e) 119 catch (Exception e)
124 { 120 {
125 m_log.ErrorFormat( 121 m_log.ErrorFormat(
126 "[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); 122 "[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData);
123 return null;
127 } 124 }
128
129 //m_log.DebugFormat("[SERIALIZER]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
130
131 return sceneObject;
132 } 125 }
133 126
134 /// <summary> 127 /// <summary>
@@ -194,8 +187,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
194 { 187 {
195 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); 188 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
196 //int time = System.Environment.TickCount; 189 //int time = System.Environment.TickCount;
197
198 SceneObjectGroup sceneObject = new SceneObjectGroup();
199 190
200 // libomv.types changes UUID to Guid 191 // libomv.types changes UUID to Guid
201 xmlData = xmlData.Replace("<UUID>", "<Guid>"); 192 xmlData = xmlData.Replace("<UUID>", "<Guid>");
@@ -212,21 +203,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
212 203
213 XmlNodeList parts = doc.GetElementsByTagName("SceneObjectPart"); 204 XmlNodeList parts = doc.GetElementsByTagName("SceneObjectPart");
214 205
215 // Process the root part first 206 if (parts.Count == 0)
216 if (parts.Count > 0)
217 { 207 {
218 StringReader sr = new StringReader(parts[0].OuterXml); 208 m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed: No SceneObjectPart nodes. xml was " + xmlData);
219 XmlTextReader reader = new XmlTextReader(sr); 209 return null;
220 sceneObject.SetRootPart(SceneObjectPart.FromXml(reader));
221 reader.Close();
222 sr.Close();
223 } 210 }
224 211
212 StringReader sr = new StringReader(parts[0].OuterXml);
213 XmlTextReader reader = new XmlTextReader(sr);
214 SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader));
215 reader.Close();
216 sr.Close();
217
225 // Then deal with the rest 218 // Then deal with the rest
226 for (int i = 1; i < parts.Count; i++) 219 for (int i = 1; i < parts.Count; i++)
227 { 220 {
228 StringReader sr = new StringReader(parts[i].OuterXml); 221 sr = new StringReader(parts[i].OuterXml);
229 XmlTextReader reader = new XmlTextReader(sr); 222 reader = new XmlTextReader(sr);
230 SceneObjectPart part = SceneObjectPart.FromXml(reader); 223 SceneObjectPart part = SceneObjectPart.FromXml(reader);
231 sceneObject.AddPart(part); 224 sceneObject.AddPart(part);
232 part.StoreUndoState(); 225 part.StoreUndoState();
@@ -238,15 +231,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
238 // ever a problem. 231 // ever a problem.
239 232
240 sceneObject.LoadScriptState(doc); 233 sceneObject.LoadScriptState(doc);
234 return sceneObject;
241 } 235 }
242 catch (Exception e) 236 catch (Exception e)
243 { 237 {
244 m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); 238 m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData);
239 return null;
245 } 240 }
246
247 //m_log.DebugFormat("[SERIALIZER]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
248
249 return sceneObject;
250 } 241 }
251 242
252 /// <summary> 243 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
index bb8f27d..3b0e77f 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
@@ -128,7 +128,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
128 128
129 private SceneObjectGroup NewSOG() 129 private SceneObjectGroup NewSOG()
130 { 130 {
131 SceneObjectGroup sog = new SceneObjectGroup();
132 SceneObjectPart sop = new SceneObjectPart(UUID.Random(), PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero); 131 SceneObjectPart sop = new SceneObjectPart(UUID.Random(), PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero);
133 sop.Name = RandomName(); 132 sop.Name = RandomName();
134 sop.Description = sop.Name; 133 sop.Description = sop.Name;
@@ -136,9 +135,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
136 sop.SitName = RandomName(); 135 sop.SitName = RandomName();
137 sop.TouchName = RandomName(); 136 sop.TouchName = RandomName();
138 sop.ObjectFlags |= (uint)PrimFlags.Phantom; 137 sop.ObjectFlags |= (uint)PrimFlags.Phantom;
139
140 sog.SetRootPart(sop);
141 138
139 SceneObjectGroup sog = new SceneObjectGroup(sop);
142 scene.AddNewSceneObject(sog, false); 140 scene.AddNewSceneObject(sog, false);
143 141
144 return sog; 142 return sog;
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
index 7fb2d25..19c0fea 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
@@ -407,9 +407,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
407 sop.Shape.State = 1; 407 sop.Shape.State = 1;
408 sop.OwnerID = agent; 408 sop.OwnerID = agent;
409 409
410 SceneObjectGroup sog = new SceneObjectGroup(); 410 SceneObjectGroup sog = new SceneObjectGroup(sop);
411 sog.SetScene(scene); 411 sog.SetScene(scene);
412 sog.SetRootPart(sop);
413 412
414 return sog; 413 return sog;
415 } 414 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 65c5274..6b30959 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -53,7 +53,7 @@ using System.Text.RegularExpressions;
53 53
54namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice 54namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
55{ 55{
56 public class FreeSwitchVoiceModule : IRegionModule 56 public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule
57 { 57 {
58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 59
@@ -101,13 +101,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
101 private FreeSwitchDialplan m_FreeSwitchDialplan; 101 private FreeSwitchDialplan m_FreeSwitchDialplan;
102 102
103 private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>(); 103 private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>();
104 private Dictionary<string, string> m_ParcelAddress = new Dictionary<string, string>();
105
106 private Scene m_scene;
104 107
105 108
106 private IConfig m_config; 109 private IConfig m_config;
107 110
108 public void Initialise(Scene scene, IConfigSource config) 111 public void Initialise(Scene scene, IConfigSource config)
109 { 112 {
110 113 m_scene = scene;
111 m_config = config.Configs["FreeSwitchVoice"]; 114 m_config = config.Configs["FreeSwitchVoice"];
112 115
113 if (null == m_config) 116 if (null == m_config)
@@ -230,6 +233,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
230 { 233 {
231 OnRegisterCaps(scene, agentID, caps); 234 OnRegisterCaps(scene, agentID, caps);
232 }; 235 };
236
237
233 238
234 try 239 try
235 { 240 {
@@ -255,6 +260,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
255 260
256 public void PostInitialise() 261 public void PostInitialise()
257 { 262 {
263 if(m_pluginEnabled)
264 {
265 m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene");
266
267 // register the voice interface for this module, so the script engine can call us
268 m_scene.RegisterModuleInterface<IVoiceModule>(this);
269 }
258 } 270 }
259 271
260 public void Close() 272 public void Close()
@@ -270,7 +282,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
270 { 282 {
271 get { return true; } 283 get { return true; }
272 } 284 }
273 285
286 // <summary>
287 // implementation of IVoiceModule, called by osSetParcelSIPAddress script function
288 // </summary>
289 public void setLandSIPAddress(string SIPAddress,UUID GlobalID)
290 {
291 m_log.DebugFormat("[FreeSwitchVoice]: setLandSIPAddress parcel id {0}: setting sip address {1}",
292 GlobalID, SIPAddress);
293
294 lock (m_ParcelAddress)
295 {
296 if (m_ParcelAddress.ContainsKey(GlobalID.ToString()))
297 {
298 m_ParcelAddress[GlobalID.ToString()] = SIPAddress;
299 }
300 else
301 {
302 m_ParcelAddress.Add(GlobalID.ToString(), SIPAddress);
303 }
304 }
305 }
274 306
275 // <summary> 307 // <summary>
276 // OnRegisterCaps is invoked via the scene.EventManager 308 // OnRegisterCaps is invoked via the scene.EventManager
@@ -776,6 +808,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
776 808
777 // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same 809 // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same
778 // as the directory ID. Otherwise, it reflects the parcel's ID. 810 // as the directory ID. Otherwise, it reflects the parcel's ID.
811
812 lock (m_ParcelAddress)
813 {
814 if (m_ParcelAddress.ContainsKey( land.GlobalID.ToString() ))
815 {
816 m_log.DebugFormat("[FreeSwitchVoice]: parcel id {0}: using sip address {1}",
817 land.GlobalID, m_ParcelAddress[land.GlobalID.ToString()]);
818 return m_ParcelAddress[land.GlobalID.ToString()];
819 }
820 }
779 821
780 if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0) 822 if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0)
781 { 823 {
@@ -797,6 +839,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
797 // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator. 839 // the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator.
798 channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm); 840 channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm);
799 841
842 lock (m_ParcelAddress)
843 {
844 if (!m_ParcelAddress.ContainsKey(land.GlobalID.ToString()))
845 {
846 m_ParcelAddress.Add(land.GlobalID.ToString(),channelUri);
847 }
848 }
800 849
801 return channelUri; 850 return channelUri;
802 } 851 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 37e1ed4..d5cbfd4 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -281,7 +281,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
281 281
282 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 282 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
283 { 283 {
284 GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); 284 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
285
286 //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray();
287 GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID);
285 remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); 288 remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups);
286 } 289 }
287 290
@@ -485,6 +488,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
485 bucket[18] = 0; //dunno 488 bucket[18] = 0; //dunno
486 } 489 }
487 490
491
488 m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); 492 m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
489 if (OnNewGroupNotice != null) 493 if (OnNewGroupNotice != null)
490 { 494 {
@@ -494,7 +498,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
494 // Send notice out to everyone that wants notices 498 // Send notice out to everyone that wants notices
495 foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) 499 foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID))
496 { 500 {
497 if (member.AcceptNotices) 501 if (m_debugEnabled)
502 {
503 UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID);
504 if (targetUserProfile != null)
505 {
506 m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices);
507 }
508 else
509 {
510 m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices);
511 }
512 }
513
514 if (member.AcceptNotices)
498 { 515 {
499 // Build notice IIM 516 // Build notice IIM
500 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); 517 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
@@ -614,13 +631,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
614 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 631 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
615 632
616 List<GroupMembersData> data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); 633 List<GroupMembersData> data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID);
617 if (m_debugEnabled)
618 {
619 foreach (GroupMembersData member in data)
620 {
621 m_log.DebugFormat("[GROUPS]: {0} {1}", member.AgentID, member.Title);
622 }
623 }
624 634
625 return data; 635 return data;
626 636
@@ -632,14 +642,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
632 642
633 List<GroupRolesData> data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); 643 List<GroupRolesData> data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID);
634 644
635 if (m_debugEnabled)
636 {
637 foreach (GroupRolesData member in data)
638 {
639 m_log.DebugFormat("[GROUPS]: {0} {1}", member.Title, member.Members);
640 }
641 }
642
643 return data; 645 return data;
644 646
645 } 647 }
@@ -650,14 +652,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
650 652
651 List<GroupRoleMembersData> data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); 653 List<GroupRoleMembersData> data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID);
652 654
653 if (m_debugEnabled)
654 {
655 foreach (GroupRoleMembersData member in data)
656 {
657 m_log.DebugFormat("[GROUPS]: Av: {0} Role: {1}", member.MemberID, member.RoleID);
658 }
659 }
660
661 return data; 655 return data;
662 656
663 657
@@ -808,7 +802,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
808 { 802 {
809 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 803 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
810 804
811 // TODO: Security Checks? 805 // Security Checks are handled in the Groups Service.
812 806
813 GroupRequestID grID = GetClientGroupRequestID(remoteClient); 807 GroupRequestID grID = GetClientGroupRequestID(remoteClient);
814 808
@@ -825,6 +819,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
825 case OpenMetaverse.GroupRoleUpdate.UpdateAll: 819 case OpenMetaverse.GroupRoleUpdate.UpdateAll:
826 case OpenMetaverse.GroupRoleUpdate.UpdateData: 820 case OpenMetaverse.GroupRoleUpdate.UpdateData:
827 case OpenMetaverse.GroupRoleUpdate.UpdatePowers: 821 case OpenMetaverse.GroupRoleUpdate.UpdatePowers:
822 if (m_debugEnabled)
823 {
824 GroupPowers gp = (GroupPowers)powers;
825 m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString());
826 }
828 m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); 827 m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers);
829 break; 828 break;
830 829
@@ -1195,6 +1194,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1195 1194
1196 foreach (GroupMembershipData membership in data) 1195 foreach (GroupMembershipData membership in data)
1197 { 1196 {
1197 if (remoteClient.AgentId != dataForAgentID)
1198 {
1199 if (!membership.ListInProfile)
1200 {
1201 // If we're sending group info to remoteclient about another agent,
1202 // filter out groups the other agent doesn't want to share.
1203 continue;
1204 }
1205 }
1206
1198 OSDMap GroupDataMap = new OSDMap(6); 1207 OSDMap GroupDataMap = new OSDMap(6);
1199 OSDMap NewGroupDataMap = new OSDMap(1); 1208 OSDMap NewGroupDataMap = new OSDMap(1);
1200 1209
@@ -1281,11 +1290,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1281 // to the core Groups Stub 1290 // to the core Groups Stub
1282 remoteClient.SendGroupMembership(new GroupMembershipData[0]); 1291 remoteClient.SendGroupMembership(new GroupMembershipData[0]);
1283 1292
1284 GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), dataForAgentID).ToArray(); 1293 GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID);
1294 SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray);
1295 remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
1285 1296
1286 SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipData); 1297 }
1287 remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipData); 1298
1299 /// <summary>
1300 /// Get a list of groups memberships for the agent that are marked "ListInProfile"
1301 /// </summary>
1302 /// <param name="dataForAgentID"></param>
1303 /// <returns></returns>
1304 private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID)
1305 {
1306 List<GroupMembershipData> membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID);
1307 GroupMembershipData[] membershipArray;
1308
1309 if (requestingClient.AgentId != dataForAgentID)
1310 {
1311 Predicate<GroupMembershipData> showInProfile = delegate(GroupMembershipData membership)
1312 {
1313 return membership.ListInProfile;
1314 };
1315
1316 membershipArray = membershipData.FindAll(showInProfile).ToArray();
1317 }
1318 else
1319 {
1320 membershipArray = membershipData.ToArray();
1321 }
1322
1323 if (m_debugEnabled)
1324 {
1325 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
1326 foreach (GroupMembershipData membership in membershipArray)
1327 {
1328 m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle);
1329 }
1330 }
1288 1331
1332 return membershipArray;
1289 } 1333 }
1290 1334
1291 private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) 1335 private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle)
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
index b3eaa37..805c3d4 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
@@ -855,16 +855,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
855 IList parameters = new ArrayList(); 855 IList parameters = new ArrayList();
856 parameters.Add(param); 856 parameters.Add(param);
857 857
858 XmlRpcRequest req; 858 ConfigurableKeepAliveXmlRpcRequest req;
859 if (!m_disableKeepAlive) 859 req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive);
860 {
861 req = new XmlRpcRequest(function, parameters);
862 }
863 else
864 {
865 // This seems to solve a major problem on some windows servers
866 req = new NoKeepAliveXmlRpcRequest(function, parameters);
867 }
868 860
869 XmlRpcResponse resp = null; 861 XmlRpcResponse resp = null;
870 862
@@ -874,10 +866,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
874 } 866 }
875 catch (Exception e) 867 catch (Exception e)
876 { 868 {
869
870
877 m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); 871 m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function);
878 m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); 872 m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString());
879 873
880 874 foreach( string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None))
875 {
876 m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine);
877 }
878
881 foreach (string key in param.Keys) 879 foreach (string key in param.Keys)
882 { 880 {
883 m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); 881 m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString());
@@ -961,20 +959,24 @@ namespace Nwc.XmlRpc
961 using System.Reflection; 959 using System.Reflection;
962 960
963 /// <summary>Class supporting the request side of an XML-RPC transaction.</summary> 961 /// <summary>Class supporting the request side of an XML-RPC transaction.</summary>
964 public class NoKeepAliveXmlRpcRequest : XmlRpcRequest 962 public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest
965 { 963 {
966 private Encoding _encoding = new ASCIIEncoding(); 964 private Encoding _encoding = new ASCIIEncoding();
967 private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); 965 private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer();
968 private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); 966 private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer();
967 private bool _disableKeepAlive = true;
968
969 public string RequestResponse = String.Empty;
969 970
970 /// <summary>Instantiate an <c>XmlRpcRequest</c> for a specified method and parameters.</summary> 971 /// <summary>Instantiate an <c>XmlRpcRequest</c> for a specified method and parameters.</summary>
971 /// <param name="methodName"><c>String</c> designating the <i>object.method</i> on the server the request 972 /// <param name="methodName"><c>String</c> designating the <i>object.method</i> on the server the request
972 /// should be directed to.</param> 973 /// should be directed to.</param>
973 /// <param name="parameters"><c>ArrayList</c> of XML-RPC type parameters to invoke the request with.</param> 974 /// <param name="parameters"><c>ArrayList</c> of XML-RPC type parameters to invoke the request with.</param>
974 public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) 975 public ConfigurableKeepAliveXmlRpcRequest(String methodName, IList parameters, bool disableKeepAlive)
975 { 976 {
976 MethodName = methodName; 977 MethodName = methodName;
977 _params = parameters; 978 _params = parameters;
979 _disableKeepAlive = disableKeepAlive;
978 } 980 }
979 981
980 /// <summary>Send the request to the server.</summary> 982 /// <summary>Send the request to the server.</summary>
@@ -989,7 +991,7 @@ namespace Nwc.XmlRpc
989 request.Method = "POST"; 991 request.Method = "POST";
990 request.ContentType = "text/xml"; 992 request.ContentType = "text/xml";
991 request.AllowWriteStreamBuffering = true; 993 request.AllowWriteStreamBuffering = true;
992 request.KeepAlive = false; 994 request.KeepAlive = !_disableKeepAlive;
993 995
994 Stream stream = request.GetRequestStream(); 996 Stream stream = request.GetRequestStream();
995 XmlTextWriter xml = new XmlTextWriter(stream, _encoding); 997 XmlTextWriter xml = new XmlTextWriter(stream, _encoding);
@@ -1000,7 +1002,17 @@ namespace Nwc.XmlRpc
1000 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 1002 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
1001 StreamReader input = new StreamReader(response.GetResponseStream()); 1003 StreamReader input = new StreamReader(response.GetResponseStream());
1002 1004
1003 XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); 1005 string inputXml = input.ReadToEnd();
1006 XmlRpcResponse resp;
1007 try
1008 {
1009 resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml);
1010 }
1011 catch (Exception e)
1012 {
1013 RequestResponse = inputXml;
1014 throw e;
1015 }
1004 input.Close(); 1016 input.Close();
1005 response.Close(); 1017 response.Close();
1006 return resp; 1018 return resp;
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
index 59b7289..fbe43d6 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
@@ -66,7 +66,6 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
66 66
67 private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos) 67 private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos)
68 { 68 {
69 SceneObjectGroup x = new SceneObjectGroup();
70 SceneObjectPart y = new SceneObjectPart(); 69 SceneObjectPart y = new SceneObjectPart();
71 70
72 //Initialize part 71 //Initialize part
@@ -93,8 +92,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
93 y.TrimPermissions(); 92 y.TrimPermissions();
94 93
95 //Initialize group and add part as root part 94 //Initialize group and add part as root part
95 SceneObjectGroup x = new SceneObjectGroup(y);
96 x.SetScene(scene); 96 x.SetScene(scene);
97 x.SetRootPart(y);
98 x.RegionHandle = scene.RegionInfo.RegionHandle; 97 x.RegionHandle = scene.RegionInfo.RegionHandle;
99 x.SetScene(scene); 98 x.SetScene(scene);
100 99
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index dd58a4e..a00ba11 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -107,6 +107,7 @@ namespace OpenSim.Region.Physics.OdePlugin
107 public float MinimumGroundFlightOffset = 3f; 107 public float MinimumGroundFlightOffset = 3f;
108 108
109 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. 109 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
110 private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f; // used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider
110 111
111 112
112 private float m_buoyancy = 0f; 113 private float m_buoyancy = 0f;
@@ -477,7 +478,71 @@ namespace OpenSim.Region.Physics.OdePlugin
477 } 478 }
478 } 479 }
479 } 480 }
480 481
482 private void AlignAvatarTiltWithCurrentDirectionOfMovement(PhysicsVector movementVector)
483 {
484 movementVector.Z = 0f;
485 float magnitude = (float)Math.Sqrt((double)(movementVector.X * movementVector.X + movementVector.Y * movementVector.Y));
486 if (magnitude < 0.1f) return;
487
488 // normalize the velocity vector
489 float invMagnitude = 1.0f / magnitude;
490 movementVector.X *= invMagnitude;
491 movementVector.Y *= invMagnitude;
492
493 // if we change the capsule heading too often, the capsule can fall down
494 // therefore we snap movement vector to just 1 of 4 predefined directions (ne, nw, se, sw),
495 // meaning only 4 possible capsule tilt orientations
496 if (movementVector.X > 0)
497 {
498 // east
499 if (movementVector.Y > 0)
500 {
501 // northeast
502 movementVector.X = (float)Math.Sqrt(2.0);
503 movementVector.Y = (float)Math.Sqrt(2.0);
504 }
505 else
506 {
507 // southeast
508 movementVector.X = (float)Math.Sqrt(2.0);
509 movementVector.Y = -(float)Math.Sqrt(2.0);
510 }
511 }
512 else
513 {
514 // west
515 if (movementVector.Y > 0)
516 {
517 // northwest
518 movementVector.X = -(float)Math.Sqrt(2.0);
519 movementVector.Y = (float)Math.Sqrt(2.0);
520 }
521 else
522 {
523 // southwest
524 movementVector.X = -(float)Math.Sqrt(2.0);
525 movementVector.Y = -(float)Math.Sqrt(2.0);
526 }
527 }
528
529
530 // movementVector.Z is zero
531
532 // calculate tilt components based on desired amount of tilt and current (snapped) heading.
533 // the "-" sign is to force the tilt to be OPPOSITE the direction of movement.
534 float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane;
535 float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane;
536
537 //m_log.Debug("[PHYSICS] changing avatar tilt");
538 d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent);
539 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced
540 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent);
541 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, yTiltComponent); // same as lowstop
542 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f);
543 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
544 }
545
481 /// <summary> 546 /// <summary>
482 /// This creates the Avatar's physical Surrogate at the position supplied 547 /// This creates the Avatar's physical Surrogate at the position supplied
483 /// </summary> 548 /// </summary>
@@ -576,71 +641,13 @@ namespace OpenSim.Region.Physics.OdePlugin
576 // (with -0..0 motor stops) falls into the terrain for reasons yet 641 // (with -0..0 motor stops) falls into the terrain for reasons yet
577 // to be comprehended in their entirety. 642 // to be comprehended in their entirety.
578 #endregion 643 #endregion
644 AlignAvatarTiltWithCurrentDirectionOfMovement(new PhysicsVector(0,0,0));
579 d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); 645 d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f);
580 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); 646 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f);
581 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); 647 d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f);
582 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced 648 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced
583 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop 649 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
584 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop 650 d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop
585 #region Documentation of capsule motor StopERP and StopCFM parameters
586 // In addition to the above tilt, we allow a dynamic tilt, or
587 // wobble, to emerge as the capsule is pushed around the environment.
588 // We do this with an experimentally determined combination of
589 // StopERP and StopCFM which make the above motor stops soft.
590 // The softness of the stops should be tweaked according to two
591 // requirements:
592 //
593 // 1. Motor stops should be weak enough to allow enough wobble such
594 // that the capsule can tilt slightly more when moving, to allow
595 // "gliding" over obstacles:
596 //
597 //
598 // .-.
599 // / /
600 // / /
601 // _ / / _
602 // / \ .-. / / / \
603 // | | ----> / / / / | |
604 // | | / / `-' | |
605 // | | / / +------+ | |
606 // | | / / | | | |
607 // | | / / | | | |
608 // \_/ `-' +------+ \_/
609 // ----------------------------------------------------------
610 //
611 // Note that requirement 1 is made complicated by the ever-present
612 // slight avatar tilt (assigned in the above code to prevent avatar
613 // from falling through terrain), which introduces a direction-dependent
614 // bias into the wobble (wobbling against the existing tilt is harder
615 // than wobbling with the tilt), which makes it easier to walk over
616 // prims from some directions. I have tried to minimize this effect by
617 // minimizing the avatar tilt to the minimum that prevents the avatar from
618 // falling through the terrain.
619 //
620 // 2. Motor stops should be strong enough to prevent the capsule
621 // from being forced all the way to the ground; otherwise the
622 // capsule could slip underneath obstacles like this:
623 // _ _
624 // / \ +------+ / \
625 // | | ----> | | | |
626 // | | | | | |
627 // | | .--.___ +------+ | |
628 // | | `--.__`--.__ | |
629 // | | `--.__`--. | |
630 // \_/ `--' \_/
631 // ----------------------------------------------------------
632 //
633 //
634 // It is strongly recommended you enable USE_DRAWSTUFF if you want to
635 // tweak these values, to see how the capsule is reacting in various
636 // situations.
637 #endregion
638 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0.0035f);
639 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0.0035f);
640 d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0.0035f);
641 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
642 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
643 d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
644 } 651 }
645 652
646 // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the 653 // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the
@@ -939,6 +946,7 @@ namespace OpenSim.Region.Physics.OdePlugin
939 946
940 PhysicsVector vec = new PhysicsVector(); 947 PhysicsVector vec = new PhysicsVector();
941 d.Vector3 vel = d.BodyGetLinearVel(Body); 948 d.Vector3 vel = d.BodyGetLinearVel(Body);
949
942 float movementdivisor = 1f; 950 float movementdivisor = 1f;
943 951
944 if (!m_alwaysRun) 952 if (!m_alwaysRun)
@@ -1052,6 +1060,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1052 if (PhysicsVector.isFinite(vec)) 1060 if (PhysicsVector.isFinite(vec))
1053 { 1061 {
1054 doForce(vec); 1062 doForce(vec);
1063 if (!_zeroFlag)
1064 {
1065 AlignAvatarTiltWithCurrentDirectionOfMovement(new PhysicsVector(vec.X, vec.Y, vec.Z));
1066 }
1055 } 1067 }
1056 else 1068 else
1057 { 1069 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 726b37a..ccdd4c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -1164,6 +1164,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1164 1164
1165 land.SetMediaUrl(url); 1165 land.SetMediaUrl(url);
1166 } 1166 }
1167
1168 public void osSetParcelSIPAddress(string SIPAddress)
1169 {
1170 // What actually is the difference to the LL function?
1171 //
1172 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL");
1173
1174 m_host.AddScriptLPS(1);
1175
1176
1177 ILandObject land
1178 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1179
1180 if (land.landData.OwnerID != m_host.ObjectOwner)
1181 {
1182 OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function");
1183 return;
1184 }
1185
1186 // get the voice module
1187 IVoiceModule voiceModule = World.RequestModuleInterface<IVoiceModule>();
1188
1189 if (voiceModule != null)
1190 voiceModule.setLandSIPAddress(SIPAddress,land.landData.GlobalID);
1191 else
1192 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land");
1193
1194
1195 }
1167 1196
1168 public string osGetScriptEngineName() 1197 public string osGetScriptEngineName()
1169 { 1198 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 49aa45a..d8d3c31 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -75,6 +75,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
75 bool osConsoleCommand(string Command); 75 bool osConsoleCommand(string Command);
76 void osSetParcelMediaURL(string url); 76 void osSetParcelMediaURL(string url);
77 void osSetPrimFloatOnWater(int floatYN); 77 void osSetPrimFloatOnWater(int floatYN);
78 void osSetParcelSIPAddress(string SIPAddress);
78 79
79 // Avatar Info Commands 80 // Avatar Info Commands
80 string osGetAgentIP(string agent); 81 string osGetAgentIP(string agent);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 8f52d99..d0df390 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -183,6 +183,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
183 { 183 {
184 m_OSSL_Functions.osSetParcelMediaURL(url); 184 m_OSSL_Functions.osSetParcelMediaURL(url);
185 } 185 }
186
187 public void osSetParcelSIPAddress(string SIPAddress)
188 {
189 m_OSSL_Functions.osSetParcelSIPAddress(SIPAddress);
190 }
186 191
187 public void osSetPrimFloatOnWater(int floatYN) 192 public void osSetPrimFloatOnWater(int floatYN)
188 { 193 {
diff --git a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs
index cef678d..5443891 100644
--- a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs
@@ -236,42 +236,8 @@ namespace OpenSim.Services.Connectors
236 } 236 }
237 catch (Exception e) 237 catch (Exception e)
238 { 238 {
239 // Maybe we're talking to an old inventory server. Try this other thing. 239 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1} (old server?).",
240 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1} (old server?). Trying GetInventory.",
241 e.Source, e.Message); 240 e.Source, e.Message);
242
243 InventoryCollection inventory;
244 List<InventoryFolderBase> folders = null;
245 try
246 {
247 inventory = SynchronousRestSessionObjectPoster<Guid, InventoryCollection>.BeginPostObject(
248 "POST", m_ServerURI + "/GetInventory/", new Guid(userID), sessionID.ToString(), userID.ToString());
249 if (inventory != null)
250 folders = inventory.Folders;
251 }
252 catch (Exception ex)
253 {
254 m_log.ErrorFormat("[INVENTORY CONNECTOR]: GetInventory operation also failed, {0} {1}. Giving up.",
255 e.Source, ex.Message);
256 return new InventoryCollection();
257 }
258
259 if ((folders != null) && (folders.Count > 0))
260 {
261 m_log.DebugFormat("[INVENTORY CONNECTOR]: Received entire inventory ({0} folders) for user {1}",
262 folders.Count, userID);
263
264 folders = folders.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == folderID; });
265 List<InventoryItemBase> items = inventory.Items;
266 if (items != null)
267 {
268 items = items.FindAll(delegate(InventoryItemBase i) { return i.Folder == folderID; });
269 }
270
271 inventory.Items = items;
272 inventory.Folders = folders;
273 return inventory;
274 }
275 } 241 }
276 242
277 InventoryCollection nullCollection = new InventoryCollection(); 243 InventoryCollection nullCollection = new InventoryCollection();
diff --git a/OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs b/OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs
index e858371..eaf8b39 100644
--- a/OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs
+++ b/OpenSim/Tests/Common/Setup/BaseRequestHandlerTestHelper.cs
@@ -72,15 +72,5 @@ namespace OpenSim.Tests.Common.Setup
72 72
73 public static byte[] EmptyByteArray = new byte[] {}; 73 public static byte[] EmptyByteArray = new byte[] {};
74 74
75 public static void BaseTestHandleNoParams(BaseGetAssetStreamHandler handler, string assetsPath)
76 {
77 Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath, null, null, null), "Failed on empty params.");
78 Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath + "/", null, null, null), "Failed on single slash.");
79 }
80
81 public static void BaseTestHandleMalformedGuid(BaseGetAssetStreamHandler handler, string assetsPath)
82 {
83 Assert.AreEqual(EmptyByteArray, handler.Handle(assetsPath + "/badGuid", null, null, null), "Failed on bad guid.");
84 }
85 } 75 }
86} \ No newline at end of file 76}
diff --git a/OpenSim/Tests/Common/Setup/GetAssetStreamHandlerTestHelpers.cs b/OpenSim/Tests/Common/Setup/GetAssetStreamHandlerTestHelpers.cs
deleted file mode 100644
index ffa7283..0000000
--- a/OpenSim/Tests/Common/Setup/GetAssetStreamHandlerTestHelpers.cs
+++ /dev/null
@@ -1,122 +0,0 @@
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.IO;
31using System.Net;
32using System.Text;
33using System.Xml;
34using System.Xml.Serialization;
35using NUnit.Framework;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Servers;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Server.Base;
41using OpenSim.Tests.Common.Mock;
42
43namespace OpenSim.Tests.Common.Setup
44{
45 public class GetAssetStreamHandlerTestHelpers
46 {
47 private const string EXPECTED_CONTENT_TYPE = "application/x-metaverse-callingcard";
48
49 public static void BaseFetchExistingAssetXmlTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response)
50 {
51 byte[] expected = BaseGetAssetStreamHandler.GetXml(asset);
52
53 byte[] actual = handler.Handle("/assets/" + asset.ID , null, null, response);
54
55 Assert.Greater(actual.Length, 10, "Too short xml on fetching xml without trailing slash.");
56 Assert.AreEqual(expected, actual, "Failed on fetching xml without trailing slash.");
57 // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch.");
58
59 actual = handler.Handle("/assets/" + asset.ID + "/", null, null, response);
60 Assert.Greater(actual.Length, 10, "Too short xml on fetching xml with trailing slash.");
61 Assert.AreEqual(expected, actual, "Failed on fetching xml with trailing slash.");
62 // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch.");
63
64 actual = handler.Handle("/assets/" + asset.ID + "/badData", null, null, response);
65 Assert.Greater(actual.Length, 10, "Too short xml on fetching xml with bad trailing data.");
66 Assert.AreEqual(expected, actual, "Failed on fetching xml with bad trailing trailing slash.");
67 // Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch.");
68 }
69
70 public static void BaseFetchExistingAssetDataTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response)
71 {
72 Assert.AreEqual(asset.Data, handler.Handle("/assets/" + asset.ID + "/data", null, null, response), "Failed on fetching data without trailing slash.");
73 Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch.");
74 Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on first fetch.");
75
76 Assert.AreEqual(asset.Data, handler.Handle("/assets/" + asset.ID + "/data/", null, null, response), "Failed on fetching data with trailing slash.");
77 Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch.");
78 Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on second fetch.");
79 }
80
81 public static void BaseFetchExistingAssetMetaDataTest(AssetBase asset, BaseGetAssetStreamHandler handler, OSHttpResponse response)
82 {
83 XmlSerializer xs = new XmlSerializer(typeof(AssetMetadata));
84
85 byte[] expected = ServerUtils.SerializeResult(xs, asset.Metadata);
86
87 Assert.AreEqual(expected, handler.Handle("/assets/" + asset.ID + "/metadata", null, null, response), "Failed on fetching data without trailing slash.");
88 Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on first fetch.");
89 Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on first fetch.");
90
91 Assert.AreEqual(expected, handler.Handle("/assets/" + asset.ID + "/metadata/", null, null, response), "Failed on fetching data with trailing slash.");
92 Assert.AreEqual((int)HttpStatusCode.OK, response.StatusCode, "Wrong http response code on second fetch.");
93 Assert.AreEqual(EXPECTED_CONTENT_TYPE, response.ContentType, "Wrong http content type on second fetch.");
94 }
95
96 public static AssetBase CreateCommonTestResources(out OSHttpResponse response)
97 {
98 AssetBase asset = CreateTestAsset();
99 response = new TestOSHttpResponse();
100 return asset;
101 }
102
103 public static AssetBase CreateTestAsset()
104 {
105 byte[] expected = new byte[] { 1,2,3 };
106 AssetBase asset = new AssetBase();
107 asset.ID = Guid.NewGuid().ToString();
108 asset.Data = expected;
109 asset.Type = 2;
110
111 return asset;
112 }
113
114 public static void BaseFetchMissingAsset(BaseGetAssetStreamHandler handler, OSHttpResponse response)
115 {
116 Assert.AreEqual(
117 BaseRequestHandlerTestHelper.EmptyByteArray,
118 handler.Handle("/assets/" + Guid.NewGuid(), null, null, response), "Failed on bad guid.");
119 Assert.AreEqual((int)HttpStatusCode.NotFound, response.StatusCode, "Response code wrong in BaseFetchMissingAsset");
120 }
121 }
122}