aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEventQueue.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs48
-rw-r--r--OpenSim/Region/Framework/Interfaces/IGroupsModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs19
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISoundModule.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs114
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs60
-rw-r--r--OpenSim/Region/Framework/Scenes/KeyframeMotion.cs38
-rw-r--r--OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs30
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs382
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs107
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs199
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs107
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs88
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs76
32 files changed, 1123 insertions, 399 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
index 292efa4..d49b24e 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Interfaces
40 40
41 uint GetRegionFlags(); 41 uint GetRegionFlags();
42 bool IsManager(UUID avatarID); 42 bool IsManager(UUID avatarID);
43 43
44 /// <summary> 44 /// <summary>
45 /// Tell all clients about the current state of the region (terrain textures, water height, etc.). 45 /// Tell all clients about the current state of the region (terrain textures, water height, etc.).
46 /// </summary> 46 /// </summary>
diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
index 5512642..3780ece 100644
--- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Region.Framework.Interfaces
53 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, 53 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
54 uint timeStamp, bool offline, int parentEstateID, Vector3 position, 54 uint timeStamp, bool offline, int parentEstateID, Vector3 position,
55 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); 55 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket);
56 void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, 56 void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
57 bool isModerator, bool textMute); 57 bool isModerator, bool textMute);
58 void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); 58 void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID);
59 void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID); 59 void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID);
diff --git a/OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs b/OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs
new file mode 100644
index 0000000..a730cfd
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IExternalCapsModule.cs
@@ -0,0 +1,48 @@
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;
30using OpenSim.Framework;
31using Caps=OpenSim.Framework.Capabilities.Caps;
32
33namespace OpenSim.Region.Framework.Interfaces
34{
35 public interface IExternalCapsModule
36 {
37 /// <summary>
38 /// This function extends the simple URL configuration in the caps handlers
39 /// to facilitate more interesting computation when an external handler is
40 /// sent to the viewer.
41 /// </summary>
42 /// <param name="agentID">New user UUID</param>
43 /// <param name="caps">Internal caps registry, where the external handler will be registered</param>
44 /// <param name="capName">Name of the specific cap we are registering</param>
45 /// <param name="urlSkel">The skeleton URL provided in the caps configuration</param>
46 bool RegisterExternalUserCapsHandler(UUID agentID, Caps caps, String capName, String urlSkel);
47 }
48}
diff --git a/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs b/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
index 6885327..9ae5e87 100644
--- a/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
@@ -97,5 +97,7 @@ namespace OpenSim.Region.Framework.Interfaces
97 void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InviteeID, UUID RoleID); 97 void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InviteeID, UUID RoleID);
98 void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID GroupID, UUID InviteeID, UUID RoleID); 98 void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID GroupID, UUID InviteeID, UUID RoleID);
99 void NotifyChange(UUID GroupID); 99 void NotifyChange(UUID GroupID);
100
101 List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query);
100 } 102 }
101} \ No newline at end of file 103} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs b/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs
new file mode 100644
index 0000000..198256f
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs
@@ -0,0 +1,19 @@
1using System;
2using System.Collections.Generic;
3
4namespace OpenSim.Region.Framework.Interfaces
5{
6 public interface IServiceThrottleModule
7 {
8 /// <summary>
9 /// Enqueue a continuation meant to get a resource from elsewhere.
10 /// As usual with CPS, caller beware: if that continuation is a never-ending computation,
11 /// the whole thread will be blocked, and no requests are processed
12 /// </summary>
13 /// <param name="category">Category of the resource (e.g. name, region)</param>
14 /// <param name="itemid">The resource identifier</param>
15 /// <param name="continuation">The continuation to be executed</param>
16 void Enqueue(string category, string itemid, Action continuation);
17 }
18
19}
diff --git a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs
index 68af492..8372ddd 100644
--- a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs
@@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Interfaces
104 /// <param name="sound">Sound asset ID</param> 104 /// <param name="sound">Sound asset ID</param>
105 /// <param name="volume">Sound volume</param> 105 /// <param name="volume">Sound volume</param>
106 /// <param name="triggered">Triggered or not.</param> 106 /// <param name="triggered">Triggered or not.</param>
107 /// <param name="flags"></param>
108 /// <param name="radius">Sound radius</param> 107 /// <param name="radius">Sound radius</param>
109 /// <param name="useMaster">Play using sound master</param> 108 /// <param name="useMaster">Play using sound master</param>
110 /// <param name="isMaster">Play as sound master</param> 109 /// <param name="isMaster">Play as sound master</param>
@@ -123,5 +122,12 @@ namespace OpenSim.Region.Framework.Interfaces
123 /// <param name="max">AABB top north-east corner</param> 122 /// <param name="max">AABB top north-east corner</param>
124 void TriggerSoundLimited(UUID objectID, UUID sound, double volume, 123 void TriggerSoundLimited(UUID objectID, UUID sound, double volume,
125 Vector3 min, Vector3 max); 124 Vector3 min, Vector3 max);
125
126 /// <summary>
127 /// Set whether sounds on the given prim should be queued.
128 /// </summary>
129 /// <param name='objectID'></param>
130 /// <param name='shouldQueue'></param>
131 void SetSoundQueueing(UUID objectID, bool shouldQueue);
126 } 132 }
127} \ No newline at end of file 133} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
index 66edfed..b7400ea 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
@@ -28,8 +28,11 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Text;
31using log4net; 32using log4net;
32using OpenMetaverse; 33using OpenMetaverse;
34using OpenMetaverse.StructuredData;
35
33using OpenSim.Framework; 36using OpenSim.Framework;
34 37
35using Animation = OpenSim.Framework.Animation; 38using Animation = OpenSim.Framework.Animation;
@@ -60,6 +63,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
60 ResetDefaultAnimation(); 63 ResetDefaultAnimation();
61 } 64 }
62 65
66 public AnimationSet(OSDArray pArray)
67 {
68 ResetDefaultAnimation();
69 FromOSDArray(pArray);
70 }
71
63 public bool HasAnimation(UUID animID) 72 public bool HasAnimation(UUID animID)
64 { 73 {
65 if (m_defaultAnimation.AnimID == animID) 74 if (m_defaultAnimation.AnimID == animID)
@@ -218,5 +227,110 @@ namespace OpenSim.Region.Framework.Scenes.Animation
218 foreach (OpenSim.Framework.Animation anim in theArray) 227 foreach (OpenSim.Framework.Animation anim in theArray)
219 m_animations.Add(anim); 228 m_animations.Add(anim);
220 } 229 }
230
231 // Create representation of this AnimationSet as an OSDArray.
232 // First two entries in the array are the default and implicitDefault animations
233 // followed by the other animations.
234 public OSDArray ToOSDArray()
235 {
236 OSDArray ret = new OSDArray();
237 ret.Add(DefaultAnimation.PackUpdateMessage());
238 ret.Add(ImplicitDefaultAnimation.PackUpdateMessage());
239
240 foreach (OpenSim.Framework.Animation anim in m_animations)
241 ret.Add(anim.PackUpdateMessage());
242
243 return ret;
244 }
245
246 public void FromOSDArray(OSDArray pArray)
247 {
248 this.Clear();
249
250 if (pArray.Count >= 1)
251 {
252 m_defaultAnimation = new OpenSim.Framework.Animation((OSDMap)pArray[0]);
253 }
254 if (pArray.Count >= 2)
255 {
256 m_implicitDefaultAnimation = new OpenSim.Framework.Animation((OSDMap)pArray[1]);
257 }
258 for (int ii = 2; ii < pArray.Count; ii++)
259 {
260 m_animations.Add(new OpenSim.Framework.Animation((OSDMap)pArray[ii]));
261 }
262 }
263
264 // Compare two AnimationSets and return 'true' if the default animations are the same
265 // and all of the animations in the list are equal.
266 public override bool Equals(object obj)
267 {
268 AnimationSet other = obj as AnimationSet;
269 if (other != null)
270 {
271 if (this.DefaultAnimation.Equals(other.DefaultAnimation)
272 && this.ImplicitDefaultAnimation.Equals(other.ImplicitDefaultAnimation))
273 {
274 // The defaults are the same. Is the list of animations the same?
275 OpenSim.Framework.Animation[] thisAnims = this.ToArray();
276 OpenSim.Framework.Animation[] otherAnims = other.ToArray();
277 if (thisAnims.Length == 0 && otherAnims.Length == 0)
278 return true; // the common case
279 if (thisAnims.Length == otherAnims.Length)
280 {
281 // Do this the hard way but since the list is usually short this won't take long.
282 foreach (OpenSim.Framework.Animation thisAnim in thisAnims)
283 {
284 bool found = false;
285 foreach (OpenSim.Framework.Animation otherAnim in otherAnims)
286 {
287 if (thisAnim.Equals(otherAnim))
288 {
289 found = true;
290 break;
291 }
292 }
293 if (!found)
294 {
295 // If anything is not in the other list, these are not equal
296 return false;
297 }
298 }
299 // Found everything in the other list. Since lists are equal length, they must be equal.
300 return true;
301 }
302 }
303 return false;
304 }
305 // Don't know what was passed, but the base system will figure it out for me.
306 return base.Equals(obj);
307 }
308
309 public override string ToString()
310 {
311 StringBuilder buff = new StringBuilder();
312 buff.Append("dflt=");
313 buff.Append(DefaultAnimation.ToString());
314 buff.Append(",iDflt=");
315 if (DefaultAnimation.Equals(ImplicitDefaultAnimation))
316 buff.Append("same");
317 else
318 buff.Append(ImplicitDefaultAnimation.ToString());
319 if (m_animations.Count > 0)
320 {
321 buff.Append(",anims=");
322 bool firstTime = true;
323 foreach (OpenSim.Framework.Animation anim in m_animations)
324 {
325 if (!firstTime)
326 buff.Append(",");
327 buff.Append("<");
328 buff.Append(anim.ToString());
329 buff.Append(">");
330 firstTime = false;
331 }
332 }
333 return buff.ToString();
334 }
221 } 335 }
222} 336}
diff --git a/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
index c2b0468..b79dd8f 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
@@ -104,5 +104,31 @@ namespace OpenSim.Region.Framework.Scenes.Animation
104 104
105 return UUID.Zero; 105 return UUID.Zero;
106 } 106 }
107
108 /// <summary>
109 /// Get the name of the animation given a UUID. If there is no matching animation
110 /// return the UUID as a string.
111 /// </summary>
112 public static string GetDefaultAnimationName(UUID uuid)
113 {
114 string ret = "unknown";
115 if (AnimsUUID.ContainsValue(uuid))
116 {
117 foreach (KeyValuePair<string, UUID> kvp in AnimsUUID)
118 {
119 if (kvp.Value == uuid)
120 {
121 ret = kvp.Key;
122 break;
123 }
124 }
125 }
126 else
127 {
128 ret = uuid.ToString();
129 }
130
131 return ret;
132 }
107 } 133 }
108} \ No newline at end of file 134} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 65c279e..5529a25 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -93,7 +93,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
93 GetAnimName(animID), animID, m_scenePresence.Name); 93 GetAnimName(animID), animID, m_scenePresence.Name);
94 94
95 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) 95 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
96 {
96 SendAnimPack(); 97 SendAnimPack();
98 m_scenePresence.TriggerScenePresenceUpdated();
99 }
97 } 100 }
98 101
99 // Called from scripts 102 // Called from scripts
@@ -132,7 +135,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
132 GetAnimName(animID), animID, m_scenePresence.Name); 135 GetAnimName(animID), animID, m_scenePresence.Name);
133 136
134 if (m_animations.Remove(animID, allowNoDefault)) 137 if (m_animations.Remove(animID, allowNoDefault))
138 {
135 SendAnimPack(); 139 SendAnimPack();
140 m_scenePresence.TriggerScenePresenceUpdated();
141 }
136 } 142 }
137 143
138 public void avnChangeAnim(UUID animID, bool addRemove, bool sendPack) 144 public void avnChangeAnim(UUID animID, bool addRemove, bool sendPack)
@@ -180,8 +186,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
180 /// The movement animation is reserved for "main" animations 186 /// The movement animation is reserved for "main" animations
181 /// that are mutually exclusive, e.g. flying and sitting. 187 /// that are mutually exclusive, e.g. flying and sitting.
182 /// </summary> 188 /// </summary>
183 public void TrySetMovementAnimation(string anim) 189 /// <returns>'true' if the animation was updated</returns>
190 public bool TrySetMovementAnimation(string anim)
184 { 191 {
192 bool ret = false;
185 if (!m_scenePresence.IsChildAgent) 193 if (!m_scenePresence.IsChildAgent)
186 { 194 {
187// m_log.DebugFormat( 195// m_log.DebugFormat(
@@ -198,6 +206,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
198 // 16384 is CHANGED_ANIMATION 206 // 16384 is CHANGED_ANIMATION
199 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); 207 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION});
200 SendAnimPack(); 208 SendAnimPack();
209 ret = true;
201 } 210 }
202 } 211 }
203 else 212 else
@@ -206,6 +215,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
206 "[SCENE PRESENCE ANIMATOR]: Tried to set movement animation {0} on child presence {1}", 215 "[SCENE PRESENCE ANIMATOR]: Tried to set movement animation {0} on child presence {1}",
207 anim, m_scenePresence.Name); 216 anim, m_scenePresence.Name);
208 } 217 }
218 return ret;
209 } 219 }
210 220
211 /// <summary> 221 /// <summary>
@@ -439,8 +449,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
439 /// <summary> 449 /// <summary>
440 /// Update the movement animation of this avatar according to its current state 450 /// Update the movement animation of this avatar according to its current state
441 /// </summary> 451 /// </summary>
442 public void UpdateMovementAnimations() 452 /// <returns>'true' if the animation was changed</returns>
453 public bool UpdateMovementAnimations()
443 { 454 {
455 bool ret = false;
444 lock (m_animations) 456 lock (m_animations)
445 { 457 {
446 string newMovementAnimation = DetermineMovementAnimation(); 458 string newMovementAnimation = DetermineMovementAnimation();
@@ -454,9 +466,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
454 466
455 // Only set it if it's actually changed, give a script 467 // Only set it if it's actually changed, give a script
456 // a chance to stop a default animation 468 // a chance to stop a default animation
457 TrySetMovementAnimation(CurrentMovementAnimation); 469 ret = TrySetMovementAnimation(CurrentMovementAnimation);
458 } 470 }
459 } 471 }
472 return ret;
460 } 473 }
461 474
462 public UUID[] GetAnimationArray() 475 public UUID[] GetAnimationArray()
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index f555b49..11a0146 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -104,14 +104,8 @@ namespace OpenSim.Region.Framework.Scenes
104 // better than losing the object for now. 104 // better than losing the object for now.
105 if (permissionToDelete) 105 if (permissionToDelete)
106 { 106 {
107 List<uint> killIDs = new List<uint>();
108
109 foreach (SceneObjectGroup g in objectGroups) 107 foreach (SceneObjectGroup g in objectGroups)
110 { killIDs.Add(g.LocalId); 108 g.DeleteGroupFromScene(false);
111 g.DeleteGroupFromScene(true);
112 }
113
114 m_scene.SendKillObject(killIDs);
115 } 109 }
116 } 110 }
117 111
@@ -160,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
160 if (x.permissionToDelete) 154 if (x.permissionToDelete)
161 { 155 {
162 foreach (SceneObjectGroup g in x.objectGroups) 156 foreach (SceneObjectGroup g in x.objectGroups)
163 m_scene.DeleteSceneObject(g, false); 157 m_scene.DeleteSceneObject(g, true);
164 } 158 }
165 } 159 }
166 catch (Exception e) 160 catch (Exception e)
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 4733547..6e8eb91 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -743,7 +743,7 @@ namespace OpenSim.Region.Framework.Scenes
743 public event OnIncomingSceneObjectDelegate OnIncomingSceneObject; 743 public event OnIncomingSceneObjectDelegate OnIncomingSceneObject;
744 public delegate void OnIncomingSceneObjectDelegate(SceneObjectGroup so); 744 public delegate void OnIncomingSceneObjectDelegate(SceneObjectGroup so);
745 745
746 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); 746 public delegate void NewInventoryItemUploadComplete(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel);
747 747
748 public event NewInventoryItemUploadComplete OnNewInventoryItemUploadComplete; 748 public event NewInventoryItemUploadComplete OnNewInventoryItemUploadComplete;
749 749
@@ -974,6 +974,8 @@ namespace OpenSim.Region.Framework.Scenes
974 public delegate void RegionStarted(Scene scene); 974 public delegate void RegionStarted(Scene scene);
975 public event RegionStarted OnRegionStarted; 975 public event RegionStarted OnRegionStarted;
976 976
977 public delegate void RegionHeartbeatStart(Scene scene);
978 public event RegionHeartbeatStart OnRegionHeartbeatStart;
977 public delegate void RegionHeartbeatEnd(Scene scene); 979 public delegate void RegionHeartbeatEnd(Scene scene);
978 public event RegionHeartbeatEnd OnRegionHeartbeatEnd; 980 public event RegionHeartbeatEnd OnRegionHeartbeatEnd;
979 981
@@ -1024,6 +1026,16 @@ namespace OpenSim.Region.Framework.Scenes
1024 /// </remarks> 1026 /// </remarks>
1025 public event TeleportFail OnTeleportFail; 1027 public event TeleportFail OnTeleportFail;
1026 1028
1029// public delegate void GatherUuids(SceneObjectPart sop, IDictionary<UUID, AssetType> assetUuids);
1030//
1031// /// <summary>
1032// /// Triggered when UUIDs referenced by a scene object are being gathered for archiving, hg transfer, etc.
1033// /// </summary>
1034// /// <remarks>
1035// /// The listener should add references to the IDictionary<UUID, AssetType> as appropriate.
1036// /// </remarks>
1037// public event GatherUuids OnGatherUuids;
1038
1027 public class MoneyTransferArgs : EventArgs 1039 public class MoneyTransferArgs : EventArgs
1028 { 1040 {
1029 public UUID sender; 1041 public UUID sender;
@@ -2160,7 +2172,7 @@ namespace OpenSim.Region.Framework.Scenes
2160 } 2172 }
2161 } 2173 }
2162 2174
2163 public void TriggerOnNewInventoryItemUploadComplete(UUID agentID, UUID AssetID, String AssetName, int userlevel) 2175 public void TriggerOnNewInventoryItemUploadComplete(UUID agentID, AssetType type, UUID AssetID, String AssetName, int userlevel)
2164 { 2176 {
2165 NewInventoryItemUploadComplete handlerNewInventoryItemUpdateComplete = OnNewInventoryItemUploadComplete; 2177 NewInventoryItemUploadComplete handlerNewInventoryItemUpdateComplete = OnNewInventoryItemUploadComplete;
2166 if (handlerNewInventoryItemUpdateComplete != null) 2178 if (handlerNewInventoryItemUpdateComplete != null)
@@ -2169,7 +2181,7 @@ namespace OpenSim.Region.Framework.Scenes
2169 { 2181 {
2170 try 2182 try
2171 { 2183 {
2172 d(agentID, AssetID, AssetName, userlevel); 2184 d(agentID, type, AssetID, AssetName, userlevel);
2173 } 2185 }
2174 catch (Exception e) 2186 catch (Exception e)
2175 { 2187 {
@@ -3096,6 +3108,27 @@ namespace OpenSim.Region.Framework.Scenes
3096 } 3108 }
3097 } 3109 }
3098 3110
3111 public void TriggerRegionHeartbeatStart(Scene scene)
3112 {
3113 RegionHeartbeatStart handler = OnRegionHeartbeatStart;
3114
3115 if (handler != null)
3116 {
3117 foreach (RegionHeartbeatStart d in handler.GetInvocationList())
3118 {
3119 try
3120 {
3121 d(scene);
3122 }
3123 catch (Exception e)
3124 {
3125 m_log.ErrorFormat("[EVENT MANAGER]: Delegate for OnRegionHeartbeatStart failed - continuing {0} - {1}",
3126 e.Message, e.StackTrace);
3127 }
3128 }
3129 }
3130 }
3131
3099 public void TriggerRegionHeartbeatEnd(Scene scene) 3132 public void TriggerRegionHeartbeatEnd(Scene scene)
3100 { 3133 {
3101 RegionHeartbeatEnd handler = OnRegionHeartbeatEnd; 3134 RegionHeartbeatEnd handler = OnRegionHeartbeatEnd;
@@ -3251,5 +3284,26 @@ namespace OpenSim.Region.Framework.Scenes
3251 handler(scenePresence); 3284 handler(scenePresence);
3252 } 3285 }
3253 } 3286 }
3287
3288// public void TriggerGatherUuids(SceneObjectPart sop, IDictionary<UUID, AssetType> assetUuids)
3289// {
3290// GatherUuids handler = OnGatherUuids;
3291//
3292// if (handler != null)
3293// {
3294// foreach (GatherUuids d in handler.GetInvocationList())
3295// {
3296// try
3297// {
3298// d(sop, assetUuids);
3299// }
3300// catch (Exception e)
3301// {
3302// m_log.ErrorFormat("[EVENT MANAGER]: Delegate for TriggerUuidGather failed - continuing {0} - {1}",
3303// e.Message, e.StackTrace);
3304// }
3305// }
3306// }
3307// }
3254 } 3308 }
3255} 3309}
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
index d773ee7..29652aa 100644
--- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
+++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
@@ -1,6 +1,29 @@
1// Proprietary code of Avination Virtual Limited 1/*
2// (c) 2012 Melanie Thielker 2 * Copyright (c) Contributors, http://opensimulator.org/
3// 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 */
4 27
5using System; 28using System;
6using System.Timers; 29using System.Timers;
@@ -32,7 +55,6 @@ namespace OpenSim.Region.Framework.Scenes
32 private object m_lockObject = new object(); 55 private object m_lockObject = new object();
33 private object m_timerLock = new object(); 56 private object m_timerLock = new object();
34 private const double m_tickDuration = 50.0; 57 private const double m_tickDuration = 50.0;
35 private Scene m_scene;
36 58
37 public double TickDuration 59 public double TickDuration
38 { 60 {
@@ -46,8 +68,6 @@ namespace OpenSim.Region.Framework.Scenes
46 m_timer.AutoReset = true; 68 m_timer.AutoReset = true;
47 m_timer.Elapsed += OnTimer; 69 m_timer.Elapsed += OnTimer;
48 70
49 m_scene = scene;
50
51 m_timer.Start(); 71 m_timer.Start();
52 } 72 }
53 73
@@ -71,13 +91,13 @@ namespace OpenSim.Region.Framework.Scenes
71 { 91 {
72 m.OnTimer(TickDuration); 92 m.OnTimer(TickDuration);
73 } 93 }
74 catch (Exception inner) 94 catch (Exception)
75 { 95 {
76 // Don't stop processing 96 // Don't stop processing
77 } 97 }
78 } 98 }
79 } 99 }
80 catch (Exception e) 100 catch (Exception)
81 { 101 {
82 // Keep running no matter what 102 // Keep running no matter what
83 } 103 }
@@ -134,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
134 [Serializable] 154 [Serializable]
135 public class KeyframeMotion 155 public class KeyframeMotion
136 { 156 {
137 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 157// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
138 158
139 public enum PlayMode : int 159 public enum PlayMode : int
140 { 160 {
diff --git a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
index c11174d..f208afb 100644
--- a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
+++ b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
@@ -46,47 +46,33 @@ using OpenSim.Region.Framework.Scenes;
46 46
47namespace OpenSim.Region.Framework.Scenes 47namespace OpenSim.Region.Framework.Scenes
48{ 48{
49 public class RegionStatsHandler : IStreamedRequestHandler 49 public class RegionStatsHandler : BaseStreamHandler
50 { 50 {
51 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 private string osRXStatsURI = String.Empty;
54 private string osXStatsURI = String.Empty; 53 private string osXStatsURI = String.Empty;
55 //private string osSecret = String.Empty; 54 //private string osSecret = String.Empty;
56 private OpenSim.Framework.RegionInfo regionInfo; 55 private OpenSim.Framework.RegionInfo regionInfo;
57 public string localZone = TimeZone.CurrentTimeZone.StandardName; 56 public string localZone = TimeZone.CurrentTimeZone.StandardName;
58 public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); 57 public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
59 58
60 public string Name { get { return "RegionStats"; } } 59 public RegionStatsHandler(RegionInfo region_info)
61 public string Description { get { return "Region Statistics"; } } 60 : base("GET", "/" + Util.SHA1Hash(region_info.regionSecret), "RegionStats", "Region Statistics")
62
63 public RegionStatsHandler(RegionInfo region_info)
64 { 61 {
65 regionInfo = region_info; 62 regionInfo = region_info;
66 osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret);
67 osXStatsURI = Util.SHA1Hash(regionInfo.osSecret); 63 osXStatsURI = Util.SHA1Hash(regionInfo.osSecret);
68 } 64 }
69 65
70 public byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 66 protected override byte[] ProcessRequest(
67 string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
71 { 68 {
72 return Util.UTF8.GetBytes(Report()); 69 return Util.UTF8.GetBytes(Report());
73 } 70 }
74 71
75 public string ContentType 72 public override string ContentType
76 { 73 {
77 get { return "text/plain"; } 74 get { return "text/plain"; }
78 } 75 }
79
80 public string HttpMethod
81 {
82 get { return "GET"; }
83 }
84
85 public string Path
86 {
87 // This is for the region and is the regionSecret hashed
88 get { return "/" + osRXStatsURI; }
89 }
90 76
91 private string Report() 77 private string Report()
92 { 78 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index d2e41f8..8f6073a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -139,7 +139,7 @@ namespace OpenSim.Region.Framework.Scenes
139 { 139 {
140 userlevel = 1; 140 userlevel = 1;
141 } 141 }
142 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel); 142 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
143 143
144 return true; 144 return true;
145 } 145 }
@@ -178,7 +178,7 @@ namespace OpenSim.Region.Framework.Scenes
178 { 178 {
179 userlevel = 1; 179 userlevel = 1;
180 } 180 }
181 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel); 181 EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
182 182
183 if (originalFolder != UUID.Zero) 183 if (originalFolder != UUID.Zero)
184 { 184 {
@@ -417,13 +417,13 @@ namespace OpenSim.Region.Framework.Scenes
417 // is not allowed to change the export flag. 417 // is not allowed to change the export flag.
418 bool denyExportChange = false; 418 bool denyExportChange = false;
419 419
420 m_log.InfoFormat("[XXX]: B: {0} O: {1} E: {2}", itemUpd.BasePermissions, itemUpd.CurrentPermissions, itemUpd.EveryOnePermissions); 420// m_log.DebugFormat("[XXX]: B: {0} O: {1} E: {2}", itemUpd.BasePermissions, itemUpd.CurrentPermissions, itemUpd.EveryOnePermissions);
421 421
422 // If the user is not the creator or doesn't have "E" in both "B" and "O", deny setting export 422 // If the user is not the creator or doesn't have "E" in both "B" and "O", deny setting export
423 if ((item.BasePermissions & (uint)(PermissionMask.All | PermissionMask.Export)) != (uint)(PermissionMask.All | PermissionMask.Export) || (item.CurrentPermissions & (uint)PermissionMask.Export) == 0 || item.CreatorIdAsUuid != item.Owner) 423 if ((item.BasePermissions & (uint)(PermissionMask.All | PermissionMask.Export)) != (uint)(PermissionMask.All | PermissionMask.Export) || (item.CurrentPermissions & (uint)PermissionMask.Export) == 0 || item.CreatorIdAsUuid != item.Owner)
424 denyExportChange = true; 424 denyExportChange = true;
425 425
426 m_log.InfoFormat("[XXX]: Deny Export Update {0}", denyExportChange); 426// m_log.DebugFormat("[XXX]: Deny Export Update {0}", denyExportChange);
427 427
428 // If it is already set, force it set and also force full perm 428 // If it is already set, force it set and also force full perm
429 // else prevent setting it. It can and should never be set unless 429 // else prevent setting it. It can and should never be set unless
@@ -447,7 +447,7 @@ namespace OpenSim.Region.Framework.Scenes
447 // If the new state is exportable, force full perm 447 // If the new state is exportable, force full perm
448 if ((itemUpd.EveryOnePermissions & (uint)PermissionMask.Export) != 0) 448 if ((itemUpd.EveryOnePermissions & (uint)PermissionMask.Export) != 0)
449 { 449 {
450 m_log.InfoFormat("[XXX]: Force full perm"); 450// m_log.DebugFormat("[XXX]: Force full perm");
451 itemUpd.NextPermissions = (uint)(PermissionMask.All); 451 itemUpd.NextPermissions = (uint)(PermissionMask.All);
452 } 452 }
453 } 453 }
@@ -485,7 +485,10 @@ namespace OpenSim.Region.Framework.Scenes
485 item.SaleType = itemUpd.SaleType; 485 item.SaleType = itemUpd.SaleType;
486 486
487 InventoryService.UpdateItem(item); 487 InventoryService.UpdateItem(item);
488 remoteClient.SendBulkUpdateInventory(item); 488
489 // We cannot send out a bulk update here, since this will cause editing of clothing to start
490 // failing frequently. Possibly this is a race with a separate transaction that uploads the asset.
491// remoteClient.SendBulkUpdateInventory(item);
489 } 492 }
490 493
491 if (UUID.Zero != transactionID) 494 if (UUID.Zero != transactionID)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index ce6415a..421cb08 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -416,6 +416,7 @@ namespace OpenSim.Region.Framework.Scenes
416 void ProcessViewerEffect(IClientAPI remoteClient, List<ViewerEffectEventHandlerArg> args) 416 void ProcessViewerEffect(IClientAPI remoteClient, List<ViewerEffectEventHandlerArg> args)
417 { 417 {
418 // TODO: don't create new blocks if recycling an old packet 418 // TODO: don't create new blocks if recycling an old packet
419 bool discardableEffects = true;
419 ViewerEffectPacket.EffectBlock[] effectBlockArray = new ViewerEffectPacket.EffectBlock[args.Count]; 420 ViewerEffectPacket.EffectBlock[] effectBlockArray = new ViewerEffectPacket.EffectBlock[args.Count];
420 for (int i = 0; i < args.Count; i++) 421 for (int i = 0; i < args.Count; i++)
421 { 422 {
@@ -427,17 +428,34 @@ namespace OpenSim.Region.Framework.Scenes
427 effect.Type = args[i].Type; 428 effect.Type = args[i].Type;
428 effect.TypeData = args[i].TypeData; 429 effect.TypeData = args[i].TypeData;
429 effectBlockArray[i] = effect; 430 effectBlockArray[i] = effect;
431
432 if ((EffectType)effect.Type != EffectType.LookAt && (EffectType)effect.Type != EffectType.Beam)
433 discardableEffects = false;
434
435 //m_log.DebugFormat("[YYY]: VE {0} {1} {2}", effect.AgentID, effect.Duration, (EffectType)effect.Type);
430 } 436 }
431 437
432 ForEachClient( 438 ForEachScenePresence(sp =>
433 delegate(IClientAPI client)
434 { 439 {
435 if (client.AgentId != remoteClient.AgentId) 440 if (sp.ControllingClient.AgentId != remoteClient.AgentId)
436 client.SendViewerEffect(effectBlockArray); 441 {
437 } 442 if (!discardableEffects ||
438 ); 443 (discardableEffects && ShouldSendDiscardableEffect(remoteClient, sp)))
444 {
445 //m_log.DebugFormat("[YYY]: Sending to {0}", sp.UUID);
446 sp.ControllingClient.SendViewerEffect(effectBlockArray);
447 }
448 //else
449 // m_log.DebugFormat("[YYY]: Not sending to {0}", sp.UUID);
450 }
451 });
439 } 452 }
440 453
454 private bool ShouldSendDiscardableEffect(IClientAPI thisClient, ScenePresence other)
455 {
456 return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10;
457 }
458
441 private class DescendentsRequestData 459 private class DescendentsRequestData
442 { 460 {
443 public IClientAPI RemoteClient; 461 public IClientAPI RemoteClient;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 2b58795..0d9028c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -230,6 +230,8 @@ namespace OpenSim.Region.Framework.Scenes
230 public bool m_seeIntoBannedRegion = false; 230 public bool m_seeIntoBannedRegion = false;
231 public int MaxUndoCount = 5; 231 public int MaxUndoCount = 5;
232 232
233 public bool SeeIntoRegion { get; set; }
234
233 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 235 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
234 public bool LoginLock = false; 236 public bool LoginLock = false;
235 237
@@ -396,10 +398,12 @@ namespace OpenSim.Region.Framework.Scenes
396 if (value) 398 if (value)
397 { 399 {
398 if (!m_active) 400 if (!m_active)
399 Start(); 401 Start(false);
400 } 402 }
401 else 403 else
402 { 404 {
405 // This appears assymetric with Start() above but is not - setting m_active = false stops the loops
406 // XXX: Possibly this should be in an explicit Stop() method for symmetry.
403 m_active = false; 407 m_active = false;
404 } 408 }
405 } 409 }
@@ -859,9 +863,11 @@ namespace OpenSim.Region.Framework.Scenes
859 //Animation states 863 //Animation states
860 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 864 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
861 865
866
867 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
868
862 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 869 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
863 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 870 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
864
865 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); 871 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
866 if (RegionInfo.NonphysPrimMin > 0) 872 if (RegionInfo.NonphysPrimMin > 0)
867 { 873 {
@@ -1361,10 +1367,18 @@ namespace OpenSim.Region.Framework.Scenes
1361 } 1367 }
1362 } 1368 }
1363 1369
1370 public override void Start()
1371 {
1372 Start(true);
1373 }
1374
1364 /// <summary> 1375 /// <summary>
1365 /// Start the scene 1376 /// Start the scene
1366 /// </summary> 1377 /// </summary>
1367 public void Start() 1378 /// <param name='startScripts'>
1379 /// Start the scripts within the scene.
1380 /// </param>
1381 public void Start(bool startScripts)
1368 { 1382 {
1369 m_active = true; 1383 m_active = true;
1370 1384
@@ -1401,6 +1415,8 @@ namespace OpenSim.Region.Framework.Scenes
1401 m_heartbeatThread 1415 m_heartbeatThread
1402 = Watchdog.StartThread( 1416 = Watchdog.StartThread(
1403 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); 1417 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
1418
1419 StartScripts();
1404 } 1420 }
1405 1421
1406 /// <summary> 1422 /// <summary>
@@ -1557,6 +1573,8 @@ namespace OpenSim.Region.Framework.Scenes
1557 1573
1558 try 1574 try
1559 { 1575 {
1576 EventManager.TriggerRegionHeartbeatStart(this);
1577
1560 // Apply taints in terrain module to terrain in physics scene 1578 // Apply taints in terrain module to terrain in physics scene
1561 if (Frame % m_update_terrain == 0) 1579 if (Frame % m_update_terrain == 0)
1562 { 1580 {
@@ -2937,6 +2955,7 @@ namespace OpenSim.Region.Framework.Scenes
2937 { 2955 {
2938 ScenePresence sp; 2956 ScenePresence sp;
2939 bool vialogin; 2957 bool vialogin;
2958 bool reallyNew = true;
2940 2959
2941 // Validation occurs in LLUDPServer 2960 // Validation occurs in LLUDPServer
2942 // 2961 //
@@ -2995,16 +3014,21 @@ namespace OpenSim.Region.Framework.Scenes
2995 m_log.WarnFormat( 3014 m_log.WarnFormat(
2996 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 3015 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2997 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 3016 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
3017 reallyNew = false;
2998 } 3018 }
2999 3019
3000 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 3020 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
3001 // client is for a root or child agent. 3021 // client is for a root or child agent.
3002 client.SceneAgent = sp; 3022 client.SceneAgent = sp;
3003 3023
3004 // Cache the user's name 3024 // This is currently also being done earlier in NewUserConnection for real users to see if this
3025 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other
3026 // places. However, we still need to do it here for NPCs.
3005 CacheUserName(sp, aCircuit); 3027 CacheUserName(sp, aCircuit);
3006 3028
3007 EventManager.TriggerOnNewClient(client); 3029 if (reallyNew)
3030 EventManager.TriggerOnNewClient(client);
3031
3008 if (vialogin) 3032 if (vialogin)
3009 EventManager.TriggerOnClientLogin(client); 3033 EventManager.TriggerOnClientLogin(client);
3010 } 3034 }
@@ -3025,7 +3049,7 @@ namespace OpenSim.Region.Framework.Scenes
3025 { 3049 {
3026 string first = aCircuit.firstname, last = aCircuit.lastname; 3050 string first = aCircuit.firstname, last = aCircuit.lastname;
3027 3051
3028 if (sp.PresenceType == PresenceType.Npc) 3052 if (sp != null && sp.PresenceType == PresenceType.Npc)
3029 { 3053 {
3030 UserManagementModule.AddUser(aCircuit.AgentID, first, last); 3054 UserManagementModule.AddUser(aCircuit.AgentID, first, last);
3031 } 3055 }
@@ -3242,8 +3266,6 @@ namespace OpenSim.Region.Framework.Scenes
3242 { 3266 {
3243 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; 3267 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
3244 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; 3268 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
3245 client.OnSetStartLocationRequest += SetHomeRezPoint;
3246 client.OnRegionHandleRequest += RegionHandleRequest;
3247 } 3269 }
3248 3270
3249 public virtual void SubscribeToClientNetworkEvents(IClientAPI client) 3271 public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
@@ -3369,8 +3391,6 @@ namespace OpenSim.Region.Framework.Scenes
3369 { 3391 {
3370 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; 3392 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
3371 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; 3393 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
3372 client.OnSetStartLocationRequest -= SetHomeRezPoint;
3373 client.OnRegionHandleRequest -= RegionHandleRequest;
3374 } 3394 }
3375 3395
3376 public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client) 3396 public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
@@ -3496,33 +3516,6 @@ namespace OpenSim.Region.Framework.Scenes
3496 } 3516 }
3497 3517
3498 /// <summary> 3518 /// <summary>
3499 /// Sets the Home Point. The LoginService uses this to know where to put a user when they log-in
3500 /// </summary>
3501 /// <param name="remoteClient"></param>
3502 /// <param name="regionHandle"></param>
3503 /// <param name="position"></param>
3504 /// <param name="lookAt"></param>
3505 /// <param name="flags"></param>
3506 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3507 {
3508 //Add half the avatar's height so that the user doesn't fall through prims
3509 ScenePresence presence;
3510 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3511 {
3512 if (presence.Appearance != null)
3513 {
3514 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3515 }
3516 }
3517
3518 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3519 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3520 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
3521 else
3522 m_dialogModule.SendAlertToUser(remoteClient, "Set Home request Failed.");
3523 }
3524
3525 /// <summary>
3526 /// Get the avatar apperance for the given client. 3519 /// Get the avatar apperance for the given client.
3527 /// </summary> 3520 /// </summary>
3528 /// <param name="client"></param> 3521 /// <param name="client"></param>
@@ -3594,15 +3587,8 @@ namespace OpenSim.Region.Framework.Scenes
3594 if (closeChildAgents && isChildAgent) 3587 if (closeChildAgents && isChildAgent)
3595 { 3588 {
3596 // Tell a single agent to disconnect from the region. 3589 // Tell a single agent to disconnect from the region.
3597 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3590 // Let's do this via UDP
3598 if (eq != null) 3591 avatar.ControllingClient.SendShutdownConnectionNotice();
3599 {
3600 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3601 }
3602 else
3603 {
3604 avatar.ControllingClient.SendShutdownConnectionNotice();
3605 }
3606 } 3592 }
3607 3593
3608 // Only applies to root agents. 3594 // Only applies to root agents.
@@ -3618,16 +3604,13 @@ namespace OpenSim.Region.Framework.Scenes
3618 if (closeChildAgents && CapsModule != null) 3604 if (closeChildAgents && CapsModule != null)
3619 CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode); 3605 CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode);
3620 3606
3621// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3622// // this method is doing is HORRIBLE!!!
3623 // Commented pending deletion since this method no longer appears to do anything at all
3624// avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3625
3626 if (closeChildAgents && !isChildAgent) 3607 if (closeChildAgents && !isChildAgent)
3627 { 3608 {
3628 List<ulong> regions = avatar.KnownRegionHandles; 3609 List<ulong> regions = avatar.KnownRegionHandles;
3629 regions.Remove(RegionInfo.RegionHandle); 3610 regions.Remove(RegionInfo.RegionHandle);
3630 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3611
3612 // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours.
3613 m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions);
3631 } 3614 }
3632 3615
3633 m_eventManager.TriggerClientClosed(agentID, this); 3616 m_eventManager.TriggerClientClosed(agentID, this);
@@ -3644,7 +3627,7 @@ namespace OpenSim.Region.Framework.Scenes
3644 delegate(IClientAPI client) 3627 delegate(IClientAPI client)
3645 { 3628 {
3646 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3629 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3647 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3630 try { client.SendKillObject(new List<uint> { avatar.LocalId }); }
3648 catch (NullReferenceException) { } 3631 catch (NullReferenceException) { }
3649 }); 3632 });
3650 } 3633 }
@@ -3725,7 +3708,8 @@ namespace OpenSim.Region.Framework.Scenes
3725 } 3708 }
3726 deleteIDs.Add(localID); 3709 deleteIDs.Add(localID);
3727 } 3710 }
3728 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); }); 3711
3712 ForEachClient(c => c.SendKillObject(deleteIDs));
3729 } 3713 }
3730 3714
3731 #endregion 3715 #endregion
@@ -3847,41 +3831,47 @@ namespace OpenSim.Region.Framework.Scenes
3847 return false; 3831 return false;
3848 } 3832 }
3849 3833
3850 ScenePresence sp = GetScenePresence(agent.AgentID); 3834 lock (agent)
3851
3852 // If we have noo presence here or if that presence is a zombie root
3853 // presence that will be kicled, we need a new CAPS object.
3854 if (sp == null || (sp != null && !sp.IsChildAgent))
3855 { 3835 {
3856 if (CapsModule != null) 3836 ScenePresence sp = GetScenePresence(agent.AgentID);
3837
3838 if (sp != null)
3857 { 3839 {
3858 lock (agent) 3840 if (!sp.IsChildAgent)
3859 { 3841 {
3860 CapsModule.SetAgentCapsSeeds(agent); 3842 // We have a root agent. Is it in transit?
3861 CapsModule.CreateCaps(agent.AgentID, agent.circuitcode); 3843 if (!EntityTransferModule.IsInTransit(sp.UUID))
3862 } 3844 {
3863 } 3845 // We have a zombie from a crashed session.
3864 } 3846 // Or the same user is trying to be root twice here, won't work.
3847 // Kill it.
3848 m_log.WarnFormat(
3849 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3850 sp.Name, sp.UUID, RegionInfo.RegionName);
3865 3851
3866 if (sp != null) 3852 if (sp.ControllingClient != null)
3867 { 3853 sp.ControllingClient.Close(true, true);
3868 if (!sp.IsChildAgent)
3869 {
3870 // We have a zombie from a crashed session.
3871 // Or the same user is trying to be root twice here, won't work.
3872 // Kill it.
3873 m_log.WarnFormat(
3874 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3875 sp.Name, sp.UUID, RegionInfo.RegionName);
3876 3854
3877 sp.ControllingClient.Close(true, true); 3855 sp = null;
3878 sp = null; 3856 }
3857 //else
3858 // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName);
3859 }
3860 else
3861 {
3862 // We have a child agent here
3863 sp.DoNotCloseAfterTeleport = true;
3864 //m_log.WarnFormat("[SCENE]: Existing child scene presence for {0} {1} in {2}", sp.Name, sp.UUID, RegionInfo.RegionName);
3865 }
3879 } 3866 }
3880 }
3881 3867
3882 lock (agent) 3868 // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags.
3883 { 3869 // We need the circuit data here for some of the subsequent checks. (groups, for example)
3884 //On login test land permisions 3870 // If the checks fail, we remove the circuit.
3871 agent.teleportFlags = teleportFlags;
3872 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
3873
3874 // On login test land permisions
3885 if (vialogin) 3875 if (vialogin)
3886 { 3876 {
3887 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3877 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
@@ -3890,6 +3880,7 @@ namespace OpenSim.Region.Framework.Scenes
3890 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y)) 3880 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3891 { 3881 {
3892 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3882 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3883 m_authenticateHandler.RemoveCircuit(agent.circuitcode);
3893 return false; 3884 return false;
3894 } 3885 }
3895 } 3886 }
@@ -3901,31 +3892,35 @@ namespace OpenSim.Region.Framework.Scenes
3901 try 3892 try
3902 { 3893 {
3903 if (!VerifyUserPresence(agent, out reason)) 3894 if (!VerifyUserPresence(agent, out reason))
3895 {
3896 m_authenticateHandler.RemoveCircuit(agent.circuitcode);
3904 return false; 3897 return false;
3905 } catch (Exception e) 3898 }
3899 }
3900 catch (Exception e)
3906 { 3901 {
3907 m_log.ErrorFormat( 3902 m_log.ErrorFormat(
3908 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3903 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3904
3905 m_authenticateHandler.RemoveCircuit(agent.circuitcode);
3909 return false; 3906 return false;
3910 } 3907 }
3911 } 3908 }
3912 3909
3913 try 3910 try
3914 { 3911 {
3915 // Always check estate if this is a login. Always 3912 if (!AuthorizeUser(agent, SeeIntoRegion, out reason))
3916 // check if banned regions are to be blacked out.
3917 if (vialogin || (!m_seeIntoBannedRegion))
3918 { 3913 {
3919 if (!AuthorizeUser(agent, out reason)) 3914 m_authenticateHandler.RemoveCircuit(agent.circuitcode);
3920 { 3915 return false;
3921 return false;
3922 }
3923 } 3916 }
3924 } 3917 }
3925 catch (Exception e) 3918 catch (Exception e)
3926 { 3919 {
3927 m_log.ErrorFormat( 3920 m_log.ErrorFormat(
3928 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 3921 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
3922
3923 m_authenticateHandler.RemoveCircuit(agent.circuitcode);
3929 return false; 3924 return false;
3930 } 3925 }
3931 3926
@@ -3950,14 +3945,18 @@ namespace OpenSim.Region.Framework.Scenes
3950 sp.AdjustKnownSeeds(); 3945 sp.AdjustKnownSeeds();
3951 3946
3952 if (CapsModule != null) 3947 if (CapsModule != null)
3948 {
3953 CapsModule.SetAgentCapsSeeds(agent); 3949 CapsModule.SetAgentCapsSeeds(agent);
3950 CapsModule.CreateCaps(agent.AgentID, agent.circuitcode);
3951 }
3954 } 3952 }
3955 } 3953 }
3956 }
3957 3954
3958 // In all cases, add or update the circuit data with the new agent circuit data and teleport flags 3955 // Try caching an incoming user name much earlier on to see if this helps with an issue
3959 agent.teleportFlags = teleportFlags; 3956 // where HG users are occasionally seen by others as "Unknown User" because their UUIDName
3960 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3957 // request for the HG avatar appears to trigger before the user name is cached.
3958 CacheUserName(null, agent);
3959 }
3961 3960
3962 if (CapsModule != null) 3961 if (CapsModule != null)
3963 { 3962 {
@@ -4156,7 +4155,7 @@ namespace OpenSim.Region.Framework.Scenes
4156 /// <param name="reason">outputs the reason to this string</param> 4155 /// <param name="reason">outputs the reason to this string</param>
4157 /// <returns>True if the region accepts this agent. False if it does not. False will 4156 /// <returns>True if the region accepts this agent. False if it does not. False will
4158 /// also return a reason.</returns> 4157 /// also return a reason.</returns>
4159 protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason) 4158 protected virtual bool AuthorizeUser(AgentCircuitData agent, bool bypassAccessControl, out string reason)
4160 { 4159 {
4161 reason = String.Empty; 4160 reason = String.Empty;
4162 4161
@@ -4191,51 +4190,58 @@ namespace OpenSim.Region.Framework.Scenes
4191 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!"); 4190 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
4192 } 4191 }
4193 4192
4194 List<UUID> agentGroups = new List<UUID>(); 4193 // We only test the things below when we want to cut off
4195 4194 // child agents from being present in the scene for which their root
4196 if (m_groupsModule != null) 4195 // agent isn't allowed. Otherwise, we allow child agents. The test for
4196 // the root is done elsewhere (QueryAccess)
4197 if (!bypassAccessControl)
4197 { 4198 {
4198 GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID); 4199 List<UUID> agentGroups = new List<UUID>();
4199 4200
4200 if (GroupMembership != null) 4201 if (m_groupsModule != null)
4201 {
4202 for (int i = 0; i < GroupMembership.Length; i++)
4203 agentGroups.Add(GroupMembership[i].GroupID);
4204 }
4205 else
4206 { 4202 {
4207 m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!"); 4203 GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID);
4204
4205 if (GroupMembership != null)
4206 {
4207 for (int i = 0; i < GroupMembership.Length; i++)
4208 agentGroups.Add(GroupMembership[i].GroupID);
4209 }
4210 else
4211 {
4212 m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!");
4213 }
4208 } 4214 }
4209 }
4210 4215
4211 bool groupAccess = false; 4216 bool groupAccess = false;
4212 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups; 4217 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups;
4213 4218
4214 if (estateGroups != null) 4219 if (estateGroups != null)
4215 {
4216 foreach (UUID group in estateGroups)
4217 { 4220 {
4218 if (agentGroups.Contains(group)) 4221 foreach (UUID group in estateGroups)
4219 { 4222 {
4220 groupAccess = true; 4223 if (agentGroups.Contains(group))
4221 break; 4224 {
4225 groupAccess = true;
4226 break;
4227 }
4222 } 4228 }
4223 } 4229 }
4224 } 4230 else
4225 else 4231 {
4226 { 4232 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
4227 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); 4233 }
4228 }
4229 4234
4230 if (!RegionInfo.EstateSettings.PublicAccess && 4235 if (!RegionInfo.EstateSettings.PublicAccess &&
4231 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && 4236 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) &&
4232 !groupAccess) 4237 !groupAccess)
4233 { 4238 {
4234 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", 4239 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
4235 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 4240 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4236 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", 4241 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
4237 RegionInfo.RegionName); 4242 RegionInfo.RegionName);
4238 return false; 4243 return false;
4244 }
4239 } 4245 }
4240 4246
4241 // TODO: estate/region settings are not properly hooked up 4247 // TODO: estate/region settings are not properly hooked up
@@ -4365,8 +4371,6 @@ namespace OpenSim.Region.Framework.Scenes
4365 m_log.DebugFormat( 4371 m_log.DebugFormat(
4366 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 4372 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
4367 4373
4368 // XPTO: if this agent is not allowed here as root, always return false
4369
4370 // We have to wait until the viewer contacts this region after receiving EAC. 4374 // We have to wait until the viewer contacts this region after receiving EAC.
4371 // That calls AddNewClient, which finally creates the ScenePresence 4375 // That calls AddNewClient, which finally creates the ScenePresence
4372 int flags = GetUserFlags(cAgentData.AgentID); 4376 int flags = GetUserFlags(cAgentData.AgentID);
@@ -4394,10 +4398,30 @@ namespace OpenSim.Region.Framework.Scenes
4394 4398
4395 if (childAgentUpdate != null) 4399 if (childAgentUpdate != null)
4396 { 4400 {
4401 if (cAgentData.SessionID != childAgentUpdate.ControllingClient.SessionId)
4402 {
4403 m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", childAgentUpdate.UUID, cAgentData.SessionID);
4404 Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}",
4405 childAgentUpdate.UUID, childAgentUpdate.ControllingClient.SessionId, cAgentData.SessionID));
4406 }
4407
4397 childAgentUpdate.ChildAgentDataUpdate(cAgentData); 4408 childAgentUpdate.ChildAgentDataUpdate(cAgentData);
4409
4410 int ntimes = 20;
4411 if (cAgentData.SenderWantsToWaitForRoot)
4412 {
4413 while (childAgentUpdate.IsChildAgent && ntimes-- > 0)
4414 Thread.Sleep(1000);
4415
4416 m_log.DebugFormat(
4417 "[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits",
4418 childAgentUpdate.Name, childAgentUpdate.UUID, childAgentUpdate.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 20 - ntimes);
4419
4420 if (childAgentUpdate.IsChildAgent)
4421 return false;
4422 }
4398 return true; 4423 return true;
4399 } 4424 }
4400
4401 return false; 4425 return false;
4402 } 4426 }
4403 4427
@@ -4413,20 +4437,24 @@ namespace OpenSim.Region.Framework.Scenes
4413 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); 4437 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
4414 if (childAgentUpdate != null) 4438 if (childAgentUpdate != null)
4415 { 4439 {
4416 // I can't imagine *yet* why we would get an update if the agent is a root agent.. 4440 if (childAgentUpdate.ControllingClient.SessionId == cAgentData.SessionID)
4417 // however to avoid a race condition crossing borders..
4418 if (childAgentUpdate.IsChildAgent)
4419 { 4441 {
4420 uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); 4442 // I can't imagine *yet* why we would get an update if the agent is a root agent..
4421 uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); 4443 // however to avoid a race condition crossing borders..
4422 uint tRegionX = RegionInfo.RegionLocX; 4444 if (childAgentUpdate.IsChildAgent)
4423 uint tRegionY = RegionInfo.RegionLocY; 4445 {
4424 //Send Data to ScenePresence 4446 uint rRegionX = (uint)(cAgentData.RegionHandle >> 40);
4425 childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); 4447 uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8);
4426 // Not Implemented: 4448 uint tRegionX = RegionInfo.RegionLocX;
4427 //TODO: Do we need to pass the message on to one of our neighbors? 4449 uint tRegionY = RegionInfo.RegionLocY;
4450 //Send Data to ScenePresence
4451 childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
4452 // Not Implemented:
4453 //TODO: Do we need to pass the message on to one of our neighbors?
4454 }
4428 } 4455 }
4429 4456 else
4457 m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}", childAgentUpdate.UUID, cAgentData.SessionID);
4430 return true; 4458 return true;
4431 } 4459 }
4432 4460
@@ -4449,10 +4477,6 @@ namespace OpenSim.Region.Framework.Scenes
4449 m_log.WarnFormat( 4477 m_log.WarnFormat(
4450 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", 4478 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4451 agentID, RegionInfo.RegionName); 4479 agentID, RegionInfo.RegionName);
4452// else
4453// m_log.DebugFormat(
4454// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
4455// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes);
4456 4480
4457 return sp; 4481 return sp;
4458 } 4482 }
@@ -4469,6 +4493,25 @@ namespace OpenSim.Region.Framework.Scenes
4469 4493
4470 return false; 4494 return false;
4471 } 4495 }
4496 /// <summary>
4497 /// Authenticated close (via network)
4498 /// </summary>
4499 /// <param name="agentID"></param>
4500 /// <param name="force"></param>
4501 /// <param name="auth_token"></param>
4502 /// <returns></returns>
4503 public bool IncomingCloseAgent(UUID agentID, bool force, string auth_token)
4504 {
4505 //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token);
4506
4507 // Check that the auth_token is valid
4508 AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID);
4509 if (acd != null && acd.SessionID.ToString() == auth_token)
4510 return IncomingCloseAgent(agentID, force);
4511 else
4512 m_log.ErrorFormat("[SCENE]: Request to close agent {0} with invalid authorization token {1}", agentID, auth_token);
4513 return false;
4514 }
4472 4515
4473 public bool IncomingCloseAgent(UUID agentID) 4516 public bool IncomingCloseAgent(UUID agentID)
4474 { 4517 {
@@ -4491,7 +4534,6 @@ namespace OpenSim.Region.Framework.Scenes
4491 public bool IncomingCloseAgent(UUID agentID, bool force) 4534 public bool IncomingCloseAgent(UUID agentID, bool force)
4492 { 4535 {
4493 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4536 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4494
4495 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4537 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4496 if (presence != null) 4538 if (presence != null)
4497 { 4539 {
@@ -4499,7 +4541,7 @@ namespace OpenSim.Region.Framework.Scenes
4499 return true; 4541 return true;
4500 } 4542 }
4501 4543
4502 // Agent not here 4544 // Agent not here
4503 return false; 4545 return false;
4504 } 4546 }
4505 4547
@@ -5089,21 +5131,6 @@ namespace OpenSim.Region.Framework.Scenes
5089 5131
5090 #endregion 5132 #endregion
5091 5133
5092 public void RegionHandleRequest(IClientAPI client, UUID regionID)
5093 {
5094 ulong handle = 0;
5095 if (regionID == RegionInfo.RegionID)
5096 handle = RegionInfo.RegionHandle;
5097 else
5098 {
5099 GridRegion r = GridService.GetRegionByUUID(UUID.Zero, regionID);
5100 if (r != null)
5101 handle = r.RegionHandle;
5102 }
5103
5104 if (handle != 0)
5105 client.SendRegionHandle(regionID, handle);
5106 }
5107 5134
5108// Commented pending deletion since this method no longer appears to do anything at all 5135// Commented pending deletion since this method no longer appears to do anything at all
5109// public bool NeedSceneCacheClear(UUID agentID) 5136// public bool NeedSceneCacheClear(UUID agentID)
@@ -5655,12 +5682,12 @@ Environment.Exit(1);
5655 List<SceneObjectGroup> objects, 5682 List<SceneObjectGroup> objects,
5656 out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) 5683 out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
5657 { 5684 {
5658 minX = 256; 5685 minX = float.MaxValue;
5659 maxX = -256; 5686 maxX = float.MinValue;
5660 minY = 256; 5687 minY = float.MaxValue;
5661 maxY = -256; 5688 maxY = float.MinValue;
5662 minZ = 8192; 5689 minZ = float.MaxValue;
5663 maxZ = -256; 5690 maxZ = float.MinValue;
5664 5691
5665 List<Vector3> offsets = new List<Vector3>(); 5692 List<Vector3> offsets = new List<Vector3>();
5666 5693
@@ -5800,17 +5827,6 @@ Environment.Exit(1);
5800 { 5827 {
5801 reason = "You are banned from the region"; 5828 reason = "You are banned from the region";
5802 5829
5803 if (EntityTransferModule.IsInTransit(agentID))
5804 {
5805 reason = "Agent is still in transit from this region";
5806
5807 m_log.WarnFormat(
5808 "[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit",
5809 agentID, RegionInfo.RegionName);
5810
5811 return false;
5812 }
5813
5814 if (Permissions.IsGod(agentID)) 5830 if (Permissions.IsGod(agentID))
5815 { 5831 {
5816 reason = String.Empty; 5832 reason = String.Empty;
@@ -5860,7 +5876,7 @@ Environment.Exit(1);
5860 5876
5861 try 5877 try
5862 { 5878 {
5863 if (!AuthorizeUser(aCircuit, out reason)) 5879 if (!AuthorizeUser(aCircuit, false, out reason))
5864 { 5880 {
5865 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); 5881 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5866 return false; 5882 return false;
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 74c9582..4eef162 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -562,6 +562,10 @@ namespace OpenSim.Region.Framework.Scenes
562 get { return false; } 562 get { return false; }
563 } 563 }
564 564
565 public virtual void Start()
566 {
567 }
568
565 public void Restart() 569 public void Restart()
566 { 570 {
567 // This has to be here to fire the event 571 // This has to be here to fire the event
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 775a4c2..52f46f2 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -200,7 +200,7 @@ namespace OpenSim.Region.Framework.Scenes
200 /// This Closes child agents on neighboring regions 200 /// This Closes child agents on neighboring regions
201 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 201 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
202 /// </summary> 202 /// </summary>
203 protected void SendCloseChildAgentAsync(UUID agentID, ulong regionHandle) 203 protected void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token)
204 { 204 {
205 // let's do our best, but there's not much we can do if the neighbour doesn't accept. 205 // let's do our best, but there's not much we can do if the neighbour doesn't accept.
206 206
@@ -209,23 +209,25 @@ namespace OpenSim.Region.Framework.Scenes
209 Utils.LongToUInts(regionHandle, out x, out y); 209 Utils.LongToUInts(regionHandle, out x, out y);
210 210
211 GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y); 211 GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y);
212 m_scene.SimulationService.CloseChildAgent(destination, agentID);
213 }
214 212
215 private void SendCloseChildAgentCompleted(IAsyncResult iar) 213 m_log.DebugFormat(
216 { 214 "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName);
217 SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate)iar.AsyncState; 215
218 icon.EndInvoke(iar); 216 m_scene.SimulationService.CloseAgent(destination, agentID, auth_token);
219 } 217 }
220 218
221 public void SendCloseChildAgentConnections(UUID agentID, List<ulong> regionslst) 219 /// <summary>
220 /// Closes a child agents in a collection of regions. Does so asynchronously
221 /// so that the caller doesn't wait.
222 /// </summary>
223 /// <param name="agentID"></param>
224 /// <param name="regionslst"></param>
225 public void SendCloseChildAgentConnections(UUID agentID, string auth_code, List<ulong> regionslst)
222 { 226 {
223 foreach (ulong handle in regionslst) 227 foreach (ulong handle in regionslst)
224 { 228 {
225 SendCloseChildAgentDelegate d = SendCloseChildAgentAsync; 229 ulong handleCopy = handle;
226 d.BeginInvoke(agentID, handle, 230 Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); });
227 SendCloseChildAgentCompleted,
228 d);
229 } 231 }
230 } 232 }
231 233
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index c70342f..c5c083a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -420,29 +420,6 @@ namespace OpenSim.Region.Framework.Scenes
420 return false; 420 return false;
421 } 421 }
422 422
423 /// <summary>
424 /// Set the debug packet level on each current scene. This level governs which packets are printed out to the
425 /// console.
426 /// </summary>
427 /// <param name="newDebug"></param>
428 /// <param name="name">Name of avatar to debug</param>
429 public void SetDebugPacketLevelOnCurrentScene(int newDebug, string name)
430 {
431 ForEachSelectedScene(scene =>
432 scene.ForEachScenePresence(sp =>
433 {
434 if (name == null || sp.Name == name)
435 {
436 m_log.DebugFormat(
437 "Packet debug for {0} ({1}) set to {2}",
438 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug);
439
440 sp.ControllingClient.DebugPacketLevel = newDebug;
441 }
442 })
443 );
444 }
445
446 public List<ScenePresence> GetCurrentSceneAvatars() 423 public List<ScenePresence> GetCurrentSceneAvatars()
447 { 424 {
448 List<ScenePresence> avatars = new List<ScenePresence>(); 425 List<ScenePresence> avatars = new List<ScenePresence>();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index f8624e7..8c50a81 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -67,6 +67,12 @@ namespace OpenSim.Region.Framework.Scenes
67 { 67 {
68 int scriptsStarted = 0; 68 int scriptsStarted = 0;
69 69
70 if (m_scene == null)
71 {
72 m_log.DebugFormat("[PRIM INVENTORY]: m_scene is null. Unable to create script instances");
73 return 0;
74 }
75
70 // Don't start scripts if they're turned off in the region! 76 // Don't start scripts if they're turned off in the region!
71 if (!m_scene.RegionInfo.RegionSettings.DisableScripts) 77 if (!m_scene.RegionInfo.RegionSettings.DisableScripts)
72 { 78 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index f306651..9e3d875 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1867,11 +1867,11 @@ namespace OpenSim.Region.Framework.Scenes
1867 /// <summary> 1867 /// <summary>
1868 /// Delete this group from its scene. 1868 /// Delete this group from its scene.
1869 /// </summary> 1869 /// </summary>
1870 /// 1870 /// <remarks>
1871 /// This only handles the in-world consequences of deletion (e.g. any avatars sitting on it are forcibly stood 1871 /// This only handles the in-world consequences of deletion (e.g. any avatars sitting on it are forcibly stood
1872 /// up and all avatars receive notification of its removal. Removal of the scene object from database backup 1872 /// up and all avatars receive notification of its removal. Removal of the scene object from database backup
1873 /// must be handled by the caller. 1873 /// must be handled by the caller.
1874 /// 1874 /// </remarks>
1875 /// <param name="silent">If true then deletion is not broadcast to clients</param> 1875 /// <param name="silent">If true then deletion is not broadcast to clients</param>
1876 public void DeleteGroupFromScene(bool silent) 1876 public void DeleteGroupFromScene(bool silent)
1877 { 1877 {
@@ -1885,10 +1885,10 @@ namespace OpenSim.Region.Framework.Scenes
1885 { 1885 {
1886 SceneObjectPart part = parts[i]; 1886 SceneObjectPart part = parts[i];
1887 1887
1888 Scene.ForEachRootScenePresence(delegate(ScenePresence avatar) 1888 Scene.ForEachScenePresence(sp =>
1889 { 1889 {
1890 if (avatar.ParentID == LocalId) 1890 if (!sp.IsChildAgent && sp.ParentID == LocalId)
1891 avatar.StandUp(); 1891 sp.StandUp();
1892 1892
1893 if (!silent) 1893 if (!silent)
1894 { 1894 {
@@ -1896,9 +1896,9 @@ namespace OpenSim.Region.Framework.Scenes
1896 if (part == m_rootPart) 1896 if (part == m_rootPart)
1897 { 1897 {
1898 if (!IsAttachment 1898 if (!IsAttachment
1899 || AttachedAvatar == avatar.ControllingClient.AgentId 1899 || AttachedAvatar == sp.UUID
1900 || !HasPrivateAttachmentPoint) 1900 || !HasPrivateAttachmentPoint)
1901 avatar.ControllingClient.SendKillObject(m_regionHandle, new List<uint> { part.LocalId }); 1901 sp.ControllingClient.SendKillObject(new List<uint> { part.LocalId });
1902 } 1902 }
1903 } 1903 }
1904 }); 1904 });
@@ -2207,7 +2207,7 @@ namespace OpenSim.Region.Framework.Scenes
2207 if (!userExposed) 2207 if (!userExposed)
2208 dupe.IsAttachment = true; 2208 dupe.IsAttachment = true;
2209 2209
2210 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); 2210 dupe.m_sittingAvatars = new List<UUID>();
2211 2211
2212 if (!userExposed) 2212 if (!userExposed)
2213 { 2213 {
@@ -3810,20 +3810,23 @@ namespace OpenSim.Region.Framework.Scenes
3810 /// <summary> 3810 /// <summary>
3811 /// Update just the root prim position in a linkset 3811 /// Update just the root prim position in a linkset
3812 /// </summary> 3812 /// </summary>
3813 /// <param name="pos"></param> 3813 /// <param name="newPos"></param>
3814 public void UpdateRootPosition(Vector3 pos) 3814 public void UpdateRootPosition(Vector3 newPos)
3815 { 3815 {
3816 // needs to be called with phys building true 3816 // needs to be called with phys building true
3817 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); 3817 Vector3 oldPos;
3818 Vector3 oldPos = 3818
3819 new Vector3(AbsolutePosition.X + m_rootPart.OffsetPosition.X, 3819 // FIXME: This improves the situation where editing just the root prim of an attached object would send
3820 AbsolutePosition.Y + m_rootPart.OffsetPosition.Y, 3820 // all the other parts to oblivion after detach/reattach. However, a problem remains since the root prim
3821 AbsolutePosition.Z + m_rootPart.OffsetPosition.Z); 3821 // still ends up in the wrong position on reattach.
3822 if (IsAttachment)
3823 oldPos = RootPart.OffsetPosition;
3824 else
3825 oldPos = AbsolutePosition + RootPart.OffsetPosition;
3826
3822 Vector3 diff = oldPos - newPos; 3827 Vector3 diff = oldPos - newPos;
3823 Vector3 axDiff = new Vector3(diff.X, diff.Y, diff.Z);
3824 Quaternion partRotation = m_rootPart.RotationOffset; 3828 Quaternion partRotation = m_rootPart.RotationOffset;
3825 axDiff *= Quaternion.Inverse(partRotation); 3829 diff *= Quaternion.Inverse(partRotation);
3826 diff = axDiff;
3827 3830
3828 SceneObjectPart[] parts = m_parts.GetArray(); 3831 SceneObjectPart[] parts = m_parts.GetArray();
3829 for (int i = 0; i < parts.Length; i++) 3832 for (int i = 0; i < parts.Length; i++)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 261e958..59a453a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -231,6 +231,13 @@ namespace OpenSim.Region.Framework.Scenes
231 231
232 public double SoundRadius; 232 public double SoundRadius;
233 233
234 /// <summary>
235 /// Should sounds played from this prim be queued?
236 /// </summary>
237 /// <remarks>
238 /// This should only be changed by sound modules. It is up to sound modules as to how they interpret this setting.
239 /// </remarks>
240 public bool SoundQueueing { get; set; }
234 241
235 public uint TimeStampFull; 242 public uint TimeStampFull;
236 243
@@ -383,8 +390,6 @@ namespace OpenSim.Region.Framework.Scenes
383 390
384 private SOPVehicle m_vehicleParams = null; 391 private SOPVehicle m_vehicleParams = null;
385 392
386 private KeyframeMotion m_keyframeMotion = null;
387
388 public KeyframeMotion KeyframeMotion 393 public KeyframeMotion KeyframeMotion
389 { 394 {
390 get; set; 395 get; set;
@@ -536,7 +541,11 @@ namespace OpenSim.Region.Framework.Scenes
536 CreatorID = uuid; 541 CreatorID = uuid;
537 } 542 }
538 if (parts.Length >= 2) 543 if (parts.Length >= 2)
544 {
539 CreatorData = parts[1]; 545 CreatorData = parts[1];
546 if (!CreatorData.EndsWith("/"))
547 CreatorData += "/";
548 }
540 if (parts.Length >= 3) 549 if (parts.Length >= 3)
541 name = parts[2]; 550 name = parts[2];
542 551
@@ -815,7 +824,8 @@ namespace OpenSim.Region.Framework.Scenes
815 } 824 }
816 825
817 // Tell the physics engines that this prim changed. 826 // Tell the physics engines that this prim changed.
818 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 827 if (ParentGroup != null && ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
828 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
819 } 829 }
820 catch (Exception e) 830 catch (Exception e)
821 { 831 {
@@ -933,7 +943,7 @@ namespace OpenSim.Region.Framework.Scenes
933 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString()); 943 //m_log.Info("[PART]: RO2:" + actor.Orientation.ToString());
934 } 944 }
935 945
936 if (ParentGroup != null) 946 if (ParentGroup != null && ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene != null)
937 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 947 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
938 //} 948 //}
939 } 949 }
@@ -1218,23 +1228,14 @@ namespace OpenSim.Region.Framework.Scenes
1218 // the mappings more consistant. 1228 // the mappings more consistant.
1219 public Vector3 SitTargetPositionLL 1229 public Vector3 SitTargetPositionLL
1220 { 1230 {
1221 get { return new Vector3(m_sitTargetPosition.X, m_sitTargetPosition.Y,m_sitTargetPosition.Z); } 1231 get { return m_sitTargetPosition; }
1222 set { m_sitTargetPosition = value; } 1232 set { m_sitTargetPosition = value; }
1223 } 1233 }
1224 1234
1225 public Quaternion SitTargetOrientationLL 1235 public Quaternion SitTargetOrientationLL
1226 { 1236 {
1227 get 1237 get { return m_sitTargetOrientation; }
1228 { 1238 set { m_sitTargetOrientation = value; }
1229 return new Quaternion(
1230 m_sitTargetOrientation.X,
1231 m_sitTargetOrientation.Y,
1232 m_sitTargetOrientation.Z,
1233 m_sitTargetOrientation.W
1234 );
1235 }
1236
1237 set { m_sitTargetOrientation = new Quaternion(value.X, value.Y, value.Z, value.W); }
1238 } 1239 }
1239 1240
1240 public bool Stopped 1241 public bool Stopped
@@ -4350,30 +4351,31 @@ namespace OpenSim.Region.Framework.Scenes
4350 } 4351 }
4351 } 4352 }
4352 4353
4353 public void UpdateGroupPosition(Vector3 pos) 4354 public void UpdateGroupPosition(Vector3 newPos)
4354 { 4355 {
4355 if ((pos.X != GroupPosition.X) || 4356 Vector3 oldPos = GroupPosition;
4356 (pos.Y != GroupPosition.Y) || 4357
4357 (pos.Z != GroupPosition.Z)) 4358 if ((newPos.X != oldPos.X) ||
4359 (newPos.Y != oldPos.Y) ||
4360 (newPos.Z != oldPos.Z))
4358 { 4361 {
4359 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
4360 GroupPosition = newPos; 4362 GroupPosition = newPos;
4361 ScheduleTerseUpdate(); 4363 ScheduleTerseUpdate();
4362 } 4364 }
4363 } 4365 }
4364 4366
4365 /// <summary> 4367 /// <summary>
4366 /// 4368 /// Update this part's offset position.
4367 /// </summary> 4369 /// </summary>
4368 /// <param name="pos"></param> 4370 /// <param name="pos"></param>
4369 public void UpdateOffSet(Vector3 pos) 4371 public void UpdateOffSet(Vector3 newPos)
4370 { 4372 {
4371 if ((pos.X != OffsetPosition.X) || 4373 Vector3 oldPos = OffsetPosition;
4372 (pos.Y != OffsetPosition.Y) ||
4373 (pos.Z != OffsetPosition.Z))
4374 {
4375 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
4376 4374
4375 if ((newPos.X != oldPos.X) ||
4376 (newPos.Y != oldPos.Y) ||
4377 (newPos.Z != oldPos.Z))
4378 {
4377 if (ParentGroup.RootPart.GetStatusSandbox()) 4379 if (ParentGroup.RootPart.GetStatusSandbox())
4378 { 4380 {
4379 if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10) 4381 if (Util.GetDistanceTo(ParentGroup.RootPart.StatusSandboxPos, newPos) > 10)
@@ -4642,6 +4644,11 @@ namespace OpenSim.Region.Framework.Scenes
4642 } 4644 }
4643 } 4645 }
4644*/ 4646*/
4647 if (pa != null)
4648 {
4649 pa.SetMaterial(Material);
4650 DoPhysicsPropertyUpdate(UsePhysics, true);
4651 }
4645 } 4652 }
4646 else // it already has a physical representation 4653 else // it already has a physical representation
4647 { 4654 {
@@ -5014,6 +5021,14 @@ namespace OpenSim.Region.Framework.Scenes
5014 oldTex.DefaultTexture = fallbackOldFace; 5021 oldTex.DefaultTexture = fallbackOldFace;
5015 } 5022 }
5016 5023
5024 // Materials capable viewers can send a ObjectImage packet
5025 // when nothing in TE has changed. MaterialID should be updated
5026 // by the RenderMaterials CAP handler, so updating it here may cause a
5027 // race condtion. Therefore, if no non-materials TE fields have changed,
5028 // we should ignore any changes and not update Shape.TextureEntry
5029
5030 bool otherFieldsChanged = false;
5031
5017 for (int i = 0 ; i < GetNumberOfSides(); i++) 5032 for (int i = 0 ; i < GetNumberOfSides(); i++)
5018 { 5033 {
5019 5034
@@ -5040,18 +5055,36 @@ namespace OpenSim.Region.Framework.Scenes
5040 // Max change, skip the rest of testing 5055 // Max change, skip the rest of testing
5041 if (changeFlags == (Changed.TEXTURE | Changed.COLOR)) 5056 if (changeFlags == (Changed.TEXTURE | Changed.COLOR))
5042 break; 5057 break;
5058
5059 if (!otherFieldsChanged)
5060 {
5061 if (oldFace.Bump != newFace.Bump) otherFieldsChanged = true;
5062 if (oldFace.Fullbright != newFace.Fullbright) otherFieldsChanged = true;
5063 if (oldFace.Glow != newFace.Glow) otherFieldsChanged = true;
5064 if (oldFace.MediaFlags != newFace.MediaFlags) otherFieldsChanged = true;
5065 if (oldFace.OffsetU != newFace.OffsetU) otherFieldsChanged = true;
5066 if (oldFace.OffsetV != newFace.OffsetV) otherFieldsChanged = true;
5067 if (oldFace.RepeatU != newFace.RepeatU) otherFieldsChanged = true;
5068 if (oldFace.RepeatV != newFace.RepeatV) otherFieldsChanged = true;
5069 if (oldFace.Rotation != newFace.Rotation) otherFieldsChanged = true;
5070 if (oldFace.Shiny != newFace.Shiny) otherFieldsChanged = true;
5071 if (oldFace.TexMapType != newFace.TexMapType) otherFieldsChanged = true;
5072 }
5043 } 5073 }
5044 5074
5045 m_shape.TextureEntry = newTex.GetBytes(); 5075 if (changeFlags != 0 || otherFieldsChanged)
5046 if (changeFlags != 0) 5076 {
5047 TriggerScriptChangedEvent(changeFlags); 5077 m_shape.TextureEntry = newTex.GetBytes();
5048 UpdateFlag = UpdateRequired.FULL; 5078 if (changeFlags != 0)
5049 ParentGroup.HasGroupChanged = true; 5079 TriggerScriptChangedEvent(changeFlags);
5080 UpdateFlag = UpdateRequired.FULL;
5081 ParentGroup.HasGroupChanged = true;
5050 5082
5051 //This is madness.. 5083 //This is madness..
5052 //ParentGroup.ScheduleGroupForFullUpdate(); 5084 //ParentGroup.ScheduleGroupForFullUpdate();
5053 //This is sparta 5085 //This is sparta
5054 ScheduleFullUpdate(); 5086 ScheduleFullUpdate();
5087 }
5055 } 5088 }
5056 5089
5057 5090
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index d04d87b..3be0623 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -696,7 +696,8 @@ namespace OpenSim.Region.Framework.Scenes
696 /// </param> 696 /// </param>
697 public void StopScriptInstance(TaskInventoryItem item) 697 public void StopScriptInstance(TaskInventoryItem item)
698 { 698 {
699 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID); 699 if (m_part.ParentGroup.Scene != null)
700 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
700 701
701 // At the moment, even stopped scripts are counted as active, which is probably wrong. 702 // At the moment, even stopped scripts are counted as active, which is probably wrong.
702// m_part.ParentGroup.AddActiveScriptCount(-1); 703// m_part.ParentGroup.AddActiveScriptCount(-1);
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 0ab267a..c4876b3 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -29,7 +29,9 @@ using System;
29using System.Xml; 29using System.Xml;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using System.Threading;
32using System.Timers; 33using System.Timers;
34using Timer = System.Timers.Timer;
33using OpenMetaverse; 35using OpenMetaverse;
34using log4net; 36using log4net;
35using Nini.Config; 37using Nini.Config;
@@ -78,7 +80,7 @@ namespace OpenSim.Region.Framework.Scenes
78// m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name); 80// m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name);
79// } 81// }
80 82
81 private void TriggerScenePresenceUpdated() 83 public void TriggerScenePresenceUpdated()
82 { 84 {
83 if (m_scene != null) 85 if (m_scene != null)
84 m_scene.EventManager.TriggerScenePresenceUpdated(this); 86 m_scene.EventManager.TriggerScenePresenceUpdated(this);
@@ -142,6 +144,8 @@ namespace OpenSim.Region.Framework.Scenes
142 private Vector3 m_lastVelocity; 144 private Vector3 m_lastVelocity;
143 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); 145 private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
144 146
147 private bool m_followCamAuto = false;
148
145 149
146 private Vector3? m_forceToApply; 150 private Vector3? m_forceToApply;
147 private int m_userFlags; 151 private int m_userFlags;
@@ -760,6 +764,13 @@ namespace OpenSim.Region.Framework.Scenes
760 } 764 }
761 } 765 }
762 766
767 /// <summary>
768 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
769 /// teleport is reusing the connection.
770 /// </summary>
771 /// <remarks>May be refactored or move somewhere else soon.</remarks>
772 public bool DoNotCloseAfterTeleport { get; set; }
773
763 private float m_speedModifier = 1.0f; 774 private float m_speedModifier = 1.0f;
764 775
765 public float SpeedModifier 776 public float SpeedModifier
@@ -874,6 +885,7 @@ namespace OpenSim.Region.Framework.Scenes
874 { 885 {
875 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 886 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
876 ControllingClient.OnAgentUpdate += HandleAgentUpdate; 887 ControllingClient.OnAgentUpdate += HandleAgentUpdate;
888 ControllingClient.OnAgentCameraUpdate += HandleAgentCamerasUpdate;
877 ControllingClient.OnAgentRequestSit += HandleAgentRequestSit; 889 ControllingClient.OnAgentRequestSit += HandleAgentRequestSit;
878 ControllingClient.OnAgentSit += HandleAgentSit; 890 ControllingClient.OnAgentSit += HandleAgentSit;
879 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; 891 ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
@@ -1153,7 +1165,6 @@ namespace OpenSim.Region.Framework.Scenes
1153 1165
1154 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1166 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1155 1167
1156 m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
1157 } 1168 }
1158 1169
1159 public int GetStateSource() 1170 public int GetStateSource()
@@ -1306,7 +1317,26 @@ namespace OpenSim.Region.Framework.Scenes
1306 1317
1307 public void StopFlying() 1318 public void StopFlying()
1308 { 1319 {
1309 ControllingClient.StopFlying(this); 1320 Vector3 pos = AbsolutePosition;
1321 if (Appearance.AvatarHeight != 127.0f)
1322 pos += new Vector3(0f, 0f, (Appearance.AvatarHeight / 6f));
1323 else
1324 pos += new Vector3(0f, 0f, (1.56f / 6f));
1325
1326 AbsolutePosition = pos;
1327
1328 // attach a suitable collision plane regardless of the actual situation to force the LLClient to land.
1329 // Collision plane below the avatar's position a 6th of the avatar's height is suitable.
1330 // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a
1331 // certain amount.. because the LLClient wouldn't land in that situation anyway.
1332
1333 // why are we still testing for this really old height value default???
1334 if (Appearance.AvatarHeight != 127.0f)
1335 CollisionPlane = new Vector4(0, 0, 0, pos.Z - Appearance.AvatarHeight / 6f);
1336 else
1337 CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f / 6f));
1338
1339 ControllingClient.SendAgentTerseUpdate(this);
1310 } 1340 }
1311 1341
1312 /// <summary> 1342 /// <summary>
@@ -1480,6 +1510,26 @@ namespace OpenSim.Region.Framework.Scenes
1480 1510
1481 } 1511 }
1482 1512
1513 private bool WaitForUpdateAgent(IClientAPI client)
1514 {
1515 // Before UpdateAgent, m_originRegionID is UUID.Zero; after, it's non-Zero
1516 int count = 20;
1517 while (m_originRegionID.Equals(UUID.Zero) && count-- > 0)
1518 {
1519 m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.RegionInfo.RegionName);
1520 Thread.Sleep(200);
1521 }
1522
1523 if (m_originRegionID.Equals(UUID.Zero))
1524 {
1525 // Movement into region will fail
1526 m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived", client.Name);
1527 return false;
1528 }
1529
1530 return true;
1531 }
1532
1483 /// <summary> 1533 /// <summary>
1484 /// Complete Avatar's movement into the region. 1534 /// Complete Avatar's movement into the region.
1485 /// </summary> 1535 /// </summary>
@@ -1497,6 +1547,15 @@ namespace OpenSim.Region.Framework.Scenes
1497 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", 1547 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
1498 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); 1548 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
1499 1549
1550 // Make sure it's not a login agent. We don't want to wait for updates during login
1551 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
1552 {
1553 // Let's wait until UpdateAgent (called by departing region) is done
1554 if (!WaitForUpdateAgent(client))
1555 // The sending region never sent the UpdateAgent data, we have to refuse
1556 return;
1557 }
1558
1500 Vector3 look = Velocity; 1559 Vector3 look = Velocity;
1501 1560
1502 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1561 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
@@ -1518,11 +1577,17 @@ namespace OpenSim.Region.Framework.Scenes
1518 1577
1519 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1578 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1520 MakeRootAgent(AbsolutePosition, flying); 1579 MakeRootAgent(AbsolutePosition, flying);
1580
1581 // Tell the client that we're totally ready
1521 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1582 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1522 1583
1584 // Remember in HandleUseCircuitCode, we delayed this to here
1585 if (m_teleportFlags > 0)
1586 SendInitialDataToMe();
1587
1523// m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); 1588// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1524 1589
1525 if ((m_callbackURI != null) && !m_callbackURI.Equals("")) 1590 if (!string.IsNullOrEmpty(m_callbackURI))
1526 { 1591 {
1527 // We cannot sleep here since this would hold up the inbound packet processing thread, as 1592 // We cannot sleep here since this would hold up the inbound packet processing thread, as
1528 // CompleteMovement() is executed synchronously. However, it might be better to delay the release 1593 // CompleteMovement() is executed synchronously. However, it might be better to delay the release
@@ -1550,7 +1615,6 @@ namespace OpenSim.Region.Framework.Scenes
1550 // Create child agents in neighbouring regions 1615 // Create child agents in neighbouring regions
1551 if (openChildAgents && !IsChildAgent) 1616 if (openChildAgents && !IsChildAgent)
1552 { 1617 {
1553
1554 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1618 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1555 if (m_agentTransfer != null) 1619 if (m_agentTransfer != null)
1556 m_agentTransfer.EnableChildAgents(this); 1620 m_agentTransfer.EnableChildAgents(this);
@@ -1573,6 +1637,7 @@ namespace OpenSim.Region.Framework.Scenes
1573// m_log.DebugFormat( 1637// m_log.DebugFormat(
1574// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1638// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1575// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 1639// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
1640
1576 } 1641 }
1577 1642
1578 /// <summary> 1643 /// <summary>
@@ -1653,9 +1718,9 @@ namespace OpenSim.Region.Framework.Scenes
1653 /// </summary> 1718 /// </summary>
1654 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1719 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1655 { 1720 {
1656// m_log.DebugFormat( 1721 //m_log.DebugFormat(
1657// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", 1722 // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
1658// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); 1723 // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
1659 1724
1660 if (IsChildAgent) 1725 if (IsChildAgent)
1661 { 1726 {
@@ -1663,10 +1728,6 @@ namespace OpenSim.Region.Framework.Scenes
1663 return; 1728 return;
1664 } 1729 }
1665 1730
1666 ++m_movementUpdateCount;
1667 if (m_movementUpdateCount < 1)
1668 m_movementUpdateCount = 1;
1669
1670 #region Sanity Checking 1731 #region Sanity Checking
1671 1732
1672 // This is irritating. Really. 1733 // This is irritating. Really.
@@ -1697,21 +1758,6 @@ namespace OpenSim.Region.Framework.Scenes
1697 1758
1698 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; 1759 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
1699 1760
1700 // Camera location in world. We'll need to raytrace
1701 // from this location from time to time.
1702 CameraPosition = agentData.CameraCenter;
1703 if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance)
1704 {
1705 ReprioritizeUpdates();
1706 m_lastCameraPosition = CameraPosition;
1707 }
1708
1709 // Use these three vectors to figure out what the agent is looking at
1710 // Convert it to a Matrix and/or Quaternion
1711 CameraAtAxis = agentData.CameraAtAxis;
1712 CameraLeftAxis = agentData.CameraLeftAxis;
1713 CameraUpAxis = agentData.CameraUpAxis;
1714
1715 // The Agent's Draw distance setting 1761 // The Agent's Draw distance setting
1716 // When we get to the point of re-computing neighbors everytime this 1762 // When we get to the point of re-computing neighbors everytime this
1717 // changes, then start using the agent's drawdistance rather than the 1763 // changes, then start using the agent's drawdistance rather than the
@@ -1996,10 +2042,79 @@ namespace OpenSim.Region.Framework.Scenes
1996 SendControlsToScripts(flagsForScripts); 2042 SendControlsToScripts(flagsForScripts);
1997 } 2043 }
1998 2044
2045 // We need to send this back to the client in order to see the edit beams
2046 if ((State & (uint)AgentState.Editing) != 0)
2047 ControllingClient.SendAgentTerseUpdate(this);
2048
1999 m_scene.EventManager.TriggerOnClientMovement(this); 2049 m_scene.EventManager.TriggerOnClientMovement(this);
2000 TriggerScenePresenceUpdated();
2001 } 2050 }
2002 2051
2052
2053 /// <summary>
2054 /// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering.
2055 /// </summary>
2056 private void HandleAgentCamerasUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
2057 {
2058 //m_log.DebugFormat(
2059 // "[SCENE PRESENCE]: In {0} received agent camera update from {1}, flags {2}",
2060 // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
2061
2062 if (IsChildAgent)
2063 {
2064 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
2065 return;
2066 }
2067
2068 ++m_movementUpdateCount;
2069 if (m_movementUpdateCount < 1)
2070 m_movementUpdateCount = 1;
2071
2072
2073 AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
2074
2075 // Camera location in world. We'll need to raytrace
2076 // from this location from time to time.
2077 CameraPosition = agentData.CameraCenter;
2078 if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance)
2079 {
2080 ReprioritizeUpdates();
2081 m_lastCameraPosition = CameraPosition;
2082 }
2083
2084 // Use these three vectors to figure out what the agent is looking at
2085 // Convert it to a Matrix and/or Quaternion
2086 CameraAtAxis = agentData.CameraAtAxis;
2087 CameraLeftAxis = agentData.CameraLeftAxis;
2088 CameraUpAxis = agentData.CameraUpAxis;
2089
2090 // The Agent's Draw distance setting
2091 // When we get to the point of re-computing neighbors everytime this
2092 // changes, then start using the agent's drawdistance rather than the
2093 // region's draw distance.
2094 // DrawDistance = agentData.Far;
2095 DrawDistance = Scene.DefaultDrawDistance;
2096
2097 // Check if Client has camera in 'follow cam' or 'build' mode.
2098 Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
2099
2100 m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
2101 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
2102
2103
2104 //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
2105 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
2106 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
2107 {
2108 if (m_followCamAuto)
2109 {
2110 Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
2111 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
2112 }
2113 }
2114
2115 TriggerScenePresenceUpdated();
2116 }
2117
2003 /// <summary> 2118 /// <summary>
2004 /// Calculate an update to move the presence to the set target. 2119 /// Calculate an update to move the presence to the set target.
2005 /// </summary> 2120 /// </summary>
@@ -2308,6 +2423,7 @@ namespace OpenSim.Region.Framework.Scenes
2308 AddToPhysicalScene(false); 2423 AddToPhysicalScene(false);
2309 2424
2310 Animator.TrySetMovementAnimation("STAND"); 2425 Animator.TrySetMovementAnimation("STAND");
2426 TriggerScenePresenceUpdated();
2311 } 2427 }
2312 2428
2313 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2429 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -2406,7 +2522,7 @@ namespace OpenSim.Region.Framework.Scenes
2406 ControllingClient.SendSitResponse( 2522 ControllingClient.SendSitResponse(
2407 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); 2523 part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2408 2524
2409 m_requestedSitTargetUUID = targetID; 2525 m_requestedSitTargetUUID = part.UUID;
2410 2526
2411 HandleAgentSit(ControllingClient, UUID); 2527 HandleAgentSit(ControllingClient, UUID);
2412 2528
@@ -2434,7 +2550,7 @@ namespace OpenSim.Region.Framework.Scenes
2434 if (part != null) 2550 if (part != null)
2435 { 2551 {
2436 m_requestedSitTargetID = part.LocalId; 2552 m_requestedSitTargetID = part.LocalId;
2437 m_requestedSitTargetUUID = targetID; 2553 m_requestedSitTargetUUID = part.UUID;
2438 2554
2439 } 2555 }
2440 else 2556 else
@@ -2633,6 +2749,7 @@ namespace OpenSim.Region.Framework.Scenes
2633 } 2749 }
2634 Animator.TrySetMovementAnimation(sitAnimation); 2750 Animator.TrySetMovementAnimation(sitAnimation);
2635 SendAvatarDataToAllAgents(); 2751 SendAvatarDataToAllAgents();
2752 TriggerScenePresenceUpdated();
2636 } 2753 }
2637 } 2754 }
2638 2755
@@ -2641,6 +2758,7 @@ namespace OpenSim.Region.Framework.Scenes
2641// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. 2758// m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick..
2642 m_AngularVelocity = Vector3.Zero; 2759 m_AngularVelocity = Vector3.Zero;
2643 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); 2760 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
2761 TriggerScenePresenceUpdated();
2644 SitGround = true; 2762 SitGround = true;
2645 RemoveFromPhysicalScene(); 2763 RemoveFromPhysicalScene();
2646 } 2764 }
@@ -2657,11 +2775,13 @@ namespace OpenSim.Region.Framework.Scenes
2657 public void HandleStartAnim(IClientAPI remoteClient, UUID animID) 2775 public void HandleStartAnim(IClientAPI remoteClient, UUID animID)
2658 { 2776 {
2659 Animator.AddAnimation(animID, UUID.Zero); 2777 Animator.AddAnimation(animID, UUID.Zero);
2778 TriggerScenePresenceUpdated();
2660 } 2779 }
2661 2780
2662 public void HandleStopAnim(IClientAPI remoteClient, UUID animID) 2781 public void HandleStopAnim(IClientAPI remoteClient, UUID animID)
2663 { 2782 {
2664 Animator.RemoveAnimation(animID, false); 2783 Animator.RemoveAnimation(animID, false);
2784 TriggerScenePresenceUpdated();
2665 } 2785 }
2666 2786
2667 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack) 2787 public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
@@ -2879,11 +2999,12 @@ namespace OpenSim.Region.Framework.Scenes
2879 SendOtherAgentsAppearanceToMe(); 2999 SendOtherAgentsAppearanceToMe();
2880 3000
2881 EntityBase[] entities = Scene.Entities.GetEntities(); 3001 EntityBase[] entities = Scene.Entities.GetEntities();
2882 foreach(EntityBase e in entities) 3002 foreach (EntityBase e in entities)
2883 { 3003 {
2884 if (e != null && e is SceneObjectGroup) 3004 if (e != null && e is SceneObjectGroup)
2885 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); 3005 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
2886 } 3006 }
3007
2887 }); 3008 });
2888 } 3009 }
2889 3010
@@ -3109,7 +3230,7 @@ namespace OpenSim.Region.Framework.Scenes
3109 cadu.Velocity = Velocity; 3230 cadu.Velocity = Velocity;
3110 3231
3111 AgentPosition agentpos = new AgentPosition(); 3232 AgentPosition agentpos = new AgentPosition();
3112 agentpos.CopyFrom(cadu); 3233 agentpos.CopyFrom(cadu, ControllingClient.SessionId);
3113 3234
3114 // Let's get this out of the update loop 3235 // Let's get this out of the update loop
3115 Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); 3236 Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); });
@@ -3347,10 +3468,12 @@ namespace OpenSim.Region.Framework.Scenes
3347 if (byebyeRegions.Count > 0) 3468 if (byebyeRegions.Count > 0)
3348 { 3469 {
3349 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); 3470 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
3350 Util.FireAndForget(delegate 3471
3351 { 3472 AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID);
3352 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, byebyeRegions); 3473 string auth = string.Empty;
3353 }); 3474 if (acd != null)
3475 auth = acd.SessionID.ToString();
3476 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
3354 } 3477 }
3355 3478
3356 foreach (ulong handle in byebyeRegions) 3479 foreach (ulong handle in byebyeRegions)
@@ -3451,6 +3574,7 @@ namespace OpenSim.Region.Framework.Scenes
3451 3574
3452 cAgent.AgentID = UUID; 3575 cAgent.AgentID = UUID;
3453 cAgent.RegionID = Scene.RegionInfo.RegionID; 3576 cAgent.RegionID = Scene.RegionInfo.RegionID;
3577 cAgent.SessionID = ControllingClient.SessionId;
3454 3578
3455 cAgent.Position = AbsolutePosition; 3579 cAgent.Position = AbsolutePosition;
3456 cAgent.Velocity = m_velocity; 3580 cAgent.Velocity = m_velocity;
@@ -3693,7 +3817,8 @@ namespace OpenSim.Region.Framework.Scenes
3693 3817
3694// if (m_updateCount > 0) 3818// if (m_updateCount > 0)
3695// { 3819// {
3696 Animator.UpdateMovementAnimations(); 3820 if (Animator.UpdateMovementAnimations())
3821 TriggerScenePresenceUpdated();
3697// m_updateCount--; 3822// m_updateCount--;
3698// } 3823// }
3699 3824
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index ce4fb40..68918d3 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -1346,7 +1346,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1346 if (sop.MediaUrl != null) 1346 if (sop.MediaUrl != null)
1347 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); 1347 writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString());
1348 1348
1349 if (sop.DynAttrs.Count > 0) 1349 if (sop.DynAttrs.CountNamespaces > 0)
1350 { 1350 {
1351 writer.WriteStartElement("DynAttrs"); 1351 writer.WriteStartElement("DynAttrs");
1352 sop.DynAttrs.WriteXml(writer); 1352 sop.DynAttrs.WriteXml(writer);
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 5398ab9..bf32251 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -290,6 +290,9 @@ namespace OpenSim.Region.Framework.Scenes
290 290
291 private void statsHeartBeat(object sender, EventArgs e) 291 private void statsHeartBeat(object sender, EventArgs e)
292 { 292 {
293 if (!m_scene.Active)
294 return;
295
293 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[23]; 296 SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[23];
294 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock(); 297 SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
295 298
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
index 52ad538..d670dad 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
@@ -33,7 +33,9 @@ using NUnit.Framework;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35using OpenSim.Framework.Communications;
36using OpenSim.Region.CoreModules.Framework.EntityTransfer;
36using OpenSim.Region.CoreModules.Framework.InventoryAccess; 37using OpenSim.Region.CoreModules.Framework.InventoryAccess;
38using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
37using OpenSim.Region.CoreModules.World.Permissions; 39using OpenSim.Region.CoreModules.World.Permissions;
38using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
@@ -52,6 +54,24 @@ namespace OpenSim.Region.Framework.Scenes.Tests
52 [TestFixture] 54 [TestFixture]
53 public class SceneObjectDeRezTests : OpenSimTestCase 55 public class SceneObjectDeRezTests : OpenSimTestCase
54 { 56 {
57 [TestFixtureSetUp]
58 public void FixtureInit()
59 {
60 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
61 // This facility was added after the original async delete tests were written, so it may be possible now
62 // to not bother explicitly disabling their async (since everything will be running sync).
63 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
64 }
65
66 [TestFixtureTearDown]
67 public void TearDown()
68 {
69 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
70 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
71 // tests really shouldn't).
72 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
73 }
74
55 /// <summary> 75 /// <summary>
56 /// Test deleting an object from a scene. 76 /// Test deleting an object from a scene.
57 /// </summary> 77 /// </summary>
@@ -59,46 +79,96 @@ namespace OpenSim.Region.Framework.Scenes.Tests
59 public void TestDeRezSceneObject() 79 public void TestDeRezSceneObject()
60 { 80 {
61 TestHelpers.InMethod(); 81 TestHelpers.InMethod();
62// log4net.Config.XmlConfigurator.Configure();
63 82
64 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 83 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
65 84
66 TestScene scene = new SceneHelpers().SetupScene(); 85 TestScene scene = new SceneHelpers().SetupScene();
67 IConfigSource configSource = new IniConfigSource(); 86 SceneHelpers.SetupSceneModules(scene, new PermissionsModule());
68 IConfig config = configSource.AddConfig("Startup"); 87 TestClient client = (TestClient)SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
69 config.Set("serverside_object_permissions", true);
70 SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() });
71 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
72 88
73 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 89 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
74 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 90 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
75 sogd.Enabled = false; 91 sogd.Enabled = false;
76 92
77 SceneObjectPart part 93 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "so1", userId);
78 = new SceneObjectPart(userId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero); 94 uint soLocalId = so.LocalId;
79 part.Name = "obj1";
80 scene.AddNewSceneObject(new SceneObjectGroup(part), false);
81 95
82 List<uint> localIds = new List<uint>(); 96 List<uint> localIds = new List<uint>();
83 localIds.Add(part.LocalId); 97 localIds.Add(so.LocalId);
84 scene.DeRezObjects(client, localIds, UUID.Zero, DeRezAction.Delete, UUID.Zero); 98 scene.DeRezObjects(client, localIds, UUID.Zero, DeRezAction.Delete, UUID.Zero);
85 99
86 // Check that object isn't deleted until we crank the sogd handle. 100 // Check that object isn't deleted until we crank the sogd handle.
87 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 101 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
88 Assert.That(retrievedPart, Is.Not.Null); 102 Assert.That(retrievedPart, Is.Not.Null);
89 Assert.That(retrievedPart.ParentGroup.IsDeleted, Is.False); 103 Assert.That(retrievedPart.ParentGroup.IsDeleted, Is.False);
90 104
91 sogd.InventoryDeQueueAndDelete(); 105 sogd.InventoryDeQueueAndDelete();
92 106
93 SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(part.LocalId); 107 SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId);
94 Assert.That(retrievedPart2, Is.Null); 108 Assert.That(retrievedPart2, Is.Null);
109
110 Assert.That(client.ReceivedKills.Count, Is.EqualTo(1));
111 Assert.That(client.ReceivedKills[0], Is.EqualTo(soLocalId));
112 }
113
114 /// <summary>
115 /// Test that child and root agents correctly receive KillObject notifications.
116 /// </summary>
117 [Test]
118 public void TestDeRezSceneObjectToAgents()
119 {
120 TestHelpers.InMethod();
121// TestHelpers.EnableLogging();
122
123 SceneHelpers sh = new SceneHelpers();
124 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
125 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999);
126
127 // We need this so that the creation of the root client for userB in sceneB can trigger the creation of a child client in sceneA
128 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
129 EntityTransferModule etmB = new EntityTransferModule();
130 IConfigSource config = new IniConfigSource();
131 IConfig modulesConfig = config.AddConfig("Modules");
132 modulesConfig.Set("EntityTransferModule", etmB.Name);
133 modulesConfig.Set("SimulationServices", lscm.Name);
134 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
135 SceneHelpers.SetupSceneModules(sceneB, config, etmB);
136
137 // We need this for derez
138 SceneHelpers.SetupSceneModules(sceneA, new PermissionsModule());
139
140 UserAccount uaA = UserAccountHelpers.CreateUserWithInventory(sceneA, "Andy", "AAA", 0x1, "");
141 UserAccount uaB = UserAccountHelpers.CreateUserWithInventory(sceneA, "Brian", "BBB", 0x2, "");
142
143 TestClient clientA = (TestClient)SceneHelpers.AddScenePresence(sceneA, uaA).ControllingClient;
144
145 // This is the more long-winded route we have to take to get a child client created for userB in sceneA
146 // rather than just calling AddScenePresence() as for userA
147 AgentCircuitData acd = SceneHelpers.GenerateAgentData(uaB);
148 TestClient clientB = new TestClient(acd, sceneB);
149 List<TestClient> childClientsB = new List<TestClient>();
150 EntityTransferHelpers.SetUpInformClientOfNeighbour(clientB, childClientsB);
151
152 SceneHelpers.AddScenePresence(sceneB, clientB, acd);
153
154 SceneObjectGroup so = SceneHelpers.AddSceneObject(sceneA);
155 uint soLocalId = so.LocalId;
156
157 sceneA.DeleteSceneObject(so, false);
158
159 Assert.That(clientA.ReceivedKills.Count, Is.EqualTo(1));
160 Assert.That(clientA.ReceivedKills[0], Is.EqualTo(soLocalId));
161
162 Assert.That(childClientsB[0].ReceivedKills.Count, Is.EqualTo(1));
163 Assert.That(childClientsB[0].ReceivedKills[0], Is.EqualTo(soLocalId));
95 } 164 }
96 165
97 /// <summary> 166 /// <summary>
98 /// Test deleting an object from a scene where the deleter is not the owner 167 /// Test deleting an object from a scene where the deleter is not the owner
99 /// </summary> 168 /// </summary>
100 /// 169 /// <remarks>
101 /// This test assumes that the deleter is not a god. 170 /// This test assumes that the deleter is not a god.
171 /// </remarks>
102 [Test] 172 [Test]
103 public void TestDeRezSceneObjectNotOwner() 173 public void TestDeRezSceneObjectNotOwner()
104 { 174 {
@@ -109,10 +179,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
109 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001"); 179 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001");
110 180
111 TestScene scene = new SceneHelpers().SetupScene(); 181 TestScene scene = new SceneHelpers().SetupScene();
112 IConfigSource configSource = new IniConfigSource(); 182 SceneHelpers.SetupSceneModules(scene, new PermissionsModule());
113 IConfig config = configSource.AddConfig("Startup");
114 config.Set("serverside_object_permissions", true);
115 SceneHelpers.SetupSceneModules(scene, configSource, new object[] { new PermissionsModule() });
116 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient; 183 IClientAPI client = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
117 184
118 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 185 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index bbfbbfc..bbe34d2 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -119,7 +119,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
119 119
120 UUID spUuid = TestHelpers.ParseTail(0x1); 120 UUID spUuid = TestHelpers.ParseTail(0x1);
121 121
122 // The etm is only invoked by this test to check whether an agent is still in transit if there is a dupe
123 EntityTransferModule etm = new EntityTransferModule();
124
125 IConfigSource config = new IniConfigSource();
126 IConfig modulesConfig = config.AddConfig("Modules");
127 modulesConfig.Set("EntityTransferModule", etm.Name);
128 IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
129
130 // In order to run a single threaded regression test we do not want the entity transfer module waiting
131 // for a callback from the destination scene before removing its avatar data.
132 entityTransferConfig.Set("wait_for_callback", false);
133
122 TestScene scene = new SceneHelpers().SetupScene(); 134 TestScene scene = new SceneHelpers().SetupScene();
135 SceneHelpers.SetupSceneModules(scene, config, etm);
123 SceneHelpers.AddScenePresence(scene, spUuid); 136 SceneHelpers.AddScenePresence(scene, spUuid);
124 SceneHelpers.AddScenePresence(scene, spUuid); 137 SceneHelpers.AddScenePresence(scene, spUuid);
125 138
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
new file mode 100644
index 0000000..4ae7a8e
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
@@ -0,0 +1,88 @@
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.Reflection;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using Timer = System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.ClientStack.Linden;
43using OpenSim.Region.CoreModules.Framework;
44using OpenSim.Region.CoreModules.Framework.EntityTransfer;
45using OpenSim.Region.CoreModules.World.Serialiser;
46using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Tests.Common;
50using OpenSim.Tests.Common.Mock;
51using GridRegion = OpenSim.Services.Interfaces.GridRegion;
52
53namespace OpenSim.Region.Framework.Scenes.Tests
54{
55 [TestFixture]
56 public class ScenePresenceCapabilityTests : OpenSimTestCase
57 {
58 [Test]
59 public void TestChildAgentSingleRegionCapabilities()
60 {
61 TestHelpers.InMethod();
62// TestHelpers.EnableLogging();
63
64 UUID spUuid = TestHelpers.ParseTail(0x1);
65
66 // XXX: This is not great since the use of statics will mean that this has to be manually cleaned up for
67 // any subsequent test.
68 // XXX: May replace with a mock IHttpServer later.
69 BaseHttpServer httpServer = new BaseHttpServer(99999);
70 MainServer.AddHttpServer(httpServer);
71 MainServer.Instance = httpServer;
72
73 CapabilitiesModule capsMod = new CapabilitiesModule();
74 TestScene scene = new SceneHelpers().SetupScene();
75 SceneHelpers.SetupSceneModules(scene, capsMod);
76
77 ScenePresence sp = SceneHelpers.AddChildScenePresence(scene, spUuid);
78 //Assert.That(capsMod.GetCapsForUser(spUuid), Is.Not.Null);
79
80 // TODO: Need to add tests for other ICapabiltiesModule methods.
81
82 scene.IncomingCloseAgent(sp.UUID, false);
83 //Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null);
84
85 // TODO: Need to add tests for other ICapabiltiesModule methods.
86 }
87 }
88}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
index 8775949..5df9aba 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs
@@ -95,11 +95,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
95 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); 95 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
96 96
97 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); 97 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
98 TestClient tc = new TestClient(acd, sceneA, sh.SceneManager); 98 TestClient tc = new TestClient(acd, sceneA);
99 List<TestClient> destinationTestClients = new List<TestClient>(); 99 List<TestClient> destinationTestClients = new List<TestClient>();
100 EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); 100 EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients);
101 101
102 ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager); 102 ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
103 originalSp.AbsolutePosition = new Vector3(128, 32, 10); 103 originalSp.AbsolutePosition = new Vector3(128, 32, 10);
104 104
105// originalSp.Flying = true; 105// originalSp.Flying = true;
@@ -112,6 +112,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
112 //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero); 112 //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero);
113 moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2))); 113 moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2)));
114 moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; 114 moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
115 moveArgs.SessionID = acd.SessionID;
115 116
116 originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs); 117 originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs);
117 118
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index de4458d..afd2779 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -136,10 +136,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
136 SceneHelpers.SetupSceneModules(sceneB, config, etmB); 136 SceneHelpers.SetupSceneModules(sceneB, config, etmB);
137 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); 137 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
138 138
139 // FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
140 lscm.ServiceVersion = "SIMULATION/0.1";
141
139 Vector3 teleportPosition = new Vector3(10, 11, 12); 142 Vector3 teleportPosition = new Vector3(10, 11, 12);
140 Vector3 teleportLookAt = new Vector3(20, 21, 22); 143 Vector3 teleportLookAt = new Vector3(20, 21, 22);
141 144
142 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); 145 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId);
143 sp.AbsolutePosition = new Vector3(30, 31, 32); 146 sp.AbsolutePosition = new Vector3(30, 31, 32);
144 147
145 List<TestClient> destinationTestClients = new List<TestClient>(); 148 List<TestClient> destinationTestClients = new List<TestClient>();
@@ -224,7 +227,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
224 Vector3 teleportPosition = new Vector3(10, 11, 12); 227 Vector3 teleportPosition = new Vector3(10, 11, 12);
225 Vector3 teleportLookAt = new Vector3(20, 21, 22); 228 Vector3 teleportLookAt = new Vector3(20, 21, 22);
226 229
227 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); 230 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId);
228 sp.AbsolutePosition = preTeleportPosition; 231 sp.AbsolutePosition = preTeleportPosition;
229 232
230 // Make sceneB return false on query access 233 // Make sceneB return false on query access
@@ -300,7 +303,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
300 Vector3 teleportPosition = new Vector3(10, 11, 12); 303 Vector3 teleportPosition = new Vector3(10, 11, 12);
301 Vector3 teleportLookAt = new Vector3(20, 21, 22); 304 Vector3 teleportLookAt = new Vector3(20, 21, 22);
302 305
303 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); 306 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId);
304 sp.AbsolutePosition = preTeleportPosition; 307 sp.AbsolutePosition = preTeleportPosition;
305 308
306 // Make sceneB refuse CreateAgent 309 // Make sceneB refuse CreateAgent
@@ -389,7 +392,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
389 Vector3 teleportPosition = new Vector3(10, 11, 12); 392 Vector3 teleportPosition = new Vector3(10, 11, 12);
390 Vector3 teleportLookAt = new Vector3(20, 21, 22); 393 Vector3 teleportLookAt = new Vector3(20, 21, 22);
391 394
392 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); 395 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId);
393 sp.AbsolutePosition = preTeleportPosition; 396 sp.AbsolutePosition = preTeleportPosition;
394 397
395 sceneA.RequestTeleportLocation( 398 sceneA.RequestTeleportLocation(
@@ -428,7 +431,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
428 public void TestSameSimulatorNeighbouringRegions() 431 public void TestSameSimulatorNeighbouringRegions()
429 { 432 {
430 TestHelpers.InMethod(); 433 TestHelpers.InMethod();
431 TestHelpers.EnableLogging(); 434// TestHelpers.EnableLogging();
432 435
433 UUID userId = TestHelpers.ParseTail(0x1); 436 UUID userId = TestHelpers.ParseTail(0x1);
434 437
@@ -454,15 +457,18 @@ namespace OpenSim.Region.Framework.Scenes.Tests
454 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); 457 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
455 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); 458 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
456 459
460 // FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
461 lscm.ServiceVersion = "SIMULATION/0.1";
462
457 Vector3 teleportPosition = new Vector3(10, 11, 12); 463 Vector3 teleportPosition = new Vector3(10, 11, 12);
458 Vector3 teleportLookAt = new Vector3(20, 21, 22); 464 Vector3 teleportLookAt = new Vector3(20, 21, 22);
459 465
460 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); 466 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
461 TestClient tc = new TestClient(acd, sceneA, sh.SceneManager); 467 TestClient tc = new TestClient(acd, sceneA);
462 List<TestClient> destinationTestClients = new List<TestClient>(); 468 List<TestClient> destinationTestClients = new List<TestClient>();
463 EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); 469 EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients);
464 470
465 ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager); 471 ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
466 beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32); 472 beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32);
467 473
468 Assert.That(beforeSceneASp, Is.Not.Null); 474 Assert.That(beforeSceneASp, Is.Not.Null);
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index b09ae39..e60a025 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -34,6 +34,7 @@ using System.Threading;
34using log4net; 34using log4net;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenMetaverse.Assets; 36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData;
37using OpenSim.Framework; 38using OpenSim.Framework;
38using OpenSim.Region.Framework.Scenes.Serialization; 39using OpenSim.Region.Framework.Scenes.Serialization;
39using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
@@ -180,6 +181,14 @@ namespace OpenSim.Region.Framework.Scenes
180 if (!assetUuids.ContainsKey(tii.AssetID)) 181 if (!assetUuids.ContainsKey(tii.AssetID))
181 GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids); 182 GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids);
182 } 183 }
184
185 // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
186 // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
187 // inventory transfer. There needs to be a way for a module to register a method without assuming a
188 // Scene.EventManager is present.
189// part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
190
191 GatherMaterialsUuids(part, assetUuids);
183 } 192 }
184 catch (Exception e) 193 catch (Exception e)
185 { 194 {
@@ -205,6 +214,73 @@ namespace OpenSim.Region.Framework.Scenes
205// } 214// }
206 215
207 /// <summary> 216 /// <summary>
217 /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
218 /// </summary>
219 /// <param name="part"></param>
220 /// <param name="assetUuids"></param>
221 public void GatherMaterialsUuids(SceneObjectPart part, IDictionary<UUID, AssetType> assetUuids)
222 {
223 // scan thru the dynAttrs map of this part for any textures used as materials
224 OSD osdMaterials = null;
225
226 lock (part.DynAttrs)
227 {
228 if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
229 {
230 OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
231
232 if (materialsStore == null)
233 return;
234
235 materialsStore.TryGetValue("Materials", out osdMaterials);
236 }
237
238 if (osdMaterials != null)
239 {
240 //m_log.Info("[UUID Gatherer]: found Materials: " + OSDParser.SerializeJsonString(osd));
241
242 if (osdMaterials is OSDArray)
243 {
244 OSDArray matsArr = osdMaterials as OSDArray;
245 foreach (OSDMap matMap in matsArr)
246 {
247 try
248 {
249 if (matMap.ContainsKey("Material"))
250 {
251 OSDMap mat = matMap["Material"] as OSDMap;
252 if (mat.ContainsKey("NormMap"))
253 {
254 UUID normalMapId = mat["NormMap"].AsUUID();
255 if (normalMapId != UUID.Zero)
256 {
257 assetUuids[normalMapId] = AssetType.Texture;
258 //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString());
259 }
260 }
261 if (mat.ContainsKey("SpecMap"))
262 {
263 UUID specularMapId = mat["SpecMap"].AsUUID();
264 if (specularMapId != UUID.Zero)
265 {
266 assetUuids[specularMapId] = AssetType.Texture;
267 //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString());
268 }
269 }
270 }
271
272 }
273 catch (Exception e)
274 {
275 m_log.Warn("[UUID Gatherer]: exception getting materials: " + e.Message);
276 }
277 }
278 }
279 }
280 }
281 }
282
283 /// <summary>
208 /// Get an asset synchronously, potentially using an asynchronous callback. If the 284 /// Get an asset synchronously, potentially using an asynchronous callback. If the
209 /// asynchronous callback is used, we will wait for it to complete. 285 /// asynchronous callback is used, we will wait for it to complete.
210 /// </summary> 286 /// </summary>