aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorJonathan Freedman2010-12-05 11:49:15 -0800
committerJonathan Freedman2010-12-05 11:49:15 -0800
commit45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a (patch)
tree0351fb2c756a46d522fe41798c3969e020a3258d /OpenSim/Region/Framework
parentMerge branch 'master-core' into mantis5110 (diff)
parentMerge branch 'master' of /var/git/opensim/ (diff)
downloadopensim-SC_OLD-45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a.zip
opensim-SC_OLD-45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a.tar.gz
opensim-SC_OLD-45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a.tar.bz2
opensim-SC_OLD-45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a.tar.xz
Merge branch 'master-core' into mantis5110
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRestartModule.cs39
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserManagement.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs84
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs275
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs164
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs40
11 files changed, 318 insertions, 337 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IRestartModule.cs b/OpenSim/Region/Framework/Interfaces/IRestartModule.cs
new file mode 100644
index 0000000..c68550f
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IRestartModule.cs
@@ -0,0 +1,39 @@
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 OpenMetaverse;
30
31namespace OpenSim.Region.Framework.Interfaces
32{
33 public interface IRestartModule
34 {
35 TimeSpan TimeUntilRestart { get; }
36 void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice);
37 void AbortRestart(string message);
38 }
39}
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index 1a5cb7e..2904ee8 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -9,5 +9,6 @@ namespace OpenSim.Region.Framework.Interfaces
9 { 9 {
10 string GetUserName(UUID uuid); 10 string GetUserName(UUID uuid);
11 void AddUser(UUID uuid, string userData); 11 void AddUser(UUID uuid, string userData);
12 void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
12 } 13 }
13} 14}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 06f8ac1..2cf0ced 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -416,6 +416,10 @@ namespace OpenSim.Region.Framework.Scenes
416 416
417 if ((item != null) && (item.Owner == senderId)) 417 if ((item != null) && (item.Owner == senderId))
418 { 418 {
419 IUserManagement uman = RequestModuleInterface<IUserManagement>();
420 if (uman != null)
421 uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
422
419 if (!Permissions.BypassPermissions()) 423 if (!Permissions.BypassPermissions())
420 { 424 {
421 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) 425 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 55fca9b..fcfb4d7 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -893,60 +893,6 @@ namespace OpenSim.Region.Framework.Scenes
893 return new GridRegion(RegionInfo); 893 return new GridRegion(RegionInfo);
894 } 894 }
895 895
896 /// <summary>
897 /// Given float seconds, this will restart the region.
898 /// </summary>
899 /// <param name="seconds">float indicating duration before restart.</param>
900 public virtual void Restart(float seconds)
901 {
902 // notifications are done in 15 second increments
903 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
904 // It's a 'Cancel restart' request.
905
906 // RestartNow() does immediate restarting.
907 if (seconds < 15)
908 {
909 m_restartTimer.Stop();
910 m_dialogModule.SendGeneralAlert("Restart Aborted");
911 }
912 else
913 {
914 // Now we figure out what to set the timer to that does the notifications and calls, RestartNow()
915 m_restartTimer.Interval = 15000;
916 m_incrementsof15seconds = (int)seconds / 15;
917 m_RestartTimerCounter = 0;
918 m_restartTimer.AutoReset = true;
919 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
920 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
921 m_restartTimer.Start();
922 m_dialogModule.SendNotificationToUsersInRegion(
923 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0)));
924 }
925 }
926
927 // The Restart timer has occured.
928 // We have to figure out if this is a notification or if the number of seconds specified in Restart
929 // have elapsed.
930 // If they have elapsed, call RestartNow()
931 public void RestartTimer_Elapsed(object sender, ElapsedEventArgs e)
932 {
933 m_RestartTimerCounter++;
934 if (m_RestartTimerCounter <= m_incrementsof15seconds)
935 {
936 if (m_RestartTimerCounter == 4 || m_RestartTimerCounter == 6 || m_RestartTimerCounter == 7)
937 m_dialogModule.SendNotificationToUsersInRegion(
938 UUID.Random(),
939 String.Empty,
940 RegionInfo.RegionName + ": Restarting in " + ((8 - m_RestartTimerCounter) * 15) + " seconds");
941 }
942 else
943 {
944 m_restartTimer.Stop();
945 m_restartTimer.AutoReset = false;
946 RestartNow();
947 }
948 }
949
950 // This causes the region to restart immediatley. 896 // This causes the region to restart immediatley.
951 public void RestartNow() 897 public void RestartNow()
952 { 898 {
@@ -969,7 +915,8 @@ namespace OpenSim.Region.Framework.Scenes
969 Close(); 915 Close();
970 916
971 m_log.Error("[REGION]: Firing Region Restart Message"); 917 m_log.Error("[REGION]: Firing Region Restart Message");
972 base.Restart(0); 918
919 base.Restart();
973 } 920 }
974 921
975 // This is a helper function that notifies root agents in this region that a new sim near them has come up 922 // This is a helper function that notifies root agents in this region that a new sim near them has come up
@@ -2050,7 +1997,7 @@ namespace OpenSim.Region.Framework.Scenes
2050 /// <param name="group">Object Id</param> 1997 /// <param name="group">Object Id</param>
2051 /// <param name="silent">Suppress broadcasting changes to other clients.</param> 1998 /// <param name="silent">Suppress broadcasting changes to other clients.</param>
2052 public void DeleteSceneObject(SceneObjectGroup group, bool silent) 1999 public void DeleteSceneObject(SceneObjectGroup group, bool silent)
2053 { 2000 {
2054// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); 2001// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
2055 2002
2056 //SceneObjectPart rootPart = group.GetChildPart(group.UUID); 2003 //SceneObjectPart rootPart = group.GetChildPart(group.UUID);
@@ -2091,7 +2038,7 @@ namespace OpenSim.Region.Framework.Scenes
2091 2038
2092 group.DeleteGroupFromScene(silent); 2039 group.DeleteGroupFromScene(silent);
2093 2040
2094// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2041// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2095 } 2042 }
2096 2043
2097 /// <summary> 2044 /// <summary>
@@ -2110,9 +2057,12 @@ namespace OpenSim.Region.Framework.Scenes
2110 // Force a database update so that the scene object group ID is accurate. It's possible that the 2057 // Force a database update so that the scene object group ID is accurate. It's possible that the
2111 // group has recently been delinked from another group but that this change has not been persisted 2058 // group has recently been delinked from another group but that this change has not been persisted
2112 // to the DB. 2059 // to the DB.
2113 ForceSceneObjectBackup(so); 2060 // This is an expensive thing to do so only do it if absolutely necessary.
2061 if (so.HasGroupChangedDueToDelink)
2062 ForceSceneObjectBackup(so);
2063
2114 so.DetachFromBackup(); 2064 so.DetachFromBackup();
2115 SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID); 2065 SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID);
2116 } 2066 }
2117 2067
2118 // We need to keep track of this state in case this group is still queued for further backup. 2068 // We need to keep track of this state in case this group is still queued for further backup.
@@ -2377,16 +2327,14 @@ namespace OpenSim.Region.Framework.Scenes
2377 m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName); 2327 m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
2378 return false; 2328 return false;
2379 } 2329 }
2380 2330
2381 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 2); 2331 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2382 2332
2383 newObject.ResumeScripts(); 2333 newObject.ResumeScripts();
2384 2334
2385 // Do this as late as possible so that listeners have full access to the incoming object 2335 // Do this as late as possible so that listeners have full access to the incoming object
2386 EventManager.TriggerOnIncomingSceneObject(newObject); 2336 EventManager.TriggerOnIncomingSceneObject(newObject);
2387 2337
2388 TriggerChangedTeleport(newObject);
2389
2390 return true; 2338 return true;
2391 } 2339 }
2392 2340
@@ -2494,7 +2442,7 @@ namespace OpenSim.Region.Framework.Scenes
2494 return true; 2442 return true;
2495 } 2443 }
2496 2444
2497 private void TriggerChangedTeleport(SceneObjectGroup sog) 2445 private int GetStateSource(SceneObjectGroup sog)
2498 { 2446 {
2499 ScenePresence sp = GetScenePresence(sog.OwnerID); 2447 ScenePresence sp = GetScenePresence(sog.OwnerID);
2500 2448
@@ -2505,13 +2453,12 @@ namespace OpenSim.Region.Framework.Scenes
2505 if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) 2453 if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default))
2506 { 2454 {
2507 // This will get your attention 2455 // This will get your attention
2508 //m_log.Error("[XXX] Triggering "); 2456 //m_log.Error("[XXX] Triggering CHANGED_TELEPORT");
2509 2457
2510 // Trigger CHANGED_TELEPORT 2458 return 5; // StateSource.Teleporting
2511 sp.Scene.EventManager.TriggerOnScriptChangedEvent(sog.LocalId, (uint)Changed.TELEPORT);
2512 } 2459 }
2513
2514 } 2460 }
2461 return 2; // StateSource.PrimCrossing
2515 } 2462 }
2516 2463
2517 #endregion 2464 #endregion
@@ -2616,6 +2563,7 @@ namespace OpenSim.Region.Framework.Scenes
2616 } 2563 }
2617 else 2564 else
2618 m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); 2565 m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
2566
2619 } 2567 }
2620 } 2568 }
2621 2569
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index c71aefa..f343bc8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -218,18 +218,6 @@ namespace OpenSim.Region.Framework.Scenes
218 218
219 #region admin stuff 219 #region admin stuff
220 220
221 /// <summary>
222 /// Region Restart - Seconds till restart.
223 /// </summary>
224 /// <param name="seconds"></param>
225 public virtual void Restart(int seconds)
226 {
227 m_log.Error("[REGION]: passing Restart Message up the namespace");
228 restart handlerPhysicsCrash = OnRestart;
229 if (handlerPhysicsCrash != null)
230 handlerPhysicsCrash(RegionInfo);
231 }
232
233 public virtual bool PresenceChildStatus(UUID avatarID) 221 public virtual bool PresenceChildStatus(UUID avatarID)
234 { 222 {
235 return false; 223 return false;
@@ -562,6 +550,14 @@ namespace OpenSim.Region.Framework.Scenes
562 get { return false; } 550 get { return false; }
563 } 551 }
564 552
553 public void Restart()
554 {
555 // This has to be here to fire the event
556 restart handlerPhysicsCrash = OnRestart;
557 if (handlerPhysicsCrash != null)
558 handlerPhysicsCrash(RegionInfo);
559 }
560
565 public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); 561 public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep);
566 } 562 }
567} 563}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4ec530e..f17fb28 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -119,10 +119,19 @@ namespace OpenSim.Region.Framework.Scenes
119 timeFirstChanged = DateTime.Now.Ticks; 119 timeFirstChanged = DateTime.Now.Ticks;
120 } 120 }
121 m_hasGroupChanged = value; 121 m_hasGroupChanged = value;
122
123// m_log.DebugFormat(
124// "[SCENE OBJECT GROUP]: HasGroupChanged set to {0} for {1} {2}", m_hasGroupChanged, Name, LocalId);
122 } 125 }
123 126
124 get { return m_hasGroupChanged; } 127 get { return m_hasGroupChanged; }
125 } 128 }
129
130 /// <summary>
131 /// Has the group changed due to an unlink operation? We record this in order to optimize deletion, since
132 /// an unlinked group currently has to be persisted to the database before we can perform an unlink operation.
133 /// </summary>
134 public bool HasGroupChangedDueToDelink { get; private set; }
126 135
127 private bool isTimeToPersist() 136 private bool isTimeToPersist()
128 { 137 {
@@ -1330,6 +1339,7 @@ namespace OpenSim.Region.Framework.Scenes
1330 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; 1339 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity;
1331 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; 1340 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
1332 HasGroupChanged = false; 1341 HasGroupChanged = false;
1342 HasGroupChangedDueToDelink = false;
1333 1343
1334 m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this); 1344 m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
1335 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); 1345 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
@@ -2208,8 +2218,9 @@ namespace OpenSim.Region.Framework.Scenes
2208 2218
2209 linkPart.Rezzed = RootPart.Rezzed; 2219 linkPart.Rezzed = RootPart.Rezzed;
2210 2220
2211 //HasGroupChanged = true; 2221 // When we delete a group, we currently have to force persist to the database if the object id has changed
2212 //ScheduleGroupForFullUpdate(); 2222 // (since delete works by deleting all rows which have a given object id)
2223 objectGroup.HasGroupChangedDueToDelink = true;
2213 2224
2214 return objectGroup; 2225 return objectGroup;
2215 } 2226 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index ba592c4..f87056e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -449,7 +449,10 @@ namespace OpenSim.Region.Framework.Scenes
449 } 449 }
450 } 450 }
451 451
452 public string CreatorData // = <profile url>;<name> 452 /// <summary>
453 /// Data about the creator in the form profile_url;name
454 /// </summary>
455 public string CreatorData
453 { 456 {
454 get { return m_creatorData; } 457 get { return m_creatorData; }
455 set { m_creatorData = value; } 458 set { m_creatorData = value; }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4526a59..d88526f 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -445,8 +445,36 @@ namespace OpenSim.Region.Framework.Scenes
445 PhysicsActor actor = m_physicsActor; 445 PhysicsActor actor = m_physicsActor;
446 if (actor != null) 446 if (actor != null)
447 m_pos = actor.Position; 447 m_pos = actor.Position;
448 else
449 {
450 // Obtain the correct position of a seated avatar.
451 // In addition to providing the correct position while
452 // the avatar is seated, this value will also
453 // be used as the location to unsit to.
454 //
455 // If m_parentID is not 0, assume we are a seated avatar
456 // and we should return the position based on the sittarget
457 // offset and rotation of the prim we are seated on.
458 //
459 // Generally, m_pos will contain the position of the avatar
460 // in the sim unless the avatar is on a sit target. While
461 // on a sit target, m_pos will contain the desired offset
462 // without the parent rotation applied.
463 if (m_parentID != 0)
464 {
465 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
466 if (part != null)
467 {
468 return m_parentPosition + (m_pos * part.GetWorldRotation());
469 }
470 else
471 {
472 return m_parentPosition + m_pos;
473 }
474 }
475 }
448 476
449 return m_parentPosition + m_pos; 477 return m_pos;
450 } 478 }
451 set 479 set
452 { 480 {
@@ -703,7 +731,9 @@ namespace OpenSim.Region.Framework.Scenes
703 // Note: This won't send data *to* other clients in that region (children don't send) 731 // Note: This won't send data *to* other clients in that region (children don't send)
704 732
705// MIC: This gets called again in CompleteMovement 733// MIC: This gets called again in CompleteMovement
706 SendInitialFullUpdateToAllClients(); 734 // SendInitialFullUpdateToAllClients();
735 SendOtherAgentsAvatarDataToMe();
736 SendOtherAgentsAppearanceToMe();
707 737
708 RegisterToEvents(); 738 RegisterToEvents();
709 SetDirectionVectors(); 739 SetDirectionVectors();
@@ -1613,7 +1643,7 @@ namespace OpenSim.Region.Framework.Scenes
1613 { 1643 {
1614 AbsolutePosition = part.AbsolutePosition; 1644 AbsolutePosition = part.AbsolutePosition;
1615 Velocity = Vector3.Zero; 1645 Velocity = Vector3.Zero;
1616 SendFullUpdateToAllClients(); 1646 SendAvatarDataToAllAgents();
1617 1647
1618 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1648 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID);
1619 } 1649 }
@@ -1688,7 +1718,7 @@ namespace OpenSim.Region.Framework.Scenes
1688 m_parentPosition = Vector3.Zero; 1718 m_parentPosition = Vector3.Zero;
1689 1719
1690 m_parentID = 0; 1720 m_parentID = 0;
1691 SendFullUpdateToAllClients(); 1721 SendAvatarDataToAllAgents();
1692 m_requestedSitTargetID = 0; 1722 m_requestedSitTargetID = 0;
1693 if (m_physicsActor != null && m_appearance != null) 1723 if (m_physicsActor != null && m_appearance != null)
1694 { 1724 {
@@ -2154,7 +2184,7 @@ namespace OpenSim.Region.Framework.Scenes
2154 RemoveFromPhysicalScene(); 2184 RemoveFromPhysicalScene();
2155 2185
2156 Animator.TrySetMovementAnimation(sitAnimation); 2186 Animator.TrySetMovementAnimation(sitAnimation);
2157 SendFullUpdateToAllClients(); 2187 SendAvatarDataToAllAgents();
2158 // This may seem stupid, but Our Full updates don't send avatar rotation :P 2188 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2159 // So we're also sending a terse update (which has avatar rotation) 2189 // So we're also sending a terse update (which has avatar rotation)
2160 // [Update] We do now. 2190 // [Update] We do now.
@@ -2379,165 +2409,183 @@ namespace OpenSim.Region.Framework.Scenes
2379 } 2409 }
2380 2410
2381 /// <summary> 2411 /// <summary>
2382 /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) 2412 /// Do everything required once a client completes its movement into a region and becomes
2413 /// a root agent.
2383 /// </summary> 2414 /// </summary>
2384 /// <param name="remoteAvatar"></param> 2415 private void SendInitialData()
2385 public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar)
2386 { 2416 {
2387 // 2 stage check is needed. 2417 // Moved this into CompleteMovement to ensure that m_appearance is initialized before
2388 if (remoteAvatar == null) 2418 // the inventory arrives
2389 return; 2419 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2390
2391 IClientAPI cl = remoteAvatar.ControllingClient;
2392 if (cl == null)
2393 return;
2394
2395 if (m_appearance.Texture == null)
2396 return;
2397 2420
2398// MT: This is needed for sit. It's legal to send it to oneself, and the name 2421 bool cachedappearance = false;
2399// of the method is a misnomer
2400//
2401// if (LocalId == remoteAvatar.LocalId)
2402// {
2403// m_log.WarnFormat("[SCENEPRESENCE]: An agent is attempting to send avatar data to itself; {0}", UUID);
2404// return;
2405// }
2406 2422
2407 if (IsChildAgent) 2423 // We have an appearance but we may not have the baked textures. Check the asset cache
2424 // to see if all the baked textures are already here.
2425 if (m_scene.AvatarFactory != null)
2408 { 2426 {
2409 m_log.WarnFormat("[SCENEPRESENCE]: A child agent is attempting to send out avatar data; {0}", UUID); 2427 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient);
2410 return; 2428 }
2429 else
2430 {
2431 m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name);
2411 } 2432 }
2412 2433
2413 remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); 2434 // If we aren't using a cached appearance, then clear out the baked textures
2414 m_scene.StatsReporter.AddAgentUpdates(1); 2435 if (! cachedappearance)
2436 {
2437 m_appearance.ResetAppearance();
2438 if (m_scene.AvatarFactory != null)
2439 m_scene.AvatarFactory.QueueAppearanceSave(UUID);
2440 }
2441
2442 // This agent just became root. We are going to tell everyone about it. The process of
2443 // getting other avatars information was initiated in the constructor... don't do it
2444 // again here... this comes after the cached appearance check because the avatars
2445 // appearance goes into the avatar update packet
2446 SendAvatarDataToAllAgents();
2447 SendAppearanceToAgent(this);
2448
2449 // If we are using the the cached appearance then send it out to everyone
2450 if (cachedappearance)
2451 {
2452 m_log.InfoFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name);
2453
2454 // If the avatars baked textures are all in the cache, then we have a
2455 // complete appearance... send it out, if not, then we'll send it when
2456 // the avatar finishes updating its appearance
2457 SendAppearanceToAllOtherAgents();
2458 }
2415 } 2459 }
2416 2460
2417 /// <summary> 2461 /// <summary>
2418 /// Tell *ALL* agents about this agent 2462 /// Send this agent's avatar data to all other root and child agents in the scene
2463 /// This agent must be root. This avatar will receive its own update.
2419 /// </summary> 2464 /// </summary>
2420 public void SendInitialFullUpdateToAllClients() 2465 public void SendAvatarDataToAllAgents()
2421 { 2466 {
2422 m_perfMonMS = Util.EnvironmentTickCount(); 2467 // only send update from root agents to other clients; children are only "listening posts"
2423 int avUpdates = 0; 2468 if (IsChildAgent)
2424 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
2425 { 2469 {
2426 ++avUpdates; 2470 m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent");
2427 2471 return;
2428 // Don't update ourselves 2472 }
2429 if (avatar.LocalId == LocalId) 2473
2430 return; 2474 m_perfMonMS = Util.EnvironmentTickCount();
2431
2432 // If this is a root agent, then get info about the avatar
2433 if (!IsChildAgent)
2434 {
2435 SendFullUpdateToOtherClient(avatar);
2436 }
2437 2475
2438 // If the other avatar is a root 2476 int count = 0;
2439 if (!avatar.IsChildAgent) 2477 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2440 { 2478 {
2441 avatar.SendFullUpdateToOtherClient(this); 2479 SendAvatarDataToAgent(scenePresence);
2442 avatar.SendAppearanceToOtherAgent(this); 2480 count++;
2443 avatar.Animator.SendAnimPackToClient(ControllingClient); 2481 });
2444 }
2445 });
2446 2482
2447 m_scene.StatsReporter.AddAgentUpdates(avUpdates); 2483 m_scene.StatsReporter.AddAgentUpdates(count);
2448 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2484 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2449
2450 //Animator.SendAnimPack();
2451 } 2485 }
2452 2486
2453 public void SendFullUpdateToAllClients() 2487 /// <summary>
2488 /// Send avatar data for all other root agents to this agent, this agent
2489 /// can be either a child or root
2490 /// </summary>
2491 public void SendOtherAgentsAvatarDataToMe()
2454 { 2492 {
2455 m_perfMonMS = Util.EnvironmentTickCount(); 2493 m_perfMonMS = Util.EnvironmentTickCount();
2456 2494
2457 // only send update from root agents to other clients; children are only "listening posts"
2458 if (IsChildAgent)
2459 {
2460 m_log.Warn("[SCENEPRESENCE] attempt to send update from a childagent");
2461 return;
2462 }
2463
2464 int count = 0; 2495 int count = 0;
2465 m_scene.ForEachScenePresence(delegate(ScenePresence sp) 2496 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2466 { 2497 {
2467 if (sp.IsChildAgent) 2498 // only send information about root agents
2468 return; 2499 if (scenePresence.IsChildAgent)
2469 SendFullUpdateToOtherClient(sp); 2500 return;
2470 ++count; 2501
2471 }); 2502 // only send information about other root agents
2503 if (scenePresence.UUID == UUID)
2504 return;
2505
2506 scenePresence.SendAvatarDataToAgent(this);
2507 count++;
2508 });
2509
2472 m_scene.StatsReporter.AddAgentUpdates(count); 2510 m_scene.StatsReporter.AddAgentUpdates(count);
2473 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2511 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2474
2475 Animator.SendAnimPack();
2476 } 2512 }
2477 2513
2478 /// <summary> 2514 /// <summary>
2479 /// Do everything required once a client completes its movement into a region 2515 /// Send avatar data to an agent.
2480 /// </summary> 2516 /// </summary>
2481 public void SendInitialData() 2517 /// <param name="avatar"></param>
2518 public void SendAvatarDataToAgent(ScenePresence avatar)
2482 { 2519 {
2483 // Moved this into CompleteMovement to ensure that m_appearance is initialized before 2520// m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
2484 // the inventory arrives
2485 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2486 2521
2487 m_controllingClient.SendAvatarDataImmediate(this); 2522 avatar.ControllingClient.SendAvatarDataImmediate(this);
2488 if (m_scene.AvatarFactory != null) 2523 Animator.SendAnimPackToClient(avatar.ControllingClient);
2489 { 2524 }
2490 if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) 2525
2491 { 2526 /// <summary>
2492// m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); 2527 /// Send this agent's appearance to all other root and child agents in the scene
2493 m_controllingClient.SendAppearance( 2528 /// This agent must be root.
2494 m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); 2529 /// </summary>
2495 } 2530 public void SendAppearanceToAllOtherAgents()
2496 } 2531 {
2497 else 2532 // only send update from root agents to other clients; children are only "listening posts"
2533 if (IsChildAgent)
2498 { 2534 {
2499 m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); 2535 m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent");
2536 return;
2500 } 2537 }
2538
2539 m_perfMonMS = Util.EnvironmentTickCount();
2501 2540
2502 SendInitialFullUpdateToAllClients(); 2541 int count = 0;
2542 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2543 {
2544 if (scenePresence.UUID == UUID)
2545 return;
2546
2547 SendAppearanceToAgent(scenePresence);
2548 count++;
2549 });
2550
2551 m_scene.StatsReporter.AddAgentUpdates(count);
2552 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2503 } 2553 }
2504 2554
2505 /// <summary> 2555 /// <summary>
2506 /// 2556 /// Send appearance from all other root agents to this agent. this agent
2557 /// can be either root or child
2507 /// </summary> 2558 /// </summary>
2508 public void SendAppearanceToAllOtherAgents() 2559 public void SendOtherAgentsAppearanceToMe()
2509 { 2560 {
2510// DEBUG ON
2511// m_log.WarnFormat("[SCENEPRESENCE]: Send appearance from {0} to all other agents", m_uuid);
2512// DEBUG OFF
2513 m_perfMonMS = Util.EnvironmentTickCount(); 2561 m_perfMonMS = Util.EnvironmentTickCount();
2514 2562
2563 int count = 0;
2515 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2564 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2516 { 2565 {
2517 if (scenePresence.UUID != UUID) 2566 // only send information about root agents
2518 { 2567 if (scenePresence.IsChildAgent)
2519 SendAppearanceToOtherAgent(scenePresence); 2568 return;
2520 } 2569
2570 // only send information about other root agents
2571 if (scenePresence.UUID == UUID)
2572 return;
2573
2574 scenePresence.SendAppearanceToAgent(this);
2575 count++;
2521 }); 2576 });
2522 2577
2578 m_scene.StatsReporter.AddAgentUpdates(count);
2523 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2579 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2524 } 2580 }
2525 2581
2526 /// <summary> 2582 /// <summary>
2527 /// Send appearance data to an agent that isn't this one. 2583 /// Send appearance data to an agent.
2528 /// </summary> 2584 /// </summary>
2529 /// <param name="avatar"></param> 2585 /// <param name="avatar"></param>
2530 public void SendAppearanceToOtherAgent(ScenePresence avatar) 2586 public void SendAppearanceToAgent(ScenePresence avatar)
2531 { 2587 {
2532 if (LocalId == avatar.LocalId)
2533 {
2534 m_log.WarnFormat("[SCENE PRESENCE]: An agent is attempting to send appearance data to itself; {0}", UUID);
2535 return;
2536 }
2537
2538// DEBUG ON
2539// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); 2588// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
2540// DEBUG OFF
2541 2589
2542 avatar.ControllingClient.SendAppearance( 2590 avatar.ControllingClient.SendAppearance(
2543 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); 2591 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
@@ -3050,9 +3098,6 @@ namespace OpenSim.Region.Framework.Scenes
3050 3098
3051 public void CopyFrom(AgentData cAgent) 3099 public void CopyFrom(AgentData cAgent)
3052 { 3100 {
3053// DEBUG ON
3054 m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM");
3055// DEBUG OFF
3056 m_originRegionID = cAgent.RegionID; 3101 m_originRegionID = cAgent.RegionID;
3057 3102
3058 m_callbackURI = cAgent.CallbackURI; 3103 m_callbackURI = cAgent.CallbackURI;
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 9cf5a39..6c9826f 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -409,12 +409,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
409 #region SOPXmlProcessors 409 #region SOPXmlProcessors
410 private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader) 410 private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader)
411 { 411 {
412 obj.AllowedDrop = reader.ReadElementContentAsBoolean("AllowedDrop", String.Empty); 412 obj.AllowedDrop = Util.ReadBoolean(reader);
413 } 413 }
414 414
415 private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader) 415 private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader)
416 { 416 {
417 obj.CreatorID = ReadUUID(reader, "CreatorID"); 417 obj.CreatorID = Util.ReadUUID(reader, "CreatorID");
418 } 418 }
419 419
420 private static void ProcessCreatorData(SceneObjectPart obj, XmlTextReader reader) 420 private static void ProcessCreatorData(SceneObjectPart obj, XmlTextReader reader)
@@ -424,7 +424,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
424 424
425 private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader) 425 private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader)
426 { 426 {
427 obj.FolderID = ReadUUID(reader, "FolderID"); 427 obj.FolderID = Util.ReadUUID(reader, "FolderID");
428 } 428 }
429 429
430 private static void ProcessInventorySerial(SceneObjectPart obj, XmlTextReader reader) 430 private static void ProcessInventorySerial(SceneObjectPart obj, XmlTextReader reader)
@@ -439,7 +439,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
439 439
440 private static void ProcessUUID(SceneObjectPart obj, XmlTextReader reader) 440 private static void ProcessUUID(SceneObjectPart obj, XmlTextReader reader)
441 { 441 {
442 obj.UUID = ReadUUID(reader, "UUID"); 442 obj.UUID = Util.ReadUUID(reader, "UUID");
443 } 443 }
444 444
445 private static void ProcessLocalId(SceneObjectPart obj, XmlTextReader reader) 445 private static void ProcessLocalId(SceneObjectPart obj, XmlTextReader reader)
@@ -459,7 +459,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
459 459
460 private static void ProcessPassTouches(SceneObjectPart obj, XmlTextReader reader) 460 private static void ProcessPassTouches(SceneObjectPart obj, XmlTextReader reader)
461 { 461 {
462 obj.PassTouches = reader.ReadElementContentAsBoolean("PassTouches", String.Empty); 462 obj.PassTouches = Util.ReadBoolean(reader);
463 } 463 }
464 464
465 private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader) 465 private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader)
@@ -474,32 +474,32 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
474 474
475 private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader) 475 private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader)
476 { 476 {
477 obj.GroupPosition = ReadVector(reader, "GroupPosition"); 477 obj.GroupPosition = Util.ReadVector(reader, "GroupPosition");
478 } 478 }
479 479
480 private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader) 480 private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader)
481 { 481 {
482 obj.OffsetPosition = ReadVector(reader, "OffsetPosition"); ; 482 obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ;
483 } 483 }
484 484
485 private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader) 485 private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader)
486 { 486 {
487 obj.RotationOffset = ReadQuaternion(reader, "RotationOffset"); 487 obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset");
488 } 488 }
489 489
490 private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader) 490 private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader)
491 { 491 {
492 obj.Velocity = ReadVector(reader, "Velocity"); 492 obj.Velocity = Util.ReadVector(reader, "Velocity");
493 } 493 }
494 494
495 private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader) 495 private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader)
496 { 496 {
497 obj.AngularVelocity = ReadVector(reader, "AngularVelocity"); 497 obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity");
498 } 498 }
499 499
500 private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader) 500 private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader)
501 { 501 {
502 obj.Acceleration = ReadVector(reader, "Acceleration"); 502 obj.Acceleration = Util.ReadVector(reader, "Acceleration");
503 } 503 }
504 504
505 private static void ProcessDescription(SceneObjectPart obj, XmlTextReader reader) 505 private static void ProcessDescription(SceneObjectPart obj, XmlTextReader reader)
@@ -553,7 +553,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
553 553
554 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) 554 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
555 { 555 {
556 obj.Scale = ReadVector(reader, "Scale"); 556 obj.Scale = Util.ReadVector(reader, "Scale");
557 } 557 }
558 558
559 private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader) 559 private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader)
@@ -563,22 +563,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
563 563
564 private static void ProcessSitTargetOrientation(SceneObjectPart obj, XmlTextReader reader) 564 private static void ProcessSitTargetOrientation(SceneObjectPart obj, XmlTextReader reader)
565 { 565 {
566 obj.SitTargetOrientation = ReadQuaternion(reader, "SitTargetOrientation"); 566 obj.SitTargetOrientation = Util.ReadQuaternion(reader, "SitTargetOrientation");
567 } 567 }
568 568
569 private static void ProcessSitTargetPosition(SceneObjectPart obj, XmlTextReader reader) 569 private static void ProcessSitTargetPosition(SceneObjectPart obj, XmlTextReader reader)
570 { 570 {
571 obj.SitTargetPosition = ReadVector(reader, "SitTargetPosition"); 571 obj.SitTargetPosition = Util.ReadVector(reader, "SitTargetPosition");
572 } 572 }
573 573
574 private static void ProcessSitTargetPositionLL(SceneObjectPart obj, XmlTextReader reader) 574 private static void ProcessSitTargetPositionLL(SceneObjectPart obj, XmlTextReader reader)
575 { 575 {
576 obj.SitTargetPositionLL = ReadVector(reader, "SitTargetPositionLL"); 576 obj.SitTargetPositionLL = Util.ReadVector(reader, "SitTargetPositionLL");
577 } 577 }
578 578
579 private static void ProcessSitTargetOrientationLL(SceneObjectPart obj, XmlTextReader reader) 579 private static void ProcessSitTargetOrientationLL(SceneObjectPart obj, XmlTextReader reader)
580 { 580 {
581 obj.SitTargetOrientationLL = ReadQuaternion(reader, "SitTargetOrientationLL"); 581 obj.SitTargetOrientationLL = Util.ReadQuaternion(reader, "SitTargetOrientationLL");
582 } 582 }
583 583
584 private static void ProcessParentID(SceneObjectPart obj, XmlTextReader reader) 584 private static void ProcessParentID(SceneObjectPart obj, XmlTextReader reader)
@@ -614,17 +614,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
614 614
615 private static void ProcessGroupID(SceneObjectPart obj, XmlTextReader reader) 615 private static void ProcessGroupID(SceneObjectPart obj, XmlTextReader reader)
616 { 616 {
617 obj.GroupID = ReadUUID(reader, "GroupID"); 617 obj.GroupID = Util.ReadUUID(reader, "GroupID");
618 } 618 }
619 619
620 private static void ProcessOwnerID(SceneObjectPart obj, XmlTextReader reader) 620 private static void ProcessOwnerID(SceneObjectPart obj, XmlTextReader reader)
621 { 621 {
622 obj.OwnerID = ReadUUID(reader, "OwnerID"); 622 obj.OwnerID = Util.ReadUUID(reader, "OwnerID");
623 } 623 }
624 624
625 private static void ProcessLastOwnerID(SceneObjectPart obj, XmlTextReader reader) 625 private static void ProcessLastOwnerID(SceneObjectPart obj, XmlTextReader reader)
626 { 626 {
627 obj.LastOwnerID = ReadUUID(reader, "LastOwnerID"); 627 obj.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID");
628 } 628 }
629 629
630 private static void ProcessBaseMask(SceneObjectPart obj, XmlTextReader reader) 630 private static void ProcessBaseMask(SceneObjectPart obj, XmlTextReader reader)
@@ -654,16 +654,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
654 654
655 private static void ProcessFlags(SceneObjectPart obj, XmlTextReader reader) 655 private static void ProcessFlags(SceneObjectPart obj, XmlTextReader reader)
656 { 656 {
657 string value = reader.ReadElementContentAsString("Flags", String.Empty); 657 obj.Flags = Util.ReadEnum<PrimFlags>(reader, "Flags");
658 // !!!!! to deal with flags without commas
659 if (value.Contains(" ") && !value.Contains(","))
660 value = value.Replace(" ", ", ");
661 obj.Flags = (PrimFlags)Enum.Parse(typeof(PrimFlags), value);
662 } 658 }
663 659
664 private static void ProcessCollisionSound(SceneObjectPart obj, XmlTextReader reader) 660 private static void ProcessCollisionSound(SceneObjectPart obj, XmlTextReader reader)
665 { 661 {
666 obj.CollisionSound = ReadUUID(reader, "CollisionSound"); 662 obj.CollisionSound = Util.ReadUUID(reader, "CollisionSound");
667 } 663 }
668 664
669 private static void ProcessCollisionSoundVolume(SceneObjectPart obj, XmlTextReader reader) 665 private static void ProcessCollisionSoundVolume(SceneObjectPart obj, XmlTextReader reader)
@@ -690,7 +686,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
690 #region TaskInventoryXmlProcessors 686 #region TaskInventoryXmlProcessors
691 private static void ProcessTIAssetID(TaskInventoryItem item, XmlTextReader reader) 687 private static void ProcessTIAssetID(TaskInventoryItem item, XmlTextReader reader)
692 { 688 {
693 item.AssetID = ReadUUID(reader, "AssetID"); 689 item.AssetID = Util.ReadUUID(reader, "AssetID");
694 } 690 }
695 691
696 private static void ProcessTIBasePermissions(TaskInventoryItem item, XmlTextReader reader) 692 private static void ProcessTIBasePermissions(TaskInventoryItem item, XmlTextReader reader)
@@ -705,7 +701,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
705 701
706 private static void ProcessTICreatorID(TaskInventoryItem item, XmlTextReader reader) 702 private static void ProcessTICreatorID(TaskInventoryItem item, XmlTextReader reader)
707 { 703 {
708 item.CreatorID = ReadUUID(reader, "CreatorID"); 704 item.CreatorID = Util.ReadUUID(reader, "CreatorID");
709 } 705 }
710 706
711 private static void ProcessTICreatorData(TaskInventoryItem item, XmlTextReader reader) 707 private static void ProcessTICreatorData(TaskInventoryItem item, XmlTextReader reader)
@@ -730,7 +726,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
730 726
731 private static void ProcessTIGroupID(TaskInventoryItem item, XmlTextReader reader) 727 private static void ProcessTIGroupID(TaskInventoryItem item, XmlTextReader reader)
732 { 728 {
733 item.GroupID = ReadUUID(reader, "GroupID"); 729 item.GroupID = Util.ReadUUID(reader, "GroupID");
734 } 730 }
735 731
736 private static void ProcessTIGroupPermissions(TaskInventoryItem item, XmlTextReader reader) 732 private static void ProcessTIGroupPermissions(TaskInventoryItem item, XmlTextReader reader)
@@ -745,20 +741,20 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
745 741
746 private static void ProcessTIItemID(TaskInventoryItem item, XmlTextReader reader) 742 private static void ProcessTIItemID(TaskInventoryItem item, XmlTextReader reader)
747 { 743 {
748 item.ItemID = ReadUUID(reader, "ItemID"); 744 item.ItemID = Util.ReadUUID(reader, "ItemID");
749 } 745 }
750 746
751 private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader) 747 private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader)
752 { 748 {
753 ReadUUID(reader, "OldItemID"); 749 Util.ReadUUID(reader, "OldItemID");
754 // On deserialization, the old item id MUST BE UUID.Zero!!!!! 750 // On deserialization, the old item id MUST BE UUID.Zero!!!!!
755 // Setting this to the saved value will BREAK script persistence! 751 // Setting this to the saved value will BREAK script persistence!
756 // item.OldItemID = ReadUUID(reader, "OldItemID"); 752 // item.OldItemID = Util.ReadUUID(reader, "OldItemID");
757 } 753 }
758 754
759 private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader) 755 private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader)
760 { 756 {
761 item.LastOwnerID = ReadUUID(reader, "LastOwnerID"); 757 item.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID");
762 } 758 }
763 759
764 private static void ProcessTIName(TaskInventoryItem item, XmlTextReader reader) 760 private static void ProcessTIName(TaskInventoryItem item, XmlTextReader reader)
@@ -773,7 +769,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
773 769
774 private static void ProcessTIOwnerID(TaskInventoryItem item, XmlTextReader reader) 770 private static void ProcessTIOwnerID(TaskInventoryItem item, XmlTextReader reader)
775 { 771 {
776 item.OwnerID = ReadUUID(reader, "OwnerID"); 772 item.OwnerID = Util.ReadUUID(reader, "OwnerID");
777 } 773 }
778 774
779 private static void ProcessTICurrentPermissions(TaskInventoryItem item, XmlTextReader reader) 775 private static void ProcessTICurrentPermissions(TaskInventoryItem item, XmlTextReader reader)
@@ -783,17 +779,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
783 779
784 private static void ProcessTIParentID(TaskInventoryItem item, XmlTextReader reader) 780 private static void ProcessTIParentID(TaskInventoryItem item, XmlTextReader reader)
785 { 781 {
786 item.ParentID = ReadUUID(reader, "ParentID"); 782 item.ParentID = Util.ReadUUID(reader, "ParentID");
787 } 783 }
788 784
789 private static void ProcessTIParentPartID(TaskInventoryItem item, XmlTextReader reader) 785 private static void ProcessTIParentPartID(TaskInventoryItem item, XmlTextReader reader)
790 { 786 {
791 item.ParentPartID = ReadUUID(reader, "ParentPartID"); 787 item.ParentPartID = Util.ReadUUID(reader, "ParentPartID");
792 } 788 }
793 789
794 private static void ProcessTIPermsGranter(TaskInventoryItem item, XmlTextReader reader) 790 private static void ProcessTIPermsGranter(TaskInventoryItem item, XmlTextReader reader)
795 { 791 {
796 item.PermsGranter = ReadUUID(reader, "PermsGranter"); 792 item.PermsGranter = Util.ReadUUID(reader, "PermsGranter");
797 } 793 }
798 794
799 private static void ProcessTIPermsMask(TaskInventoryItem item, XmlTextReader reader) 795 private static void ProcessTIPermsMask(TaskInventoryItem item, XmlTextReader reader)
@@ -808,7 +804,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
808 804
809 private static void ProcessTIOwnerChanged(TaskInventoryItem item, XmlTextReader reader) 805 private static void ProcessTIOwnerChanged(TaskInventoryItem item, XmlTextReader reader)
810 { 806 {
811 item.OwnerChanged = reader.ReadElementContentAsBoolean("OwnerChanged", String.Empty); 807 item.OwnerChanged = Util.ReadBoolean(reader);
812 } 808 }
813 809
814 #endregion 810 #endregion
@@ -922,7 +918,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
922 918
923 private static void ProcessShpScale(PrimitiveBaseShape shp, XmlTextReader reader) 919 private static void ProcessShpScale(PrimitiveBaseShape shp, XmlTextReader reader)
924 { 920 {
925 shp.Scale = ReadVector(reader, "Scale"); 921 shp.Scale = Util.ReadVector(reader, "Scale");
926 } 922 }
927 923
928 private static void ProcessShpState(PrimitiveBaseShape shp, XmlTextReader reader) 924 private static void ProcessShpState(PrimitiveBaseShape shp, XmlTextReader reader)
@@ -932,25 +928,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
932 928
933 private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader) 929 private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader)
934 { 930 {
935 string value = reader.ReadElementContentAsString("ProfileShape", String.Empty); 931 shp.ProfileShape = Util.ReadEnum<ProfileShape>(reader, "ProfileShape");
936 // !!!!! to deal with flags without commas
937 if (value.Contains(" ") && !value.Contains(","))
938 value = value.Replace(" ", ", ");
939 shp.ProfileShape = (ProfileShape)Enum.Parse(typeof(ProfileShape), value);
940 } 932 }
941 933
942 private static void ProcessShpHollowShape(PrimitiveBaseShape shp, XmlTextReader reader) 934 private static void ProcessShpHollowShape(PrimitiveBaseShape shp, XmlTextReader reader)
943 { 935 {
944 string value = reader.ReadElementContentAsString("HollowShape", String.Empty); 936 shp.HollowShape = Util.ReadEnum<HollowShape>(reader, "HollowShape");
945 // !!!!! to deal with flags without commas
946 if (value.Contains(" ") && !value.Contains(","))
947 value = value.Replace(" ", ", ");
948 shp.HollowShape = (HollowShape)Enum.Parse(typeof(HollowShape), value);
949 } 937 }
950 938
951 private static void ProcessShpSculptTexture(PrimitiveBaseShape shp, XmlTextReader reader) 939 private static void ProcessShpSculptTexture(PrimitiveBaseShape shp, XmlTextReader reader)
952 { 940 {
953 shp.SculptTexture = ReadUUID(reader, "SculptTexture"); 941 shp.SculptTexture = Util.ReadUUID(reader, "SculptTexture");
954 } 942 }
955 943
956 private static void ProcessShpSculptType(PrimitiveBaseShape shp, XmlTextReader reader) 944 private static void ProcessShpSculptType(PrimitiveBaseShape shp, XmlTextReader reader)
@@ -1045,17 +1033,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1045 1033
1046 private static void ProcessShpFlexiEntry(PrimitiveBaseShape shp, XmlTextReader reader) 1034 private static void ProcessShpFlexiEntry(PrimitiveBaseShape shp, XmlTextReader reader)
1047 { 1035 {
1048 shp.FlexiEntry = reader.ReadElementContentAsBoolean("FlexiEntry", String.Empty); 1036 shp.FlexiEntry = Util.ReadBoolean(reader);
1049 } 1037 }
1050 1038
1051 private static void ProcessShpLightEntry(PrimitiveBaseShape shp, XmlTextReader reader) 1039 private static void ProcessShpLightEntry(PrimitiveBaseShape shp, XmlTextReader reader)
1052 { 1040 {
1053 shp.LightEntry = reader.ReadElementContentAsBoolean("LightEntry", String.Empty); 1041 shp.LightEntry = Util.ReadBoolean(reader);
1054 } 1042 }
1055 1043
1056 private static void ProcessShpSculptEntry(PrimitiveBaseShape shp, XmlTextReader reader) 1044 private static void ProcessShpSculptEntry(PrimitiveBaseShape shp, XmlTextReader reader)
1057 { 1045 {
1058 shp.SculptEntry = reader.ReadElementContentAsBoolean("SculptEntry", String.Empty); 1046 shp.SculptEntry = Util.ReadBoolean(reader);
1059 } 1047 }
1060 1048
1061 private static void ProcessShpMedia(PrimitiveBaseShape shp, XmlTextReader reader) 1049 private static void ProcessShpMedia(PrimitiveBaseShape shp, XmlTextReader reader)
@@ -1220,16 +1208,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1220 1208
1221 static void WriteFlags(XmlTextWriter writer, string name, string flagsStr, Dictionary<string, object> options) 1209 static void WriteFlags(XmlTextWriter writer, string name, string flagsStr, Dictionary<string, object> options)
1222 { 1210 {
1223 // Older versions of serialization can't cope with commas 1211 // Older versions of serialization can't cope with commas, so we eliminate the commas
1224 if (options.ContainsKey("version")) 1212 writer.WriteElementString(name, flagsStr.Replace(",", ""));
1225 {
1226 float version = 0.5F;
1227 float.TryParse(options["version"].ToString(), out version);
1228 if (version < 0.5)
1229 flagsStr = flagsStr.Replace(",", "");
1230 }
1231
1232 writer.WriteElementString(name, flagsStr);
1233 } 1213 }
1234 1214
1235 static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options, Scene scene) 1215 static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options, Scene scene)
@@ -1459,66 +1439,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1459 return obj; 1439 return obj;
1460 } 1440 }
1461 1441
1462 static UUID ReadUUID(XmlTextReader reader, string name)
1463 {
1464 UUID id;
1465 string idStr;
1466
1467 reader.ReadStartElement(name);
1468
1469 if (reader.Name == "Guid")
1470 idStr = reader.ReadElementString("Guid");
1471 else // UUID
1472 idStr = reader.ReadElementString("UUID");
1473
1474 UUID.TryParse(idStr, out id);
1475 reader.ReadEndElement();
1476
1477 return id;
1478 }
1479
1480 static Vector3 ReadVector(XmlTextReader reader, string name)
1481 {
1482 Vector3 vec;
1483
1484 reader.ReadStartElement(name);
1485 vec.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // X or x
1486 vec.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Y or y
1487 vec.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Z or z
1488 reader.ReadEndElement();
1489
1490 return vec;
1491 }
1492
1493 static Quaternion ReadQuaternion(XmlTextReader reader, string name)
1494 {
1495 Quaternion quat = new Quaternion();
1496
1497 reader.ReadStartElement(name);
1498 while (reader.NodeType != XmlNodeType.EndElement)
1499 {
1500 switch (reader.Name.ToLower())
1501 {
1502 case "x":
1503 quat.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1504 break;
1505 case "y":
1506 quat.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1507 break;
1508 case "z":
1509 quat.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1510 break;
1511 case "w":
1512 quat.W = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1513 break;
1514 }
1515 }
1516
1517 reader.ReadEndElement();
1518
1519 return quat;
1520 }
1521
1522 static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name) 1442 static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name)
1523 { 1443 {
1524 TaskInventoryDictionary tinv = new TaskInventoryDictionary(); 1444 TaskInventoryDictionary tinv = new TaskInventoryDictionary();
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index f57cf98..b84298f 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -121,13 +121,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests
121 "Not exactly sure what this is asserting..."); 121 "Not exactly sure what this is asserting...");
122 122
123 // Delink part 2 123 // Delink part 2
124 grp1.DelinkFromGroup(part2.LocalId); 124 SceneObjectGroup grp3 = grp1.DelinkFromGroup(part2.LocalId);
125 125
126 if (debugtest) 126 if (debugtest)
127 m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset); 127 m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset);
128 128
129 Assert.That(grp1.Parts.Length, Is.EqualTo(1), "Group 1 still contained part2 after delink."); 129 Assert.That(grp1.Parts.Length, Is.EqualTo(1), "Group 1 still contained part2 after delink.");
130 Assert.That(part2.AbsolutePosition == Vector3.Zero, "The absolute position should be zero"); 130 Assert.That(part2.AbsolutePosition == Vector3.Zero, "The absolute position should be zero");
131 Assert.That(grp3.HasGroupChangedDueToDelink, Is.True);
131 } 132 }
132 133
133 [Test] 134 [Test]
@@ -325,7 +326,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
325 326
326 SceneObjectGroup sog = new SceneObjectGroup(rootPart); 327 SceneObjectGroup sog = new SceneObjectGroup(rootPart);
327 sog.AddPart(linkPart); 328 sog.AddPart(linkPart);
328 scene.AddNewSceneObject(sog, true); 329 scene.AddNewSceneObject(sog, true);
329 330
330 // In a test, we have to crank the backup handle manually. Normally this would be done by the timer invoked 331 // In a test, we have to crank the backup handle manually. Normally this would be done by the timer invoked
331 // scene backup thread. 332 // scene backup thread.
@@ -333,7 +334,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
333 334
334 // These changes should occur immediately without waiting for a backup pass 335 // These changes should occur immediately without waiting for a backup pass
335 SceneObjectGroup groupToDelete = sog.DelinkFromGroup(linkPart, false); 336 SceneObjectGroup groupToDelete = sog.DelinkFromGroup(linkPart, false);
337
338 Assert.That(groupToDelete.HasGroupChangedDueToDelink, Is.True);
336 scene.DeleteSceneObject(groupToDelete, false); 339 scene.DeleteSceneObject(groupToDelete, false);
340 Assert.That(groupToDelete.HasGroupChangedDueToDelink, Is.False);
337 341
338 List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID); 342 List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID);
339 343
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index aee2d10..3978a7d 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -86,23 +86,33 @@ namespace OpenSim.Region.Framework.Scenes
86 /// <param name="assetUuids">The assets gathered</param> 86 /// <param name="assetUuids">The assets gathered</param>
87 public void GatherAssetUuids(UUID assetUuid, AssetType assetType, IDictionary<UUID, AssetType> assetUuids) 87 public void GatherAssetUuids(UUID assetUuid, AssetType assetType, IDictionary<UUID, AssetType> assetUuids)
88 { 88 {
89 assetUuids[assetUuid] = assetType; 89 try
90 90 {
91 if (AssetType.Bodypart == assetType || AssetType.Clothing == assetType) 91 assetUuids[assetUuid] = assetType;
92 { 92
93 GetWearableAssetUuids(assetUuid, assetUuids); 93 if (AssetType.Bodypart == assetType || AssetType.Clothing == assetType)
94 } 94 {
95 else if (AssetType.Gesture == assetType) 95 GetWearableAssetUuids(assetUuid, assetUuids);
96 { 96 }
97 GetGestureAssetUuids(assetUuid, assetUuids); 97 else if (AssetType.Gesture == assetType)
98 } 98 {
99 else if (AssetType.LSLText == assetType) 99 GetGestureAssetUuids(assetUuid, assetUuids);
100 { 100 }
101 GetScriptAssetUuids(assetUuid, assetUuids); 101 else if (AssetType.LSLText == assetType)
102 {
103 GetScriptAssetUuids(assetUuid, assetUuids);
104 }
105 else if (AssetType.Object == assetType)
106 {
107 GetSceneObjectAssetUuids(assetUuid, assetUuids);
108 }
102 } 109 }
103 else if (AssetType.Object == assetType) 110 catch (Exception)
104 { 111 {
105 GetSceneObjectAssetUuids(assetUuid, assetUuids); 112 m_log.ErrorFormat(
113 "[UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}",
114 assetUuid, assetType);
115 throw;
106 } 116 }
107 } 117 }
108 118