aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs6
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs3
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs4
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IInterregionComms.cs8
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISnmpModule.cs27
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs13
-rw-r--r--OpenSim/Region/Framework/ModuleLoader.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs244
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs355
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Permissions.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs502
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs50
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs224
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs563
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs227
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs794
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs907
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/UndoState.cs87
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs4
29 files changed, 3080 insertions, 1034 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index e668dae..a7770ad 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Xml;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
31using OpenSim.Framework; 32using OpenSim.Framework;
@@ -75,6 +76,10 @@ namespace OpenSim.Region.Framework.Interfaces
75 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns> 76 /// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
76 ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt); 77 ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt);
77 78
79 // Same as above, but also load script states from a separate doc
80 ISceneEntity RezSingleAttachmentFromInventory(
81 IScenePresence presence, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc);
82
78 /// <summary> 83 /// <summary>
79 /// Rez multiple attachments from a user's inventory 84 /// Rez multiple attachments from a user's inventory
80 /// </summary> 85 /// </summary>
@@ -96,7 +101,6 @@ namespace OpenSim.Region.Framework.Interfaces
96 /// <param name="itemID"></param> 101 /// <param name="itemID"></param>
97 void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID); 102 void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID);
98 103
99 /// <summary>
100 /// Update the position of an attachment. 104 /// Update the position of an attachment.
101 /// </summary> 105 /// </summary>
102 /// <param name="sog"></param> 106 /// <param name="sog"></param>
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 15060fd..4b17b9a 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -115,6 +115,8 @@ namespace OpenSim.Region.Framework.Interfaces
115 /// <param name="stateSource"></param> 115 /// <param name="stateSource"></param>
116 void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); 116 void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
117 117
118 ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
119
118 /// <summary> 120 /// <summary>
119 /// Stop a script which is in this prim's inventory. 121 /// Stop a script which is in this prim's inventory.
120 /// </summary> 122 /// </summary>
@@ -229,5 +231,6 @@ namespace OpenSim.Region.Framework.Interfaces
229 /// A <see cref="Dictionary`2"/> 231 /// A <see cref="Dictionary`2"/>
230 /// </returns> 232 /// </returns>
231 Dictionary<UUID, string> GetScriptStates(); 233 Dictionary<UUID, string> GetScriptStates();
234 Dictionary<UUID, string> GetScriptStates(bool oldIDs);
232 } 235 }
233} 236}
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 07e97d5..c38ecd9 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -40,11 +40,11 @@ namespace OpenSim.Region.Framework.Interfaces
40 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, 40 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position,
41 Vector3 lookAt, uint teleportFlags); 41 Vector3 lookAt, uint teleportFlags);
42 42
43 bool TeleportHome(UUID id, IClientAPI client);
44
43 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, 45 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
44 Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq); 46 Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq);
45 47
46 void TeleportHome(UUID id, IClientAPI client);
47
48 bool Cross(ScenePresence agent, bool isFlying); 48 bool Cross(ScenePresence agent, bool isFlying);
49 49
50 void AgentArrivedAtDestination(UUID agent); 50 void AgentArrivedAtDestination(UUID agent);
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
index 721f0ee..72e79ed 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
@@ -45,5 +45,7 @@ namespace OpenSim.Region.Framework.Interfaces
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>
47 void sendRegionHandshakeToAll(); 47 void sendRegionHandshakeToAll();
48 void TriggerEstateInfoChange();
49 void TriggerRegionInfoChange();
48 } 50 }
49} 51}
diff --git a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
index 2d6287f..67a500f 100644
--- a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
+++ b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
@@ -68,6 +68,14 @@ namespace OpenSim.Region.Framework.Interfaces
68 bool SendReleaseAgent(ulong regionHandle, UUID id, string uri); 68 bool SendReleaseAgent(ulong regionHandle, UUID id, string uri);
69 69
70 /// <summary> 70 /// <summary>
71 /// Close chid agent.
72 /// </summary>
73 /// <param name="regionHandle"></param>
74 /// <param name="id"></param>
75 /// <returns></returns>
76 bool SendCloseChildAgent(ulong regionHandle, UUID id);
77
78 /// <summary>
71 /// Close agent. 79 /// Close agent.
72 /// </summary> 80 /// </summary>
73 /// <param name="regionHandle"></param> 81 /// <param name="regionHandle"></param>
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index 950e4b0..9d68eb4 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -55,6 +55,8 @@ namespace OpenSim.Region.Framework.Interfaces
55 55
56 ArrayList GetScriptErrors(UUID itemID); 56 ArrayList GetScriptErrors(UUID itemID);
57 57
58 bool HasScript(UUID itemID, out bool running);
59
58 void SaveAllState(); 60 void SaveAllState();
59 61
60 /// <summary> 62 /// <summary>
diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs
new file mode 100644
index 0000000..e01f649
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs
@@ -0,0 +1,27 @@
1///////////////////////////////////////////////////////////////////
2//
3// (c) Careminster LImited, Melanie Thielker and the Meta7 Team
4//
5// This file is not open source. All rights reserved
6// Mod 2
7
8using OpenSim.Region.Framework.Scenes;
9
10public interface ISnmpModule
11{
12 void Trap(int code, string Message, Scene scene);
13 void Critical(string Message, Scene scene);
14 void Warning(string Message, Scene scene);
15 void Major(string Message, Scene scene);
16 void ColdStart(int step , Scene scene);
17 void Shutdown(int step , Scene scene);
18 //
19 // Node Start/stop events
20 //
21 void LinkUp(Scene scene);
22 void LinkDown(Scene scene);
23 void BootInfo(string data, Scene scene);
24 void trapDebug(string Module,string data, Scene scene);
25 void trapXMRE(int data, string Message, Scene scene);
26
27}
diff --git a/OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs b/OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs
new file mode 100644
index 0000000..d1a4d8e
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs
@@ -0,0 +1,13 @@
1///////////////////////////////////////////////////////////////////
2//
3// (c) Careminster Limited, Melanie Thielker and the Meta7 Team
4//
5// This file is not open source. All rights reserved
6//
7
8using OpenSim.Region.Framework.Scenes;
9
10public interface IUserAccountCacheModule
11{
12 void Remove(string name);
13}
diff --git a/OpenSim/Region/Framework/ModuleLoader.cs b/OpenSim/Region/Framework/ModuleLoader.cs
index 14ecd44..32ee674 100644
--- a/OpenSim/Region/Framework/ModuleLoader.cs
+++ b/OpenSim/Region/Framework/ModuleLoader.cs
@@ -227,7 +227,8 @@ namespace OpenSim.Region.Framework
227 pluginAssembly.FullName, e.Message, e.StackTrace); 227 pluginAssembly.FullName, e.Message, e.StackTrace);
228 228
229 // justincc: Right now this is fatal to really get the user's attention 229 // justincc: Right now this is fatal to really get the user's attention
230 throw e; 230 // TomMeta: WTF? No, how about we /don't/ throw a fatal exception when there's no need to?
231 //throw e;
231 } 232 }
232 } 233 }
233 234
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index e9e1845..175e8ed 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Threading;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using log4net; 32using log4net;
@@ -42,7 +43,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
42 /// </summary> 43 /// </summary>
43 public class ScenePresenceAnimator 44 public class ScenePresenceAnimator
44 { 45 {
45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 47
47 public AnimationSet Animations 48 public AnimationSet Animations
48 { 49 {
@@ -57,11 +58,17 @@ namespace OpenSim.Region.Framework.Scenes.Animation
57 { 58 {
58 get { return m_movementAnimation; } 59 get { return m_movementAnimation; }
59 } 60 }
60 protected string m_movementAnimation = "DEFAULT"; 61 // protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist!
61 62 protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init.
62 private int m_animTickFall; 63 private int m_animTickFall;
63 private int m_animTickJump; 64// private int m_animTickJump;
64 65 public int m_animTickJump; // ScenePresence has to see this to control +Z force
66 public bool m_jumping = false; // Add for jumping
67 public float m_jumpVelocity = 0f; // Add for jumping
68 private int m_landing = 0; // Add for jumping
69 public bool m_falling = false; // Add for falling
70 private float m_fallHeight; // Add for falling
71
65 /// <value> 72 /// <value>
66 /// The scene presence that this animator applies to 73 /// The scene presence that this animator applies to
67 /// </value> 74 /// </value>
@@ -122,7 +129,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
122 129
123 public void ResetAnimations() 130 public void ResetAnimations()
124 { 131 {
132Console.WriteLine("ResetA.............");
125 m_animations.Clear(); 133 m_animations.Clear();
134TrySetMovementAnimation("STAND");
126 } 135 }
127 136
128 /// <summary> 137 /// <summary>
@@ -152,15 +161,16 @@ namespace OpenSim.Region.Framework.Scenes.Animation
152 /// </summary> 161 /// </summary>
153 public string GetMovementAnimation() 162 public string GetMovementAnimation()
154 { 163 {
155 const float FALL_DELAY = 0.33f; 164//Console.WriteLine("GMA-------"); //##
156 const float PREJUMP_DELAY = 0.25f; 165//#@ const float FALL_DELAY = 0.33f;
157 166 const float FALL_DELAY = 800f; //## mS
167//rm for jumping const float PREJUMP_DELAY = 0.25f;
168 const float PREJUMP_DELAY = 200f; // mS add for jumping
169 const float JUMP_PERIOD = 800f; // mS add for jumping
158 #region Inputs 170 #region Inputs
159 if (m_scenePresence.SitGround) 171
160 {
161 return "SIT_GROUND_CONSTRAINED";
162 }
163 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; 172 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
173// m_log.DebugFormat("[ANIM]: Control flags: {0}", controlFlags);
164 PhysicsActor actor = m_scenePresence.PhysicsActor; 174 PhysicsActor actor = m_scenePresence.PhysicsActor;
165 175
166 // Create forward and left vectors from the current avatar rotation 176 // Create forward and left vectors from the current avatar rotation
@@ -169,13 +179,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
169 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); 179 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
170 180
171 // Check control flags 181 // Check control flags
172 bool heldForward = 182 bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
173 (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) || ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)); 183 bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
174 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; 184 bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
175 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; 185 bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
176 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; 186 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
177 bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; 187 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
178 bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
179 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; 188 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
180 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; 189 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
181 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; 190 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
@@ -183,17 +192,16 @@ namespace OpenSim.Region.Framework.Scenes.Animation
183 192
184 // Direction in which the avatar is trying to move 193 // Direction in which the avatar is trying to move
185 Vector3 move = Vector3.Zero; 194 Vector3 move = Vector3.Zero;
186 if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
187 if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; } 195 if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; }
188 if (heldLeft) { move.X += left.X; move.Y += left.Y; } 196 if (heldLeft) { move.X += left.X; move.Y += left.Y; }
189 if (heldRight) { move.X -= left.X; move.Y -= left.Y; } 197 if (heldRight) { move.X -= left.X; move.Y -= left.Y; }
190 if (heldUp) { move.Z += 1; } 198 if (heldUp) { move.Z += 1; }
191 if (heldDown) { move.Z -= 1; } 199 if (heldDown) { move.Z -= 1; }
200 if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
192 201
193 // Is the avatar trying to move? 202 // Is the avatar trying to move?
194// bool moving = (move != Vector3.Zero); 203// bool moving = (move != Vector3.Zero);
195 bool jumping = m_animTickJump != 0; 204// rm for jumping bool jumping = m_animTickJump != 0;
196
197 #endregion Inputs 205 #endregion Inputs
198 206
199 #region Flying 207 #region Flying
@@ -202,6 +210,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
202 { 210 {
203 m_animTickFall = 0; 211 m_animTickFall = 0;
204 m_animTickJump = 0; 212 m_animTickJump = 0;
213 m_jumping = false; //add for jumping
214 m_falling = true; //add for falling
215 m_jumpVelocity = 0f; //add for jumping
216 actor.Selected = false; //add for jumping flag
217 m_fallHeight = actor.Position.Z; // save latest flying height
205 218
206 if (move.X != 0f || move.Y != 0f) 219 if (move.X != 0f || move.Y != 0f)
207 { 220 {
@@ -213,8 +226,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
213 } 226 }
214 else if (move.Z < 0f) 227 else if (move.Z < 0f)
215 { 228 {
216 if (actor != null && actor.IsColliding) 229 if (actor != null && actor.IsColliding)
230 { //##
231//Console.WriteLine("LAND FLYING"); // ##
217 return "LAND"; 232 return "LAND";
233 } //#
218 else 234 else
219 return "HOVER_DOWN"; 235 return "HOVER_DOWN";
220 } 236 }
@@ -228,48 +244,127 @@ namespace OpenSim.Region.Framework.Scenes.Animation
228 244
229 #region Falling/Floating/Landing 245 #region Falling/Floating/Landing
230 246
231 if (actor == null || !actor.IsColliding) 247// rm for jumping if (actor == null || !actor.IsColliding)
248 if ((actor == null || !actor.IsColliding) && !m_jumping) // add for jumping
232 { 249 {
233 float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; 250// rm float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
251 float fallElapsed = (float)(Environment.TickCount - m_animTickFall); // add, in mS
234 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; 252 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
253//Console.WriteLine("falling t={0} v={1}", fallElapsed, fallVelocity); //##
254
255// rm for fall if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f))
256 if (!m_jumping && (fallVelocity < -3.0f) ) m_falling = true; // add for falling and jumping
235 257
236 if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f)) 258 if (m_animTickFall == 0 || (fallVelocity >= 0.0f)) // add for jumping
259 // not falling yet or going up
237 { 260 {
238 // Just started falling 261 // reset start of fall time
239 m_animTickFall = Environment.TickCount; 262 m_animTickFall = Environment.TickCount;
240 } 263 }
241 else if (!jumping && fallElapsed > FALL_DELAY) 264// else if (!jumping && fallElapsed > FALL_DELAY)
265 else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.m_wasFlying)) // add for falling and jumping
242 { 266 {
243 // Falling long enough to trigger the animation 267 // Falling long enough to trigger the animation
268//Console.WriteLine("FALLDOWN"); //##
244 return "FALLDOWN"; 269 return "FALLDOWN";
245 } 270 }
246 else if (m_animTickJump == -1)
247 {
248 m_animTickJump = 0;
249 return "STAND";
250 }
251 271
252 return m_movementAnimation; 272 return m_movementAnimation;
253 } 273 }
254 274
255 #endregion Falling/Floating/Landing 275 #endregion Falling/Floating/Landing
256 276
277
278 #region Jumping // section added for jumping...
279
280 int jumptime;
281 jumptime = Environment.TickCount - m_animTickJump;
282
283
284 if ((move.Z > 0f) && (!m_jumping))
285 {
286//Console.WriteLine("PJ {0}", jumptime); //##
287 // Start jumping, prejump
288 m_animTickFall = 0;
289 m_jumping = true;
290 m_falling = false;
291 actor.Selected = true; // borrowed for jmping flag
292 m_animTickJump = Environment.TickCount;
293 m_jumpVelocity = 0.35f;
294 return "PREJUMP";
295 }
296
297 if(m_jumping)
298 {
299 if ( (jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
300 {
301//Console.WriteLine("LA {0}", jumptime); //##
302 // end jumping
303 m_jumping = false;
304 m_falling = false;
305 actor.Selected = false; // borrowed for jumping flag
306 m_jumpVelocity = 0f;
307 m_animTickFall = Environment.TickCount;
308 return "LAND";
309 }
310 else if (jumptime > JUMP_PERIOD)
311 {
312//Console.WriteLine("JD {0}", jumptime); //##
313 // jump down
314 m_jumpVelocity = 0f;
315 return "JUMP";
316 }
317 else if (jumptime > PREJUMP_DELAY)
318 {
319//Console.WriteLine("JU {0}", jumptime); //##
320 // jump up
321 m_jumping = true;
322 m_jumpVelocity = 10f;
323 return "JUMP";
324 }
325 }
326
327 #endregion Jumping // end added section
328
257 #region Ground Movement 329 #region Ground Movement
258 330
259 if (m_movementAnimation == "FALLDOWN") 331 if (m_movementAnimation == "FALLDOWN")
260 { 332 {
333 m_falling = false;
261 m_animTickFall = Environment.TickCount; 334 m_animTickFall = Environment.TickCount;
262
263 // TODO: SOFT_LAND support 335 // TODO: SOFT_LAND support
264 return "LAND"; 336 float fallHeight = m_fallHeight - actor.Position.Z;
337//Console.WriteLine("Hit from {0}", fallHeight); //##
338 if (fallHeight > 15.0f) // add for falling
339 return "STANDUP";
340 else if (fallHeight > 8.0f) // add for falling
341 return "SOFT_LAND"; // add for falling
342 else // add for falling
343 return "LAND"; // add for falling
265 } 344 }
266 else if (m_movementAnimation == "LAND") 345// rm jumping float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
346// rm jumping if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY))
347// rm for landing return "LAND";
348 else if ((m_movementAnimation == "LAND") || (m_movementAnimation == "SOFT_LAND") || (m_movementAnimation == "STANDUP"))
267 { 349 {
268 float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; 350 int landElapsed = Environment.TickCount - m_animTickFall; // add for jumping
269 if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY)) 351 int limit = 1000; // add for jumping
270 return "LAND"; 352 if(m_movementAnimation == "LAND") limit = 350; // add for jumping
271 } 353 // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client
272 354
355 if ((m_animTickFall != 0) && (landElapsed <= limit)) // add for jumping
356 {
357//Console.WriteLine("Lelapse {0}", m_movementAnimation); //##
358 return m_movementAnimation;
359 }
360 else
361 {
362//Console.WriteLine("end/STAND"); //##
363 m_fallHeight = actor.Position.Z; // save latest flying height
364 return "STAND";
365 }
366 }
367/* This section removed, replaced by jumping section
273 m_animTickFall = 0; 368 m_animTickFall = 0;
274 369
275 if (move.Z > 0.2f) 370 if (move.Z > 0.2f)
@@ -281,7 +376,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
281 m_animTickJump = Environment.TickCount; 376 m_animTickJump = Environment.TickCount;
282 return "PREJUMP"; 377 return "PREJUMP";
283 } 378 }
284 else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f) 379 else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 800.0f)
285 { 380 {
286 // Start actual jump 381 // Start actual jump
287 if (m_animTickJump == -1) 382 if (m_animTickJump == -1)
@@ -294,41 +389,44 @@ namespace OpenSim.Region.Framework.Scenes.Animation
294 m_animTickJump = -1; 389 m_animTickJump = -1;
295 return "JUMP"; 390 return "JUMP";
296 } 391 }
297 else
298 return "JUMP";
299 } 392 }
300 else 393 else
301 { 394 {
302 // Not jumping 395 // Not jumping
303 m_animTickJump = 0; 396 m_animTickJump = 0;
304 397 */
305 if (move.X != 0f || move.Y != 0f) 398 // next section moved outside paren. and realigned for jumping
306 { 399 if (move.X != 0f || move.Y != 0f)
307 // Walking / crouchwalking / running 400 {
308 if (move.Z < 0) 401 m_fallHeight = actor.Position.Z; // save latest flying height
309 return "CROUCHWALK"; 402 m_falling = false; // Add for falling
310 else if (m_scenePresence.SetAlwaysRun) 403 // Walking / crouchwalking / running
311 return "RUN"; 404 if (move.Z < 0f)
312 else 405 return "CROUCHWALK";
313 return "WALK"; 406 else if (m_scenePresence.SetAlwaysRun)
314 } 407 return "RUN";
315 else 408 else
316 { 409 return "WALK";
317 // Not walking
318 if (move.Z < 0)
319 return "CROUCH";
320 else if (heldTurnLeft)
321 return "TURNLEFT";
322 else if (heldTurnRight)
323 return "TURNRIGHT";
324 else
325 return "STAND";
326 }
327 } 410 }
328 411// rm for jumping else
412 else if (!m_jumping) // add for jumping
413 {
414 m_falling = false; // Add for falling
415 // Not walking
416 if (move.Z < 0)
417 return "CROUCH";
418// else if (heldTurnLeft)
419// return "TURNLEFT";
420// else if (heldTurnRight)
421// return "TURNRIGHT";
422 else
423 return "STAND";
424 }
425 // end section realign for jumping
329 #endregion Ground Movement 426 #endregion Ground Movement
330 427
331 //return m_movementAnimation; 428 m_falling = false; // Add for falling
429 return m_movementAnimation;
332 } 430 }
333 431
334 /// <summary> 432 /// <summary>
@@ -337,9 +435,15 @@ namespace OpenSim.Region.Framework.Scenes.Animation
337 public void UpdateMovementAnimations() 435 public void UpdateMovementAnimations()
338 { 436 {
339 m_movementAnimation = GetMovementAnimation(); 437 m_movementAnimation = GetMovementAnimation();
340// m_log.DebugFormat( 438/* if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
341// "[SCENE PRESENCE ANIMATOR]: Got animation {0} for {1}", m_movementAnimation, m_scenePresence.Name); 439 {
342 TrySetMovementAnimation(m_movementAnimation); 440 // This was the previous behavior before PREJUMP
441 TrySetMovementAnimation("JUMP");
442 }
443 else
444 { removed for jumping */
445 TrySetMovementAnimation(m_movementAnimation);
446// rm for jumping }
343 } 447 }
344 448
345 public UUID[] GetAnimationArray() 449 public UUID[] GetAnimationArray()
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index 0ac3899..12688bd 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -104,8 +104,15 @@ 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
107 foreach (SceneObjectGroup g in objectGroups) 109 foreach (SceneObjectGroup g in objectGroups)
110 {
111 killIDs.Add(g.LocalId);
108 g.DeleteGroupFromScene(false); 112 g.DeleteGroupFromScene(false);
113 }
114
115 m_scene.SendKillObject(killIDs);
109 } 116 }
110 } 117 }
111 118
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 96da2c3..65c6a29 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -55,8 +55,12 @@ namespace OpenSim.Region.Framework.Scenes
55 55
56 public delegate void OnTerrainTickDelegate(); 56 public delegate void OnTerrainTickDelegate();
57 57
58 public delegate void OnTerrainUpdateDelegate();
59
58 public event OnTerrainTickDelegate OnTerrainTick; 60 public event OnTerrainTickDelegate OnTerrainTick;
59 61
62 public event OnTerrainUpdateDelegate OnTerrainUpdate;
63
60 public delegate void OnBackupDelegate(ISimulationDataService datastore, bool forceBackup); 64 public delegate void OnBackupDelegate(ISimulationDataService datastore, bool forceBackup);
61 65
62 public event OnBackupDelegate OnBackup; 66 public event OnBackupDelegate OnBackup;
@@ -775,6 +779,26 @@ namespace OpenSim.Region.Framework.Scenes
775 } 779 }
776 } 780 }
777 } 781 }
782 public void TriggerTerrainUpdate()
783 {
784 OnTerrainUpdateDelegate handlerTerrainUpdate = OnTerrainUpdate;
785 if (handlerTerrainUpdate != null)
786 {
787 foreach (OnTerrainUpdateDelegate d in handlerTerrainUpdate.GetInvocationList())
788 {
789 try
790 {
791 d();
792 }
793 catch (Exception e)
794 {
795 m_log.ErrorFormat(
796 "[EVENT MANAGER]: Delegate for TriggerTerrainUpdate failed - continuing. {0} {1}",
797 e.Message, e.StackTrace);
798 }
799 }
800 }
801 }
778 802
779 public void TriggerTerrainTick() 803 public void TriggerTerrainTick()
780 { 804 {
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index 1b10e3c..0a34a4c 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -157,7 +157,7 @@ namespace OpenSim.Region.Framework.Scenes
157 157
158 private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) 158 private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity)
159 { 159 {
160 uint pqueue = ComputeDistancePriority(client,entity,true); 160 uint pqueue = ComputeDistancePriority(client,entity,false);
161 161
162 ScenePresence presence = m_scene.GetScenePresence(client.AgentId); 162 ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
163 if (presence != null) 163 if (presence != null)
@@ -226,7 +226,7 @@ namespace OpenSim.Region.Framework.Scenes
226 226
227 for (int i = 0; i < queues - 1; i++) 227 for (int i = 0; i < queues - 1; i++)
228 { 228 {
229 if (distance < 10 * Math.Pow(2.0,i)) 229 if (distance < 30 * Math.Pow(2.0,i))
230 break; 230 break;
231 pqueue++; 231 pqueue++;
232 } 232 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 663aa22..53f0f2e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -124,34 +124,22 @@ namespace OpenSim.Region.Framework.Scenes
124 /// <param name="item"></param> 124 /// <param name="item"></param>
125 public bool AddInventoryItem(InventoryItemBase item) 125 public bool AddInventoryItem(InventoryItemBase item)
126 { 126 {
127 if (UUID.Zero == item.Folder) 127 InventoryFolderBase folder;
128
129 if (item.Folder == UUID.Zero)
128 { 130 {
129 InventoryFolderBase f = InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType); 131 folder = InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType);
130 if (f != null) 132 if (folder == null)
131 { 133 {
132// m_log.DebugFormat( 134 folder = InventoryService.GetRootFolder(item.Owner);
133// "[LOCAL INVENTORY SERVICES CONNECTOR]: Found folder {0} type {1} for item {2}", 135
134// f.Name, (AssetType)f.Type, item.Name); 136 if (folder == null)
135
136 item.Folder = f.ID;
137 }
138 else
139 {
140 f = InventoryService.GetRootFolder(item.Owner);
141 if (f != null)
142 {
143 item.Folder = f.ID;
144 }
145 else
146 {
147 m_log.WarnFormat(
148 "[AGENT INVENTORY]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified",
149 item.Owner, item.Name);
150 return false; 137 return false;
151 }
152 } 138 }
139
140 item.Folder = folder.ID;
153 } 141 }
154 142
155 if (InventoryService.AddItem(item)) 143 if (InventoryService.AddItem(item))
156 { 144 {
157 int userlevel = 0; 145 int userlevel = 0;
@@ -271,8 +259,7 @@ namespace OpenSim.Region.Framework.Scenes
271 259
272 // Update item with new asset 260 // Update item with new asset
273 item.AssetID = asset.FullID; 261 item.AssetID = asset.FullID;
274 if (group.UpdateInventoryItem(item)) 262 group.UpdateInventoryItem(item);
275 remoteClient.SendAgentAlertMessage("Script saved", false);
276 263
277 part.SendPropertiesToClient(remoteClient); 264 part.SendPropertiesToClient(remoteClient);
278 265
@@ -283,12 +270,7 @@ namespace OpenSim.Region.Framework.Scenes
283 { 270 {
284 // Needs to determine which engine was running it and use that 271 // Needs to determine which engine was running it and use that
285 // 272 //
286 part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0); 273 errors = part.Inventory.CreateScriptInstanceEr(item.ItemID, 0, false, DefaultScriptEngine, 0);
287 errors = part.Inventory.GetScriptErrors(item.ItemID);
288 }
289 else
290 {
291 remoteClient.SendAgentAlertMessage("Script saved", false);
292 } 274 }
293 part.ParentGroup.ResumeScripts(); 275 part.ParentGroup.ResumeScripts();
294 return errors; 276 return errors;
@@ -351,6 +333,7 @@ namespace OpenSim.Region.Framework.Scenes
351 { 333 {
352 if (UUID.Zero == transactionID) 334 if (UUID.Zero == transactionID)
353 { 335 {
336 item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
354 item.Name = itemUpd.Name; 337 item.Name = itemUpd.Name;
355 item.Description = itemUpd.Description; 338 item.Description = itemUpd.Description;
356 if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions)) 339 if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
@@ -728,6 +711,8 @@ namespace OpenSim.Region.Framework.Scenes
728 return; 711 return;
729 } 712 }
730 713
714 if (newName == null) newName = item.Name;
715
731 AssetBase asset = AssetService.Get(item.AssetID.ToString()); 716 AssetBase asset = AssetService.Get(item.AssetID.ToString());
732 717
733 if (asset != null) 718 if (asset != null)
@@ -784,6 +769,24 @@ namespace OpenSim.Region.Framework.Scenes
784 } 769 }
785 770
786 /// <summary> 771 /// <summary>
772 /// Move an item within the agent's inventory, and leave a copy (used in making a new outfit)
773 /// </summary>
774 public void MoveInventoryItemsLeaveCopy(IClientAPI remoteClient, List<InventoryItemBase> items, UUID destfolder)
775 {
776 List<InventoryItemBase> moveitems = new List<InventoryItemBase>();
777 foreach (InventoryItemBase b in items)
778 {
779 CopyInventoryItem(remoteClient, 0, remoteClient.AgentId, b.ID, b.Folder, null);
780 InventoryItemBase n = InventoryService.GetItem(b);
781 n.Folder = destfolder;
782 moveitems.Add(n);
783 remoteClient.SendInventoryItemCreateUpdate(n, 0);
784 }
785
786 MoveInventoryItem(remoteClient, moveitems);
787 }
788
789 /// <summary>
787 /// Move an item within the agent's inventory. 790 /// Move an item within the agent's inventory.
788 /// </summary> 791 /// </summary>
789 /// <param name="remoteClient"></param> 792 /// <param name="remoteClient"></param>
@@ -984,25 +987,29 @@ namespace OpenSim.Region.Framework.Scenes
984 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 987 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
985 { 988 {
986 SceneObjectPart part = GetSceneObjectPart(localID); 989 SceneObjectPart part = GetSceneObjectPart(localID);
987 if (part == null) 990 SceneObjectGroup group = null;
988 return; 991 if (part != null)
992 {
993 group = part.ParentGroup;
994 }
995 if (part != null && group != null)
996 {
997 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
998 return;
989 999
990 SceneObjectGroup group = part.ParentGroup; 1000 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
991 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) 1001 if (item == null)
992 return; 1002 return;
993
994 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
995 if (item == null)
996 return;
997 1003
998 if (item.Type == 10) 1004 if (item.Type == 10)
999 { 1005 {
1000 part.RemoveScriptEvents(itemID); 1006 part.RemoveScriptEvents(itemID);
1001 EventManager.TriggerRemoveScript(localID, itemID); 1007 EventManager.TriggerRemoveScript(localID, itemID);
1008 }
1009
1010 group.RemoveInventoryItem(localID, itemID);
1011 part.SendPropertiesToClient(remoteClient);
1002 } 1012 }
1003
1004 group.RemoveInventoryItem(localID, itemID);
1005 part.SendPropertiesToClient(remoteClient);
1006 } 1013 }
1007 1014
1008 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) 1015 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
@@ -1213,6 +1220,10 @@ namespace OpenSim.Region.Framework.Scenes
1213 if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)) 1220 if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
1214 return; 1221 return;
1215 1222
1223 bool overrideNoMod = false;
1224 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0)
1225 overrideNoMod = true;
1226
1216 if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0) 1227 if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
1217 { 1228 {
1218 // object cannot copy items to an object owned by a different owner 1229 // object cannot copy items to an object owned by a different owner
@@ -1222,7 +1233,7 @@ namespace OpenSim.Region.Framework.Scenes
1222 } 1233 }
1223 1234
1224 // must have both move and modify permission to put an item in an object 1235 // must have both move and modify permission to put an item in an object
1225 if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0) 1236 if (((part.OwnerMask & (uint)PermissionMask.Modify) == 0) && (!overrideNoMod))
1226 { 1237 {
1227 return; 1238 return;
1228 } 1239 }
@@ -1281,6 +1292,14 @@ namespace OpenSim.Region.Framework.Scenes
1281 1292
1282 public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items) 1293 public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items)
1283 { 1294 {
1295 SceneObjectPart destPart = GetSceneObjectPart(destID);
1296 if (destPart != null) // Move into a prim
1297 {
1298 foreach(UUID itemID in items)
1299 MoveTaskInventoryItem(destID, host, itemID);
1300 return destID; // Prim folder ID == prim ID
1301 }
1302
1284 InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID); 1303 InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID);
1285 1304
1286 UUID newFolderID = UUID.Random(); 1305 UUID newFolderID = UUID.Random();
@@ -1460,13 +1479,6 @@ namespace OpenSim.Region.Framework.Scenes
1460 { 1479 {
1461 agentTransactions.HandleTaskItemUpdateFromTransaction( 1480 agentTransactions.HandleTaskItemUpdateFromTransaction(
1462 remoteClient, part, transactionID, currentItem); 1481 remoteClient, part, transactionID, currentItem);
1463
1464 if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
1465 remoteClient.SendAgentAlertMessage("Notecard saved", false);
1466 else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
1467 remoteClient.SendAgentAlertMessage("Script saved", false);
1468 else
1469 remoteClient.SendAgentAlertMessage("Item saved", false);
1470 } 1482 }
1471 1483
1472 // Base ALWAYS has move 1484 // Base ALWAYS has move
@@ -1607,7 +1619,7 @@ namespace OpenSim.Region.Framework.Scenes
1607 return; 1619 return;
1608 1620
1609 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, 1621 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType,
1610 Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"), 1622 Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n\n touch_start(integer num)\n {\n }\n}"),
1611 remoteClient.AgentId); 1623 remoteClient.AgentId);
1612 AssetService.Store(asset); 1624 AssetService.Store(asset);
1613 1625
@@ -1760,23 +1772,32 @@ namespace OpenSim.Region.Framework.Scenes
1760 // build a list of eligible objects 1772 // build a list of eligible objects
1761 List<uint> deleteIDs = new List<uint>(); 1773 List<uint> deleteIDs = new List<uint>();
1762 List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>(); 1774 List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
1763 1775 List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>();
1764 // Start with true for both, then remove the flags if objects
1765 // that we can't derez are part of the selection
1766 bool permissionToTake = true;
1767 bool permissionToTakeCopy = true;
1768 bool permissionToDelete = true;
1769 1776
1770 foreach (uint localID in localIDs) 1777 foreach (uint localID in localIDs)
1771 { 1778 {
1779 // Start with true for both, then remove the flags if objects
1780 // that we can't derez are part of the selection
1781 bool permissionToTake = true;
1782 bool permissionToTakeCopy = true;
1783 bool permissionToDelete = true;
1784
1772 // Invalid id 1785 // Invalid id
1773 SceneObjectPart part = GetSceneObjectPart(localID); 1786 SceneObjectPart part = GetSceneObjectPart(localID);
1774 if (part == null) 1787 if (part == null)
1788 {
1789 //Client still thinks the object exists, kill it
1790 deleteIDs.Add(localID);
1775 continue; 1791 continue;
1792 }
1776 1793
1777 // Already deleted by someone else 1794 // Already deleted by someone else
1778 if (part.ParentGroup.IsDeleted) 1795 if (part.ParentGroup.IsDeleted)
1796 {
1797 //Client still thinks the object exists, kill it
1798 deleteIDs.Add(localID);
1779 continue; 1799 continue;
1800 }
1780 1801
1781 // Can't delete child prims 1802 // Can't delete child prims
1782 if (part != part.ParentGroup.RootPart) 1803 if (part != part.ParentGroup.RootPart)
@@ -1784,9 +1805,6 @@ namespace OpenSim.Region.Framework.Scenes
1784 1805
1785 SceneObjectGroup grp = part.ParentGroup; 1806 SceneObjectGroup grp = part.ParentGroup;
1786 1807
1787 deleteIDs.Add(localID);
1788 deleteGroups.Add(grp);
1789
1790 if (remoteClient == null) 1808 if (remoteClient == null)
1791 { 1809 {
1792 // Autoreturn has a null client. Nothing else does. So 1810 // Autoreturn has a null client. Nothing else does. So
@@ -1803,81 +1821,193 @@ namespace OpenSim.Region.Framework.Scenes
1803 } 1821 }
1804 else 1822 else
1805 { 1823 {
1806 if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) 1824 if (action == DeRezAction.TakeCopy)
1825 {
1826 if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId))
1827 permissionToTakeCopy = false;
1828 }
1829 else
1830 {
1807 permissionToTakeCopy = false; 1831 permissionToTakeCopy = false;
1808 1832 }
1809 if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) 1833 if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId))
1810 permissionToTake = false; 1834 permissionToTake = false;
1811 1835
1812 if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) 1836 if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId))
1813 permissionToDelete = false; 1837 permissionToDelete = false;
1814 } 1838 }
1815 }
1816 1839
1817 // Handle god perms 1840 // Handle god perms
1818 if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) 1841 if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
1819 { 1842 {
1820 permissionToTake = true; 1843 permissionToTake = true;
1821 permissionToTakeCopy = true; 1844 permissionToTakeCopy = true;
1822 permissionToDelete = true; 1845 permissionToDelete = true;
1823 } 1846 }
1824 1847
1825 // If we're re-saving, we don't even want to delete 1848 // If we're re-saving, we don't even want to delete
1826 if (action == DeRezAction.SaveToExistingUserInventoryItem) 1849 if (action == DeRezAction.SaveToExistingUserInventoryItem)
1827 permissionToDelete = false; 1850 permissionToDelete = false;
1828 1851
1829 // if we want to take a copy, we also don't want to delete 1852 // if we want to take a copy, we also don't want to delete
1830 // Note: after this point, the permissionToTakeCopy flag 1853 // Note: after this point, the permissionToTakeCopy flag
1831 // becomes irrelevant. It already includes the permissionToTake 1854 // becomes irrelevant. It already includes the permissionToTake
1832 // permission and after excluding no copy items here, we can 1855 // permission and after excluding no copy items here, we can
1833 // just use that. 1856 // just use that.
1834 if (action == DeRezAction.TakeCopy) 1857 if (action == DeRezAction.TakeCopy)
1835 { 1858 {
1836 // If we don't have permission, stop right here 1859 // If we don't have permission, stop right here
1837 if (!permissionToTakeCopy) 1860 if (!permissionToTakeCopy)
1838 return; 1861 return;
1839 1862
1840 permissionToTake = true; 1863 permissionToTake = true;
1841 // Don't delete 1864 // Don't delete
1842 permissionToDelete = false; 1865 permissionToDelete = false;
1843 } 1866 }
1844 1867
1845 if (action == DeRezAction.Return) 1868 if (action == DeRezAction.Return)
1846 {
1847 if (remoteClient != null)
1848 { 1869 {
1849 if (Permissions.CanReturnObjects( 1870 if (remoteClient != null)
1850 null,
1851 remoteClient.AgentId,
1852 deleteGroups))
1853 { 1871 {
1854 permissionToTake = true; 1872 if (Permissions.CanReturnObjects(
1855 permissionToDelete = true; 1873 null,
1856 1874 remoteClient.AgentId,
1857 foreach (SceneObjectGroup g in deleteGroups) 1875 deleteGroups))
1858 { 1876 {
1859 AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); 1877 permissionToTake = true;
1878 permissionToDelete = true;
1879
1880 AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
1860 } 1881 }
1861 } 1882 }
1883 else // Auto return passes through here with null agent
1884 {
1885 permissionToTake = true;
1886 permissionToDelete = true;
1887 }
1862 } 1888 }
1863 else // Auto return passes through here with null agent 1889
1890 if (permissionToTake && (!permissionToDelete))
1891 takeGroups.Add(grp);
1892
1893 if (permissionToDelete)
1864 { 1894 {
1865 permissionToTake = true; 1895 if (permissionToTake)
1866 permissionToDelete = true; 1896 deleteGroups.Add(grp);
1897 deleteIDs.Add(grp.LocalId);
1867 } 1898 }
1868 } 1899 }
1869 1900
1870 if (permissionToTake) 1901 SendKillObject(deleteIDs);
1902
1903 if (deleteGroups.Count > 0)
1871 { 1904 {
1905 foreach (SceneObjectGroup g in deleteGroups)
1906 deleteIDs.Remove(g.LocalId);
1907
1872 m_asyncSceneObjectDeleter.DeleteToInventory( 1908 m_asyncSceneObjectDeleter.DeleteToInventory(
1873 action, destinationID, deleteGroups, remoteClient, 1909 action, destinationID, deleteGroups, remoteClient,
1874 permissionToDelete); 1910 true);
1875 } 1911 }
1876 else if (permissionToDelete) 1912 if (takeGroups.Count > 0)
1913 {
1914 m_asyncSceneObjectDeleter.DeleteToInventory(
1915 action, destinationID, takeGroups, remoteClient,
1916 false);
1917 }
1918 if (deleteIDs.Count > 0)
1877 { 1919 {
1878 foreach (SceneObjectGroup g in deleteGroups) 1920 foreach (SceneObjectGroup g in deleteGroups)
1879 DeleteSceneObject(g, false); 1921 DeleteSceneObject(g, true);
1922 }
1923 }
1924
1925 public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID)
1926 {
1927 itemID = UUID.Zero;
1928 if (grp != null)
1929 {
1930 Vector3 inventoryStoredPosition = new Vector3
1931 (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
1932 ? 250
1933 : grp.AbsolutePosition.X)
1934 ,
1935 (grp.AbsolutePosition.X > (int)Constants.RegionSize)
1936 ? 250
1937 : grp.AbsolutePosition.X,
1938 grp.AbsolutePosition.Z);
1939
1940 Vector3 originalPosition = grp.AbsolutePosition;
1941
1942 grp.AbsolutePosition = inventoryStoredPosition;
1943
1944 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
1945
1946 grp.AbsolutePosition = originalPosition;
1947
1948 AssetBase asset = CreateAsset(
1949 grp.GetPartName(grp.LocalId),
1950 grp.GetPartDescription(grp.LocalId),
1951 (sbyte)AssetType.Object,
1952 Utils.StringToBytes(sceneObjectXml),
1953 remoteClient.AgentId);
1954 AssetService.Store(asset);
1955
1956 InventoryItemBase item = new InventoryItemBase();
1957 item.CreatorId = grp.RootPart.CreatorID.ToString();
1958 item.CreatorData = grp.RootPart.CreatorData;
1959 item.Owner = remoteClient.AgentId;
1960 item.ID = UUID.Random();
1961 item.AssetID = asset.FullID;
1962 item.Description = asset.Description;
1963 item.Name = asset.Name;
1964 item.AssetType = asset.Type;
1965 item.InvType = (int)InventoryType.Object;
1966
1967 InventoryFolderBase folder = InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.Object);
1968 if (folder != null)
1969 item.Folder = folder.ID;
1970 else // oopsies
1971 item.Folder = UUID.Zero;
1972
1973 // Set up base perms properly
1974 uint permsBase = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify);
1975 permsBase &= grp.RootPart.BaseMask;
1976 permsBase |= (uint)PermissionMask.Move;
1977
1978 // Make sure we don't lock it
1979 grp.RootPart.NextOwnerMask |= (uint)PermissionMask.Move;
1980
1981 if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions())
1982 {
1983 item.BasePermissions = permsBase & grp.RootPart.NextOwnerMask;
1984 item.CurrentPermissions = permsBase & grp.RootPart.NextOwnerMask;
1985 item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask;
1986 item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
1987 item.GroupPermissions = permsBase & grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
1988 }
1989 else
1990 {
1991 item.BasePermissions = permsBase;
1992 item.CurrentPermissions = permsBase & grp.RootPart.OwnerMask;
1993 item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask;
1994 item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask;
1995 item.GroupPermissions = permsBase & grp.RootPart.GroupMask;
1996 }
1997 item.CreationDate = Util.UnixTimeSinceEpoch();
1998
1999 // sets itemID so client can show item as 'attached' in inventory
2000 grp.SetFromItemID(item.ID);
2001
2002 if (AddInventoryItem(item))
2003 remoteClient.SendInventoryItemCreateUpdate(item, 0);
2004 else
2005 m_dialogModule.SendAlertToUser(remoteClient, "Operation failed");
2006
2007 itemID = item.ID;
2008 return item.AssetID;
1880 } 2009 }
2010 return UUID.Zero;
1881 } 2011 }
1882 2012
1883 /// <summary> 2013 /// <summary>
@@ -2006,6 +2136,9 @@ namespace OpenSim.Region.Framework.Scenes
2006 2136
2007 public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running) 2137 public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running)
2008 { 2138 {
2139 if (!Permissions.CanEditScript(itemID, objectID, controllingClient.AgentId))
2140 return;
2141
2009 SceneObjectPart part = GetSceneObjectPart(objectID); 2142 SceneObjectPart part = GetSceneObjectPart(objectID);
2010 if (part == null) 2143 if (part == null)
2011 return; 2144 return;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 270e582..575079f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -374,7 +374,10 @@ namespace OpenSim.Region.Framework.Scenes
374 List<UserAccount> accounts = UserAccountService.GetUserAccounts(RegionInfo.ScopeID, query); 374 List<UserAccount> accounts = UserAccountService.GetUserAccounts(RegionInfo.ScopeID, query);
375 375
376 if (accounts == null) 376 if (accounts == null)
377 {
378 m_log.DebugFormat("[LLCIENT]: ProcessAvatarPickerRequest: returned null result");
377 return; 379 return;
380 }
378 381
379 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); 382 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
380 // TODO: don't create new blocks if recycling an old packet 383 // TODO: don't create new blocks if recycling an old packet
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index e1fedf4..48beb9c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -49,6 +49,7 @@ namespace OpenSim.Region.Framework.Scenes
49 public delegate bool DuplicateObjectHandler(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition); 49 public delegate bool DuplicateObjectHandler(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition);
50 public delegate bool EditObjectHandler(UUID objectID, UUID editorID, Scene scene); 50 public delegate bool EditObjectHandler(UUID objectID, UUID editorID, Scene scene);
51 public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID, Scene scene); 51 public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID, Scene scene);
52 public delegate bool ViewObjectInventoryHandler(UUID objectID, UUID editorID, Scene scene);
52 public delegate bool MoveObjectHandler(UUID objectID, UUID moverID, Scene scene); 53 public delegate bool MoveObjectHandler(UUID objectID, UUID moverID, Scene scene);
53 public delegate bool ObjectEntryHandler(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene); 54 public delegate bool ObjectEntryHandler(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene);
54 public delegate bool ReturnObjectsHandler(ILandObject land, UUID user, List<SceneObjectGroup> objects, Scene scene); 55 public delegate bool ReturnObjectsHandler(ILandObject land, UUID user, List<SceneObjectGroup> objects, Scene scene);
@@ -116,6 +117,7 @@ namespace OpenSim.Region.Framework.Scenes
116 public event DuplicateObjectHandler OnDuplicateObject; 117 public event DuplicateObjectHandler OnDuplicateObject;
117 public event EditObjectHandler OnEditObject; 118 public event EditObjectHandler OnEditObject;
118 public event EditObjectInventoryHandler OnEditObjectInventory; 119 public event EditObjectInventoryHandler OnEditObjectInventory;
120 public event ViewObjectInventoryHandler OnViewObjectInventory;
119 public event MoveObjectHandler OnMoveObject; 121 public event MoveObjectHandler OnMoveObject;
120 public event ObjectEntryHandler OnObjectEntry; 122 public event ObjectEntryHandler OnObjectEntry;
121 public event ReturnObjectsHandler OnReturnObjects; 123 public event ReturnObjectsHandler OnReturnObjects;
@@ -401,6 +403,21 @@ namespace OpenSim.Region.Framework.Scenes
401 return true; 403 return true;
402 } 404 }
403 405
406 public bool CanViewObjectInventory(UUID objectID, UUID editorID)
407 {
408 ViewObjectInventoryHandler handler = OnViewObjectInventory;
409 if (handler != null)
410 {
411 Delegate[] list = handler.GetInvocationList();
412 foreach (ViewObjectInventoryHandler h in list)
413 {
414 if (h(objectID, editorID, m_scene) == false)
415 return false;
416 }
417 }
418 return true;
419 }
420
404 #endregion 421 #endregion
405 422
406 #region MOVE OBJECT 423 #region MOVE OBJECT
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 302103a..0cb6681 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -97,6 +97,7 @@ namespace OpenSim.Region.Framework.Scenes
97 // TODO: need to figure out how allow client agents but deny 97 // TODO: need to figure out how allow client agents but deny
98 // root agents when ACL denies access to root agent 98 // root agents when ACL denies access to root agent
99 public bool m_strictAccessControl = true; 99 public bool m_strictAccessControl = true;
100 public bool m_seeIntoBannedRegion = false;
100 public int MaxUndoCount = 5; 101 public int MaxUndoCount = 5;
101 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 102 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
102 public bool LoginLock = false; 103 public bool LoginLock = false;
@@ -112,12 +113,14 @@ namespace OpenSim.Region.Framework.Scenes
112 113
113 protected int m_splitRegionID; 114 protected int m_splitRegionID;
114 protected Timer m_restartWaitTimer = new Timer(); 115 protected Timer m_restartWaitTimer = new Timer();
116 protected Timer m_timerWatchdog = new Timer();
115 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 117 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
116 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 118 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
117 protected string m_simulatorVersion = "OpenSimulator Server"; 119 protected string m_simulatorVersion = "OpenSimulator Server";
118 protected ModuleLoader m_moduleLoader; 120 protected ModuleLoader m_moduleLoader;
119 protected AgentCircuitManager m_authenticateHandler; 121 protected AgentCircuitManager m_authenticateHandler;
120 protected SceneCommunicationService m_sceneGridService; 122 protected SceneCommunicationService m_sceneGridService;
123 protected ISnmpModule m_snmpService = null;
121 124
122 protected ISimulationDataService m_SimulationDataService; 125 protected ISimulationDataService m_SimulationDataService;
123 protected IEstateDataService m_EstateDataService; 126 protected IEstateDataService m_EstateDataService;
@@ -169,7 +172,7 @@ namespace OpenSim.Region.Framework.Scenes
169 private int m_update_events = 1; 172 private int m_update_events = 1;
170 private int m_update_backup = 200; 173 private int m_update_backup = 200;
171 private int m_update_terrain = 50; 174 private int m_update_terrain = 50;
172// private int m_update_land = 1; 175 private int m_update_land = 10;
173 private int m_update_coarse_locations = 50; 176 private int m_update_coarse_locations = 50;
174 177
175 private int agentMS; 178 private int agentMS;
@@ -184,6 +187,7 @@ namespace OpenSim.Region.Framework.Scenes
184 private int landMS; 187 private int landMS;
185 private int lastCompletedFrame; 188 private int lastCompletedFrame;
186 189
190 public bool CombineRegions = false;
187 /// <summary> 191 /// <summary>
188 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 192 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
189 /// asynchronously from the update loop. 193 /// asynchronously from the update loop.
@@ -206,10 +210,12 @@ namespace OpenSim.Region.Framework.Scenes
206 private bool m_scripts_enabled = true; 210 private bool m_scripts_enabled = true;
207 private string m_defaultScriptEngine; 211 private string m_defaultScriptEngine;
208 private int m_LastLogin; 212 private int m_LastLogin;
209 private Thread HeartbeatThread; 213 private Thread HeartbeatThread = null;
210 private volatile bool shuttingdown; 214 private volatile bool shuttingdown;
211 215
212 private int m_lastUpdate; 216 private int m_lastUpdate;
217 private int m_lastIncoming;
218 private int m_lastOutgoing;
213 private bool m_firstHeartbeat = true; 219 private bool m_firstHeartbeat = true;
214 220
215 private object m_deleting_scene_object = new object(); 221 private object m_deleting_scene_object = new object();
@@ -257,6 +263,19 @@ namespace OpenSim.Region.Framework.Scenes
257 get { return m_sceneGridService; } 263 get { return m_sceneGridService; }
258 } 264 }
259 265
266 public ISnmpModule SnmpService
267 {
268 get
269 {
270 if (m_snmpService == null)
271 {
272 m_snmpService = RequestModuleInterface<ISnmpModule>();
273 }
274
275 return m_snmpService;
276 }
277 }
278
260 public ISimulationDataService SimulationDataService 279 public ISimulationDataService SimulationDataService
261 { 280 {
262 get 281 get
@@ -549,6 +568,9 @@ namespace OpenSim.Region.Framework.Scenes
549 m_EstateDataService = estateDataService; 568 m_EstateDataService = estateDataService;
550 m_regionHandle = m_regInfo.RegionHandle; 569 m_regionHandle = m_regInfo.RegionHandle;
551 m_regionName = m_regInfo.RegionName; 570 m_regionName = m_regInfo.RegionName;
571 m_lastUpdate = Util.EnvironmentTickCount();
572 m_lastIncoming = 0;
573 m_lastOutgoing = 0;
552 574
553 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); 575 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
554 m_asyncSceneObjectDeleter.Enabled = true; 576 m_asyncSceneObjectDeleter.Enabled = true;
@@ -670,11 +692,13 @@ namespace OpenSim.Region.Framework.Scenes
670 //Animation states 692 //Animation states
671 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 693 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
672 // TODO: Change default to true once the feature is supported 694 // TODO: Change default to true once the feature is supported
673 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 695 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
674 696
675 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true); 697 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true);
676 698
677 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 699 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
700
701 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
678 if (RegionInfo.NonphysPrimMax > 0) 702 if (RegionInfo.NonphysPrimMax > 0)
679 { 703 {
680 m_maxNonphys = RegionInfo.NonphysPrimMax; 704 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -707,6 +731,7 @@ namespace OpenSim.Region.Framework.Scenes
707 m_persistAfter *= 10000000; 731 m_persistAfter *= 10000000;
708 732
709 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 733 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
734 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
710 735
711 IConfig packetConfig = m_config.Configs["PacketPool"]; 736 IConfig packetConfig = m_config.Configs["PacketPool"];
712 if (packetConfig != null) 737 if (packetConfig != null)
@@ -716,6 +741,8 @@ namespace OpenSim.Region.Framework.Scenes
716 } 741 }
717 742
718 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 743 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
744 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
745 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
719 746
720 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 747 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
721 if (m_generateMaptiles) 748 if (m_generateMaptiles)
@@ -751,9 +778,9 @@ namespace OpenSim.Region.Framework.Scenes
751 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 778 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
752 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 779 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
753 } 780 }
754 catch 781 catch (Exception e)
755 { 782 {
756 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 783 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
757 } 784 }
758 785
759 #endregion Region Config 786 #endregion Region Config
@@ -1164,7 +1191,9 @@ namespace OpenSim.Region.Framework.Scenes
1164 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1191 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1165 if (HeartbeatThread != null) 1192 if (HeartbeatThread != null)
1166 { 1193 {
1194 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1167 HeartbeatThread.Abort(); 1195 HeartbeatThread.Abort();
1196 Watchdog.AbortThread(HeartbeatThread.ManagedThreadId);
1168 HeartbeatThread = null; 1197 HeartbeatThread = null;
1169 } 1198 }
1170 m_lastUpdate = Util.EnvironmentTickCount(); 1199 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1207,9 +1236,6 @@ namespace OpenSim.Region.Framework.Scenes
1207 { 1236 {
1208 while (!shuttingdown) 1237 while (!shuttingdown)
1209 Update(); 1238 Update();
1210
1211 m_lastUpdate = Util.EnvironmentTickCount();
1212 m_firstHeartbeat = false;
1213 } 1239 }
1214 catch (ThreadAbortException) 1240 catch (ThreadAbortException)
1215 { 1241 {
@@ -1309,6 +1335,13 @@ namespace OpenSim.Region.Framework.Scenes
1309 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1335 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1310 } 1336 }
1311 1337
1338 // if (Frame % m_update_land == 0)
1339 // {
1340 // int ldMS = Util.EnvironmentTickCount();
1341 // UpdateLand();
1342 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1343 // }
1344
1312 if (Frame % m_update_backup == 0) 1345 if (Frame % m_update_backup == 0)
1313 { 1346 {
1314 int backMS = Util.EnvironmentTickCount(); 1347 int backMS = Util.EnvironmentTickCount();
@@ -1410,12 +1443,16 @@ namespace OpenSim.Region.Framework.Scenes
1410 maintc = Util.EnvironmentTickCountSubtract(maintc); 1443 maintc = Util.EnvironmentTickCountSubtract(maintc);
1411 maintc = (int)(MinFrameTime * 1000) - maintc; 1444 maintc = (int)(MinFrameTime * 1000) - maintc;
1412 1445
1446
1447 m_lastUpdate = Util.EnvironmentTickCount();
1448 m_firstHeartbeat = false;
1449
1413 if (maintc > 0) 1450 if (maintc > 0)
1414 Thread.Sleep(maintc); 1451 Thread.Sleep(maintc);
1415 1452
1416 // Tell the watchdog that this thread is still alive 1453 // Tell the watchdog that this thread is still alive
1417 Watchdog.UpdateThread(); 1454 Watchdog.UpdateThread();
1418 } 1455 }
1419 1456
1420 public void AddGroupTarget(SceneObjectGroup grp) 1457 public void AddGroupTarget(SceneObjectGroup grp)
1421 { 1458 {
@@ -1431,9 +1468,9 @@ namespace OpenSim.Region.Framework.Scenes
1431 1468
1432 private void CheckAtTargets() 1469 private void CheckAtTargets()
1433 { 1470 {
1434 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1471 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1435 lock (m_groupsWithTargets) 1472 lock (m_groupsWithTargets)
1436 objs = m_groupsWithTargets.Values; 1473 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1437 1474
1438 foreach (SceneObjectGroup entry in objs) 1475 foreach (SceneObjectGroup entry in objs)
1439 entry.checkAtTargets(); 1476 entry.checkAtTargets();
@@ -1752,14 +1789,24 @@ namespace OpenSim.Region.Framework.Scenes
1752 /// <returns></returns> 1789 /// <returns></returns>
1753 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1790 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1754 { 1791 {
1792
1793 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1794 Vector3 wpos = Vector3.Zero;
1795 // Check for water surface intersection from above
1796 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1797 {
1798 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1799 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1800 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1801 wpos.Z = wheight;
1802 }
1803
1755 Vector3 pos = Vector3.Zero; 1804 Vector3 pos = Vector3.Zero;
1756 if (RayEndIsIntersection == (byte)1) 1805 if (RayEndIsIntersection == (byte)1)
1757 { 1806 {
1758 pos = RayEnd; 1807 pos = RayEnd;
1759 return pos;
1760 } 1808 }
1761 1809 else if (RayTargetID != UUID.Zero)
1762 if (RayTargetID != UUID.Zero)
1763 { 1810 {
1764 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1811 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1765 1812
@@ -1781,7 +1828,7 @@ namespace OpenSim.Region.Framework.Scenes
1781 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1828 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1782 1829
1783 // Un-comment out the following line to Get Raytrace results printed to the console. 1830 // Un-comment out the following line to Get Raytrace results printed to the console.
1784 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1831 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1785 float ScaleOffset = 0.5f; 1832 float ScaleOffset = 0.5f;
1786 1833
1787 // If we hit something 1834 // If we hit something
@@ -1804,13 +1851,10 @@ namespace OpenSim.Region.Framework.Scenes
1804 //pos.Z -= 0.25F; 1851 //pos.Z -= 0.25F;
1805 1852
1806 } 1853 }
1807
1808 return pos;
1809 } 1854 }
1810 else 1855 else
1811 { 1856 {
1812 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1857 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1813
1814 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1858 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1815 1859
1816 // Un-comment the following line to print the raytrace results to the console. 1860 // Un-comment the following line to print the raytrace results to the console.
@@ -1819,13 +1863,12 @@ namespace OpenSim.Region.Framework.Scenes
1819 if (ei.HitTF) 1863 if (ei.HitTF)
1820 { 1864 {
1821 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1865 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1822 } else 1866 }
1867 else
1823 { 1868 {
1824 // fall back to our stupid functionality 1869 // fall back to our stupid functionality
1825 pos = RayEnd; 1870 pos = RayEnd;
1826 } 1871 }
1827
1828 return pos;
1829 } 1872 }
1830 } 1873 }
1831 else 1874 else
@@ -1836,8 +1879,12 @@ namespace OpenSim.Region.Framework.Scenes
1836 //increase height so its above the ground. 1879 //increase height so its above the ground.
1837 //should be getting the normal of the ground at the rez point and using that? 1880 //should be getting the normal of the ground at the rez point and using that?
1838 pos.Z += scale.Z / 2f; 1881 pos.Z += scale.Z / 2f;
1839 return pos; 1882// return pos;
1840 } 1883 }
1884
1885 // check against posible water intercept
1886 if (wpos.Z > pos.Z) pos = wpos;
1887 return pos;
1841 } 1888 }
1842 1889
1843 1890
@@ -1921,7 +1968,10 @@ namespace OpenSim.Region.Framework.Scenes
1921 public bool AddRestoredSceneObject( 1968 public bool AddRestoredSceneObject(
1922 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1969 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1923 { 1970 {
1924 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1971 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1972 if (result)
1973 sceneObject.IsDeleted = false;
1974 return result;
1925 } 1975 }
1926 1976
1927 /// <summary> 1977 /// <summary>
@@ -2011,6 +2061,15 @@ namespace OpenSim.Region.Framework.Scenes
2011 /// </summary> 2061 /// </summary>
2012 public void DeleteAllSceneObjects() 2062 public void DeleteAllSceneObjects()
2013 { 2063 {
2064 DeleteAllSceneObjects(false);
2065 }
2066
2067 /// <summary>
2068 /// Delete every object from the scene. This does not include attachments worn by avatars.
2069 /// </summary>
2070 public void DeleteAllSceneObjects(bool exceptNoCopy)
2071 {
2072 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
2014 lock (Entities) 2073 lock (Entities)
2015 { 2074 {
2016 EntityBase[] entities = Entities.GetEntities(); 2075 EntityBase[] entities = Entities.GetEntities();
@@ -2019,11 +2078,24 @@ namespace OpenSim.Region.Framework.Scenes
2019 if (e is SceneObjectGroup) 2078 if (e is SceneObjectGroup)
2020 { 2079 {
2021 SceneObjectGroup sog = (SceneObjectGroup)e; 2080 SceneObjectGroup sog = (SceneObjectGroup)e;
2022 if (!sog.IsAttachment) 2081 if (sog != null && !sog.IsAttachment)
2023 DeleteSceneObject((SceneObjectGroup)e, false); 2082 {
2083 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2084 {
2085 DeleteSceneObject((SceneObjectGroup)e, false);
2086 }
2087 else
2088 {
2089 toReturn.Add((SceneObjectGroup)e);
2090 }
2091 }
2024 } 2092 }
2025 } 2093 }
2026 } 2094 }
2095 if (toReturn.Count > 0)
2096 {
2097 returnObjects(toReturn.ToArray(), UUID.Zero);
2098 }
2027 } 2099 }
2028 2100
2029 /// <summary> 2101 /// <summary>
@@ -2071,6 +2143,8 @@ namespace OpenSim.Region.Framework.Scenes
2071 } 2143 }
2072 2144
2073 group.DeleteGroupFromScene(silent); 2145 group.DeleteGroupFromScene(silent);
2146 if (!silent)
2147 SendKillObject(new List<uint>() { group.LocalId });
2074 2148
2075// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2149// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2076 } 2150 }
@@ -2425,10 +2499,17 @@ namespace OpenSim.Region.Framework.Scenes
2425 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2499 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2426 public bool AddSceneObject(SceneObjectGroup sceneObject) 2500 public bool AddSceneObject(SceneObjectGroup sceneObject)
2427 { 2501 {
2502 if (sceneObject.OwnerID == UUID.Zero)
2503 {
2504 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2505 return false;
2506 }
2507
2428 // If the user is banned, we won't let any of their objects 2508 // If the user is banned, we won't let any of their objects
2429 // enter. Period. 2509 // enter. Period.
2430 // 2510 //
2431 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2511 int flags = GetUserFlags(sceneObject.OwnerID);
2512 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2432 { 2513 {
2433 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2514 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2434 "banned avatar"); 2515 "banned avatar");
@@ -2475,12 +2556,23 @@ namespace OpenSim.Region.Framework.Scenes
2475 } 2556 }
2476 else 2557 else
2477 { 2558 {
2559 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2478 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2560 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2479 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2561 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2480 } 2562 }
2563 if (sceneObject.OwnerID == UUID.Zero)
2564 {
2565 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2566 return false;
2567 }
2481 } 2568 }
2482 else 2569 else
2483 { 2570 {
2571 if (sceneObject.OwnerID == UUID.Zero)
2572 {
2573 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2574 return false;
2575 }
2484 AddRestoredSceneObject(sceneObject, true, false); 2576 AddRestoredSceneObject(sceneObject, true, false);
2485 2577
2486 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2578 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2510,6 +2602,24 @@ namespace OpenSim.Region.Framework.Scenes
2510 return 2; // StateSource.PrimCrossing 2602 return 2; // StateSource.PrimCrossing
2511 } 2603 }
2512 2604
2605 public int GetUserFlags(UUID user)
2606 {
2607 //Unfortunately the SP approach means that the value is cached until region is restarted
2608 /*
2609 ScenePresence sp;
2610 if (TryGetScenePresence(user, out sp))
2611 {
2612 return sp.UserFlags;
2613 }
2614 else
2615 {
2616 */
2617 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2618 if (uac == null)
2619 return 0;
2620 return uac.UserFlags;
2621 //}
2622 }
2513 #endregion 2623 #endregion
2514 2624
2515 #region Add/Remove Avatar Methods 2625 #region Add/Remove Avatar Methods
@@ -2531,6 +2641,7 @@ namespace OpenSim.Region.Framework.Scenes
2531 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2641 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2532 2642
2533 CheckHeartbeat(); 2643 CheckHeartbeat();
2644 ScenePresence presence;
2534 2645
2535 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2646 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2536 { 2647 {
@@ -2566,7 +2677,14 @@ namespace OpenSim.Region.Framework.Scenes
2566 2677
2567 EventManager.TriggerOnNewClient(client); 2678 EventManager.TriggerOnNewClient(client);
2568 if (vialogin) 2679 if (vialogin)
2680 {
2569 EventManager.TriggerOnClientLogin(client); 2681 EventManager.TriggerOnClientLogin(client);
2682
2683 // Send initial parcel data
2684 Vector3 pos = createdSp.AbsolutePosition;
2685 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2686 land.SendLandUpdateToClient(client);
2687 }
2570 } 2688 }
2571 } 2689 }
2572 2690
@@ -2655,19 +2773,12 @@ namespace OpenSim.Region.Framework.Scenes
2655 // and the scene presence and the client, if they exist 2773 // and the scene presence and the client, if they exist
2656 try 2774 try
2657 { 2775 {
2658 // We need to wait for the client to make UDP contact first. 2776 ScenePresence sp = GetScenePresence(agentID);
2659 // It's the UDP contact that creates the scene presence 2777 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2660 ScenePresence sp = WaitGetScenePresence(agentID); 2778
2661 if (sp != null) 2779 if (sp != null)
2662 {
2663 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2664
2665 sp.ControllingClient.Close(); 2780 sp.ControllingClient.Close();
2666 } 2781
2667 else
2668 {
2669 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2670 }
2671 // BANG! SLASH! 2782 // BANG! SLASH!
2672 m_authenticateHandler.RemoveCircuit(agentID); 2783 m_authenticateHandler.RemoveCircuit(agentID);
2673 2784
@@ -2767,6 +2878,7 @@ namespace OpenSim.Region.Framework.Scenes
2767 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2878 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2768 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2879 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2769 client.OnCopyInventoryItem += CopyInventoryItem; 2880 client.OnCopyInventoryItem += CopyInventoryItem;
2881 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2770 client.OnMoveInventoryItem += MoveInventoryItem; 2882 client.OnMoveInventoryItem += MoveInventoryItem;
2771 client.OnRemoveInventoryItem += RemoveInventoryItem; 2883 client.OnRemoveInventoryItem += RemoveInventoryItem;
2772 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2884 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2944,15 +3056,16 @@ namespace OpenSim.Region.Framework.Scenes
2944 /// </summary> 3056 /// </summary>
2945 /// <param name="agentId">The avatar's Unique ID</param> 3057 /// <param name="agentId">The avatar's Unique ID</param>
2946 /// <param name="client">The IClientAPI for the client</param> 3058 /// <param name="client">The IClientAPI for the client</param>
2947 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3059 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2948 { 3060 {
2949 if (m_teleportModule != null) 3061 if (m_teleportModule != null)
2950 m_teleportModule.TeleportHome(agentId, client); 3062 return m_teleportModule.TeleportHome(agentId, client);
2951 else 3063 else
2952 { 3064 {
2953 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3065 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2954 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3066 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2955 } 3067 }
3068 return false;
2956 } 3069 }
2957 3070
2958 /// <summary> 3071 /// <summary>
@@ -3044,6 +3157,16 @@ namespace OpenSim.Region.Framework.Scenes
3044 /// <param name="flags"></param> 3157 /// <param name="flags"></param>
3045 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3158 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3046 { 3159 {
3160 //Add half the avatar's height so that the user doesn't fall through prims
3161 ScenePresence presence;
3162 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3163 {
3164 if (presence.Appearance != null)
3165 {
3166 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3167 }
3168 }
3169
3047 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3170 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3048 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3171 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3049 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3172 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3112,8 +3235,9 @@ namespace OpenSim.Region.Framework.Scenes
3112 regions.Remove(RegionInfo.RegionHandle); 3235 regions.Remove(RegionInfo.RegionHandle);
3113 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3236 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3114 } 3237 }
3115 3238 m_log.Debug("[Scene] Beginning ClientClosed");
3116 m_eventManager.TriggerClientClosed(agentID, this); 3239 m_eventManager.TriggerClientClosed(agentID, this);
3240 m_log.Debug("[Scene] Finished ClientClosed");
3117 } 3241 }
3118 catch (NullReferenceException) 3242 catch (NullReferenceException)
3119 { 3243 {
@@ -3121,7 +3245,12 @@ namespace OpenSim.Region.Framework.Scenes
3121 // Avatar is already disposed :/ 3245 // Avatar is already disposed :/
3122 } 3246 }
3123 3247
3248 m_log.Debug("[Scene] Beginning OnRemovePresence");
3124 m_eventManager.TriggerOnRemovePresence(agentID); 3249 m_eventManager.TriggerOnRemovePresence(agentID);
3250 m_log.Debug("[Scene] Finished OnRemovePresence");
3251
3252 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3253 AttachmentsModule.SaveChangedAttachments(avatar);
3125 3254
3126 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3255 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3127 AttachmentsModule.SaveChangedAttachments(avatar); 3256 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3130,7 +3259,7 @@ namespace OpenSim.Region.Framework.Scenes
3130 delegate(IClientAPI client) 3259 delegate(IClientAPI client)
3131 { 3260 {
3132 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3261 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3133 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3262 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3134 catch (NullReferenceException) { } 3263 catch (NullReferenceException) { }
3135 }); 3264 });
3136 3265
@@ -3141,8 +3270,11 @@ namespace OpenSim.Region.Framework.Scenes
3141 } 3270 }
3142 3271
3143 // Remove the avatar from the scene 3272 // Remove the avatar from the scene
3273 m_log.Debug("[Scene] Begin RemoveScenePresence");
3144 m_sceneGraph.RemoveScenePresence(agentID); 3274 m_sceneGraph.RemoveScenePresence(agentID);
3275 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3145 m_clientManager.Remove(agentID); 3276 m_clientManager.Remove(agentID);
3277 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3146 3278
3147 try 3279 try
3148 { 3280 {
@@ -3156,9 +3288,10 @@ namespace OpenSim.Region.Framework.Scenes
3156 { 3288 {
3157 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3289 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3158 } 3290 }
3159 3291 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3160 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3292 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3161// CleanDroppedAttachments(); 3293// CleanDroppedAttachments();
3294 m_log.Debug("[Scene] The avatar has left the building");
3162 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3295 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3163 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3296 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3164 } 3297 }
@@ -3189,19 +3322,24 @@ namespace OpenSim.Region.Framework.Scenes
3189 3322
3190 #region Entities 3323 #region Entities
3191 3324
3192 public void SendKillObject(uint localID) 3325 public void SendKillObject(List<uint> localIDs)
3193 { 3326 {
3194 SceneObjectPart part = GetSceneObjectPart(localID); 3327 List<uint> deleteIDs = new List<uint>();
3195 if (part != null) // It is a prim 3328
3329 foreach (uint localID in localIDs)
3196 { 3330 {
3197 if (!part.ParentGroup.IsDeleted) // Valid 3331 SceneObjectPart part = GetSceneObjectPart(localID);
3332 if (part != null) // It is a prim
3198 { 3333 {
3199 if (part.ParentGroup.RootPart != part) // Child part 3334 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3200 return; 3335 {
3336 if (part.ParentGroup.RootPart != part) // Child part
3337 continue;
3338 }
3201 } 3339 }
3340 deleteIDs.Add(localID);
3202 } 3341 }
3203 3342 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3204 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3205 } 3343 }
3206 3344
3207 #endregion 3345 #endregion
@@ -3219,7 +3357,6 @@ namespace OpenSim.Region.Framework.Scenes
3219 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3357 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3220 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3358 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3221 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3359 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3222 m_sceneGridService.KiPrimitive += SendKillObject;
3223 m_sceneGridService.OnGetLandData += GetLandData; 3360 m_sceneGridService.OnGetLandData += GetLandData;
3224 } 3361 }
3225 3362
@@ -3228,7 +3365,6 @@ namespace OpenSim.Region.Framework.Scenes
3228 /// </summary> 3365 /// </summary>
3229 public void UnRegisterRegionWithComms() 3366 public void UnRegisterRegionWithComms()
3230 { 3367 {
3231 m_sceneGridService.KiPrimitive -= SendKillObject;
3232 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3368 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3233 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3369 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3234 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3370 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3308,13 +3444,16 @@ namespace OpenSim.Region.Framework.Scenes
3308 sp = null; 3444 sp = null;
3309 } 3445 }
3310 3446
3311 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3312 3447
3313 //On login test land permisions 3448 //On login test land permisions
3314 if (vialogin) 3449 if (vialogin)
3315 { 3450 {
3316 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3451 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3452 if (cache != null)
3453 cache.Remove(agent.firstname + " " + agent.lastname);
3454 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3317 { 3455 {
3456 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3318 return false; 3457 return false;
3319 } 3458 }
3320 } 3459 }
@@ -3337,8 +3476,13 @@ namespace OpenSim.Region.Framework.Scenes
3337 3476
3338 try 3477 try
3339 { 3478 {
3340 if (!AuthorizeUser(agent, out reason)) 3479 // Always check estate if this is a login. Always
3341 return false; 3480 // check if banned regions are to be blacked out.
3481 if (vialogin || (!m_seeIntoBannedRegion))
3482 {
3483 if (!AuthorizeUser(agent, out reason))
3484 return false;
3485 }
3342 } 3486 }
3343 catch (Exception e) 3487 catch (Exception e)
3344 { 3488 {
@@ -3440,6 +3584,8 @@ namespace OpenSim.Region.Framework.Scenes
3440 } 3584 }
3441 } 3585 }
3442 // Honor parcel landing type and position. 3586 // Honor parcel landing type and position.
3587 /*
3588 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3443 if (land != null) 3589 if (land != null)
3444 { 3590 {
3445 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3591 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3447,26 +3593,34 @@ namespace OpenSim.Region.Framework.Scenes
3447 agent.startpos = land.LandData.UserLocation; 3593 agent.startpos = land.LandData.UserLocation;
3448 } 3594 }
3449 } 3595 }
3596 */// This is now handled properly in ScenePresence.MakeRootAgent
3450 } 3597 }
3451 3598
3452 return true; 3599 return true;
3453 } 3600 }
3454 3601
3455 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3602 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3456 { 3603 {
3457 3604 reason = String.Empty;
3458 bool banned = land.IsBannedFromLand(agent.AgentID); 3605 if (Permissions.IsGod(agentID))
3459 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3606 return true;
3607
3608 ILandObject land = LandChannel.GetLandObject(posX, posY);
3609 if (land == null)
3610 return false;
3611
3612 bool banned = land.IsBannedFromLand(agentID);
3613 bool restricted = land.IsRestrictedFromLand(agentID);
3460 3614
3461 if (banned || restricted) 3615 if (banned || restricted)
3462 { 3616 {
3463 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3617 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3464 if (nearestParcel != null) 3618 if (nearestParcel != null)
3465 { 3619 {
3466 //Move agent to nearest allowed 3620 //Move agent to nearest allowed
3467 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3621 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3468 agent.startpos.X = newPosition.X; 3622 posX = newPosition.X;
3469 agent.startpos.Y = newPosition.Y; 3623 posY = newPosition.Y;
3470 } 3624 }
3471 else 3625 else
3472 { 3626 {
@@ -3528,7 +3682,7 @@ namespace OpenSim.Region.Framework.Scenes
3528 3682
3529 if (!m_strictAccessControl) return true; 3683 if (!m_strictAccessControl) return true;
3530 if (Permissions.IsGod(agent.AgentID)) return true; 3684 if (Permissions.IsGod(agent.AgentID)) return true;
3531 3685
3532 if (AuthorizationService != null) 3686 if (AuthorizationService != null)
3533 { 3687 {
3534 if (!AuthorizationService.IsAuthorizedForRegion( 3688 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3536,14 +3690,14 @@ namespace OpenSim.Region.Framework.Scenes
3536 { 3690 {
3537 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3691 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3538 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3692 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3539 3693
3540 return false; 3694 return false;
3541 } 3695 }
3542 } 3696 }
3543 3697
3544 if (m_regInfo.EstateSettings != null) 3698 if (m_regInfo.EstateSettings != null)
3545 { 3699 {
3546 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3700 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3547 { 3701 {
3548 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3702 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3549 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3703 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3733,6 +3887,13 @@ namespace OpenSim.Region.Framework.Scenes
3733 3887
3734 // We have to wait until the viewer contacts this region after receiving EAC. 3888 // We have to wait until the viewer contacts this region after receiving EAC.
3735 // That calls AddNewClient, which finally creates the ScenePresence 3889 // That calls AddNewClient, which finally creates the ScenePresence
3890 int flags = GetUserFlags(cAgentData.AgentID);
3891 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3892 {
3893 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3894 return false;
3895 }
3896
3736 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3897 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3737 if (nearestParcel == null) 3898 if (nearestParcel == null)
3738 { 3899 {
@@ -3748,7 +3909,6 @@ namespace OpenSim.Region.Framework.Scenes
3748 return false; 3909 return false;
3749 } 3910 }
3750 3911
3751
3752 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3912 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3753 3913
3754 if (childAgentUpdate != null) 3914 if (childAgentUpdate != null)
@@ -3815,12 +3975,22 @@ namespace OpenSim.Region.Framework.Scenes
3815 return false; 3975 return false;
3816 } 3976 }
3817 3977
3978 public bool IncomingCloseAgent(UUID agentID)
3979 {
3980 return IncomingCloseAgent(agentID, false);
3981 }
3982
3983 public bool IncomingCloseChildAgent(UUID agentID)
3984 {
3985 return IncomingCloseAgent(agentID, true);
3986 }
3987
3818 /// <summary> 3988 /// <summary>
3819 /// Tell a single agent to disconnect from the region. 3989 /// Tell a single agent to disconnect from the region.
3820 /// </summary> 3990 /// </summary>
3821 /// <param name="regionHandle"></param>
3822 /// <param name="agentID"></param> 3991 /// <param name="agentID"></param>
3823 public bool IncomingCloseAgent(UUID agentID) 3992 /// <param name="childOnly"></param>
3993 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3824 { 3994 {
3825 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3995 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3826 3996
@@ -3832,7 +4002,7 @@ namespace OpenSim.Region.Framework.Scenes
3832 { 4002 {
3833 m_sceneGraph.removeUserCount(false); 4003 m_sceneGraph.removeUserCount(false);
3834 } 4004 }
3835 else 4005 else if (!childOnly)
3836 { 4006 {
3837 m_sceneGraph.removeUserCount(true); 4007 m_sceneGraph.removeUserCount(true);
3838 } 4008 }
@@ -3848,9 +4018,12 @@ namespace OpenSim.Region.Framework.Scenes
3848 } 4018 }
3849 else 4019 else
3850 presence.ControllingClient.SendShutdownConnectionNotice(); 4020 presence.ControllingClient.SendShutdownConnectionNotice();
4021 presence.ControllingClient.Close(false);
4022 }
4023 else if (!childOnly)
4024 {
4025 presence.ControllingClient.Close(true);
3851 } 4026 }
3852
3853 presence.ControllingClient.Close();
3854 return true; 4027 return true;
3855 } 4028 }
3856 4029
@@ -4478,34 +4651,66 @@ namespace OpenSim.Region.Framework.Scenes
4478 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4651 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4479 } 4652 }
4480 4653
4481 public int GetHealth() 4654 public int GetHealth(out int flags, out string message)
4482 { 4655 {
4483 // Returns: 4656 // Returns:
4484 // 1 = sim is up and accepting http requests. The heartbeat has 4657 // 1 = sim is up and accepting http requests. The heartbeat has
4485 // stopped and the sim is probably locked up, but a remote 4658 // stopped and the sim is probably locked up, but a remote
4486 // admin restart may succeed 4659 // admin restart may succeed
4487 // 4660 //
4488 // 2 = Sim is up and the heartbeat is running. The sim is likely 4661 // 2 = Sim is up and the heartbeat is running. The sim is likely
4489 // usable for people within and logins _may_ work 4662 // usable for people within
4490 // 4663 //
4491 // 3 = We have seen a new user enter within the past 4 minutes 4664 // 3 = Sim is up and one packet thread is running. Sim is
4665 // unstable and will not accept new logins
4666 //
4667 // 4 = Sim is up and both packet threads are running. Sim is
4668 // likely usable
4669 //
4670 // 5 = We have seen a new user enter within the past 4 minutes
4492 // which can be seen as positive confirmation of sim health 4671 // which can be seen as positive confirmation of sim health
4493 // 4672 //
4673
4674 flags = 0;
4675 message = String.Empty;
4676
4677 CheckHeartbeat();
4678
4679 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4680 {
4681 // We're still starting
4682 // 0 means "in startup", it can't happen another way, since
4683 // to get here, we must be able to accept http connections
4684 return 0;
4685 }
4686
4494 int health=1; // Start at 1, means we're up 4687 int health=1; // Start at 1, means we're up
4495 4688
4496 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4689 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4690 {
4497 health+=1; 4691 health+=1;
4498 else 4692 flags |= 1;
4693 }
4694
4695 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4696 {
4697 health+=1;
4698 flags |= 2;
4699 }
4700
4701 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4702 {
4703 health+=1;
4704 flags |= 4;
4705 }
4706
4707 if (flags != 7)
4499 return health; 4708 return health;
4500 4709
4501 // A login in the last 4 mins? We can't be doing too badly 4710 // A login in the last 4 mins? We can't be doing too badly
4502 // 4711 //
4503 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4712 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4504 health++; 4713 health++;
4505 else
4506 return health;
4507
4508 CheckHeartbeat();
4509 4714
4510 return health; 4715 return health;
4511 } 4716 }
@@ -4698,7 +4903,7 @@ namespace OpenSim.Region.Framework.Scenes
4698 if (m_firstHeartbeat) 4903 if (m_firstHeartbeat)
4699 return; 4904 return;
4700 4905
4701 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4906 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4702 StartTimer(); 4907 StartTimer();
4703 } 4908 }
4704 4909
@@ -5112,6 +5317,54 @@ namespace OpenSim.Region.Framework.Scenes
5112 } 5317 }
5113 } 5318 }
5114 5319
5320// public void CleanDroppedAttachments()
5321// {
5322// List<SceneObjectGroup> objectsToDelete =
5323// new List<SceneObjectGroup>();
5324//
5325// lock (m_cleaningAttachments)
5326// {
5327// ForEachSOG(delegate (SceneObjectGroup grp)
5328// {
5329// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5330// {
5331// UUID agentID = grp.OwnerID;
5332// if (agentID == UUID.Zero)
5333// {
5334// objectsToDelete.Add(grp);
5335// return;
5336// }
5337//
5338// ScenePresence sp = GetScenePresence(agentID);
5339// if (sp == null)
5340// {
5341// objectsToDelete.Add(grp);
5342// return;
5343// }
5344// }
5345// });
5346// }
5347//
5348// foreach (SceneObjectGroup grp in objectsToDelete)
5349// {
5350// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5351// DeleteSceneObject(grp, true);
5352// }
5353// }
5354
5355 public void ThreadAlive(int threadCode)
5356 {
5357 switch(threadCode)
5358 {
5359 case 1: // Incoming
5360 m_lastIncoming = Util.EnvironmentTickCount();
5361 break;
5362 case 2: // Incoming
5363 m_lastOutgoing = Util.EnvironmentTickCount();
5364 break;
5365 }
5366 }
5367
5115 // This method is called across the simulation connector to 5368 // This method is called across the simulation connector to
5116 // determine if a given agent is allowed in this region 5369 // determine if a given agent is allowed in this region
5117 // AS A ROOT AGENT. Returning false here will prevent them 5370 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5120,6 +5373,14 @@ namespace OpenSim.Region.Framework.Scenes
5120 // child agent creation, thereby emulating the SL behavior. 5373 // child agent creation, thereby emulating the SL behavior.
5121 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5374 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5122 { 5375 {
5376 reason = "You are banned from the region";
5377
5378 if (Permissions.IsGod(agentID))
5379 {
5380 reason = String.Empty;
5381 return true;
5382 }
5383
5123 int num = m_sceneGraph.GetNumberOfScenePresences(); 5384 int num = m_sceneGraph.GetNumberOfScenePresences();
5124 5385
5125 if (num >= RegionInfo.RegionSettings.AgentLimit) 5386 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5131,11 +5392,82 @@ namespace OpenSim.Region.Framework.Scenes
5131 } 5392 }
5132 } 5393 }
5133 5394
5395 ScenePresence presence = GetScenePresence(agentID);
5396 IClientAPI client = null;
5397 AgentCircuitData aCircuit = null;
5398
5399 if (presence != null)
5400 {
5401 client = presence.ControllingClient;
5402 if (client != null)
5403 aCircuit = client.RequestClientInfo();
5404 }
5405
5406 // We may be called before there is a presence or a client.
5407 // Fake AgentCircuitData to keep IAuthorizationModule smiling
5408 if (client == null)
5409 {
5410 aCircuit = new AgentCircuitData();
5411 aCircuit.AgentID = agentID;
5412 aCircuit.firstname = String.Empty;
5413 aCircuit.lastname = String.Empty;
5414 }
5415
5416 try
5417 {
5418 if (!AuthorizeUser(aCircuit, out reason))
5419 {
5420 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5421 return false;
5422 }
5423 }
5424 catch (Exception e)
5425 {
5426 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message);
5427 return false;
5428 }
5429
5430 if (position == Vector3.Zero) // Teleport
5431 {
5432 float posX = 128.0f;
5433 float posY = 128.0f;
5434
5435 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5436 {
5437 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5438 return false;
5439 }
5440 }
5441 else // Walking
5442 {
5443 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5444 if (land == null)
5445 return false;
5446
5447 bool banned = land.IsBannedFromLand(agentID);
5448 bool restricted = land.IsRestrictedFromLand(agentID);
5449
5450 if (banned || restricted)
5451 return false;
5452 }
5453
5134 reason = String.Empty; 5454 reason = String.Empty;
5135 return true; 5455 return true;
5136 } 5456 }
5137 5457
5138 /// <summary> 5458 public void StartTimerWatchdog()
5459 {
5460 m_timerWatchdog.Interval = 1000;
5461 m_timerWatchdog.Elapsed += TimerWatchdog;
5462 m_timerWatchdog.AutoReset = true;
5463 m_timerWatchdog.Start();
5464 }
5465
5466 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5467 {
5468 CheckHeartbeat();
5469 }
5470
5139 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5471 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5140 /// autopilot that moves an avatar to a sit target!. 5472 /// autopilot that moves an avatar to a sit target!.
5141 /// </summary> 5473 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index ec94f10..bf861b8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -136,6 +136,8 @@ namespace OpenSim.Region.Framework.Scenes
136 get { return m_permissions; } 136 get { return m_permissions; }
137 } 137 }
138 138
139 protected string m_datastore;
140
139 /* Used by the loadbalancer plugin on GForge */ 141 /* Used by the loadbalancer plugin on GForge */
140 protected RegionStatus m_regStatus; 142 protected RegionStatus m_regStatus;
141 public RegionStatus RegionStatus 143 public RegionStatus RegionStatus
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 7cffa70..fe9fe31 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -44,8 +44,6 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
44 44
45namespace OpenSim.Region.Framework.Scenes 45namespace OpenSim.Region.Framework.Scenes
46{ 46{
47 public delegate void KiPrimitiveDelegate(uint localID);
48
49 public delegate void RemoveKnownRegionsFromAvatarList(UUID avatarID, List<ulong> regionlst); 47 public delegate void RemoveKnownRegionsFromAvatarList(UUID avatarID, List<ulong> regionlst);
50 48
51 /// <summary> 49 /// <summary>
@@ -113,8 +111,6 @@ namespace OpenSim.Region.Framework.Scenes
113// private LogOffUser handlerLogOffUser = null; 111// private LogOffUser handlerLogOffUser = null;
114// private GetLandData handlerGetLandData = null; // OnGetLandData 112// private GetLandData handlerGetLandData = null; // OnGetLandData
115 113
116 public KiPrimitiveDelegate KiPrimitive;
117
118 public SceneCommunicationService() 114 public SceneCommunicationService()
119 { 115 {
120 } 116 }
@@ -168,7 +164,7 @@ namespace OpenSim.Region.Framework.Scenes
168 164
169 if (neighbour != null) 165 if (neighbour != null)
170 { 166 {
171 m_log.DebugFormat("[INTERGRID]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize); 167 // m_log.DebugFormat("[INTERGRID]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize);
172 m_scene.EventManager.TriggerOnRegionUp(neighbour); 168 m_scene.EventManager.TriggerOnRegionUp(neighbour);
173 } 169 }
174 else 170 else
@@ -183,7 +179,7 @@ namespace OpenSim.Region.Framework.Scenes
183 //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName); 179 //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
184 180
185 List<GridRegion> neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); 181 List<GridRegion> neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID);
186 m_log.DebugFormat("[INTERGRID]: Informing {0} neighbours that this region is up", neighbours.Count); 182 //m_log.DebugFormat("[INTERGRID]: Informing {0} neighbours that this region is up", neighbours.Count);
187 foreach (GridRegion n in neighbours) 183 foreach (GridRegion n in neighbours)
188 { 184 {
189 InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync; 185 InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync;
@@ -259,46 +255,42 @@ namespace OpenSim.Region.Framework.Scenes
259 255
260 } 256 }
261 257
262 //public delegate void SendCloseChildAgentDelegate(UUID agentID, ulong regionHandle); 258 public delegate void SendCloseChildAgentDelegate(UUID agentID, ulong regionHandle);
263 //private void SendCloseChildAgentCompleted(IAsyncResult iar)
264 //{
265 // SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate)iar.AsyncState;
266 // icon.EndInvoke(iar);
267 //}
268 259
269 /// <summary> 260 /// <summary>
270 /// Closes a child agent on a given region 261 /// This Closes child agents on neighboring regions
262 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
271 /// </summary> 263 /// </summary>
272 protected void SendCloseChildAgent(UUID agentID, ulong regionHandle) 264 protected void SendCloseChildAgentAsync(UUID agentID, ulong regionHandle)
273 { 265 {
274 266
275 m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); 267 //m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle);
276 // let's do our best, but there's not much we can do if the neighbour doesn't accept. 268 // let's do our best, but there's not much we can do if the neighbour doesn't accept.
277 269
278 //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); 270 //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
279 uint x = 0, y = 0; 271 uint x = 0, y = 0;
280 Utils.LongToUInts(regionHandle, out x, out y); 272 Utils.LongToUInts(regionHandle, out x, out y);
281 GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y); 273 GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y);
282 m_scene.SimulationService.CloseAgent(destination, agentID); 274 m_scene.SimulationService.CloseChildAgent(destination, agentID);
275 }
276
277 private void SendCloseChildAgentCompleted(IAsyncResult iar)
278 {
279 SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate)iar.AsyncState;
280 icon.EndInvoke(iar);
283 } 281 }
284 282
285 /// <summary>
286 /// Closes a child agents in a collection of regions. Does so asynchronously
287 /// so that the caller doesn't wait.
288 /// </summary>
289 /// <param name="agentID"></param>
290 /// <param name="regionslst"></param>
291 public void SendCloseChildAgentConnections(UUID agentID, List<ulong> regionslst) 283 public void SendCloseChildAgentConnections(UUID agentID, List<ulong> regionslst)
292 { 284 {
293 Util.FireAndForget(delegate 285 foreach (ulong handle in regionslst)
294 { 286 {
295 foreach (ulong handle in regionslst) 287 SendCloseChildAgentDelegate d = SendCloseChildAgentAsync;
296 { 288 d.BeginInvoke(agentID, handle,
297 SendCloseChildAgent(agentID, handle); 289 SendCloseChildAgentCompleted,
298 } 290 d);
299 }); 291 }
300 } 292 }
301 293
302 public List<GridRegion> RequestNamedRegions(string name, int maxNumber) 294 public List<GridRegion> RequestNamedRegions(string name, int maxNumber)
303 { 295 {
304 return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber); 296 return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber);
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 542bd51..a4080ca 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -43,6 +43,12 @@ namespace OpenSim.Region.Framework.Scenes
43 43
44 public delegate void ObjectDuplicateDelegate(EntityBase original, EntityBase clone); 44 public delegate void ObjectDuplicateDelegate(EntityBase original, EntityBase clone);
45 45
46 public delegate void AttachToBackupDelegate(SceneObjectGroup sog);
47
48 public delegate void DetachFromBackupDelegate(SceneObjectGroup sog);
49
50 public delegate void ChangedBackupDelegate(SceneObjectGroup sog);
51
46 public delegate void ObjectCreateDelegate(EntityBase obj); 52 public delegate void ObjectCreateDelegate(EntityBase obj);
47 53
48 public delegate void ObjectDeleteDelegate(EntityBase obj); 54 public delegate void ObjectDeleteDelegate(EntityBase obj);
@@ -61,6 +67,9 @@ namespace OpenSim.Region.Framework.Scenes
61 private PhysicsCrash handlerPhysicsCrash = null; 67 private PhysicsCrash handlerPhysicsCrash = null;
62 68
63 public event ObjectDuplicateDelegate OnObjectDuplicate; 69 public event ObjectDuplicateDelegate OnObjectDuplicate;
70 public event AttachToBackupDelegate OnAttachToBackup;
71 public event DetachFromBackupDelegate OnDetachFromBackup;
72 public event ChangedBackupDelegate OnChangeBackup;
64 public event ObjectCreateDelegate OnObjectCreate; 73 public event ObjectCreateDelegate OnObjectCreate;
65 public event ObjectDeleteDelegate OnObjectRemove; 74 public event ObjectDeleteDelegate OnObjectRemove;
66 75
@@ -68,7 +77,7 @@ namespace OpenSim.Region.Framework.Scenes
68 77
69 #region Fields 78 #region Fields
70 79
71 protected object m_presenceLock = new object(); 80 protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim();
72 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); 81 protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
73 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); 82 protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>();
74 83
@@ -132,13 +141,18 @@ namespace OpenSim.Region.Framework.Scenes
132 141
133 protected internal void Close() 142 protected internal void Close()
134 { 143 {
135 lock (m_presenceLock) 144 m_scenePresencesLock.EnterWriteLock();
145 try
136 { 146 {
137 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 147 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
138 List<ScenePresence> newlist = new List<ScenePresence>(); 148 List<ScenePresence> newlist = new List<ScenePresence>();
139 m_scenePresenceMap = newmap; 149 m_scenePresenceMap = newmap;
140 m_scenePresenceArray = newlist; 150 m_scenePresenceArray = newlist;
141 } 151 }
152 finally
153 {
154 m_scenePresencesLock.ExitWriteLock();
155 }
142 156
143 lock (SceneObjectGroupsByFullID) 157 lock (SceneObjectGroupsByFullID)
144 SceneObjectGroupsByFullID.Clear(); 158 SceneObjectGroupsByFullID.Clear();
@@ -281,6 +295,33 @@ namespace OpenSim.Region.Framework.Scenes
281 protected internal bool AddRestoredSceneObject( 295 protected internal bool AddRestoredSceneObject(
282 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 296 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
283 { 297 {
298 if (!m_parentScene.CombineRegions)
299 {
300 // KF: Check for out-of-region, move inside and make static.
301 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
302 sceneObject.RootPart.GroupPosition.Y,
303 sceneObject.RootPart.GroupPosition.Z);
304 if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 ||
305 npos.X > Constants.RegionSize ||
306 npos.Y > Constants.RegionSize))
307 {
308 if (npos.X < 0.0) npos.X = 1.0f;
309 if (npos.Y < 0.0) npos.Y = 1.0f;
310 if (npos.Z < 0.0) npos.Z = 0.0f;
311 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
312 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
313
314 foreach (SceneObjectPart part in sceneObject.Parts)
315 {
316 part.GroupPosition = npos;
317 }
318 sceneObject.RootPart.Velocity = Vector3.Zero;
319 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
320 sceneObject.RootPart.Acceleration = Vector3.Zero;
321 sceneObject.RootPart.Velocity = Vector3.Zero;
322 }
323 }
324
284 if (attachToBackup && (!alreadyPersisted)) 325 if (attachToBackup && (!alreadyPersisted))
285 { 326 {
286 sceneObject.ForceInventoryPersistence(); 327 sceneObject.ForceInventoryPersistence();
@@ -498,6 +539,30 @@ namespace OpenSim.Region.Framework.Scenes
498 m_updateList[obj.UUID] = obj; 539 m_updateList[obj.UUID] = obj;
499 } 540 }
500 541
542 public void FireAttachToBackup(SceneObjectGroup obj)
543 {
544 if (OnAttachToBackup != null)
545 {
546 OnAttachToBackup(obj);
547 }
548 }
549
550 public void FireDetachFromBackup(SceneObjectGroup obj)
551 {
552 if (OnDetachFromBackup != null)
553 {
554 OnDetachFromBackup(obj);
555 }
556 }
557
558 public void FireChangeBackup(SceneObjectGroup obj)
559 {
560 if (OnChangeBackup != null)
561 {
562 OnChangeBackup(obj);
563 }
564 }
565
501 /// <summary> 566 /// <summary>
502 /// Process all pending updates 567 /// Process all pending updates
503 /// </summary> 568 /// </summary>
@@ -629,7 +694,8 @@ namespace OpenSim.Region.Framework.Scenes
629 694
630 Entities[presence.UUID] = presence; 695 Entities[presence.UUID] = presence;
631 696
632 lock (m_presenceLock) 697 m_scenePresencesLock.EnterWriteLock();
698 try
633 { 699 {
634 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 700 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
635 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 701 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -653,6 +719,10 @@ namespace OpenSim.Region.Framework.Scenes
653 m_scenePresenceMap = newmap; 719 m_scenePresenceMap = newmap;
654 m_scenePresenceArray = newlist; 720 m_scenePresenceArray = newlist;
655 } 721 }
722 finally
723 {
724 m_scenePresencesLock.ExitWriteLock();
725 }
656 } 726 }
657 727
658 /// <summary> 728 /// <summary>
@@ -667,7 +737,8 @@ namespace OpenSim.Region.Framework.Scenes
667 agentID); 737 agentID);
668 } 738 }
669 739
670 lock (m_presenceLock) 740 m_scenePresencesLock.EnterWriteLock();
741 try
671 { 742 {
672 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 743 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
673 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 744 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -689,6 +760,10 @@ namespace OpenSim.Region.Framework.Scenes
689 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 760 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
690 } 761 }
691 } 762 }
763 finally
764 {
765 m_scenePresencesLock.ExitWriteLock();
766 }
692 } 767 }
693 768
694 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 769 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1402,8 +1477,13 @@ namespace OpenSim.Region.Framework.Scenes
1402 { 1477 {
1403 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1478 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1404 { 1479 {
1405 if (m_parentScene.AttachmentsModule != null) 1480 // Set the new attachment point data in the object
1406 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(group, pos); 1481 byte attachmentPoint = group.GetAttachmentPoint();
1482 group.UpdateGroupPosition(pos);
1483 group.IsAttachment = false;
1484 group.AbsolutePosition = group.RootPart.AttachedPos;
1485 group.AttachmentPoint = attachmentPoint;
1486 group.HasGroupChanged = true;
1407 } 1487 }
1408 else 1488 else
1409 { 1489 {
@@ -1667,10 +1747,13 @@ namespace OpenSim.Region.Framework.Scenes
1667 /// <param name="childPrims"></param> 1747 /// <param name="childPrims"></param>
1668 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1748 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1669 { 1749 {
1750 SceneObjectGroup parentGroup = root.ParentGroup;
1751 if (parentGroup == null) return;
1670 Monitor.Enter(m_updateLock); 1752 Monitor.Enter(m_updateLock);
1753
1671 try 1754 try
1672 { 1755 {
1673 SceneObjectGroup parentGroup = root.ParentGroup; 1756 parentGroup.areUpdatesSuspended = true;
1674 1757
1675 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1758 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1676 1759
@@ -1682,9 +1765,13 @@ namespace OpenSim.Region.Framework.Scenes
1682 // Make sure no child prim is set for sale 1765 // Make sure no child prim is set for sale
1683 // So that, on delink, no prims are unwittingly 1766 // So that, on delink, no prims are unwittingly
1684 // left for sale and sold off 1767 // left for sale and sold off
1685 child.RootPart.ObjectSaleType = 0; 1768
1686 child.RootPart.SalePrice = 10; 1769 if (child != null)
1687 childGroups.Add(child); 1770 {
1771 child.RootPart.ObjectSaleType = 0;
1772 child.RootPart.SalePrice = 10;
1773 childGroups.Add(child);
1774 }
1688 } 1775 }
1689 1776
1690 foreach (SceneObjectGroup child in childGroups) 1777 foreach (SceneObjectGroup child in childGroups)
@@ -1700,12 +1787,13 @@ namespace OpenSim.Region.Framework.Scenes
1700 // occur on link to invoke this elsewhere (such as object selection) 1787 // occur on link to invoke this elsewhere (such as object selection)
1701 parentGroup.RootPart.CreateSelected = true; 1788 parentGroup.RootPart.CreateSelected = true;
1702 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1789 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1703 parentGroup.HasGroupChanged = true;
1704 parentGroup.ScheduleGroupForFullUpdate();
1705
1706 } 1790 }
1707 finally 1791 finally
1708 { 1792 {
1793 parentGroup.areUpdatesSuspended = false;
1794 parentGroup.HasGroupChanged = true;
1795 parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
1796 parentGroup.ScheduleGroupForFullUpdate();
1709 Monitor.Exit(m_updateLock); 1797 Monitor.Exit(m_updateLock);
1710 } 1798 }
1711 } 1799 }
@@ -1737,21 +1825,24 @@ namespace OpenSim.Region.Framework.Scenes
1737 1825
1738 SceneObjectGroup group = part.ParentGroup; 1826 SceneObjectGroup group = part.ParentGroup;
1739 if (!affectedGroups.Contains(group)) 1827 if (!affectedGroups.Contains(group))
1828 {
1829 group.areUpdatesSuspended = true;
1740 affectedGroups.Add(group); 1830 affectedGroups.Add(group);
1831 }
1741 } 1832 }
1742 } 1833 }
1743 } 1834 }
1744 1835
1745 foreach (SceneObjectPart child in childParts) 1836 if (childParts.Count > 0)
1746 { 1837 {
1747 // Unlink all child parts from their groups 1838 foreach (SceneObjectPart child in childParts)
1748 // 1839 {
1749 child.ParentGroup.DelinkFromGroup(child, true); 1840 // Unlink all child parts from their groups
1750 1841 //
1751 // These are not in affected groups and will not be 1842 child.ParentGroup.DelinkFromGroup(child, true);
1752 // handled further. Do the honors here. 1843 child.ParentGroup.HasGroupChanged = true;
1753 child.ParentGroup.HasGroupChanged = true; 1844 child.ParentGroup.ScheduleGroupForFullUpdate();
1754 child.ParentGroup.ScheduleGroupForFullUpdate(); 1845 }
1755 } 1846 }
1756 1847
1757 foreach (SceneObjectPart root in rootParts) 1848 foreach (SceneObjectPart root in rootParts)
@@ -1761,56 +1852,68 @@ namespace OpenSim.Region.Framework.Scenes
1761 // However, editing linked parts and unlinking may be different 1852 // However, editing linked parts and unlinking may be different
1762 // 1853 //
1763 SceneObjectGroup group = root.ParentGroup; 1854 SceneObjectGroup group = root.ParentGroup;
1855 group.areUpdatesSuspended = true;
1764 1856
1765 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1857 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1766 int numChildren = newSet.Count; 1858 int numChildren = newSet.Count;
1767 1859
1860 if (numChildren == 1)
1861 break;
1862
1768 // If there are prims left in a link set, but the root is 1863 // If there are prims left in a link set, but the root is
1769 // slated for unlink, we need to do this 1864 // slated for unlink, we need to do this
1865 // Unlink the remaining set
1770 // 1866 //
1771 if (numChildren != 1) 1867 bool sendEventsToRemainder = true;
1772 { 1868 if (numChildren > 1)
1773 // Unlink the remaining set 1869 sendEventsToRemainder = false;
1774 //
1775 bool sendEventsToRemainder = true;
1776 if (numChildren > 1)
1777 sendEventsToRemainder = false;
1778 1870
1779 foreach (SceneObjectPart p in newSet) 1871 foreach (SceneObjectPart p in newSet)
1872 {
1873 if (p != group.RootPart)
1780 { 1874 {
1781 if (p != group.RootPart) 1875 group.DelinkFromGroup(p, sendEventsToRemainder);
1782 group.DelinkFromGroup(p, sendEventsToRemainder); 1876 if (numChildren > 2)
1877 {
1878 p.ParentGroup.areUpdatesSuspended = true;
1879 }
1880 else
1881 {
1882 p.ParentGroup.HasGroupChanged = true;
1883 p.ParentGroup.ScheduleGroupForFullUpdate();
1884 }
1783 } 1885 }
1886 }
1784 1887
1785 // If there is more than one prim remaining, we 1888 // If there is more than one prim remaining, we
1786 // need to re-link 1889 // need to re-link
1890 //
1891 if (numChildren > 2)
1892 {
1893 // Remove old root
1894 //
1895 if (newSet.Contains(root))
1896 newSet.Remove(root);
1897
1898 // Preserve link ordering
1787 // 1899 //
1788 if (numChildren > 2) 1900 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1789 { 1901 {
1790 // Remove old root 1902 return a.LinkNum.CompareTo(b.LinkNum);
1791 // 1903 });
1792 if (newSet.Contains(root))
1793 newSet.Remove(root);
1794
1795 // Preserve link ordering
1796 //
1797 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1798 {
1799 return a.LinkNum.CompareTo(b.LinkNum);
1800 });
1801 1904
1802 // Determine new root 1905 // Determine new root
1803 // 1906 //
1804 SceneObjectPart newRoot = newSet[0]; 1907 SceneObjectPart newRoot = newSet[0];
1805 newSet.RemoveAt(0); 1908 newSet.RemoveAt(0);
1806 1909
1807 foreach (SceneObjectPart newChild in newSet) 1910 foreach (SceneObjectPart newChild in newSet)
1808 newChild.UpdateFlag = 0; 1911 newChild.UpdateFlag = 0;
1809 1912
1810 LinkObjects(newRoot, newSet); 1913 newRoot.ParentGroup.areUpdatesSuspended = true;
1811 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1914 LinkObjects(newRoot, newSet);
1812 affectedGroups.Add(newRoot.ParentGroup); 1915 if (!affectedGroups.Contains(newRoot.ParentGroup))
1813 } 1916 affectedGroups.Add(newRoot.ParentGroup);
1814 } 1917 }
1815 } 1918 }
1816 1919
@@ -1818,8 +1921,14 @@ namespace OpenSim.Region.Framework.Scenes
1818 // 1921 //
1819 foreach (SceneObjectGroup g in affectedGroups) 1922 foreach (SceneObjectGroup g in affectedGroups)
1820 { 1923 {
1924 // Child prims that have been unlinked and deleted will
1925 // return unless the root is deleted. This will remove them
1926 // from the database. They will be rewritten immediately,
1927 // minus the rows for the unlinked child prims.
1928 m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
1821 g.TriggerScriptChangedEvent(Changed.LINK); 1929 g.TriggerScriptChangedEvent(Changed.LINK);
1822 g.HasGroupChanged = true; // Persist 1930 g.HasGroupChanged = true; // Persist
1931 g.areUpdatesSuspended = false;
1823 g.ScheduleGroupForFullUpdate(); 1932 g.ScheduleGroupForFullUpdate();
1824 } 1933 }
1825 } 1934 }
@@ -1937,9 +2046,6 @@ namespace OpenSim.Region.Framework.Scenes
1937 child.ApplyNextOwnerPermissions(); 2046 child.ApplyNextOwnerPermissions();
1938 } 2047 }
1939 } 2048 }
1940
1941 copy.RootPart.ObjectSaleType = 0;
1942 copy.RootPart.SalePrice = 10;
1943 } 2049 }
1944 2050
1945 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 2051 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 905ecc9..6bd9183 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -69,10 +69,6 @@ namespace OpenSim.Region.Framework.Scenes
69 /// <summary> 69 /// <summary>
70 /// Stop the scripts contained in all the prims in this group 70 /// Stop the scripts contained in all the prims in this group
71 /// </summary> 71 /// </summary>
72 /// <param name="sceneObjectBeingDeleted">
73 /// Should be true if these scripts are being removed because the scene
74 /// object is being deleted. This will prevent spurious updates to the client.
75 /// </param>
76 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 72 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
77 { 73 {
78 SceneObjectPart[] parts = m_parts.GetArray(); 74 SceneObjectPart[] parts = m_parts.GetArray();
@@ -385,6 +381,9 @@ namespace OpenSim.Region.Framework.Scenes
385 381
386 public void ResumeScripts() 382 public void ResumeScripts()
387 { 383 {
384 if (m_scene.RegionInfo.RegionSettings.DisableScripts)
385 return;
386
388 SceneObjectPart[] parts = m_parts.GetArray(); 387 SceneObjectPart[] parts = m_parts.GetArray();
389 for (int i = 0; i < parts.Length; i++) 388 for (int i = 0; i < parts.Length; i++)
390 parts[i].Inventory.ResumeScripts(); 389 parts[i].Inventory.ResumeScripts();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 2d6d4ec..5381f63 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -24,11 +24,12 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Drawing; 30using System.Drawing;
31using System.IO; 31using System.IO;
32using System.Diagnostics;
32using System.Linq; 33using System.Linq;
33using System.Threading; 34using System.Threading;
34using System.Xml; 35using System.Xml;
@@ -105,8 +106,29 @@ namespace OpenSim.Region.Framework.Scenes
105 /// since the group's last persistent backup 106 /// since the group's last persistent backup
106 /// </summary> 107 /// </summary>
107 private bool m_hasGroupChanged = false; 108 private bool m_hasGroupChanged = false;
108 private long timeFirstChanged; 109 private long timeFirstChanged = 0;
109 private long timeLastChanged; 110 private long timeLastChanged = 0;
111 private long m_maxPersistTime = 0;
112 private long m_minPersistTime = 0;
113 private Random m_rand;
114 private bool m_suspendUpdates;
115 private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
116
117 public bool areUpdatesSuspended
118 {
119 get
120 {
121 return m_suspendUpdates;
122 }
123 set
124 {
125 m_suspendUpdates = value;
126 if (!value)
127 {
128 QueueForUpdateCheck();
129 }
130 }
131 }
110 132
111 public bool HasGroupChanged 133 public bool HasGroupChanged
112 { 134 {
@@ -114,9 +136,39 @@ namespace OpenSim.Region.Framework.Scenes
114 { 136 {
115 if (value) 137 if (value)
116 { 138 {
139 if (m_isBackedUp)
140 {
141 m_scene.SceneGraph.FireChangeBackup(this);
142 }
117 timeLastChanged = DateTime.Now.Ticks; 143 timeLastChanged = DateTime.Now.Ticks;
118 if (!m_hasGroupChanged) 144 if (!m_hasGroupChanged)
119 timeFirstChanged = DateTime.Now.Ticks; 145 timeFirstChanged = DateTime.Now.Ticks;
146 if (m_rootPart != null && m_rootPart.UUID != null && m_scene != null)
147 {
148 if (m_rand == null)
149 {
150 byte[] val = new byte[16];
151 m_rootPart.UUID.ToBytes(val, 0);
152 m_rand = new Random(BitConverter.ToInt32(val, 0));
153 }
154
155 if (m_scene.GetRootAgentCount() == 0)
156 {
157 //If the region is empty, this change has been made by an automated process
158 //and thus we delay the persist time by a random amount between 1.5 and 2.5.
159
160 float factor = 1.5f + (float)(m_rand.NextDouble());
161 m_maxPersistTime = (long)((float)m_scene.m_persistAfter * factor);
162 m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * factor);
163 }
164 else
165 {
166 //If the region is not empty, we want to obey the minimum and maximum persist times
167 //but add a random factor so we stagger the object persistance a little
168 m_maxPersistTime = (long)((float)m_scene.m_persistAfter * (1.0d - (m_rand.NextDouble() / 5.0d))); //Multiply by 1.0-1.5
169 m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * (1.0d + (m_rand.NextDouble() / 2.0d))); //Multiply by 0.8-1.0
170 }
171 }
120 } 172 }
121 m_hasGroupChanged = value; 173 m_hasGroupChanged = value;
122 174
@@ -131,7 +183,7 @@ namespace OpenSim.Region.Framework.Scenes
131 /// Has the group changed due to an unlink operation? We record this in order to optimize deletion, since 183 /// Has the group changed due to an unlink operation? We record this in order to optimize deletion, since
132 /// an unlinked group currently has to be persisted to the database before we can perform an unlink operation. 184 /// an unlinked group currently has to be persisted to the database before we can perform an unlink operation.
133 /// </summary> 185 /// </summary>
134 public bool HasGroupChangedDueToDelink { get; private set; } 186 public bool HasGroupChangedDueToDelink { get; set; }
135 187
136 private bool isTimeToPersist() 188 private bool isTimeToPersist()
137 { 189 {
@@ -141,8 +193,19 @@ namespace OpenSim.Region.Framework.Scenes
141 return false; 193 return false;
142 if (m_scene.ShuttingDown) 194 if (m_scene.ShuttingDown)
143 return true; 195 return true;
196
197 if (m_minPersistTime == 0 || m_maxPersistTime == 0)
198 {
199 m_maxPersistTime = m_scene.m_persistAfter;
200 m_minPersistTime = m_scene.m_dontPersistBefore;
201 }
202
144 long currentTime = DateTime.Now.Ticks; 203 long currentTime = DateTime.Now.Ticks;
145 if (currentTime - timeLastChanged > m_scene.m_dontPersistBefore || currentTime - timeFirstChanged > m_scene.m_persistAfter) 204
205 if (timeLastChanged == 0) timeLastChanged = currentTime;
206 if (timeFirstChanged == 0) timeFirstChanged = currentTime;
207
208 if (currentTime - timeLastChanged > m_minPersistTime || currentTime - timeFirstChanged > m_maxPersistTime)
146 return true; 209 return true;
147 return false; 210 return false;
148 } 211 }
@@ -247,10 +310,10 @@ namespace OpenSim.Region.Framework.Scenes
247 310
248 private bool m_scriptListens_atTarget; 311 private bool m_scriptListens_atTarget;
249 private bool m_scriptListens_notAtTarget; 312 private bool m_scriptListens_notAtTarget;
250
251 private bool m_scriptListens_atRotTarget; 313 private bool m_scriptListens_atRotTarget;
252 private bool m_scriptListens_notAtRotTarget; 314 private bool m_scriptListens_notAtRotTarget;
253 315
316 public bool m_dupeInProgress = false;
254 internal Dictionary<UUID, string> m_savedScriptState; 317 internal Dictionary<UUID, string> m_savedScriptState;
255 318
256 #region Properties 319 #region Properties
@@ -286,7 +349,9 @@ namespace OpenSim.Region.Framework.Scenes
286 public virtual Quaternion Rotation 349 public virtual Quaternion Rotation
287 { 350 {
288 get { return m_rotation; } 351 get { return m_rotation; }
289 set { m_rotation = value; } 352 set {
353 m_rotation = value;
354 }
290 } 355 }
291 356
292 public Quaternion GroupRotation 357 public Quaternion GroupRotation
@@ -397,7 +462,11 @@ namespace OpenSim.Region.Framework.Scenes
397 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 462 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
398 } 463 }
399 } 464 }
400 465
466 foreach (SceneObjectPart part in m_parts.GetArray())
467 {
468 part.IgnoreUndoUpdate = true;
469 }
401 if (RootPart.GetStatusSandbox()) 470 if (RootPart.GetStatusSandbox())
402 { 471 {
403 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) 472 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -411,10 +480,29 @@ namespace OpenSim.Region.Framework.Scenes
411 return; 480 return;
412 } 481 }
413 } 482 }
414
415 SceneObjectPart[] parts = m_parts.GetArray(); 483 SceneObjectPart[] parts = m_parts.GetArray();
416 for (int i = 0; i < parts.Length; i++) 484 foreach (SceneObjectPart part in parts)
417 parts[i].GroupPosition = val; 485 {
486 part.GroupPosition = val;
487 if (!m_dupeInProgress)
488 {
489 part.TriggerScriptChangedEvent(Changed.POSITION);
490 }
491 }
492 if (!m_dupeInProgress)
493 {
494 foreach (ScenePresence av in m_linkedAvatars)
495 {
496 SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID);
497 if (m_parts.TryGetValue(p.UUID, out p))
498 {
499 Vector3 offset = p.GetWorldPosition() - av.ParentPosition;
500 av.AbsolutePosition += offset;
501 av.ParentPosition = p.GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition
502 av.SendAvatarDataToAllAgents();
503 }
504 }
505 }
418 506
419 //if (m_rootPart.PhysActor != null) 507 //if (m_rootPart.PhysActor != null)
420 //{ 508 //{
@@ -573,6 +661,7 @@ namespace OpenSim.Region.Framework.Scenes
573 /// </summary> 661 /// </summary>
574 public SceneObjectGroup() 662 public SceneObjectGroup()
575 { 663 {
664
576 } 665 }
577 666
578 /// <summary> 667 /// <summary>
@@ -589,7 +678,7 @@ namespace OpenSim.Region.Framework.Scenes
589 /// Constructor. This object is added to the scene later via AttachToScene() 678 /// Constructor. This object is added to the scene later via AttachToScene()
590 /// </summary> 679 /// </summary>
591 public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) 680 public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
592 { 681 {
593 SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero)); 682 SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero));
594 } 683 }
595 684
@@ -637,6 +726,9 @@ namespace OpenSim.Region.Framework.Scenes
637 /// </summary> 726 /// </summary>
638 public virtual void AttachToBackup() 727 public virtual void AttachToBackup()
639 { 728 {
729 if (IsAttachment) return;
730 m_scene.SceneGraph.FireAttachToBackup(this);
731
640 if (InSceneBackup) 732 if (InSceneBackup)
641 { 733 {
642 //m_log.DebugFormat( 734 //m_log.DebugFormat(
@@ -679,6 +771,9 @@ namespace OpenSim.Region.Framework.Scenes
679 771
680 ApplyPhysics(m_scene.m_physicalPrim); 772 ApplyPhysics(m_scene.m_physicalPrim);
681 773
774 if (RootPart.PhysActor != null)
775 RootPart.Buoyancy = RootPart.Buoyancy;
776
682 // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled 777 // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
683 // for the same object with very different properties. The caller must schedule the update. 778 // for the same object with very different properties. The caller must schedule the update.
684 //ScheduleGroupForFullUpdate(); 779 //ScheduleGroupForFullUpdate();
@@ -724,9 +819,9 @@ namespace OpenSim.Region.Framework.Scenes
724 result.normal = inter.normal; 819 result.normal = inter.normal;
725 result.distance = inter.distance; 820 result.distance = inter.distance;
726 } 821 }
822
727 } 823 }
728 } 824 }
729
730 return result; 825 return result;
731 } 826 }
732 827
@@ -746,17 +841,19 @@ namespace OpenSim.Region.Framework.Scenes
746 minZ = 8192f; 841 minZ = 8192f;
747 842
748 SceneObjectPart[] parts = m_parts.GetArray(); 843 SceneObjectPart[] parts = m_parts.GetArray();
749 for (int i = 0; i < parts.Length; i++) 844 foreach (SceneObjectPart part in parts)
750 { 845 {
751 SceneObjectPart part = parts[i];
752
753 Vector3 worldPos = part.GetWorldPosition(); 846 Vector3 worldPos = part.GetWorldPosition();
754 Vector3 offset = worldPos - AbsolutePosition; 847 Vector3 offset = worldPos - AbsolutePosition;
755 Quaternion worldRot; 848 Quaternion worldRot;
756 if (part.ParentID == 0) 849 if (part.ParentID == 0)
850 {
757 worldRot = part.RotationOffset; 851 worldRot = part.RotationOffset;
852 }
758 else 853 else
854 {
759 worldRot = part.GetWorldRotation(); 855 worldRot = part.GetWorldRotation();
856 }
760 857
761 Vector3 frontTopLeft; 858 Vector3 frontTopLeft;
762 Vector3 frontTopRight; 859 Vector3 frontTopRight;
@@ -768,6 +865,8 @@ namespace OpenSim.Region.Framework.Scenes
768 Vector3 backBottomLeft; 865 Vector3 backBottomLeft;
769 Vector3 backBottomRight; 866 Vector3 backBottomRight;
770 867
868 // Vector3[] corners = new Vector3[8];
869
771 Vector3 orig = Vector3.Zero; 870 Vector3 orig = Vector3.Zero;
772 871
773 frontTopLeft.X = orig.X - (part.Scale.X / 2); 872 frontTopLeft.X = orig.X - (part.Scale.X / 2);
@@ -802,6 +901,38 @@ namespace OpenSim.Region.Framework.Scenes
802 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 901 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
803 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 902 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
804 903
904
905
906 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
907 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
908 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
909 //m_log.InfoFormat("pre corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z);
910 //m_log.InfoFormat("pre corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z);
911 //m_log.InfoFormat("pre corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z);
912 //m_log.InfoFormat("pre corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z);
913 //m_log.InfoFormat("pre corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z);
914
915 //for (int i = 0; i < 8; i++)
916 //{
917 // corners[i] = corners[i] * worldRot;
918 // corners[i] += offset;
919
920 // if (corners[i].X > maxX)
921 // maxX = corners[i].X;
922 // if (corners[i].X < minX)
923 // minX = corners[i].X;
924
925 // if (corners[i].Y > maxY)
926 // maxY = corners[i].Y;
927 // if (corners[i].Y < minY)
928 // minY = corners[i].Y;
929
930 // if (corners[i].Z > maxZ)
931 // maxZ = corners[i].Y;
932 // if (corners[i].Z < minZ)
933 // minZ = corners[i].Z;
934 //}
935
805 frontTopLeft = frontTopLeft * worldRot; 936 frontTopLeft = frontTopLeft * worldRot;
806 frontTopRight = frontTopRight * worldRot; 937 frontTopRight = frontTopRight * worldRot;
807 frontBottomLeft = frontBottomLeft * worldRot; 938 frontBottomLeft = frontBottomLeft * worldRot;
@@ -823,6 +954,15 @@ namespace OpenSim.Region.Framework.Scenes
823 backTopLeft += offset; 954 backTopLeft += offset;
824 backTopRight += offset; 955 backTopRight += offset;
825 956
957 //m_log.InfoFormat("corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
958 //m_log.InfoFormat("corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
959 //m_log.InfoFormat("corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
960 //m_log.InfoFormat("corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z);
961 //m_log.InfoFormat("corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z);
962 //m_log.InfoFormat("corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z);
963 //m_log.InfoFormat("corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z);
964 //m_log.InfoFormat("corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z);
965
826 if (frontTopRight.X > maxX) 966 if (frontTopRight.X > maxX)
827 maxX = frontTopRight.X; 967 maxX = frontTopRight.X;
828 if (frontTopLeft.X > maxX) 968 if (frontTopLeft.X > maxX)
@@ -968,15 +1108,20 @@ namespace OpenSim.Region.Framework.Scenes
968 1108
969 public void SaveScriptedState(XmlTextWriter writer) 1109 public void SaveScriptedState(XmlTextWriter writer)
970 { 1110 {
1111 SaveScriptedState(writer, false);
1112 }
1113
1114 public void SaveScriptedState(XmlTextWriter writer, bool oldIDs)
1115 {
971 XmlDocument doc = new XmlDocument(); 1116 XmlDocument doc = new XmlDocument();
972 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 1117 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
973 1118
974 SceneObjectPart[] parts = m_parts.GetArray(); 1119 SceneObjectPart[] parts = m_parts.GetArray();
975 for (int i = 0; i < parts.Length; i++) 1120 for (int i = 0; i < parts.Length; i++)
976 { 1121 {
977 Dictionary<UUID, string> pstates = parts[i].Inventory.GetScriptStates(); 1122 Dictionary<UUID, string> pstates = parts[i].Inventory.GetScriptStates(oldIDs);
978 foreach (KeyValuePair<UUID, string> kvp in pstates) 1123 foreach (KeyValuePair<UUID, string> kvp in pstates)
979 states.Add(kvp.Key, kvp.Value); 1124 states[kvp.Key] = kvp.Value;
980 } 1125 }
981 1126
982 if (states.Count > 0) 1127 if (states.Count > 0)
@@ -996,6 +1141,168 @@ namespace OpenSim.Region.Framework.Scenes
996 } 1141 }
997 1142
998 /// <summary> 1143 /// <summary>
1144 /// Add the avatar to this linkset (avatar is sat).
1145 /// </summary>
1146 /// <param name="agentID"></param>
1147 public void AddAvatar(UUID agentID)
1148 {
1149 ScenePresence presence;
1150 if (m_scene.TryGetScenePresence(agentID, out presence))
1151 {
1152 if (!m_linkedAvatars.Contains(presence))
1153 {
1154 m_linkedAvatars.Add(presence);
1155 }
1156 }
1157 }
1158
1159 /// <summary>
1160 /// Delete the avatar from this linkset (avatar is unsat).
1161 /// </summary>
1162 /// <param name="agentID"></param>
1163 public void DeleteAvatar(UUID agentID)
1164 {
1165 ScenePresence presence;
1166 if (m_scene.TryGetScenePresence(agentID, out presence))
1167 {
1168 if (m_linkedAvatars.Contains(presence))
1169 {
1170 m_linkedAvatars.Remove(presence);
1171 }
1172 }
1173 }
1174
1175 /// <summary>
1176 /// Returns the list of linked presences (avatars sat on this group)
1177 /// </summary>
1178 /// <param name="agentID"></param>
1179 public List<ScenePresence> GetLinkedAvatars()
1180 {
1181 return m_linkedAvatars;
1182 }
1183
1184 /// <summary>
1185 /// Attach this scene object to the given avatar.
1186 /// </summary>
1187 /// <param name="agentID"></param>
1188 /// <param name="attachmentpoint"></param>
1189 /// <param name="AttachOffset"></param>
1190 private void AttachToAgent(
1191 ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
1192 {
1193 if (avatar != null)
1194 {
1195 // don't attach attachments to child agents
1196 if (avatar.IsChildAgent) return;
1197
1198 // Remove from database and parcel prim count
1199 m_scene.DeleteFromStorage(so.UUID);
1200 m_scene.EventManager.TriggerParcelPrimCountTainted();
1201
1202 so.AttachedAvatar = avatar.UUID;
1203
1204 if (so.RootPart.PhysActor != null)
1205 {
1206 m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor);
1207 so.RootPart.PhysActor = null;
1208 }
1209
1210 so.AbsolutePosition = attachOffset;
1211 so.RootPart.AttachedPos = attachOffset;
1212 so.IsAttachment = true;
1213 so.RootPart.SetParentLocalId(avatar.LocalId);
1214 so.AttachmentPoint = attachmentpoint;
1215
1216 avatar.AddAttachment(this);
1217
1218 if (!silent)
1219 {
1220 // Killing it here will cause the client to deselect it
1221 // It then reappears on the avatar, deselected
1222 // through the full update below
1223 //
1224 if (IsSelected)
1225 {
1226 m_scene.SendKillObject(new List<uint> { m_rootPart.LocalId });
1227 }
1228
1229 IsSelected = false; // fudge....
1230 ScheduleGroupForFullUpdate();
1231 }
1232 }
1233 else
1234 {
1235 m_log.WarnFormat(
1236 "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present",
1237 UUID, avatar.ControllingClient.AgentId, Scene.RegionInfo.RegionName);
1238 }
1239 }
1240
1241 public byte GetAttachmentPoint()
1242 {
1243 return m_rootPart.Shape.State;
1244 }
1245
1246 public void DetachToGround()
1247 {
1248 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1249 if (avatar == null)
1250 return;
1251
1252 avatar.RemoveAttachment(this);
1253
1254 Vector3 detachedpos = new Vector3(127f,127f,127f);
1255 if (avatar == null)
1256 return;
1257
1258 detachedpos = avatar.AbsolutePosition;
1259 RootPart.FromItemID = UUID.Zero;
1260
1261 AbsolutePosition = detachedpos;
1262 AttachedAvatar = UUID.Zero;
1263
1264 //SceneObjectPart[] parts = m_parts.GetArray();
1265 //for (int i = 0; i < parts.Length; i++)
1266 // parts[i].AttachedAvatar = UUID.Zero;
1267
1268 m_rootPart.SetParentLocalId(0);
1269 AttachmentPoint = (byte)0;
1270 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
1271 HasGroupChanged = true;
1272 RootPart.Rezzed = DateTime.Now;
1273 RootPart.RemFlag(PrimFlags.TemporaryOnRez);
1274 AttachToBackup();
1275 m_scene.EventManager.TriggerParcelPrimCountTainted();
1276 m_rootPart.ScheduleFullUpdate();
1277 m_rootPart.ClearUndoState();
1278 }
1279
1280 public void DetachToInventoryPrep()
1281 {
1282 ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar);
1283 //Vector3 detachedpos = new Vector3(127f, 127f, 127f);
1284 if (avatar != null)
1285 {
1286 //detachedpos = avatar.AbsolutePosition;
1287 avatar.RemoveAttachment(this);
1288 }
1289
1290 AttachedAvatar = UUID.Zero;
1291
1292 /*SceneObjectPart[] parts = m_parts.GetArray();
1293 for (int i = 0; i < parts.Length; i++)
1294 parts[i].AttachedAvatar = UUID.Zero;*/
1295
1296 m_rootPart.SetParentLocalId(0);
1297 //m_rootPart.SetAttachmentPoint((byte)0);
1298 IsAttachment = false;
1299 AbsolutePosition = m_rootPart.AttachedPos;
1300 //m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim);
1301 //AttachToBackup();
1302 //m_rootPart.ScheduleFullUpdate();
1303 }
1304
1305 /// <summary>
999 /// 1306 ///
1000 /// </summary> 1307 /// </summary>
1001 /// <param name="part"></param> 1308 /// <param name="part"></param>
@@ -1045,7 +1352,10 @@ namespace OpenSim.Region.Framework.Scenes
1045 public void AddPart(SceneObjectPart part) 1352 public void AddPart(SceneObjectPart part)
1046 { 1353 {
1047 part.SetParent(this); 1354 part.SetParent(this);
1048 part.LinkNum = m_parts.Add(part.UUID, part); 1355 m_parts.Add(part.UUID, part);
1356
1357 part.LinkNum = m_parts.Count;
1358
1049 if (part.LinkNum == 2) 1359 if (part.LinkNum == 2)
1050 RootPart.LinkNum = 1; 1360 RootPart.LinkNum = 1;
1051 } 1361 }
@@ -1153,6 +1463,11 @@ namespace OpenSim.Region.Framework.Scenes
1153 /// <param name="silent">If true then deletion is not broadcast to clients</param> 1463 /// <param name="silent">If true then deletion is not broadcast to clients</param>
1154 public void DeleteGroupFromScene(bool silent) 1464 public void DeleteGroupFromScene(bool silent)
1155 { 1465 {
1466 // We need to keep track of this state in case this group is still queued for backup.
1467 IsDeleted = true;
1468
1469 DetachFromBackup();
1470
1156 SceneObjectPart[] parts = m_parts.GetArray(); 1471 SceneObjectPart[] parts = m_parts.GetArray();
1157 for (int i = 0; i < parts.Length; i++) 1472 for (int i = 0; i < parts.Length; i++)
1158 { 1473 {
@@ -1164,17 +1479,19 @@ namespace OpenSim.Region.Framework.Scenes
1164 avatar.StandUp(); 1479 avatar.StandUp();
1165 1480
1166 if (!silent) 1481 if (!silent)
1167 { 1482 {
1168 part.UpdateFlag = 0; 1483 part.UpdateFlag = 0;
1169 if (part == m_rootPart) 1484 if (part == m_rootPart)
1170 { 1485 {
1171 if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) || 1486 if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) ||
1172 (AttachmentPoint < 31) || (AttachmentPoint > 38)) 1487 (AttachmentPoint < 31) || (AttachmentPoint > 38))
1173 avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1488 avatar.ControllingClient.SendKillObject(m_regionHandle, new List<uint>() {part.LocalId});
1174 } 1489 }
1175 } 1490 }
1176 }); 1491 });
1177 } 1492 }
1493
1494
1178 } 1495 }
1179 1496
1180 public void AddScriptLPS(int count) 1497 public void AddScriptLPS(int count)
@@ -1271,7 +1588,12 @@ namespace OpenSim.Region.Framework.Scenes
1271 1588
1272 public void SetOwnerId(UUID userId) 1589 public void SetOwnerId(UUID userId)
1273 { 1590 {
1274 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1591 ForEachPart(delegate(SceneObjectPart part)
1592 {
1593
1594 part.OwnerID = userId;
1595
1596 });
1275 } 1597 }
1276 1598
1277 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1599 public void ForEachPart(Action<SceneObjectPart> whatToDo)
@@ -1303,11 +1625,17 @@ namespace OpenSim.Region.Framework.Scenes
1303 return; 1625 return;
1304 } 1626 }
1305 1627
1628 if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1629 return;
1630
1306 // Since this is the top of the section of call stack for backing up a particular scene object, don't let 1631 // Since this is the top of the section of call stack for backing up a particular scene object, don't let
1307 // any exception propogate upwards. 1632 // any exception propogate upwards.
1308 try 1633 try
1309 { 1634 {
1310 if (!m_scene.ShuttingDown) // if shutting down then there will be nothing to handle the return so leave till next restart 1635 if (!m_scene.ShuttingDown || // if shutting down then there will be nothing to handle the return so leave till next restart
1636 m_scene.LoginsDisabled || // We're starting up or doing maintenance, don't mess with things
1637 m_scene.LoadingPrims) // Land may not be valid yet
1638
1311 { 1639 {
1312 ILandObject parcel = m_scene.LandChannel.GetLandObject( 1640 ILandObject parcel = m_scene.LandChannel.GetLandObject(
1313 m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); 1641 m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y);
@@ -1334,6 +1662,7 @@ namespace OpenSim.Region.Framework.Scenes
1334 } 1662 }
1335 } 1663 }
1336 } 1664 }
1665
1337 } 1666 }
1338 1667
1339 if (m_scene.UseBackup && HasGroupChanged) 1668 if (m_scene.UseBackup && HasGroupChanged)
@@ -1341,6 +1670,20 @@ namespace OpenSim.Region.Framework.Scenes
1341 // don't backup while it's selected or you're asking for changes mid stream. 1670 // don't backup while it's selected or you're asking for changes mid stream.
1342 if (isTimeToPersist() || forcedBackup) 1671 if (isTimeToPersist() || forcedBackup)
1343 { 1672 {
1673 if (m_rootPart.PhysActor != null &&
1674 (!m_rootPart.PhysActor.IsPhysical))
1675 {
1676 // Possible ghost prim
1677 if (m_rootPart.PhysActor.Position != m_rootPart.GroupPosition)
1678 {
1679 foreach (SceneObjectPart part in m_parts.GetArray())
1680 {
1681 // Re-set physics actor positions and
1682 // orientations
1683 part.GroupPosition = m_rootPart.GroupPosition;
1684 }
1685 }
1686 }
1344// m_log.DebugFormat( 1687// m_log.DebugFormat(
1345// "[SCENE]: Storing {0}, {1} in {2}", 1688// "[SCENE]: Storing {0}, {1} in {2}",
1346// Name, UUID, m_scene.RegionInfo.RegionName); 1689// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1418,7 +1761,7 @@ namespace OpenSim.Region.Framework.Scenes
1418 // This is only necessary when userExposed is false! 1761 // This is only necessary when userExposed is false!
1419 1762
1420 bool previousAttachmentStatus = dupe.IsAttachment; 1763 bool previousAttachmentStatus = dupe.IsAttachment;
1421 1764
1422 if (!userExposed) 1765 if (!userExposed)
1423 dupe.IsAttachment = true; 1766 dupe.IsAttachment = true;
1424 1767
@@ -1436,11 +1779,11 @@ namespace OpenSim.Region.Framework.Scenes
1436 dupe.m_rootPart.TrimPermissions(); 1779 dupe.m_rootPart.TrimPermissions();
1437 1780
1438 List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray()); 1781 List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray());
1439 1782
1440 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1783 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1441 { 1784 {
1442 return p1.LinkNum.CompareTo(p2.LinkNum); 1785 return p1.LinkNum.CompareTo(p2.LinkNum);
1443 } 1786 }
1444 ); 1787 );
1445 1788
1446 foreach (SceneObjectPart part in partList) 1789 foreach (SceneObjectPart part in partList)
@@ -1460,7 +1803,7 @@ namespace OpenSim.Region.Framework.Scenes
1460 if (part.PhysActor != null && userExposed) 1803 if (part.PhysActor != null && userExposed)
1461 { 1804 {
1462 PrimitiveBaseShape pbs = newPart.Shape; 1805 PrimitiveBaseShape pbs = newPart.Shape;
1463 1806
1464 newPart.PhysActor 1807 newPart.PhysActor
1465 = m_scene.PhysicsScene.AddPrimShape( 1808 = m_scene.PhysicsScene.AddPrimShape(
1466 string.Format("{0}/{1}", newPart.Name, newPart.UUID), 1809 string.Format("{0}/{1}", newPart.Name, newPart.UUID),
@@ -1470,11 +1813,11 @@ namespace OpenSim.Region.Framework.Scenes
1470 newPart.RotationOffset, 1813 newPart.RotationOffset,
1471 part.PhysActor.IsPhysical, 1814 part.PhysActor.IsPhysical,
1472 newPart.LocalId); 1815 newPart.LocalId);
1473 1816
1474 newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); 1817 newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
1475 } 1818 }
1476 } 1819 }
1477 1820
1478 if (userExposed) 1821 if (userExposed)
1479 { 1822 {
1480 dupe.UpdateParentIDs(); 1823 dupe.UpdateParentIDs();
@@ -1589,6 +1932,7 @@ namespace OpenSim.Region.Framework.Scenes
1589 return Vector3.Zero; 1932 return Vector3.Zero;
1590 } 1933 }
1591 1934
1935 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object
1592 public void moveToTarget(Vector3 target, float tau) 1936 public void moveToTarget(Vector3 target, float tau)
1593 { 1937 {
1594 if (IsAttachment) 1938 if (IsAttachment)
@@ -1616,10 +1960,44 @@ namespace OpenSim.Region.Framework.Scenes
1616 RootPart.PhysActor.PIDActive = false; 1960 RootPart.PhysActor.PIDActive = false;
1617 } 1961 }
1618 1962
1963 public void rotLookAt(Quaternion target, float strength, float damping)
1964 {
1965 SceneObjectPart rootpart = m_rootPart;
1966 if (rootpart != null)
1967 {
1968 if (IsAttachment)
1969 {
1970 /*
1971 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
1972 if (avatar != null)
1973 {
1974 Rotate the Av?
1975 } */
1976 }
1977 else
1978 {
1979 if (rootpart.PhysActor != null)
1980 { // APID must be implemented in your physics system for this to function.
1981 rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W);
1982 rootpart.PhysActor.APIDStrength = strength;
1983 rootpart.PhysActor.APIDDamping = damping;
1984 rootpart.PhysActor.APIDActive = true;
1985 }
1986 }
1987 }
1988 }
1989
1619 public void stopLookAt() 1990 public void stopLookAt()
1620 { 1991 {
1621 if (RootPart.PhysActor != null) 1992 SceneObjectPart rootpart = m_rootPart;
1622 RootPart.PhysActor.APIDActive = false; 1993 if (rootpart != null)
1994 {
1995 if (rootpart.PhysActor != null)
1996 { // APID must be implemented in your physics system for this to function.
1997 rootpart.PhysActor.APIDActive = false;
1998 }
1999 }
2000
1623 } 2001 }
1624 2002
1625 /// <summary> 2003 /// <summary>
@@ -1677,6 +2055,8 @@ namespace OpenSim.Region.Framework.Scenes
1677 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 2055 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1678 { 2056 {
1679 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 2057 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
2058 newPart.SetParent(this);
2059
1680 AddPart(newPart); 2060 AddPart(newPart);
1681 2061
1682 SetPartAsNonRoot(newPart); 2062 SetPartAsNonRoot(newPart);
@@ -1823,11 +2203,11 @@ namespace OpenSim.Region.Framework.Scenes
1823 /// Immediately send a full update for this scene object. 2203 /// Immediately send a full update for this scene object.
1824 /// </summary> 2204 /// </summary>
1825 public void SendGroupFullUpdate() 2205 public void SendGroupFullUpdate()
1826 { 2206 {
1827 if (IsDeleted) 2207 if (IsDeleted)
1828 return; 2208 return;
1829 2209
1830// m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID); 2210// m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID);
1831 2211
1832 RootPart.SendFullUpdateToAllClients(); 2212 RootPart.SendFullUpdateToAllClients();
1833 2213
@@ -1991,6 +2371,7 @@ namespace OpenSim.Region.Framework.Scenes
1991 Quaternion oldRootRotation = linkPart.RotationOffset; 2371 Quaternion oldRootRotation = linkPart.RotationOffset;
1992 2372
1993 linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; 2373 linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
2374 linkPart.ParentID = m_rootPart.LocalId;
1994 linkPart.GroupPosition = AbsolutePosition; 2375 linkPart.GroupPosition = AbsolutePosition;
1995 Vector3 axPos = linkPart.OffsetPosition; 2376 Vector3 axPos = linkPart.OffsetPosition;
1996 2377
@@ -2023,12 +2404,15 @@ namespace OpenSim.Region.Framework.Scenes
2023 part.LinkNum += objectGroup.PrimCount; 2404 part.LinkNum += objectGroup.PrimCount;
2024 } 2405 }
2025 } 2406 }
2407 }
2026 2408
2027 linkPart.LinkNum = 2; 2409 linkPart.LinkNum = 2;
2028 2410
2029 linkPart.SetParent(this); 2411 linkPart.SetParent(this);
2030 linkPart.CreateSelected = true; 2412 linkPart.CreateSelected = true;
2031 2413
2414 lock (m_parts.SyncRoot)
2415 {
2032 //if (linkPart.PhysActor != null) 2416 //if (linkPart.PhysActor != null)
2033 //{ 2417 //{
2034 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2418 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
@@ -2186,6 +2570,7 @@ namespace OpenSim.Region.Framework.Scenes
2186 /// <param name="objectGroup"></param> 2570 /// <param name="objectGroup"></param>
2187 public virtual void DetachFromBackup() 2571 public virtual void DetachFromBackup()
2188 { 2572 {
2573 m_scene.SceneGraph.FireDetachFromBackup(this);
2189 if (m_isBackedUp && Scene != null) 2574 if (m_isBackedUp && Scene != null)
2190 m_scene.EventManager.OnBackup -= ProcessBackup; 2575 m_scene.EventManager.OnBackup -= ProcessBackup;
2191 2576
@@ -2204,7 +2589,8 @@ namespace OpenSim.Region.Framework.Scenes
2204 2589
2205 axPos *= parentRot; 2590 axPos *= parentRot;
2206 part.OffsetPosition = axPos; 2591 part.OffsetPosition = axPos;
2207 part.GroupPosition = oldGroupPosition + part.OffsetPosition; 2592 Vector3 newPos = oldGroupPosition + part.OffsetPosition;
2593 part.GroupPosition = newPos;
2208 part.OffsetPosition = Vector3.Zero; 2594 part.OffsetPosition = Vector3.Zero;
2209 part.RotationOffset = worldRot; 2595 part.RotationOffset = worldRot;
2210 2596
@@ -2215,7 +2601,7 @@ namespace OpenSim.Region.Framework.Scenes
2215 2601
2216 part.LinkNum = linkNum; 2602 part.LinkNum = linkNum;
2217 2603
2218 part.OffsetPosition = part.GroupPosition - AbsolutePosition; 2604 part.OffsetPosition = newPos - AbsolutePosition;
2219 2605
2220 Quaternion rootRotation = m_rootPart.RotationOffset; 2606 Quaternion rootRotation = m_rootPart.RotationOffset;
2221 2607
@@ -2225,7 +2611,7 @@ namespace OpenSim.Region.Framework.Scenes
2225 2611
2226 parentRot = m_rootPart.RotationOffset; 2612 parentRot = m_rootPart.RotationOffset;
2227 oldRot = part.RotationOffset; 2613 oldRot = part.RotationOffset;
2228 Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; 2614 Quaternion newRot = Quaternion.Inverse(parentRot) * worldRot;
2229 part.RotationOffset = newRot; 2615 part.RotationOffset = newRot;
2230 } 2616 }
2231 2617
@@ -2472,8 +2858,12 @@ namespace OpenSim.Region.Framework.Scenes
2472 } 2858 }
2473 } 2859 }
2474 2860
2861 RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect);
2475 for (int i = 0; i < parts.Length; i++) 2862 for (int i = 0; i < parts.Length; i++)
2476 parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect); 2863 {
2864 if (parts[i] != RootPart)
2865 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect);
2866 }
2477 } 2867 }
2478 } 2868 }
2479 2869
@@ -2486,6 +2876,17 @@ namespace OpenSim.Region.Framework.Scenes
2486 } 2876 }
2487 } 2877 }
2488 2878
2879
2880
2881 /// <summary>
2882 /// Gets the number of parts
2883 /// </summary>
2884 /// <returns></returns>
2885 public int GetPartCount()
2886 {
2887 return Parts.Count();
2888 }
2889
2489 /// <summary> 2890 /// <summary>
2490 /// Update the texture entry for this part 2891 /// Update the texture entry for this part
2491 /// </summary> 2892 /// </summary>
@@ -2542,7 +2943,6 @@ namespace OpenSim.Region.Framework.Scenes
2542 { 2943 {
2543// m_log.DebugFormat( 2944// m_log.DebugFormat(
2544// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); 2945// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
2545
2546 RootPart.StoreUndoState(true); 2946 RootPart.StoreUndoState(true);
2547 2947
2548 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 2948 scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
@@ -2643,7 +3043,6 @@ namespace OpenSim.Region.Framework.Scenes
2643 prevScale.X *= x; 3043 prevScale.X *= x;
2644 prevScale.Y *= y; 3044 prevScale.Y *= y;
2645 prevScale.Z *= z; 3045 prevScale.Z *= z;
2646
2647// RootPart.IgnoreUndoUpdate = true; 3046// RootPart.IgnoreUndoUpdate = true;
2648 RootPart.Resize(prevScale); 3047 RootPart.Resize(prevScale);
2649// RootPart.IgnoreUndoUpdate = false; 3048// RootPart.IgnoreUndoUpdate = false;
@@ -2674,7 +3073,9 @@ namespace OpenSim.Region.Framework.Scenes
2674 } 3073 }
2675 3074
2676// obPart.IgnoreUndoUpdate = false; 3075// obPart.IgnoreUndoUpdate = false;
2677// obPart.StoreUndoState(); 3076 HasGroupChanged = true;
3077 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
3078 ScheduleGroupForTerseUpdate();
2678 } 3079 }
2679 3080
2680// m_log.DebugFormat( 3081// m_log.DebugFormat(
@@ -2734,9 +3135,9 @@ namespace OpenSim.Region.Framework.Scenes
2734 { 3135 {
2735 SceneObjectPart part = GetChildPart(localID); 3136 SceneObjectPart part = GetChildPart(localID);
2736 3137
2737// SceneObjectPart[] parts = m_parts.GetArray(); 3138 SceneObjectPart[] parts = m_parts.GetArray();
2738// for (int i = 0; i < parts.Length; i++) 3139 for (int i = 0; i < parts.Length; i++)
2739// parts[i].StoreUndoState(); 3140 parts[i].StoreUndoState();
2740 3141
2741 if (part != null) 3142 if (part != null)
2742 { 3143 {
@@ -2792,10 +3193,27 @@ namespace OpenSim.Region.Framework.Scenes
2792 obPart.OffsetPosition = obPart.OffsetPosition + diff; 3193 obPart.OffsetPosition = obPart.OffsetPosition + diff;
2793 } 3194 }
2794 3195
2795 AbsolutePosition = newPos; 3196 //We have to set undoing here because otherwise an undo state will be saved
3197 if (!m_rootPart.Undoing)
3198 {
3199 m_rootPart.Undoing = true;
3200 AbsolutePosition = newPos;
3201 m_rootPart.Undoing = false;
3202 }
3203 else
3204 {
3205 AbsolutePosition = newPos;
3206 }
2796 3207
2797 HasGroupChanged = true; 3208 HasGroupChanged = true;
2798 ScheduleGroupForTerseUpdate(); 3209 if (m_rootPart.Undoing)
3210 {
3211 ScheduleGroupForFullUpdate();
3212 }
3213 else
3214 {
3215 ScheduleGroupForTerseUpdate();
3216 }
2799 } 3217 }
2800 3218
2801 public void OffsetForNewRegion(Vector3 offset) 3219 public void OffsetForNewRegion(Vector3 offset)
@@ -2877,10 +3295,7 @@ namespace OpenSim.Region.Framework.Scenes
2877 public void UpdateSingleRotation(Quaternion rot, uint localID) 3295 public void UpdateSingleRotation(Quaternion rot, uint localID)
2878 { 3296 {
2879 SceneObjectPart part = GetChildPart(localID); 3297 SceneObjectPart part = GetChildPart(localID);
2880
2881 SceneObjectPart[] parts = m_parts.GetArray(); 3298 SceneObjectPart[] parts = m_parts.GetArray();
2882 for (int i = 0; i < parts.Length; i++)
2883 parts[i].StoreUndoState();
2884 3299
2885 if (part != null) 3300 if (part != null)
2886 { 3301 {
@@ -2918,7 +3333,16 @@ namespace OpenSim.Region.Framework.Scenes
2918 if (part.UUID == m_rootPart.UUID) 3333 if (part.UUID == m_rootPart.UUID)
2919 { 3334 {
2920 UpdateRootRotation(rot); 3335 UpdateRootRotation(rot);
2921 AbsolutePosition = pos; 3336 if (!m_rootPart.Undoing)
3337 {
3338 m_rootPart.Undoing = true;
3339 AbsolutePosition = pos;
3340 m_rootPart.Undoing = false;
3341 }
3342 else
3343 {
3344 AbsolutePosition = pos;
3345 }
2922 } 3346 }
2923 else 3347 else
2924 { 3348 {
@@ -2942,9 +3366,10 @@ namespace OpenSim.Region.Framework.Scenes
2942 3366
2943 Quaternion axRot = rot; 3367 Quaternion axRot = rot;
2944 Quaternion oldParentRot = m_rootPart.RotationOffset; 3368 Quaternion oldParentRot = m_rootPart.RotationOffset;
2945
2946 m_rootPart.StoreUndoState(); 3369 m_rootPart.StoreUndoState();
2947 m_rootPart.UpdateRotation(rot); 3370
3371 //Don't use UpdateRotation because it schedules an update prematurely
3372 m_rootPart.RotationOffset = rot;
2948 if (m_rootPart.PhysActor != null) 3373 if (m_rootPart.PhysActor != null)
2949 { 3374 {
2950 m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; 3375 m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset;
@@ -2958,15 +3383,18 @@ namespace OpenSim.Region.Framework.Scenes
2958 if (prim.UUID != m_rootPart.UUID) 3383 if (prim.UUID != m_rootPart.UUID)
2959 { 3384 {
2960 prim.IgnoreUndoUpdate = true; 3385 prim.IgnoreUndoUpdate = true;
3386
3387 Quaternion NewRot = oldParentRot * prim.RotationOffset;
3388 NewRot = Quaternion.Inverse(axRot) * NewRot;
3389 prim.RotationOffset = NewRot;
3390
2961 Vector3 axPos = prim.OffsetPosition; 3391 Vector3 axPos = prim.OffsetPosition;
3392
2962 axPos *= oldParentRot; 3393 axPos *= oldParentRot;
2963 axPos *= Quaternion.Inverse(axRot); 3394 axPos *= Quaternion.Inverse(axRot);
2964 prim.OffsetPosition = axPos; 3395 prim.OffsetPosition = axPos;
2965 Quaternion primsRot = prim.RotationOffset; 3396
2966 Quaternion newRot = primsRot * oldParentRot; 3397 prim.IgnoreUndoUpdate = false;
2967 newRot *= Quaternion.Inverse(axRot);
2968 prim.RotationOffset = newRot;
2969 prim.ScheduleTerseUpdate();
2970 prim.IgnoreUndoUpdate = false; 3398 prim.IgnoreUndoUpdate = false;
2971 } 3399 }
2972 } 3400 }
@@ -2980,8 +3408,8 @@ namespace OpenSim.Region.Framework.Scenes
2980//// childpart.StoreUndoState(); 3408//// childpart.StoreUndoState();
2981// } 3409// }
2982// } 3410// }
2983 3411 HasGroupChanged = true;
2984 m_rootPart.ScheduleTerseUpdate(); 3412 ScheduleGroupForFullUpdate();
2985 3413
2986// m_log.DebugFormat( 3414// m_log.DebugFormat(
2987// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", 3415// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}",
@@ -3209,7 +3637,6 @@ namespace OpenSim.Region.Framework.Scenes
3209 public float GetMass() 3637 public float GetMass()
3210 { 3638 {
3211 float retmass = 0f; 3639 float retmass = 0f;
3212
3213 SceneObjectPart[] parts = m_parts.GetArray(); 3640 SceneObjectPart[] parts = m_parts.GetArray();
3214 for (int i = 0; i < parts.Length; i++) 3641 for (int i = 0; i < parts.Length; i++)
3215 retmass += parts[i].GetMass(); 3642 retmass += parts[i].GetMass();
@@ -3303,6 +3730,14 @@ namespace OpenSim.Region.Framework.Scenes
3303 SetFromItemID(uuid); 3730 SetFromItemID(uuid);
3304 } 3731 }
3305 3732
3733 public void ResetOwnerChangeFlag()
3734 {
3735 ForEachPart(delegate(SceneObjectPart part)
3736 {
3737 part.ResetOwnerChangeFlag();
3738 });
3739 }
3740
3306 #endregion 3741 #endregion
3307 } 3742 }
3308} 3743}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 3a4f52e..0a8edf9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -62,7 +62,8 @@ namespace OpenSim.Region.Framework.Scenes
62 TELEPORT = 512, 62 TELEPORT = 512,
63 REGION_RESTART = 1024, 63 REGION_RESTART = 1024,
64 MEDIA = 2048, 64 MEDIA = 2048,
65 ANIMATION = 16384 65 ANIMATION = 16384,
66 POSITION = 32768
66 } 67 }
67 68
68 // I don't really know where to put this except here. 69 // I don't really know where to put this except here.
@@ -177,6 +178,15 @@ namespace OpenSim.Region.Framework.Scenes
177 178
178 public UUID FromFolderID; 179 public UUID FromFolderID;
179 180
181 // The following two are to hold the attachment data
182 // while an object is inworld
183 [XmlIgnore]
184 public byte AttachPoint = 0;
185
186 [XmlIgnore]
187 public Vector3 AttachOffset = Vector3.Zero;
188
189 [XmlIgnore]
180 public int STATUS_ROTATE_X; 190 public int STATUS_ROTATE_X;
181 191
182 public int STATUS_ROTATE_Y; 192 public int STATUS_ROTATE_Y;
@@ -246,6 +256,7 @@ namespace OpenSim.Region.Framework.Scenes
246 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 256 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
247 private Vector3 m_sitTargetPosition; 257 private Vector3 m_sitTargetPosition;
248 private string m_sitAnimation = "SIT"; 258 private string m_sitAnimation = "SIT";
259 private bool m_occupied; // KF if any av is sitting on this prim
249 private string m_text = String.Empty; 260 private string m_text = String.Empty;
250 private string m_touchName = String.Empty; 261 private string m_touchName = String.Empty;
251 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); 262 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5);
@@ -289,6 +300,7 @@ namespace OpenSim.Region.Framework.Scenes
289 protected Vector3 m_lastAcceleration; 300 protected Vector3 m_lastAcceleration;
290 protected Vector3 m_lastAngularVelocity; 301 protected Vector3 m_lastAngularVelocity;
291 protected int m_lastTerseSent; 302 protected int m_lastTerseSent;
303 protected float m_buoyancy = 0.0f;
292 304
293 /// <summary> 305 /// <summary>
294 /// Stores media texture data 306 /// Stores media texture data
@@ -341,7 +353,7 @@ namespace OpenSim.Region.Framework.Scenes
341 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 353 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
342 Quaternion rotationOffset, Vector3 offsetPosition) 354 Quaternion rotationOffset, Vector3 offsetPosition)
343 { 355 {
344 m_name = "Primitive"; 356 m_name = "Object";
345 357
346 Rezzed = DateTime.UtcNow; 358 Rezzed = DateTime.UtcNow;
347 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 359 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
@@ -396,7 +408,7 @@ namespace OpenSim.Region.Framework.Scenes
396 private uint _ownerMask = (uint)PermissionMask.All; 408 private uint _ownerMask = (uint)PermissionMask.All;
397 private uint _groupMask = (uint)PermissionMask.None; 409 private uint _groupMask = (uint)PermissionMask.None;
398 private uint _everyoneMask = (uint)PermissionMask.None; 410 private uint _everyoneMask = (uint)PermissionMask.None;
399 private uint _nextOwnerMask = (uint)PermissionMask.All; 411 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
400 private PrimFlags _flags = PrimFlags.None; 412 private PrimFlags _flags = PrimFlags.None;
401 private DateTime m_expires; 413 private DateTime m_expires;
402 private DateTime m_rezzed; 414 private DateTime m_rezzed;
@@ -495,12 +507,16 @@ namespace OpenSim.Region.Framework.Scenes
495 } 507 }
496 508
497 /// <value> 509 /// <value>
498 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 510 /// Get the inventory list
499 /// </value> 511 /// </value>
500 public TaskInventoryDictionary TaskInventory 512 public TaskInventoryDictionary TaskInventory
501 { 513 {
502 get { return m_inventory.Items; } 514 get {
503 set { m_inventory.Items = value; } 515 return m_inventory.Items;
516 }
517 set {
518 m_inventory.Items = value;
519 }
504 } 520 }
505 521
506 /// <summary> 522 /// <summary>
@@ -641,14 +657,12 @@ namespace OpenSim.Region.Framework.Scenes
641 set { m_LoopSoundSlavePrims = value; } 657 set { m_LoopSoundSlavePrims = value; }
642 } 658 }
643 659
644
645 public Byte[] TextureAnimation 660 public Byte[] TextureAnimation
646 { 661 {
647 get { return m_TextureAnimation; } 662 get { return m_TextureAnimation; }
648 set { m_TextureAnimation = value; } 663 set { m_TextureAnimation = value; }
649 } 664 }
650 665
651
652 public Byte[] ParticleSystem 666 public Byte[] ParticleSystem
653 { 667 {
654 get { return m_particleSystem; } 668 get { return m_particleSystem; }
@@ -685,9 +699,11 @@ namespace OpenSim.Region.Framework.Scenes
685 { 699 {
686 // If this is a linkset, we don't want the physics engine mucking up our group position here. 700 // If this is a linkset, we don't want the physics engine mucking up our group position here.
687 PhysicsActor actor = PhysActor; 701 PhysicsActor actor = PhysActor;
688 if (actor != null && _parentID == 0) 702 if (_parentID == 0)
689 { 703 {
690 m_groupPosition = actor.Position; 704 if (actor != null)
705 m_groupPosition = actor.Position;
706 return m_groupPosition;
691 } 707 }
692 708
693 if (m_parentGroup.IsAttachment) 709 if (m_parentGroup.IsAttachment)
@@ -697,12 +713,14 @@ namespace OpenSim.Region.Framework.Scenes
697 return sp.AbsolutePosition; 713 return sp.AbsolutePosition;
698 } 714 }
699 715
716 // use root prim's group position. Physics may have updated it
717 if (ParentGroup.RootPart != this)
718 m_groupPosition = ParentGroup.RootPart.GroupPosition;
700 return m_groupPosition; 719 return m_groupPosition;
701 } 720 }
702 set 721 set
703 { 722 {
704 m_groupPosition = value; 723 m_groupPosition = value;
705
706 PhysicsActor actor = PhysActor; 724 PhysicsActor actor = PhysActor;
707 if (actor != null) 725 if (actor != null)
708 { 726 {
@@ -722,22 +740,13 @@ namespace OpenSim.Region.Framework.Scenes
722 740
723 // Tell the physics engines that this prim changed. 741 // Tell the physics engines that this prim changed.
724 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 742 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
743
725 } 744 }
726 catch (Exception e) 745 catch (Exception e)
727 { 746 {
728 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 747 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
729 } 748 }
730 } 749 }
731
732 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
733 if (m_sitTargetAvatar != UUID.Zero)
734 {
735 ScenePresence avatar;
736 if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar))
737 {
738 avatar.ParentPosition = GetWorldPosition();
739 }
740 }
741 } 750 }
742 } 751 }
743 752
@@ -746,7 +755,7 @@ namespace OpenSim.Region.Framework.Scenes
746 get { return m_offsetPosition; } 755 get { return m_offsetPosition; }
747 set 756 set
748 { 757 {
749// StoreUndoState(); 758 Vector3 oldpos = m_offsetPosition;
750 m_offsetPosition = value; 759 m_offsetPosition = value;
751 760
752 if (ParentGroup != null && !ParentGroup.IsDeleted) 761 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -761,7 +770,22 @@ namespace OpenSim.Region.Framework.Scenes
761 if (m_parentGroup.Scene != null) 770 if (m_parentGroup.Scene != null)
762 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 771 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
763 } 772 }
773
774 if (!m_parentGroup.m_dupeInProgress)
775 {
776 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
777 foreach (ScenePresence av in avs)
778 {
779 if (av.ParentID == m_localId)
780 {
781 Vector3 offset = (m_offsetPosition - oldpos);
782 av.AbsolutePosition += offset;
783 av.SendAvatarDataToAllAgents();
784 }
785 }
786 }
764 } 787 }
788 TriggerScriptChangedEvent(Changed.POSITION);
765 } 789 }
766 } 790 }
767 791
@@ -888,7 +912,16 @@ namespace OpenSim.Region.Framework.Scenes
888 /// <summary></summary> 912 /// <summary></summary>
889 public Vector3 Acceleration 913 public Vector3 Acceleration
890 { 914 {
891 get { return m_acceleration; } 915 get
916 {
917 PhysicsActor actor = PhysActor;
918 if (actor != null)
919 {
920 m_acceleration = actor.Acceleration;
921 }
922 return m_acceleration;
923 }
924
892 set { m_acceleration = value; } 925 set { m_acceleration = value; }
893 } 926 }
894 927
@@ -1219,6 +1252,13 @@ namespace OpenSim.Region.Framework.Scenes
1219 _flags = value; 1252 _flags = value;
1220 } 1253 }
1221 } 1254 }
1255
1256 [XmlIgnore]
1257 public bool IsOccupied // KF If an av is sittingon this prim
1258 {
1259 get { return m_occupied; }
1260 set { m_occupied = value; }
1261 }
1222 1262
1223 /// <summary> 1263 /// <summary>
1224 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1264 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
@@ -1278,6 +1318,19 @@ namespace OpenSim.Region.Framework.Scenes
1278 set { m_collisionSoundVolume = value; } 1318 set { m_collisionSoundVolume = value; }
1279 } 1319 }
1280 1320
1321 public float Buoyancy
1322 {
1323 get { return m_buoyancy; }
1324 set
1325 {
1326 m_buoyancy = value;
1327 if (PhysActor != null)
1328 {
1329 PhysActor.Buoyancy = value;
1330 }
1331 }
1332 }
1333
1281 #endregion Public Properties with only Get 1334 #endregion Public Properties with only Get
1282 1335
1283 private uint ApplyMask(uint val, bool set, uint mask) 1336 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1649,6 +1702,9 @@ namespace OpenSim.Region.Framework.Scenes
1649 1702
1650 // Move afterwards ResetIDs as it clears the localID 1703 // Move afterwards ResetIDs as it clears the localID
1651 dupe.LocalId = localID; 1704 dupe.LocalId = localID;
1705 if(dupe.PhysActor != null)
1706 dupe.PhysActor.LocalID = localID;
1707
1652 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1708 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1653 dupe._lastOwnerID = OwnerID; 1709 dupe._lastOwnerID = OwnerID;
1654 1710
@@ -2010,19 +2066,17 @@ namespace OpenSim.Region.Framework.Scenes
2010 public Vector3 GetWorldPosition() 2066 public Vector3 GetWorldPosition()
2011 { 2067 {
2012 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 2068 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
2013
2014 Vector3 axPos = OffsetPosition; 2069 Vector3 axPos = OffsetPosition;
2015
2016 axPos *= parentRot; 2070 axPos *= parentRot;
2017 Vector3 translationOffsetPosition = axPos; 2071 Vector3 translationOffsetPosition = axPos;
2018 2072 if(_parentID == 0)
2019// m_log.DebugFormat("[SCENE OBJECT PART]: Found group pos {0} for part {1}", GroupPosition, Name); 2073 {
2020 2074 return GroupPosition;
2021 Vector3 worldPos = GroupPosition + translationOffsetPosition; 2075 }
2022 2076 else
2023// m_log.DebugFormat("[SCENE OBJECT PART]: Found world pos {0} for part {1}", worldPos, Name); 2077 {
2024 2078 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
2025 return worldPos; 2079 }
2026 } 2080 }
2027 2081
2028 /// <summary> 2082 /// <summary>
@@ -2662,17 +2716,18 @@ namespace OpenSim.Region.Framework.Scenes
2662 //Trys to fetch sound id from prim's inventory. 2716 //Trys to fetch sound id from prim's inventory.
2663 //Prim's inventory doesn't support non script items yet 2717 //Prim's inventory doesn't support non script items yet
2664 2718
2665 lock (TaskInventory) 2719 TaskInventory.LockItemsForRead(true);
2720
2721 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2666 { 2722 {
2667 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2723 if (item.Value.Name == sound)
2668 { 2724 {
2669 if (item.Value.Name == sound) 2725 soundID = item.Value.ItemID;
2670 { 2726 break;
2671 soundID = item.Value.ItemID;
2672 break;
2673 }
2674 } 2727 }
2675 } 2728 }
2729
2730 TaskInventory.LockItemsForRead(false);
2676 } 2731 }
2677 2732
2678 m_parentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp) 2733 m_parentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2755,7 +2810,7 @@ namespace OpenSim.Region.Framework.Scenes
2755 2810
2756 public void RotLookAt(Quaternion target, float strength, float damping) 2811 public void RotLookAt(Quaternion target, float strength, float damping)
2757 { 2812 {
2758 rotLookAt(target, strength, damping); 2813 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup.
2759 } 2814 }
2760 2815
2761 public void rotLookAt(Quaternion target, float strength, float damping) 2816 public void rotLookAt(Quaternion target, float strength, float damping)
@@ -3001,8 +3056,8 @@ namespace OpenSim.Region.Framework.Scenes
3001 { 3056 {
3002 const float ROTATION_TOLERANCE = 0.01f; 3057 const float ROTATION_TOLERANCE = 0.01f;
3003 const float VELOCITY_TOLERANCE = 0.001f; 3058 const float VELOCITY_TOLERANCE = 0.001f;
3004 const float POSITION_TOLERANCE = 0.05f; 3059 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
3005 const int TIME_MS_TOLERANCE = 3000; 3060 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
3006 3061
3007 if (m_updateFlag == 1) 3062 if (m_updateFlag == 1)
3008 { 3063 {
@@ -3016,7 +3071,7 @@ namespace OpenSim.Region.Framework.Scenes
3016 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3071 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
3017 { 3072 {
3018 AddTerseUpdateToAllAvatars(); 3073 AddTerseUpdateToAllAvatars();
3019 ClearUpdateSchedule(); 3074
3020 3075
3021 // This causes the Scene to 'poll' physical objects every couple of frames 3076 // This causes the Scene to 'poll' physical objects every couple of frames
3022 // bad, so it's been replaced by an event driven method. 3077 // bad, so it's been replaced by an event driven method.
@@ -3034,16 +3089,18 @@ namespace OpenSim.Region.Framework.Scenes
3034 m_lastAngularVelocity = AngularVelocity; 3089 m_lastAngularVelocity = AngularVelocity;
3035 m_lastTerseSent = Environment.TickCount; 3090 m_lastTerseSent = Environment.TickCount;
3036 } 3091 }
3092 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
3093 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
3037 } 3094 }
3038 else 3095 else
3039 { 3096 {
3040 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 3097 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
3041 { 3098 {
3042 AddFullUpdateToAllAvatars(); 3099 AddFullUpdateToAllAvatars();
3043 ClearUpdateSchedule(); 3100 m_updateFlag = 0; //Same here
3044 } 3101 }
3045 } 3102 }
3046 ClearUpdateSchedule(); 3103 m_updateFlag = 0;
3047 } 3104 }
3048 3105
3049 /// <summary> 3106 /// <summary>
@@ -3071,17 +3128,16 @@ namespace OpenSim.Region.Framework.Scenes
3071 if (!UUID.TryParse(sound, out soundID)) 3128 if (!UUID.TryParse(sound, out soundID))
3072 { 3129 {
3073 // search sound file from inventory 3130 // search sound file from inventory
3074 lock (TaskInventory) 3131 TaskInventory.LockItemsForRead(true);
3132 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
3075 { 3133 {
3076 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3134 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
3077 { 3135 {
3078 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3136 soundID = item.Value.ItemID;
3079 { 3137 break;
3080 soundID = item.Value.ItemID;
3081 break;
3082 }
3083 } 3138 }
3084 } 3139 }
3140 TaskInventory.LockItemsForRead(false);
3085 } 3141 }
3086 3142
3087 if (soundID == UUID.Zero) 3143 if (soundID == UUID.Zero)
@@ -3492,7 +3548,7 @@ namespace OpenSim.Region.Framework.Scenes
3492 3548
3493 public void StopLookAt() 3549 public void StopLookAt()
3494 { 3550 {
3495 m_parentGroup.stopLookAt(); 3551 m_parentGroup.stopLookAt(); // This calls method in SceneObjectGroup.
3496 3552
3497 m_parentGroup.ScheduleGroupForTerseUpdate(); 3553 m_parentGroup.ScheduleGroupForTerseUpdate();
3498 } 3554 }
@@ -3543,45 +3599,45 @@ namespace OpenSim.Region.Framework.Scenes
3543 // TODO: May need to fix for group comparison 3599 // TODO: May need to fix for group comparison
3544 if (last.Compare(this)) 3600 if (last.Compare(this))
3545 { 3601 {
3546 // m_log.DebugFormat( 3602 // m_log.DebugFormat(
3547 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", 3603 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3548 // Name, LocalId, m_undo.Count); 3604 // Name, LocalId, m_undo.Count);
3549 3605
3550 return; 3606 return;
3551 } 3607 }
3552 } 3608 }
3553 } 3609 }
3554 3610
3555 // m_log.DebugFormat( 3611 // m_log.DebugFormat(
3556 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", 3612 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3557 // Name, LocalId, forGroup, m_undo.Count); 3613 // Name, LocalId, forGroup, m_undo.Count);
3558 3614
3559 if (m_parentGroup.GetSceneMaxUndo() > 0) 3615 if (m_parentGroup.GetSceneMaxUndo() > 0)
3560 { 3616 {
3561 UndoState nUndo = new UndoState(this, forGroup); 3617 UndoState nUndo = new UndoState(this, forGroup);
3562 3618
3563 m_undo.Push(nUndo); 3619 m_undo.Push(nUndo);
3564 3620
3565 if (m_redo.Count > 0) 3621 if (m_redo.Count > 0)
3566 m_redo.Clear(); 3622 m_redo.Clear();
3567 3623
3568 // m_log.DebugFormat( 3624 // m_log.DebugFormat(
3569 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", 3625 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3570 // Name, LocalId, forGroup, m_undo.Count); 3626 // Name, LocalId, forGroup, m_undo.Count);
3571 } 3627 }
3572 } 3628 }
3573 } 3629 }
3574 } 3630 }
3575// else 3631 // else
3576// { 3632 // {
3577// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); 3633 // m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3578// } 3634 // }
3579 } 3635 }
3580// else 3636 // else
3581// { 3637 // {
3582// m_log.DebugFormat( 3638 // m_log.DebugFormat(
3583// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); 3639 // "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3584// } 3640 // }
3585 } 3641 }
3586 3642
3587 /// <summary> 3643 /// <summary>
@@ -4628,8 +4684,9 @@ namespace OpenSim.Region.Framework.Scenes
4628 { 4684 {
4629 m_shape.TextureEntry = textureEntry; 4685 m_shape.TextureEntry = textureEntry;
4630 TriggerScriptChangedEvent(Changed.TEXTURE); 4686 TriggerScriptChangedEvent(Changed.TEXTURE);
4631 4687 m_updateFlag = 1;
4632 ParentGroup.HasGroupChanged = true; 4688 ParentGroup.HasGroupChanged = true;
4689
4633 //This is madness.. 4690 //This is madness..
4634 //ParentGroup.ScheduleGroupForFullUpdate(); 4691 //ParentGroup.ScheduleGroupForFullUpdate();
4635 //This is sparta 4692 //This is sparta
@@ -4826,5 +4883,17 @@ namespace OpenSim.Region.Framework.Scenes
4826 Color color = Color; 4883 Color color = Color;
4827 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 4884 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4828 } 4885 }
4886
4887 public void ResetOwnerChangeFlag()
4888 {
4889 List<UUID> inv = Inventory.GetInventoryList();
4890
4891 foreach (UUID itemID in inv)
4892 {
4893 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
4894 item.OwnerChanged = false;
4895 Inventory.UpdateInventoryItem(item, false, false);
4896 }
4897 }
4829 } 4898 }
4830} 4899}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 9446741..4edc220 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -48,6 +48,9 @@ namespace OpenSim.Region.Framework.Scenes
48 private string m_inventoryFileName = String.Empty; 48 private string m_inventoryFileName = String.Empty;
49 private byte[] m_inventoryFileData = new byte[0]; 49 private byte[] m_inventoryFileData = new byte[0];
50 private uint m_inventoryFileNameSerial = 0; 50 private uint m_inventoryFileNameSerial = 0;
51 private bool m_inventoryPrivileged = false;
52
53 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
51 54
52 /// <value> 55 /// <value>
53 /// The part to which the inventory belongs. 56 /// The part to which the inventory belongs.
@@ -84,11 +87,14 @@ namespace OpenSim.Region.Framework.Scenes
84 /// </value> 87 /// </value>
85 protected internal TaskInventoryDictionary Items 88 protected internal TaskInventoryDictionary Items
86 { 89 {
87 get { return m_items; } 90 get {
91 return m_items;
92 }
88 set 93 set
89 { 94 {
90 m_items = value; 95 m_items = value;
91 m_inventorySerial++; 96 m_inventorySerial++;
97 QueryScriptStates();
92 } 98 }
93 } 99 }
94 100
@@ -123,38 +129,45 @@ namespace OpenSim.Region.Framework.Scenes
123 public void ResetInventoryIDs() 129 public void ResetInventoryIDs()
124 { 130 {
125 if (null == m_part) 131 if (null == m_part)
126 return; 132 m_items.LockItemsForWrite(true);
127 133
128 lock (m_items) 134 if (Items.Count == 0)
129 { 135 {
130 if (0 == m_items.Count) 136 m_items.LockItemsForWrite(false);
131 return; 137 return;
138 }
132 139
133 IList<TaskInventoryItem> items = GetInventoryItems(); 140 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
134 m_items.Clear(); 141 Items.Clear();
135 142
136 foreach (TaskInventoryItem item in items) 143 foreach (TaskInventoryItem item in items)
137 { 144 {
138 item.ResetIDs(m_part.UUID); 145 item.ResetIDs(m_part.UUID);
139 m_items.Add(item.ItemID, item); 146 Items.Add(item.ItemID, item);
140 }
141 } 147 }
148 m_items.LockItemsForWrite(false);
142 } 149 }
143 150
144 public void ResetObjectID() 151 public void ResetObjectID()
145 { 152 {
146 lock (Items) 153 m_items.LockItemsForWrite(true);
154
155 if (Items.Count == 0)
147 { 156 {
148 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 157 m_items.LockItemsForWrite(false);
149 Items.Clear(); 158 return;
150
151 foreach (TaskInventoryItem item in items)
152 {
153 item.ParentPartID = m_part.UUID;
154 item.ParentID = m_part.UUID;
155 Items.Add(item.ItemID, item);
156 }
157 } 159 }
160
161 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
162 Items.Clear();
163
164 foreach (TaskInventoryItem item in items)
165 {
166 item.ParentPartID = m_part.UUID;
167 item.ParentID = m_part.UUID;
168 Items.Add(item.ItemID, item);
169 }
170 m_items.LockItemsForWrite(false);
158 } 171 }
159 172
160 /// <summary> 173 /// <summary>
@@ -163,12 +176,11 @@ namespace OpenSim.Region.Framework.Scenes
163 /// <param name="ownerId"></param> 176 /// <param name="ownerId"></param>
164 public void ChangeInventoryOwner(UUID ownerId) 177 public void ChangeInventoryOwner(UUID ownerId)
165 { 178 {
166 lock (Items) 179 m_items.LockItemsForWrite(true);
180 if (0 == Items.Count)
167 { 181 {
168 if (0 == Items.Count) 182 m_items.LockItemsForWrite(false);
169 { 183 return;
170 return;
171 }
172 } 184 }
173 185
174 HasInventoryChanged = true; 186 HasInventoryChanged = true;
@@ -184,6 +196,7 @@ namespace OpenSim.Region.Framework.Scenes
184 item.PermsGranter = UUID.Zero; 196 item.PermsGranter = UUID.Zero;
185 item.OwnerChanged = true; 197 item.OwnerChanged = true;
186 } 198 }
199 m_items.LockItemsForWrite(false);
187 } 200 }
188 201
189 /// <summary> 202 /// <summary>
@@ -192,12 +205,11 @@ namespace OpenSim.Region.Framework.Scenes
192 /// <param name="groupID"></param> 205 /// <param name="groupID"></param>
193 public void ChangeInventoryGroup(UUID groupID) 206 public void ChangeInventoryGroup(UUID groupID)
194 { 207 {
195 lock (Items) 208 m_items.LockItemsForWrite(true);
209 if (0 == Items.Count)
196 { 210 {
197 if (0 == Items.Count) 211 m_items.LockItemsForWrite(false);
198 { 212 return;
199 return;
200 }
201 } 213 }
202 214
203 // Don't let this set the HasGroupChanged flag for attachments 215 // Don't let this set the HasGroupChanged flag for attachments
@@ -209,12 +221,45 @@ namespace OpenSim.Region.Framework.Scenes
209 m_part.ParentGroup.HasGroupChanged = true; 221 m_part.ParentGroup.HasGroupChanged = true;
210 } 222 }
211 223
212 List<TaskInventoryItem> items = GetInventoryItems(); 224 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
213 foreach (TaskInventoryItem item in items) 225 foreach (TaskInventoryItem item in items)
214 { 226 {
215 if (groupID != item.GroupID) 227 if (groupID != item.GroupID)
228 {
216 item.GroupID = groupID; 229 item.GroupID = groupID;
230 }
217 } 231 }
232 m_items.LockItemsForWrite(false);
233 }
234
235 private void QueryScriptStates()
236 {
237 if (m_part == null || m_part.ParentGroup == null)
238 return;
239
240 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
241 if (engines == null) // No engine at all
242 return;
243
244 Items.LockItemsForRead(true);
245 foreach (TaskInventoryItem item in Items.Values)
246 {
247 if (item.InvType == (int)InventoryType.LSL)
248 {
249 foreach (IScriptModule e in engines)
250 {
251 bool running;
252
253 if (e.HasScript(item.ItemID, out running))
254 {
255 item.ScriptRunning = running;
256 break;
257 }
258 }
259 }
260 }
261
262 Items.LockItemsForRead(false);
218 } 263 }
219 264
220 /// <summary> 265 /// <summary>
@@ -222,9 +267,14 @@ namespace OpenSim.Region.Framework.Scenes
222 /// </summary> 267 /// </summary>
223 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 268 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
224 { 269 {
225 List<TaskInventoryItem> scripts = GetInventoryScripts(); 270 Items.LockItemsForRead(true);
226 foreach (TaskInventoryItem item in scripts) 271 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
227 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 272 Items.LockItemsForRead(false);
273 foreach (TaskInventoryItem item in items)
274 {
275 if ((int)InventoryType.LSL == item.InvType)
276 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
277 }
228 } 278 }
229 279
230 public ArrayList GetScriptErrors(UUID itemID) 280 public ArrayList GetScriptErrors(UUID itemID)
@@ -257,9 +307,18 @@ namespace OpenSim.Region.Framework.Scenes
257 /// </param> 307 /// </param>
258 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 308 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
259 { 309 {
260 List<TaskInventoryItem> scripts = GetInventoryScripts(); 310 Items.LockItemsForRead(true);
261 foreach (TaskInventoryItem item in scripts) 311 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
262 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 312 Items.LockItemsForRead(false);
313
314 foreach (TaskInventoryItem item in items)
315 {
316 if ((int)InventoryType.LSL == item.InvType)
317 {
318 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
319 m_part.RemoveScriptEvents(item.ItemID);
320 }
321 }
263 } 322 }
264 323
265 /// <summary> 324 /// <summary>
@@ -275,7 +334,10 @@ namespace OpenSim.Region.Framework.Scenes
275 // item.Name, item.ItemID, Name, UUID); 334 // item.Name, item.ItemID, Name, UUID);
276 335
277 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 336 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
337 {
338 StoreScriptError(item.ItemID, "no permission");
278 return; 339 return;
340 }
279 341
280 m_part.AddFlag(PrimFlags.Scripted); 342 m_part.AddFlag(PrimFlags.Scripted);
281 343
@@ -284,14 +346,13 @@ namespace OpenSim.Region.Framework.Scenes
284 if (stateSource == 2 && // Prim crossing 346 if (stateSource == 2 && // Prim crossing
285 m_part.ParentGroup.Scene.m_trustBinaries) 347 m_part.ParentGroup.Scene.m_trustBinaries)
286 { 348 {
287 lock (m_items) 349 m_items.LockItemsForWrite(true);
288 { 350 m_items[item.ItemID].PermsMask = 0;
289 m_items[item.ItemID].PermsMask = 0; 351 m_items[item.ItemID].PermsGranter = UUID.Zero;
290 m_items[item.ItemID].PermsGranter = UUID.Zero; 352 m_items.LockItemsForWrite(false);
291 }
292
293 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 353 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
294 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 354 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
355 StoreScriptErrors(item.ItemID, null);
295 m_part.ParentGroup.AddActiveScriptCount(1); 356 m_part.ParentGroup.AddActiveScriptCount(1);
296 m_part.ScheduleFullUpdate(); 357 m_part.ScheduleFullUpdate();
297 return; 358 return;
@@ -300,6 +361,8 @@ namespace OpenSim.Region.Framework.Scenes
300 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 361 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
301 if (null == asset) 362 if (null == asset)
302 { 363 {
364 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
365 StoreScriptError(item.ItemID, msg);
303 m_log.ErrorFormat( 366 m_log.ErrorFormat(
304 "[PRIM INVENTORY]: " + 367 "[PRIM INVENTORY]: " +
305 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 368 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
@@ -311,15 +374,20 @@ namespace OpenSim.Region.Framework.Scenes
311 if (m_part.ParentGroup.m_savedScriptState != null) 374 if (m_part.ParentGroup.m_savedScriptState != null)
312 RestoreSavedScriptState(item.OldItemID, item.ItemID); 375 RestoreSavedScriptState(item.OldItemID, item.ItemID);
313 376
314 lock (m_items) 377 m_items.LockItemsForWrite(true);
315 { 378
316 m_items[item.ItemID].PermsMask = 0; 379 m_items[item.ItemID].PermsMask = 0;
317 m_items[item.ItemID].PermsGranter = UUID.Zero; 380 m_items[item.ItemID].PermsGranter = UUID.Zero;
318 } 381
382 m_items.LockItemsForWrite(false);
319 383
320 string script = Utils.BytesToString(asset.Data); 384 string script = Utils.BytesToString(asset.Data);
321 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 385 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
322 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 386 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
387 StoreScriptErrors(item.ItemID, null);
388 if (!item.ScriptRunning)
389 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
390 m_part.LocalId, item.ItemID);
323 m_part.ParentGroup.AddActiveScriptCount(1); 391 m_part.ParentGroup.AddActiveScriptCount(1);
324 m_part.ScheduleFullUpdate(); 392 m_part.ScheduleFullUpdate();
325 } 393 }
@@ -383,21 +451,145 @@ namespace OpenSim.Region.Framework.Scenes
383 451
384 /// <summary> 452 /// <summary>
385 /// Start a script which is in this prim's inventory. 453 /// Start a script which is in this prim's inventory.
454 /// Some processing may occur in the background, but this routine returns asap.
386 /// </summary> 455 /// </summary>
387 /// <param name="itemId"> 456 /// <param name="itemId">
388 /// A <see cref="UUID"/> 457 /// A <see cref="UUID"/>
389 /// </param> 458 /// </param>
390 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 459 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
391 { 460 {
392 TaskInventoryItem item = GetInventoryItem(itemId); 461 lock (m_scriptErrors)
393 if (item != null) 462 {
394 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 463 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
464 m_scriptErrors.Remove(itemId);
465 }
466 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
467 }
468
469 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
470 {
471 m_items.LockItemsForRead(true);
472 if (m_items.ContainsKey(itemId))
473 {
474 if (m_items.ContainsKey(itemId))
475 {
476 m_items.LockItemsForRead(false);
477 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
478 }
479 else
480 {
481 m_items.LockItemsForRead(false);
482 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
483 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
484 StoreScriptError(itemId, msg);
485 m_log.ErrorFormat(
486 "[PRIM INVENTORY]: " +
487 "Couldn't start script with ID {0} since it {1}", itemId, msg);
488 }
489 }
395 else 490 else
491 {
492 m_items.LockItemsForRead(false);
493 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
494 StoreScriptError(itemId, msg);
396 m_log.ErrorFormat( 495 m_log.ErrorFormat(
397 "[PRIM INVENTORY]: " + 496 "[PRIM INVENTORY]: " +
398 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 497 "Couldn't start script with ID {0} since it {1}", itemId, msg);
399 itemId, m_part.Name, m_part.UUID, 498 }
400 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 499
500 }
501
502 /// <summary>
503 /// Start a script which is in this prim's inventory and return any compilation error messages.
504 /// </summary>
505 /// <param name="itemId">
506 /// A <see cref="UUID"/>
507 /// </param>
508 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
509 {
510 ArrayList errors;
511
512 // Indicate to CreateScriptInstanceInternal() we want it to
513 // post any compilation/loading error messages
514 lock (m_scriptErrors)
515 {
516 m_scriptErrors[itemId] = null;
517 }
518
519 // Perform compilation/loading
520 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
521
522 // Wait for and retrieve any errors
523 lock (m_scriptErrors)
524 {
525 while ((errors = m_scriptErrors[itemId]) == null)
526 {
527 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
528 {
529 m_log.ErrorFormat(
530 "[PRIM INVENTORY]: " +
531 "timedout waiting for script {0} errors", itemId);
532 errors = m_scriptErrors[itemId];
533 if (errors == null)
534 {
535 errors = new ArrayList(1);
536 errors.Add("timedout waiting for errors");
537 }
538 break;
539 }
540 }
541 m_scriptErrors.Remove(itemId);
542 }
543 return errors;
544 }
545
546 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
547 private void StoreScriptErrors(UUID itemId, ArrayList errors)
548 {
549 lock (m_scriptErrors)
550 {
551 // If compilation/loading initiated via CreateScriptInstance(),
552 // it does not want the errors, so just get out
553 if (!m_scriptErrors.ContainsKey(itemId))
554 {
555 return;
556 }
557
558 // Initiated via CreateScriptInstanceEr(), if we know what the
559 // errors are, save them and wake CreateScriptInstanceEr().
560 if (errors != null)
561 {
562 m_scriptErrors[itemId] = errors;
563 System.Threading.Monitor.PulseAll(m_scriptErrors);
564 return;
565 }
566 }
567
568 // Initiated via CreateScriptInstanceEr() but we don't know what
569 // the errors are yet, so retrieve them from the script engine.
570 // This may involve some waiting internal to GetScriptErrors().
571 errors = GetScriptErrors(itemId);
572
573 // Get a default non-null value to indicate success.
574 if (errors == null)
575 {
576 errors = new ArrayList();
577 }
578
579 // Post to CreateScriptInstanceEr() and wake it up
580 lock (m_scriptErrors)
581 {
582 m_scriptErrors[itemId] = errors;
583 System.Threading.Monitor.PulseAll(m_scriptErrors);
584 }
585 }
586
587 // Like StoreScriptErrors(), but just posts a single string message
588 private void StoreScriptError(UUID itemId, string message)
589 {
590 ArrayList errors = new ArrayList(1);
591 errors.Add(message);
592 StoreScriptErrors(itemId, errors);
401 } 593 }
402 594
403 /// <summary> 595 /// <summary>
@@ -410,15 +602,7 @@ namespace OpenSim.Region.Framework.Scenes
410 /// </param> 602 /// </param>
411 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 603 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
412 { 604 {
413 bool scriptPresent = false; 605 if (m_items.ContainsKey(itemId))
414
415 lock (m_items)
416 {
417 if (m_items.ContainsKey(itemId))
418 scriptPresent = true;
419 }
420
421 if (scriptPresent)
422 { 606 {
423 if (!sceneObjectBeingDeleted) 607 if (!sceneObjectBeingDeleted)
424 m_part.RemoveScriptEvents(itemId); 608 m_part.RemoveScriptEvents(itemId);
@@ -443,14 +627,16 @@ namespace OpenSim.Region.Framework.Scenes
443 /// <returns></returns> 627 /// <returns></returns>
444 private bool InventoryContainsName(string name) 628 private bool InventoryContainsName(string name)
445 { 629 {
446 lock (m_items) 630 m_items.LockItemsForRead(true);
631 foreach (TaskInventoryItem item in m_items.Values)
447 { 632 {
448 foreach (TaskInventoryItem item in m_items.Values) 633 if (item.Name == name)
449 { 634 {
450 if (item.Name == name) 635 m_items.LockItemsForRead(false);
451 return true; 636 return true;
452 } 637 }
453 } 638 }
639 m_items.LockItemsForRead(false);
454 return false; 640 return false;
455 } 641 }
456 642
@@ -492,8 +678,9 @@ namespace OpenSim.Region.Framework.Scenes
492 /// <param name="item"></param> 678 /// <param name="item"></param>
493 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 679 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
494 { 680 {
495 List<TaskInventoryItem> il = GetInventoryItems(); 681 m_items.LockItemsForRead(true);
496 682 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
683 m_items.LockItemsForRead(false);
497 foreach (TaskInventoryItem i in il) 684 foreach (TaskInventoryItem i in il)
498 { 685 {
499 if (i.Name == item.Name) 686 if (i.Name == item.Name)
@@ -531,14 +718,14 @@ namespace OpenSim.Region.Framework.Scenes
531 item.Name = name; 718 item.Name = name;
532 item.GroupID = m_part.GroupID; 719 item.GroupID = m_part.GroupID;
533 720
534 lock (m_items) 721 m_items.LockItemsForWrite(true);
535 m_items.Add(item.ItemID, item); 722 m_items.Add(item.ItemID, item);
536 723 m_items.LockItemsForWrite(false);
537 if (allowedDrop) 724 if (allowedDrop)
538 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 725 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
539 else 726 else
540 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 727 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
541 728
542 m_inventorySerial++; 729 m_inventorySerial++;
543 //m_inventorySerial += 2; 730 //m_inventorySerial += 2;
544 HasInventoryChanged = true; 731 HasInventoryChanged = true;
@@ -554,15 +741,15 @@ namespace OpenSim.Region.Framework.Scenes
554 /// <param name="items"></param> 741 /// <param name="items"></param>
555 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 742 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
556 { 743 {
557 lock (m_items) 744 m_items.LockItemsForWrite(true);
745 foreach (TaskInventoryItem item in items)
558 { 746 {
559 foreach (TaskInventoryItem item in items) 747 m_items.Add(item.ItemID, item);
560 { 748// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
561 m_items.Add(item.ItemID, item);
562// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
563 }
564 m_inventorySerial++;
565 } 749 }
750 m_items.LockItemsForWrite(false);
751
752 m_inventorySerial++;
566 } 753 }
567 754
568 /// <summary> 755 /// <summary>
@@ -573,10 +760,9 @@ namespace OpenSim.Region.Framework.Scenes
573 public TaskInventoryItem GetInventoryItem(UUID itemId) 760 public TaskInventoryItem GetInventoryItem(UUID itemId)
574 { 761 {
575 TaskInventoryItem item; 762 TaskInventoryItem item;
576 763 m_items.LockItemsForRead(true);
577 lock (m_items) 764 m_items.TryGetValue(itemId, out item);
578 m_items.TryGetValue(itemId, out item); 765 m_items.LockItemsForRead(false);
579
580 return item; 766 return item;
581 } 767 }
582 768
@@ -592,15 +778,16 @@ namespace OpenSim.Region.Framework.Scenes
592 { 778 {
593 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 779 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
594 780
595 lock (m_items) 781 m_items.LockItemsForRead(true);
782
783 foreach (TaskInventoryItem item in m_items.Values)
596 { 784 {
597 foreach (TaskInventoryItem item in m_items.Values) 785 if (item.Name == name)
598 { 786 items.Add(item);
599 if (item.Name == name)
600 items.Add(item);
601 }
602 } 787 }
603 788
789 m_items.LockItemsForRead(false);
790
604 return items; 791 return items;
605 } 792 }
606 793
@@ -619,6 +806,9 @@ namespace OpenSim.Region.Framework.Scenes
619 string xmlData = Utils.BytesToString(rezAsset.Data); 806 string xmlData = Utils.BytesToString(rezAsset.Data);
620 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 807 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
621 808
809 group.RootPart.AttachPoint = group.RootPart.Shape.State;
810 group.RootPart.AttachOffset = group.AbsolutePosition;
811
622 group.ResetIDs(); 812 group.ResetIDs();
623 813
624 SceneObjectPart rootPart = group.GetChildPart(group.UUID); 814 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
@@ -693,8 +883,9 @@ namespace OpenSim.Region.Framework.Scenes
693 883
694 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 884 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
695 { 885 {
696 TaskInventoryItem it = GetInventoryItem(item.ItemID); 886 m_items.LockItemsForWrite(true);
697 if (it != null) 887
888 if (m_items.ContainsKey(item.ItemID))
698 { 889 {
699// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); 890// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
700 891
@@ -707,14 +898,10 @@ namespace OpenSim.Region.Framework.Scenes
707 item.GroupID = m_part.GroupID; 898 item.GroupID = m_part.GroupID;
708 899
709 if (item.AssetID == UUID.Zero) 900 if (item.AssetID == UUID.Zero)
710 item.AssetID = it.AssetID; 901 item.AssetID = m_items[item.ItemID].AssetID;
711 902
712 lock (m_items) 903 m_items[item.ItemID] = item;
713 { 904 m_inventorySerial++;
714 m_items[item.ItemID] = item;
715 m_inventorySerial++;
716 }
717
718 if (fireScriptEvents) 905 if (fireScriptEvents)
719 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 906 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
720 907
@@ -723,7 +910,7 @@ namespace OpenSim.Region.Framework.Scenes
723 HasInventoryChanged = true; 910 HasInventoryChanged = true;
724 m_part.ParentGroup.HasGroupChanged = true; 911 m_part.ParentGroup.HasGroupChanged = true;
725 } 912 }
726 913 m_items.LockItemsForWrite(false);
727 return true; 914 return true;
728 } 915 }
729 else 916 else
@@ -734,8 +921,9 @@ namespace OpenSim.Region.Framework.Scenes
734 item.ItemID, m_part.Name, m_part.UUID, 921 item.ItemID, m_part.Name, m_part.UUID,
735 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 922 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
736 } 923 }
737 return false; 924 m_items.LockItemsForWrite(false);
738 925
926 return false;
739 } 927 }
740 928
741 /// <summary> 929 /// <summary>
@@ -746,43 +934,59 @@ namespace OpenSim.Region.Framework.Scenes
746 /// in this prim's inventory.</returns> 934 /// in this prim's inventory.</returns>
747 public int RemoveInventoryItem(UUID itemID) 935 public int RemoveInventoryItem(UUID itemID)
748 { 936 {
749 TaskInventoryItem item = GetInventoryItem(itemID); 937 m_items.LockItemsForRead(true);
750 if (item != null) 938
939 if (m_items.ContainsKey(itemID))
751 { 940 {
752 int type = m_items[itemID].InvType; 941 int type = m_items[itemID].InvType;
942 m_items.LockItemsForRead(false);
753 if (type == 10) // Script 943 if (type == 10) // Script
754 { 944 {
755 m_part.RemoveScriptEvents(itemID);
756 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 945 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
757 } 946 }
947 m_items.LockItemsForWrite(true);
758 m_items.Remove(itemID); 948 m_items.Remove(itemID);
949 m_items.LockItemsForWrite(false);
759 m_inventorySerial++; 950 m_inventorySerial++;
760 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 951 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
761 952
762 HasInventoryChanged = true; 953 HasInventoryChanged = true;
763 m_part.ParentGroup.HasGroupChanged = true; 954 m_part.ParentGroup.HasGroupChanged = true;
764 955
765 if (!ContainsScripts()) 956 int scriptcount = 0;
957 m_items.LockItemsForRead(true);
958 foreach (TaskInventoryItem item in m_items.Values)
959 {
960 if (item.Type == 10)
961 {
962 scriptcount++;
963 }
964 }
965 m_items.LockItemsForRead(false);
966
967
968 if (scriptcount <= 0)
969 {
766 m_part.RemFlag(PrimFlags.Scripted); 970 m_part.RemFlag(PrimFlags.Scripted);
971 }
767 972
768 m_part.ScheduleFullUpdate(); 973 m_part.ScheduleFullUpdate();
769 974
770 return type; 975 return type;
771
772 } 976 }
773 else 977 else
774 { 978 {
979 m_items.LockItemsForRead(false);
775 m_log.ErrorFormat( 980 m_log.ErrorFormat(
776 "[PRIM INVENTORY]: " + 981 "[PRIM INVENTORY]: " +
777 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 982 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
778 itemID, m_part.Name, m_part.UUID, 983 itemID, m_part.Name, m_part.UUID);
779 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
780 } 984 }
781 985
782 return -1; 986 return -1;
783 } 987 }
784 988
785 private bool CreateInventoryFile() 989 private bool CreateInventoryFileName()
786 { 990 {
787// m_log.DebugFormat( 991// m_log.DebugFormat(
788// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", 992// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}",
@@ -791,116 +995,124 @@ namespace OpenSim.Region.Framework.Scenes
791 if (m_inventoryFileName == String.Empty || 995 if (m_inventoryFileName == String.Empty ||
792 m_inventoryFileNameSerial < m_inventorySerial) 996 m_inventoryFileNameSerial < m_inventorySerial)
793 { 997 {
794 // Something changed, we need to create a new file
795 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 998 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
796 m_inventoryFileNameSerial = m_inventorySerial; 999 m_inventoryFileNameSerial = m_inventorySerial;
797 1000
798 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 1001 return true;
1002 }
1003
1004 return false;
1005 }
1006
1007 /// <summary>
1008 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
1009 /// </summary>
1010 /// <param name="xferManager"></param>
1011 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
1012 {
1013 bool changed = CreateInventoryFileName();
1014
1015 bool includeAssets = false;
1016 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1017 includeAssets = true;
1018
1019 if (m_inventoryPrivileged != includeAssets)
1020 changed = true;
1021
1022 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1023
1024 Items.LockItemsForRead(true);
1025
1026 if (m_inventorySerial == 0) // No inventory
1027 {
1028 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1029 Items.LockItemsForRead(false);
1030 return;
1031 }
799 1032
800 lock (m_items) 1033 if (m_items.Count == 0) // No inventory
1034 {
1035 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1036 return;
1037 }
1038
1039 if (!changed)
1040 {
1041 if (m_inventoryFileData.Length > 2)
801 { 1042 {
802 foreach (TaskInventoryItem item in m_items.Values) 1043 xferManager.AddNewFile(m_inventoryFileName,
803 { 1044 m_inventoryFileData);
804// m_log.DebugFormat( 1045 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
805// "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", 1046 Util.StringToBytes256(m_inventoryFileName));
806// item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId);
807 1047
808 UUID ownerID = item.OwnerID; 1048 Items.LockItemsForRead(false);
809 uint everyoneMask = 0; 1049 return;
810 uint baseMask = item.BasePermissions; 1050 }
811 uint ownerMask = item.CurrentPermissions; 1051 }
812 uint groupMask = item.GroupPermissions;
813 1052
814 invString.AddItemStart(); 1053 m_inventoryPrivileged = includeAssets;
815 invString.AddNameValueLine("item_id", item.ItemID.ToString());
816 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
817 1054
818 invString.AddPermissionsStart(); 1055 foreach (TaskInventoryItem item in m_items.Values)
1056 {
1057 UUID ownerID = item.OwnerID;
1058 uint everyoneMask = 0;
1059 uint baseMask = item.BasePermissions;
1060 uint ownerMask = item.CurrentPermissions;
1061 uint groupMask = item.GroupPermissions;
819 1062
820 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 1063 invString.AddItemStart();
821 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 1064 invString.AddNameValueLine("item_id", item.ItemID.ToString());
822 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); 1065 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
823 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
824 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
825 1066
826 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 1067 invString.AddPermissionsStart();
827 invString.AddNameValueLine("owner_id", ownerID.ToString());
828 1068
829 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 1069 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1070 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1071 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1072 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1073 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
830 1074
831 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 1075 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
832 invString.AddSectionEnd(); 1076 invString.AddNameValueLine("owner_id", ownerID.ToString());
833 1077
834 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 1078 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
835 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
836 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
837 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
838 1079
839 invString.AddSaleStart(); 1080 invString.AddNameValueLine("group_id", item.GroupID.ToString());
840 invString.AddNameValueLine("sale_type", "not"); 1081 invString.AddSectionEnd();
841 invString.AddNameValueLine("sale_price", "0");
842 invString.AddSectionEnd();
843 1082
844 invString.AddNameValueLine("name", item.Name + "|"); 1083 if (includeAssets)
845 invString.AddNameValueLine("desc", item.Description + "|"); 1084 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1085 else
1086 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1087 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
1088 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
1089 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
846 1090
847 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 1091 invString.AddSaleStart();
848 invString.AddSectionEnd(); 1092 invString.AddNameValueLine("sale_type", "not");
849 } 1093 invString.AddNameValueLine("sale_price", "0");
850 } 1094 invString.AddSectionEnd();
851 1095
852 m_inventoryFileData = Utils.StringToBytes(invString.BuildString); 1096 invString.AddNameValueLine("name", item.Name + "|");
1097 invString.AddNameValueLine("desc", item.Description + "|");
853 1098
854 return true; 1099 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1100 invString.AddSectionEnd();
855 } 1101 }
856 1102
857 // No need to recreate, the existing file is fine 1103 Items.LockItemsForRead(false);
858 return false;
859 }
860 1104
861 /// <summary> 1105 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
862 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
863 /// </summary>
864 /// <param name="xferManager"></param>
865 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
866 {
867 lock (m_items)
868 {
869 // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing
870 // a new script if any previous deletion has left the prim inventory empty.
871 if (m_items.Count == 0) // No inventory
872 {
873// m_log.DebugFormat(
874// "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items",
875// m_part.Name, m_part.LocalId, m_part.UUID, client.Name);
876 1106
877 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1107 if (m_inventoryFileData.Length > 2)
878 return; 1108 {
879 } 1109 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
880 1110 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
881 CreateInventoryFile(); 1111 Util.StringToBytes256(m_inventoryFileName));
882 1112 return;
883 // In principle, we should only do the rest if the inventory changed;
884 // by sending m_inventorySerial to the client, it ought to know
885 // that nothing changed and that it doesn't need to request the file.
886 // Unfortunately, it doesn't look like the client optimizes this;
887 // the client seems to always come back and request the Xfer,
888 // no matter what value m_inventorySerial has.
889 // FIXME: Could probably be > 0 here rather than > 2
890 if (m_inventoryFileData.Length > 2)
891 {
892 // Add the file for Xfer
893 // m_log.DebugFormat(
894 // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}",
895 // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId);
896
897 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
898 }
899
900 // Tell the client we're ready to Xfer the file
901 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
902 Util.StringToBytes256(m_inventoryFileName));
903 } 1113 }
1114
1115 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
904 } 1116 }
905 1117
906 /// <summary> 1118 /// <summary>
@@ -911,10 +1123,11 @@ namespace OpenSim.Region.Framework.Scenes
911 { 1123 {
912 if (HasInventoryChanged) 1124 if (HasInventoryChanged)
913 { 1125 {
914 HasInventoryChanged = false; 1126 Items.LockItemsForRead(true);
915 List<TaskInventoryItem> items = GetInventoryItems(); 1127 datastore.StorePrimInventory(m_part.UUID, Items.Values);
916 datastore.StorePrimInventory(m_part.UUID, items); 1128 Items.LockItemsForRead(false);
917 1129
1130 HasInventoryChanged = false;
918 } 1131 }
919 } 1132 }
920 1133
@@ -981,82 +1194,63 @@ namespace OpenSim.Region.Framework.Scenes
981 { 1194 {
982 uint mask=0x7fffffff; 1195 uint mask=0x7fffffff;
983 1196
984 lock (m_items) 1197 foreach (TaskInventoryItem item in m_items.Values)
985 { 1198 {
986 foreach (TaskInventoryItem item in m_items.Values) 1199 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1200 mask &= ~((uint)PermissionMask.Copy >> 13);
1201 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1202 mask &= ~((uint)PermissionMask.Transfer >> 13);
1203 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1204 mask &= ~((uint)PermissionMask.Modify >> 13);
1205
1206 if (item.InvType == (int)InventoryType.Object)
987 { 1207 {
988 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1208 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
989 mask &= ~((uint)PermissionMask.Copy >> 13); 1209 mask &= ~((uint)PermissionMask.Copy >> 13);
990 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1210 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
991 mask &= ~((uint)PermissionMask.Transfer >> 13); 1211 mask &= ~((uint)PermissionMask.Transfer >> 13);
992 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1212 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
993 mask &= ~((uint)PermissionMask.Modify >> 13); 1213 mask &= ~((uint)PermissionMask.Modify >> 13);
994
995 if (item.InvType != (int)InventoryType.Object)
996 {
997 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
998 mask &= ~((uint)PermissionMask.Copy >> 13);
999 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1000 mask &= ~((uint)PermissionMask.Transfer >> 13);
1001 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1002 mask &= ~((uint)PermissionMask.Modify >> 13);
1003 }
1004 else
1005 {
1006 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1007 mask &= ~((uint)PermissionMask.Copy >> 13);
1008 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1009 mask &= ~((uint)PermissionMask.Transfer >> 13);
1010 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1011 mask &= ~((uint)PermissionMask.Modify >> 13);
1012 }
1013
1014 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1015 mask &= ~(uint)PermissionMask.Copy;
1016 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1017 mask &= ~(uint)PermissionMask.Transfer;
1018 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1019 mask &= ~(uint)PermissionMask.Modify;
1020 } 1214 }
1215
1216 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1217 mask &= ~(uint)PermissionMask.Copy;
1218 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1219 mask &= ~(uint)PermissionMask.Transfer;
1220 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1221 mask &= ~(uint)PermissionMask.Modify;
1021 } 1222 }
1022
1023 return mask; 1223 return mask;
1024 } 1224 }
1025 1225
1026 public void ApplyNextOwnerPermissions() 1226 public void ApplyNextOwnerPermissions()
1027 { 1227 {
1028 lock (m_items) 1228 foreach (TaskInventoryItem item in m_items.Values)
1029 { 1229 {
1030 foreach (TaskInventoryItem item in m_items.Values) 1230 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
1031 { 1231 {
1032 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1232 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1033 { 1233 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1034 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1234 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1035 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1235 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1036 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1236 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1037 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1237 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1038 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1039 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1040 }
1041 item.CurrentPermissions &= item.NextPermissions;
1042 item.BasePermissions &= item.NextPermissions;
1043 item.EveryonePermissions &= item.NextPermissions;
1044 item.OwnerChanged = true;
1045 item.PermsMask = 0;
1046 item.PermsGranter = UUID.Zero;
1047 } 1238 }
1239 item.OwnerChanged = true;
1240 item.CurrentPermissions &= item.NextPermissions;
1241 item.BasePermissions &= item.NextPermissions;
1242 item.EveryonePermissions &= item.NextPermissions;
1243 item.PermsMask = 0;
1244 item.PermsGranter = UUID.Zero;
1048 } 1245 }
1049 } 1246 }
1050 1247
1051 public void ApplyGodPermissions(uint perms) 1248 public void ApplyGodPermissions(uint perms)
1052 { 1249 {
1053 lock (m_items) 1250 foreach (TaskInventoryItem item in m_items.Values)
1054 { 1251 {
1055 foreach (TaskInventoryItem item in m_items.Values) 1252 item.CurrentPermissions = perms;
1056 { 1253 item.BasePermissions = perms;
1057 item.CurrentPermissions = perms;
1058 item.BasePermissions = perms;
1059 }
1060 } 1254 }
1061 1255
1062 m_inventorySerial++; 1256 m_inventorySerial++;
@@ -1069,17 +1263,13 @@ namespace OpenSim.Region.Framework.Scenes
1069 /// <returns></returns> 1263 /// <returns></returns>
1070 public bool ContainsScripts() 1264 public bool ContainsScripts()
1071 { 1265 {
1072 lock (m_items) 1266 foreach (TaskInventoryItem item in m_items.Values)
1073 { 1267 {
1074 foreach (TaskInventoryItem item in m_items.Values) 1268 if (item.InvType == (int)InventoryType.LSL)
1075 { 1269 {
1076 if (item.InvType == (int)InventoryType.LSL) 1270 return true;
1077 {
1078 return true;
1079 }
1080 } 1271 }
1081 } 1272 }
1082
1083 return false; 1273 return false;
1084 } 1274 }
1085 1275
@@ -1087,11 +1277,8 @@ namespace OpenSim.Region.Framework.Scenes
1087 { 1277 {
1088 List<UUID> ret = new List<UUID>(); 1278 List<UUID> ret = new List<UUID>();
1089 1279
1090 lock (m_items) 1280 foreach (TaskInventoryItem item in m_items.Values)
1091 { 1281 ret.Add(item.ItemID);
1092 foreach (TaskInventoryItem item in m_items.Values)
1093 ret.Add(item.ItemID);
1094 }
1095 1282
1096 return ret; 1283 return ret;
1097 } 1284 }
@@ -1122,6 +1309,11 @@ namespace OpenSim.Region.Framework.Scenes
1122 1309
1123 public Dictionary<UUID, string> GetScriptStates() 1310 public Dictionary<UUID, string> GetScriptStates()
1124 { 1311 {
1312 return GetScriptStates(false);
1313 }
1314
1315 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1316 {
1125 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1317 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1126 1318
1127 if (m_part.ParentGroup.Scene == null) // Group not in a scene 1319 if (m_part.ParentGroup.Scene == null) // Group not in a scene
@@ -1132,25 +1324,35 @@ namespace OpenSim.Region.Framework.Scenes
1132 if (engines == null) // No engine at all 1324 if (engines == null) // No engine at all
1133 return ret; 1325 return ret;
1134 1326
1135 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1327 Items.LockItemsForRead(true);
1136 1328 foreach (TaskInventoryItem item in m_items.Values)
1137 foreach (TaskInventoryItem item in scripts)
1138 { 1329 {
1139 foreach (IScriptModule e in engines) 1330 if (item.InvType == (int)InventoryType.LSL)
1140 { 1331 {
1141 if (e != null) 1332 foreach (IScriptModule e in engines)
1142 { 1333 {
1143 string n = e.GetXMLState(item.ItemID); 1334 if (e != null)
1144 if (n != String.Empty)
1145 { 1335 {
1146 if (!ret.ContainsKey(item.ItemID)) 1336 string n = e.GetXMLState(item.ItemID);
1147 ret[item.ItemID] = n; 1337 if (n != String.Empty)
1148 break; 1338 {
1339 if (oldIDs)
1340 {
1341 if (!ret.ContainsKey(item.OldItemID))
1342 ret[item.OldItemID] = n;
1343 }
1344 else
1345 {
1346 if (!ret.ContainsKey(item.ItemID))
1347 ret[item.ItemID] = n;
1348 }
1349 break;
1350 }
1149 } 1351 }
1150 } 1352 }
1151 } 1353 }
1152 } 1354 }
1153 1355 Items.LockItemsForRead(false);
1154 return ret; 1356 return ret;
1155 } 1357 }
1156 1358
@@ -1160,21 +1362,27 @@ namespace OpenSim.Region.Framework.Scenes
1160 if (engines == null) 1362 if (engines == null)
1161 return; 1363 return;
1162 1364
1163 List<TaskInventoryItem> scripts = GetInventoryScripts();
1164 1365
1165 foreach (TaskInventoryItem item in scripts) 1366 Items.LockItemsForRead(true);
1367
1368 foreach (TaskInventoryItem item in m_items.Values)
1166 { 1369 {
1167 foreach (IScriptModule engine in engines) 1370 if (item.InvType == (int)InventoryType.LSL)
1168 { 1371 {
1169 if (engine != null) 1372 foreach (IScriptModule engine in engines)
1170 { 1373 {
1171 if (item.OwnerChanged) 1374 if (engine != null)
1172 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1375 {
1173 item.OwnerChanged = false; 1376 if (item.OwnerChanged)
1174 engine.ResumeScript(item.ItemID); 1377 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1378 item.OwnerChanged = false;
1379 engine.ResumeScript(item.ItemID);
1380 }
1175 } 1381 }
1176 } 1382 }
1177 } 1383 }
1384
1385 Items.LockItemsForRead(false);
1178 } 1386 }
1179 } 1387 }
1180} 1388}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3834b79..35870c5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Xml;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using System.Timers; 32using System.Timers;
@@ -72,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
72// { 73// {
73// m_log.Debug("[SCENE PRESENCE] Destructor called"); 74// m_log.Debug("[SCENE PRESENCE] Destructor called");
74// } 75// }
75 76
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 77 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 78
78 public PresenceType PresenceType { get; private set; } 79 public PresenceType PresenceType { get; private set; }
@@ -89,7 +90,9 @@ namespace OpenSim.Region.Framework.Scenes
89 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis 90 /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
90 /// issue #1716 91 /// issue #1716
91 /// </summary> 92 /// </summary>
92 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); 93// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f);
94 // Value revised by KF 091121 by comparison with SL.
95 private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
93 96
94 /// <summary> 97 /// <summary>
95 /// Movement updates for agents in neighboring regions are sent directly to clients. 98 /// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -117,6 +120,7 @@ namespace OpenSim.Region.Framework.Scenes
117 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is 120 /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
118 /// necessary. 121 /// necessary.
119 /// </remarks> 122 /// </remarks>
123
120 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 124 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
121 125
122 public Object AttachmentsSyncLock { get; private set; } 126 public Object AttachmentsSyncLock { get; private set; }
@@ -130,13 +134,21 @@ namespace OpenSim.Region.Framework.Scenes
130 public Vector3 lastKnownAllowedPosition; 134 public Vector3 lastKnownAllowedPosition;
131 public bool sentMessageAboutRestrictedParcelFlyingDown; 135 public bool sentMessageAboutRestrictedParcelFlyingDown;
132 public Vector4 CollisionPlane = Vector4.UnitW; 136 public Vector4 CollisionPlane = Vector4.UnitW;
133 137
138 private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation
139 private Vector3 m_avUnscriptedSitPos; // for non-scripted prims
134 private Vector3 m_lastPosition; 140 private Vector3 m_lastPosition;
141 private Vector3 m_lastWorldPosition;
135 private Quaternion m_lastRotation; 142 private Quaternion m_lastRotation;
136 private Vector3 m_lastVelocity; 143 private Vector3 m_lastVelocity;
137 //private int m_lastTerseSent; 144 //private int m_lastTerseSent;
138 145
139 private Vector3? m_forceToApply; 146 private Vector3? m_forceToApply;
147 private int m_userFlags;
148 public int UserFlags
149 {
150 get { return m_userFlags; }
151 }
140 private TeleportFlags m_teleportFlags; 152 private TeleportFlags m_teleportFlags;
141 public TeleportFlags TeleportFlags 153 public TeleportFlags TeleportFlags
142 { 154 {
@@ -159,6 +171,9 @@ namespace OpenSim.Region.Framework.Scenes
159 private Vector3 m_lastChildAgentUpdatePosition; 171 private Vector3 m_lastChildAgentUpdatePosition;
160 private Vector3 m_lastChildAgentUpdateCamPosition; 172 private Vector3 m_lastChildAgentUpdateCamPosition;
161 173
174 private bool m_flyingOld; // add for fly velocity control
175 public bool m_wasFlying; // add for fly velocity control
176
162 private const int LAND_VELOCITYMAG_MAX = 12; 177 private const int LAND_VELOCITYMAG_MAX = 12;
163 178
164 public bool IsRestrictedToRegion; 179 public bool IsRestrictedToRegion;
@@ -169,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes
169 184
170 protected ulong crossingFromRegion; 185 protected ulong crossingFromRegion;
171 186
172 private readonly Vector3[] Dir_Vectors = new Vector3[9]; 187 private readonly Vector3[] Dir_Vectors = new Vector3[11];
173 188
174 189
175 protected Timer m_reprioritization_timer; 190 protected Timer m_reprioritization_timer;
@@ -184,12 +199,14 @@ namespace OpenSim.Region.Framework.Scenes
184 private bool m_autopilotMoving; 199 private bool m_autopilotMoving;
185 private Vector3 m_autoPilotTarget; 200 private Vector3 m_autoPilotTarget;
186 private bool m_sitAtAutoTarget; 201 private bool m_sitAtAutoTarget;
202 private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit
187 203
188 private string m_nextSitAnimation = String.Empty; 204 private string m_nextSitAnimation = String.Empty;
189 205
190 //PauPaw:Proper PID Controler for autopilot************ 206 //PauPaw:Proper PID Controler for autopilot************
191 public bool MovingToTarget { get; private set; } 207 public bool MovingToTarget { get; private set; }
192 public Vector3 MoveToPositionTarget { get; private set; } 208 public Vector3 MoveToPositionTarget { get; private set; }
209 private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
193 210
194 /// <summary> 211 /// <summary>
195 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying). 212 /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying).
@@ -199,7 +216,13 @@ namespace OpenSim.Region.Framework.Scenes
199 private bool m_followCamAuto; 216 private bool m_followCamAuto;
200 217
201 private int m_movementUpdateCount; 218 private int m_movementUpdateCount;
219 private int m_lastColCount = -1; //KF: Look for Collision chnages
220 private int m_updateCount = 0; //KF: Update Anims for a while
221 private static readonly int UPDATE_COUNT = 10; // how many frames to update for
202 private const int NumMovementsBetweenRayCast = 5; 222 private const int NumMovementsBetweenRayCast = 5;
223 private List<uint> m_lastColliders = new List<uint>();
224
225 private object m_syncRoot = new Object();
203 226
204 private bool CameraConstraintActive; 227 private bool CameraConstraintActive;
205 //private int m_moveToPositionStateStatus; 228 //private int m_moveToPositionStateStatus;
@@ -240,7 +263,9 @@ namespace OpenSim.Region.Framework.Scenes
240 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, 263 DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
241 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, 264 DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
242 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, 265 DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS,
243 DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, 266 DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG,
267 DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
268 DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
244 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 269 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
245 } 270 }
246 271
@@ -476,9 +501,11 @@ namespace OpenSim.Region.Framework.Scenes
476 { 501 {
477 get 502 get
478 { 503 {
479 if (PhysicsActor != null) 504 PhysicsActor actor = m_physicsActor;
480 { 505// if (actor != null)
481 m_pos = PhysicsActor.Position; 506 if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting!
507 {
508 m_pos = actor.Position;
482 509
483// m_log.DebugFormat( 510// m_log.DebugFormat(
484// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!", 511// "[SCENE PRESENCE]: Set position {0} for {1} in {2} via getting AbsolutePosition!",
@@ -504,7 +531,7 @@ namespace OpenSim.Region.Framework.Scenes
504 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 531 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
505 if (part != null) 532 if (part != null)
506 { 533 {
507 return ParentPosition + (m_pos * part.GetWorldRotation()); 534 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
508 } 535 }
509 else 536 else
510 { 537 {
@@ -530,8 +557,10 @@ namespace OpenSim.Region.Framework.Scenes
530 } 557 }
531 } 558 }
532 559
533 m_pos = value; 560// Changed this to update unconditionally to make npose work
534 ParentPosition = Vector3.Zero; 561// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
562 m_pos = value;
563 m_parentPosition = Vector3.Zero;
535 564
536// m_log.DebugFormat( 565// m_log.DebugFormat(
537// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 566// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -589,15 +618,39 @@ namespace OpenSim.Region.Framework.Scenes
589 } 618 }
590 } 619 }
591 620
621 public Quaternion OffsetRotation
622 {
623 get { return m_offsetRotation; }
624 set { m_offsetRotation = value; }
625 }
592 private Quaternion m_bodyRot = Quaternion.Identity; 626 private Quaternion m_bodyRot = Quaternion.Identity;
593 627
594 public Quaternion Rotation 628 public Quaternion Rotation
595 { 629 {
596 get { return m_bodyRot; } 630 get {
597 set 631 if (m_parentID != 0)
598 { 632 {
633 if (m_offsetRotation != null)
634 {
635 return m_offsetRotation;
636 }
637 else
638 {
639 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
640 }
641
642 }
643 else
644 {
645 return m_bodyRot;
646 }
647 }
648 set {
599 m_bodyRot = value; 649 m_bodyRot = value;
600// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 650 if (m_parentID != 0)
651 {
652 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
653 }
601 } 654 }
602 } 655 }
603 656
@@ -615,12 +668,15 @@ namespace OpenSim.Region.Framework.Scenes
615 set { m_isChildAgent = value; } 668 set { m_isChildAgent = value; }
616 } 669 }
617 670
671 private uint m_parentID;
672
673
618 public uint ParentID 674 public uint ParentID
619 { 675 {
620 get { return m_parentID; } 676 get { return m_parentID; }
621 set { m_parentID = value; } 677 set { m_parentID = value; }
622 } 678 }
623 private uint m_parentID; 679
624 680
625 public float Health 681 public float Health
626 { 682 {
@@ -753,6 +809,7 @@ namespace OpenSim.Region.Framework.Scenes
753 m_localId = m_scene.AllocateLocalId(); 809 m_localId = m_scene.AllocateLocalId();
754 810
755 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 811 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
812 m_userFlags = account.UserFlags;
756 813
757 if (account != null) 814 if (account != null)
758 UserLevel = account.UserLevel; 815 UserLevel = account.UserLevel;
@@ -771,10 +828,7 @@ namespace OpenSim.Region.Framework.Scenes
771 m_reprioritization_timer.AutoReset = false; 828 m_reprioritization_timer.AutoReset = false;
772 829
773 AdjustKnownSeeds(); 830 AdjustKnownSeeds();
774
775 // TODO: I think, this won't send anything, as we are still a child here...
776 Animator.TrySetMovementAnimation("STAND"); 831 Animator.TrySetMovementAnimation("STAND");
777
778 // we created a new ScenePresence (a new child agent) in a fresh region. 832 // we created a new ScenePresence (a new child agent) in a fresh region.
779 // Request info about all the (root) agents in this region 833 // Request info about all the (root) agents in this region
780 // Note: This won't send data *to* other clients in that region (children don't send) 834 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -815,26 +869,30 @@ namespace OpenSim.Region.Framework.Scenes
815 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 869 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
816 Dir_Vectors[4] = Vector3.UnitZ; //UP 870 Dir_Vectors[4] = Vector3.UnitZ; //UP
817 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 871 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
818 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 872 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
819 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 873 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
820 Dir_Vectors[7] = -Vector3.UnitX; //BACK 874 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
875 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
876 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
821 } 877 }
822 878
823 private Vector3[] GetWalkDirectionVectors() 879 private Vector3[] GetWalkDirectionVectors()
824 { 880 {
825 Vector3[] vector = new Vector3[9]; 881 Vector3[] vector = new Vector3[11];
826 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD 882 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
827 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK 883 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
828 vector[2] = Vector3.UnitY; //LEFT 884 vector[2] = Vector3.UnitY; //LEFT
829 vector[3] = -Vector3.UnitY; //RIGHT 885 vector[3] = -Vector3.UnitY; //RIGHT
830 vector[4] = new Vector3(CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 886 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
831 vector[5] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 887 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
832 vector[8] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 888 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
833 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z) * 2); //FORWARD Nudge 889 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
834 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK Nudge 890 vector[8] = Vector3.UnitY; //LEFT_NUDGE
891 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
892 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
835 return vector; 893 return vector;
836 } 894 }
837 895
838 #endregion 896 #endregion
839 897
840 public uint GenerateClientFlags(UUID ObjectID) 898 public uint GenerateClientFlags(UUID ObjectID)
@@ -849,6 +907,8 @@ namespace OpenSim.Region.Framework.Scenes
849 /// </summary> 907 /// </summary>
850 public void SendPrimUpdates() 908 public void SendPrimUpdates()
851 { 909 {
910 m_sceneViewer.SendPrimUpdates();
911
852 SceneViewer.SendPrimUpdates(); 912 SceneViewer.SendPrimUpdates();
853 } 913 }
854 914
@@ -894,6 +954,62 @@ namespace OpenSim.Region.Framework.Scenes
894 pos.Y = crossedBorder.BorderLine.Z - 1; 954 pos.Y = crossedBorder.BorderLine.Z - 1;
895 } 955 }
896 956
957 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
958 if (land != null)
959 {
960 // If we come in via login, landmark or map, we want to
961 // honor landing points. If we come in via Lure, we want
962 // to ignore them.
963 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
964 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
965 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
966 {
967 // Don't restrict gods, estate managers, or land owners to
968 // the TP point. This behaviour mimics agni.
969 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
970 land.LandData.UserLocation != Vector3.Zero &&
971 GodLevel < 200 &&
972 ((land.LandData.OwnerID != m_uuid &&
973 (!m_scene.Permissions.IsGod(m_uuid)) &&
974 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
975 {
976 pos = land.LandData.UserLocation;
977 }
978 }
979
980 land.SendLandUpdateToClient(ControllingClient);
981 }
982
983 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
984 {
985 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
986
987 if (pos.X < 0)
988 {
989 emergencyPos.X = (int)Constants.RegionSize + pos.X;
990 if (!(pos.Y < 0))
991 emergencyPos.Y = pos.Y;
992 if (!(pos.Z < 0))
993 emergencyPos.Z = pos.Z;
994 }
995 if (pos.Y < 0)
996 {
997 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
998 if (!(pos.X < 0))
999 emergencyPos.X = pos.X;
1000 if (!(pos.Z < 0))
1001 emergencyPos.Z = pos.Z;
1002 }
1003 if (pos.Z < 0)
1004 {
1005 emergencyPos.Z = 128;
1006 if (!(pos.Y < 0))
1007 emergencyPos.Y = pos.Y;
1008 if (!(pos.X < 0))
1009 emergencyPos.X = pos.X;
1010 }
1011 }
1012
897 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1013 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
898 { 1014 {
899 m_log.WarnFormat( 1015 m_log.WarnFormat(
@@ -1026,16 +1142,21 @@ namespace OpenSim.Region.Framework.Scenes
1026 /// <summary> 1142 /// <summary>
1027 /// Removes physics plugin scene representation of this agent if it exists. 1143 /// Removes physics plugin scene representation of this agent if it exists.
1028 /// </summary> 1144 /// </summary>
1029 private void RemoveFromPhysicalScene() 1145 public void RemoveFromPhysicalScene()
1030 { 1146 {
1031 if (PhysicsActor != null) 1147 if (PhysicsActor != null)
1032 { 1148 {
1033 PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1149 try
1034 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1150 {
1035 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1151 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1036 PhysicsActor.UnSubscribeEvents(); 1152 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1037 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1153 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1038 PhysicsActor = null; 1154 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1155 m_physicsActor.UnSubscribeEvents();
1156 PhysicsActor = null;
1157 }
1158 catch
1159 { }
1039 } 1160 }
1040 } 1161 }
1041 1162
@@ -1051,10 +1172,12 @@ namespace OpenSim.Region.Framework.Scenes
1051 1172
1052 RemoveFromPhysicalScene(); 1173 RemoveFromPhysicalScene();
1053 Velocity = Vector3.Zero; 1174 Velocity = Vector3.Zero;
1175 CheckLandingPoint(ref pos);
1054 AbsolutePosition = pos; 1176 AbsolutePosition = pos;
1055 AddToPhysicalScene(isFlying); 1177 AddToPhysicalScene(isFlying);
1056 1178
1057 SendTerseUpdateToAllClients(); 1179 SendTerseUpdateToAllClients();
1180
1058 } 1181 }
1059 1182
1060 public void TeleportWithMomentum(Vector3 pos) 1183 public void TeleportWithMomentum(Vector3 pos)
@@ -1064,6 +1187,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 isFlying = PhysicsActor.Flying; 1187 isFlying = PhysicsActor.Flying;
1065 1188
1066 RemoveFromPhysicalScene(); 1189 RemoveFromPhysicalScene();
1190 CheckLandingPoint(ref pos);
1067 AbsolutePosition = pos; 1191 AbsolutePosition = pos;
1068 AddToPhysicalScene(isFlying); 1192 AddToPhysicalScene(isFlying);
1069 1193
@@ -1271,11 +1395,12 @@ namespace OpenSim.Region.Framework.Scenes
1271 /// <summary> 1395 /// <summary>
1272 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1396 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1273 /// </summary> 1397 /// </summary>
1398 /// <summary>
1399 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1400 /// </summary>
1274 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1401 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1275 { 1402 {
1276// m_log.DebugFormat( 1403 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1277// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1278// Scene.RegionInfo.RegionName, remoteClient.Name);
1279 1404
1280 //if (IsChildAgent) 1405 //if (IsChildAgent)
1281 //{ 1406 //{
@@ -1350,6 +1475,10 @@ namespace OpenSim.Region.Framework.Scenes
1350 1475
1351 #endregion Inputs 1476 #endregion Inputs
1352 1477
1478 // Make anims work for client side autopilot
1479 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
1480 m_updateCount = UPDATE_COUNT;
1481
1353 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) 1482 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1354 { 1483 {
1355 StandUp(); 1484 StandUp();
@@ -1380,6 +1509,9 @@ namespace OpenSim.Region.Framework.Scenes
1380 1509
1381 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1510 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1382 { 1511 {
1512 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1513 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1514
1383 // TODO: This doesn't prevent the user from walking yet. 1515 // TODO: This doesn't prevent the user from walking yet.
1384 // Setting parent ID would fix this, if we knew what value 1516 // Setting parent ID would fix this, if we knew what value
1385 // to use. Or we could add a m_isSitting variable. 1517 // to use. Or we could add a m_isSitting variable.
@@ -1469,7 +1601,7 @@ namespace OpenSim.Region.Framework.Scenes
1469 1601
1470 if ((MovementFlag & (byte)(uint)DCF) == 0) 1602 if ((MovementFlag & (byte)(uint)DCF) == 0)
1471 { 1603 {
1472 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1604 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1473 { 1605 {
1474 MovementFlag |= (byte)nudgehack; 1606 MovementFlag |= (byte)nudgehack;
1475 } 1607 }
@@ -1481,13 +1613,13 @@ namespace OpenSim.Region.Framework.Scenes
1481 } 1613 }
1482 else 1614 else
1483 { 1615 {
1484 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1616 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1485 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1617 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1486 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1618 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1487 ) // This or is for Nudge forward 1619 ) // This or is for Nudge forward
1488 { 1620 {
1489// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1621 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1490 MovementFlag -= ((byte)(uint)DCF); 1622 m_movementflag -= ((byte)(uint)DCF);
1491 update_movementflag = true; 1623 update_movementflag = true;
1492 1624
1493 /* 1625 /*
@@ -1548,21 +1680,21 @@ namespace OpenSim.Region.Framework.Scenes
1548 // which occurs later in the main scene loop 1680 // which occurs later in the main scene loop
1549 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1681 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1550 { 1682 {
1551// m_log.DebugFormat( 1683 // m_log.DebugFormat(
1552// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1684 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1553// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1685 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1554 1686
1555 AddNewMovement(agent_control_v3); 1687 AddNewMovement(agent_control_v3);
1556 } 1688 }
1557// else 1689 // else
1558// { 1690 // {
1559// if (!update_movementflag) 1691 // if (!update_movementflag)
1560// { 1692 // {
1561// m_log.DebugFormat( 1693 // m_log.DebugFormat(
1562// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1694 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1563// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1695 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1564// } 1696 // }
1565// } 1697 // }
1566 1698
1567 if (update_movementflag && ParentID == 0) 1699 if (update_movementflag && ParentID == 0)
1568 Animator.UpdateMovementAnimations(); 1700 Animator.UpdateMovementAnimations();
@@ -1581,20 +1713,20 @@ namespace OpenSim.Region.Framework.Scenes
1581 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1713 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1582 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1714 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1583 { 1715 {
1584// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1716 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1585 1717
1586 bool updated = false; 1718 bool updated = false;
1587 1719
1588// m_log.DebugFormat( 1720 // m_log.DebugFormat(
1589// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1721 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1590// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1722 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1591 1723
1592 if (!m_autopilotMoving) 1724 if (!m_autopilotMoving)
1593 { 1725 {
1594 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1726 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1595// m_log.DebugFormat( 1727 // m_log.DebugFormat(
1596// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1728 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1597// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1729 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1598 1730
1599 // Check the error term of the current position in relation to the target position 1731 // Check the error term of the current position in relation to the target position
1600 if (distanceToTarget <= 1) 1732 if (distanceToTarget <= 1)
@@ -1617,7 +1749,7 @@ namespace OpenSim.Region.Framework.Scenes
1617 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1749 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1618 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1750 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1619 // Ignore z component of vector 1751 // Ignore z component of vector
1620// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1752 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1621 LocalVectorToTarget3D.Normalize(); 1753 LocalVectorToTarget3D.Normalize();
1622 1754
1623 // update avatar movement flags. the avatar coordinate system is as follows: 1755 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1683,9 +1815,9 @@ namespace OpenSim.Region.Framework.Scenes
1683 updated = true; 1815 updated = true;
1684 } 1816 }
1685 1817
1686// m_log.DebugFormat( 1818 // m_log.DebugFormat(
1687// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1819 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1688// LocalVectorToTarget3D, agent_control_v3, Name); 1820 // LocalVectorToTarget3D, agent_control_v3, Name);
1689 1821
1690 agent_control_v3 += LocalVectorToTarget3D; 1822 agent_control_v3 += LocalVectorToTarget3D;
1691 } 1823 }
@@ -1714,9 +1846,12 @@ namespace OpenSim.Region.Framework.Scenes
1714 /// </param> 1846 /// </param>
1715 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) 1847 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
1716 { 1848 {
1717 m_log.DebugFormat( 1849 if (SitGround)
1718 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", 1850 StandUp();
1719 Name, pos, m_scene.RegionInfo.RegionName); 1851
1852// m_log.DebugFormat(
1853// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1854// Name, pos, m_scene.RegionInfo.RegionName);
1720 1855
1721 if (pos.X < 0 || pos.X >= Constants.RegionSize 1856 if (pos.X < 0 || pos.X >= Constants.RegionSize
1722 || pos.Y < 0 || pos.Y >= Constants.RegionSize 1857 || pos.Y < 0 || pos.Y >= Constants.RegionSize
@@ -1742,9 +1877,9 @@ namespace OpenSim.Region.Framework.Scenes
1742 if (pos.Z - terrainHeight < 0.2) 1877 if (pos.Z - terrainHeight < 0.2)
1743 pos.Z = terrainHeight; 1878 pos.Z = terrainHeight;
1744 1879
1745 m_log.DebugFormat( 1880// m_log.DebugFormat(
1746 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", 1881// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1747 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); 1882// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1748 1883
1749 if (noFly) 1884 if (noFly)
1750 PhysicsActor.Flying = false; 1885 PhysicsActor.Flying = false;
@@ -1780,7 +1915,7 @@ namespace OpenSim.Region.Framework.Scenes
1780 /// </summary> 1915 /// </summary>
1781 public void ResetMoveToTarget() 1916 public void ResetMoveToTarget()
1782 { 1917 {
1783 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 1918// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1784 1919
1785 MovingToTarget = false; 1920 MovingToTarget = false;
1786 MoveToPositionTarget = Vector3.Zero; 1921 MoveToPositionTarget = Vector3.Zero;
@@ -1806,7 +1941,7 @@ namespace OpenSim.Region.Framework.Scenes
1806 Velocity = Vector3.Zero; 1941 Velocity = Vector3.Zero;
1807 SendAvatarDataToAllAgents(); 1942 SendAvatarDataToAllAgents();
1808 1943
1809 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1944 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1810 } 1945 }
1811 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1946 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1812 m_requestedSitTargetUUID = UUID.Zero; 1947 m_requestedSitTargetUUID = UUID.Zero;
@@ -1843,24 +1978,22 @@ namespace OpenSim.Region.Framework.Scenes
1843 1978
1844 if (ParentID != 0) 1979 if (ParentID != 0)
1845 { 1980 {
1846 m_log.Debug("StandupCode Executed"); 1981 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1847 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1848 if (part != null) 1982 if (part != null)
1849 { 1983 {
1984 part.TaskInventory.LockItemsForRead(true);
1850 TaskInventoryDictionary taskIDict = part.TaskInventory; 1985 TaskInventoryDictionary taskIDict = part.TaskInventory;
1851 if (taskIDict != null) 1986 if (taskIDict != null)
1852 { 1987 {
1853 lock (taskIDict) 1988 foreach (UUID taskID in taskIDict.Keys)
1854 { 1989 {
1855 foreach (UUID taskID in taskIDict.Keys) 1990 UnRegisterControlEventsToScript(LocalId, taskID);
1856 { 1991 taskIDict[taskID].PermsMask &= ~(
1857 UnRegisterControlEventsToScript(LocalId, taskID); 1992 2048 | //PERMISSION_CONTROL_CAMERA
1858 taskIDict[taskID].PermsMask &= ~( 1993 4); // PERMISSION_TAKE_CONTROLS
1859 2048 | //PERMISSION_CONTROL_CAMERA
1860 4); // PERMISSION_TAKE_CONTROLS
1861 }
1862 } 1994 }
1863 } 1995 }
1996 part.TaskInventory.LockItemsForRead(false);
1864 1997
1865 // Reset sit target. 1998 // Reset sit target.
1866 if (part.SitTargetAvatar == UUID) 1999 if (part.SitTargetAvatar == UUID)
@@ -1871,21 +2004,59 @@ namespace OpenSim.Region.Framework.Scenes
1871 ParentPosition = part.GetWorldPosition(); 2004 ParentPosition = part.GetWorldPosition();
1872 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2005 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1873 } 2006 }
1874 2007 // part.GetWorldRotation() is the rotation of the object being sat on
1875 if (PhysicsActor == null) 2008 // Rotation is the sittiing Av's rotation
2009
2010 Quaternion partRot;
2011// if (part.LinkNum == 1)
2012// { // Root prim of linkset
2013// partRot = part.ParentGroup.RootPart.RotationOffset;
2014// }
2015// else
2016// { // single or child prim
2017
2018// }
2019 if (part == null) //CW: Part may be gone. llDie() for example.
1876 { 2020 {
1877 AddToPhysicalScene(false); 2021 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2022 }
2023 else
2024 {
2025 partRot = part.GetWorldRotation();
1878 } 2026 }
1879 2027
1880 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2028 Quaternion partIRot = Quaternion.Inverse(partRot);
1881 ParentPosition = Vector3.Zero;
1882 2029
1883 ParentID = 0; 2030 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2031 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
2032
2033
2034 if (m_physicsActor == null)
2035 {
2036 AddToPhysicalScene(false);
2037 }
2038 //CW: If the part isn't null then we can set the current position
2039 if (part != null)
2040 {
2041 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2042 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2043 part.IsOccupied = false;
2044 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2045 }
2046 else
2047 {
2048 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2049 AbsolutePosition = m_lastWorldPosition;
2050 }
2051
2052 m_parentPosition = Vector3.Zero;
2053 m_parentID = 0;
2054 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1884 SendAvatarDataToAllAgents(); 2055 SendAvatarDataToAllAgents();
1885 m_requestedSitTargetID = 0; 2056 m_requestedSitTargetID = 0;
1886 } 2057 }
1887 2058
1888 Animator.TrySetMovementAnimation("STAND"); 2059 Animator.UpdateMovementAnimations();
1889 } 2060 }
1890 2061
1891 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2062 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -1917,9 +2088,7 @@ namespace OpenSim.Region.Framework.Scenes
1917 UUID avOnTargetAlready = part.SitTargetAvatar; 2088 UUID avOnTargetAlready = part.SitTargetAvatar;
1918 2089
1919 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2090 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1920 bool SitTargetisSet = 2091 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1921 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1922 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1923 2092
1924 if (SitTargetisSet && SitTargetUnOccupied) 2093 if (SitTargetisSet && SitTargetUnOccupied)
1925 { 2094 {
@@ -1935,87 +2104,168 @@ namespace OpenSim.Region.Framework.Scenes
1935 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2104 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1936 { 2105 {
1937 bool autopilot = true; 2106 bool autopilot = true;
2107 Vector3 autopilotTarget = new Vector3();
2108 Quaternion sitOrientation = Quaternion.Identity;
1938 Vector3 pos = new Vector3(); 2109 Vector3 pos = new Vector3();
1939 Quaternion sitOrientation = pSitOrientation;
1940 Vector3 cameraEyeOffset = Vector3.Zero; 2110 Vector3 cameraEyeOffset = Vector3.Zero;
1941 Vector3 cameraAtOffset = Vector3.Zero; 2111 Vector3 cameraAtOffset = Vector3.Zero;
1942 bool forceMouselook = false; 2112 bool forceMouselook = false;
1943 2113
1944 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2114 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1945 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2115 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1946 if (part != null) 2116 if (part == null) return;
2117
2118 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2119 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2120
2121 // part is the prim to sit on
2122 // offset is the world-ref vector distance from that prim center to the click-spot
2123 // UUID is the UUID of the Avatar doing the clicking
2124
2125 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2126
2127 // Is a sit target available?
2128 Vector3 avSitOffSet = part.SitTargetPosition;
2129 Quaternion avSitOrientation = part.SitTargetOrientation;
2130
2131 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2132 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2133 Quaternion partRot;
2134// if (part.LinkNum == 1)
2135// { // Root prim of linkset
2136// partRot = part.ParentGroup.RootPart.RotationOffset;
2137// }
2138// else
2139// { // single or child prim
2140 partRot = part.GetWorldRotation();
2141// }
2142 Quaternion partIRot = Quaternion.Inverse(partRot);
2143//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2144 // Sit analysis rewritten by KF 091125
2145 if (SitTargetisSet) // scipted sit
1947 { 2146 {
1948 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2147 if (!part.IsOccupied)
1949 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2148 {
1950 2149//Console.WriteLine("Scripted, unoccupied");
1951 // Is a sit target available? 2150 part.SitTargetAvatar = UUID; // set that Av will be on it
1952 Vector3 avSitOffSet = part.SitTargetPosition; 2151 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1953 Quaternion avSitOrientation = part.SitTargetOrientation; 2152
1954 UUID avOnTargetAlready = part.SitTargetAvatar; 2153 Quaternion nrot = avSitOrientation;
1955 2154 if (!part.IsRoot)
1956 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1957 bool SitTargetisSet =
1958 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1959 (
1960 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1961 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1962 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1963 )
1964 ));
1965
1966// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
1967
1968 if (SitTargetisSet && SitTargetUnOccupied)
1969 {
1970 part.SitTargetAvatar = UUID;
1971 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1972 sitOrientation = avSitOrientation;
1973 autopilot = false;
1974 }
1975 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1976
1977 pos = part.AbsolutePosition + offset;
1978 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1979 //{
1980 // offset = pos;
1981 //autopilot = false;
1982 //}
1983 if (PhysicsActor != null)
1984 {
1985 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1986 // We can remove the physicsActor until they stand up.
1987 m_sitAvatarHeight = PhysicsActor.Size.Z;
1988
1989 if (autopilot)
1990 { 2155 {
1991 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2156 nrot = part.RotationOffset * avSitOrientation;
1992 {
1993 autopilot = false;
1994
1995 RemoveFromPhysicalScene();
1996 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1997 }
1998 } 2157 }
1999 else 2158 sitOrientation = nrot; // Change rotatione to the scripted one
2159 OffsetRotation = nrot;
2160 autopilot = false; // Jump direct to scripted llSitPos()
2161 }
2162 else
2163 {
2164//Console.WriteLine("Scripted, occupied");
2165 return;
2166 }
2167 }
2168 else // Not Scripted
2169 {
2170 if ( (Math.Abs(offset.X) > 0.1f) || (Math.Abs(offset.Y) > 0.1f) ) // Changed 0.5M to 0.1M as they want to be able to sit close together
2171 {
2172 // large prim & offset, ignore if other Avs sitting
2173// offset.Z -= 0.05f;
2174 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2175 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2176
2177//Console.WriteLine(" offset ={0}", offset);
2178//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2179//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2180
2181 }
2182 else // small offset
2183 {
2184//Console.WriteLine("Small offset");
2185 if (!part.IsOccupied)
2186 {
2187 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2188 autopilotTarget = part.AbsolutePosition;
2189//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2190 }
2191 else return; // occupied small
2192 } // end large/small
2193 } // end Scripted/not
2194
2195 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2196
2197 cameraAtOffset = part.GetCameraAtOffset();
2198 cameraEyeOffset = part.GetCameraEyeOffset();
2199 forceMouselook = part.GetForceMouselook();
2200 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2201 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2202
2203 if (m_physicsActor != null)
2204 {
2205 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2206 // We can remove the physicsActor until they stand up.
2207 m_sitAvatarHeight = m_physicsActor.Size.Z;
2208 if (autopilot)
2209 { // its not a scripted sit
2210// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2211 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
2000 { 2212 {
2213 autopilot = false; // close enough
2214 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2215 Not using the part's position because returning the AV to the last known standing
2216 position is likely to be more friendly, isn't it? */
2001 RemoveFromPhysicalScene(); 2217 RemoveFromPhysicalScene();
2002 } 2218 Velocity = Vector3.Zero;
2219 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2220 } // else the autopilot will get us close
2221 }
2222 else
2223 { // its a scripted sit
2224 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2225 I *am* using the part's position this time because we have no real idea how far away
2226 the avatar is from the sit target. */
2227 RemoveFromPhysicalScene();
2228 Velocity = Vector3.Zero;
2003 } 2229 }
2004
2005 cameraAtOffset = part.GetCameraAtOffset();
2006 cameraEyeOffset = part.GetCameraEyeOffset();
2007 forceMouselook = part.GetForceMouselook();
2008 } 2230 }
2009 2231 else return; // physactor is null!
2010 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2232
2011 m_requestedSitTargetUUID = targetID; 2233 Vector3 offsetr; // = offset * partIRot;
2234 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2235 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2236 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2237 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2238 //offsetr = offset * partIRot;
2239//
2240 // }
2241 // else
2242 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2243 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2244 // (offset * partRot);
2245 // }
2246
2247//Console.WriteLine(" ");
2248//Console.WriteLine("link number ={0}", part.LinkNum);
2249//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2250//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2251//Console.WriteLine("Click offst ={0}", offset);
2252//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2253//Console.WriteLine("offsetr ={0}", offsetr);
2254//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2255//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2256
2257 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2258 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2259
2260 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2012 // This calls HandleAgentSit twice, once from here, and the client calls 2261 // This calls HandleAgentSit twice, once from here, and the client calls
2013 // HandleAgentSit itself after it gets to the location 2262 // HandleAgentSit itself after it gets to the location
2014 // It doesn't get to the location until we've moved them there though 2263 // It doesn't get to the location until we've moved them there though
2015 // which happens in HandleAgentSit :P 2264 // which happens in HandleAgentSit :P
2016 m_autopilotMoving = autopilot; 2265 m_autopilotMoving = autopilot;
2017 m_autoPilotTarget = pos; 2266 m_autoPilotTarget = autopilotTarget;
2018 m_sitAtAutoTarget = autopilot; 2267 m_sitAtAutoTarget = autopilot;
2268 m_initialSitTarget = autopilotTarget;
2019 if (!autopilot) 2269 if (!autopilot)
2020 HandleAgentSit(remoteClient, UUID); 2270 HandleAgentSit(remoteClient, UUID);
2021 } 2271 }
@@ -2281,45 +2531,127 @@ namespace OpenSim.Region.Framework.Scenes
2281 { 2531 {
2282 if (part.SitTargetAvatar == UUID) 2532 if (part.SitTargetAvatar == UUID)
2283 { 2533 {
2534//Console.WriteLine("Scripted Sit");
2535 // Scripted sit
2284 Vector3 sitTargetPos = part.SitTargetPosition; 2536 Vector3 sitTargetPos = part.SitTargetPosition;
2285 Quaternion sitTargetOrient = part.SitTargetOrientation; 2537 Quaternion sitTargetOrient = part.SitTargetOrientation;
2286
2287 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2288 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2289
2290 //Quaternion result = (sitTargetOrient * vq) * nq;
2291
2292 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2538 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2293 m_pos += SIT_TARGET_ADJUSTMENT; 2539 m_pos += SIT_TARGET_ADJUSTMENT;
2294 Rotation = sitTargetOrient; 2540 if (!part.IsRoot)
2295 //Rotation = sitTargetOrient; 2541 {
2296 ParentPosition = part.AbsolutePosition; 2542 m_pos *= part.RotationOffset;
2297 2543 }
2298 //SendTerseUpdateToAllClients(); 2544 m_bodyRot = sitTargetOrient;
2545 m_parentPosition = part.AbsolutePosition;
2546 part.IsOccupied = true;
2547 part.ParentGroup.AddAvatar(agentID);
2299 } 2548 }
2300 else 2549 else
2301 { 2550 {
2302 m_pos -= part.AbsolutePosition; 2551 // if m_avUnscriptedSitPos is zero then Av sits above center
2303 ParentPosition = part.AbsolutePosition; 2552 // Else Av sits at m_avUnscriptedSitPos
2304 } 2553
2554 // Non-scripted sit by Kitto Flora 21Nov09
2555 // Calculate angle of line from prim to Av
2556 Quaternion partIRot;
2557// if (part.LinkNum == 1)
2558// { // Root prim of linkset
2559// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2560// }
2561// else
2562// { // single or child prim
2563 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2564// }
2565 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2566 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2567 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2568 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2569 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2570 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2571 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2572 // Av sits at world euler <0,0, z>, translated by part rotation
2573 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2574
2575 m_parentPosition = part.AbsolutePosition;
2576 part.IsOccupied = true;
2577 part.ParentGroup.AddAvatar(agentID);
2578 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2579 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2580 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2581 m_avUnscriptedSitPos; // adds click offset, if any
2582 //Set up raytrace to find top surface of prim
2583 Vector3 size = part.Scale;
2584 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2585 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2586 Vector3 down = new Vector3(0f, 0f, -1f);
2587//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2588 m_scene.PhysicsScene.RaycastWorld(
2589 start, // Vector3 position,
2590 down, // Vector3 direction,
2591 mag, // float length,
2592 SitAltitudeCallback); // retMethod
2593 } // end scripted/not
2305 } 2594 }
2306 else 2595 else // no Av
2307 { 2596 {
2308 return; 2597 return;
2309 } 2598 }
2310 } 2599 }
2311 ParentID = m_requestedSitTargetID; 2600 ParentID = m_requestedSitTargetID;
2312 2601
2602 //We want our offsets to reference the root prim, not the child we may have sat on
2603 if (!part.IsRoot)
2604 {
2605 m_parentID = part.ParentGroup.RootPart.LocalId;
2606 m_pos += part.OffsetPosition;
2607 }
2608 else
2609 {
2610 m_parentID = m_requestedSitTargetID;
2611 }
2612
2613 if (part.SitTargetAvatar != UUID)
2614 {
2615 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2616 }
2313 Velocity = Vector3.Zero; 2617 Velocity = Vector3.Zero;
2314 RemoveFromPhysicalScene(); 2618 RemoveFromPhysicalScene();
2315
2316 Animator.TrySetMovementAnimation(sitAnimation); 2619 Animator.TrySetMovementAnimation(sitAnimation);
2317 SendAvatarDataToAllAgents(); 2620 SendAvatarDataToAllAgents();
2318 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2319 // So we're also sending a terse update (which has avatar rotation)
2320 // [Update] We do now.
2321 //SendTerseUpdateToAllClients(); 2621 //SendTerseUpdateToAllClients();
2322 } 2622 }
2623
2624 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2625 {
2626 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2627 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2628 if(hitYN)
2629 {
2630 // m_pos = Av offset from prim center to make look like on center
2631 // m_parentPosition = Actual center pos of prim
2632 // collisionPoint = spot on prim where we want to sit
2633 // collisionPoint.Z = global sit surface height
2634 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2635 Quaternion partIRot;
2636// if (part.LinkNum == 1)
2637/// { // Root prim of linkset
2638// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2639// }
2640// else
2641// { // single or child prim
2642 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2643// }
2644 if (m_initialSitTarget != null)
2645 {
2646 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2647 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2648 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2649 m_pos += offset;
2650 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2651 }
2652
2653 }
2654 } // End SitAltitudeCallback KF.
2323 2655
2324 /// <summary> 2656 /// <summary>
2325 /// Event handler for the 'Always run' setting on the client 2657 /// Event handler for the 'Always run' setting on the client
@@ -2349,6 +2681,19 @@ namespace OpenSim.Region.Framework.Scenes
2349 Vector3 direc = vec * Rotation; 2681 Vector3 direc = vec * Rotation;
2350 direc.Normalize(); 2682 direc.Normalize();
2351 2683
2684 if (PhysicsActor.Flying != m_flyingOld) // add for fly velocity control
2685 {
2686 m_flyingOld = PhysicsActor.Flying; // add for fly velocity control
2687 if (!PhysicsActor.Flying)
2688 m_wasFlying = true; // add for fly velocity control
2689 }
2690
2691 if (PhysicsActor.IsColliding == true)
2692 m_wasFlying = false; // add for fly velocity control
2693
2694 if ((vec.Z == 0f) && !PhysicsActor.Flying)
2695 direc.Z = 0f; // Prevent camera WASD up.
2696
2352 direc *= 0.03f * 128f * SpeedModifier; 2697 direc *= 0.03f * 128f * SpeedModifier;
2353 2698
2354 if (PhysicsActor != null) 2699 if (PhysicsActor != null)
@@ -2367,6 +2712,10 @@ namespace OpenSim.Region.Framework.Scenes
2367 // m_log.Info("[AGENT]: Stop Flying"); 2712 // m_log.Info("[AGENT]: Stop Flying");
2368 //} 2713 //}
2369 } 2714 }
2715 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2716 {
2717 direc *= 0.0f;
2718 }
2370 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding) 2719 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding)
2371 { 2720 {
2372 if (direc.Z > 2.0f) 2721 if (direc.Z > 2.0f)
@@ -2427,6 +2776,9 @@ namespace OpenSim.Region.Framework.Scenes
2427 2776
2428 CheckForSignificantMovement(); // sends update to the modules. 2777 CheckForSignificantMovement(); // sends update to the modules.
2429 } 2778 }
2779
2780 //Sending prim updates AFTER the avatar terse updates are sent
2781 SendPrimUpdates();
2430 } 2782 }
2431 2783
2432 #endregion 2784 #endregion
@@ -3146,6 +3498,7 @@ namespace OpenSim.Region.Framework.Scenes
3146 m_callbackURI = cAgent.CallbackURI; 3498 m_callbackURI = cAgent.CallbackURI;
3147 3499
3148 m_pos = cAgent.Position; 3500 m_pos = cAgent.Position;
3501
3149 m_velocity = cAgent.Velocity; 3502 m_velocity = cAgent.Velocity;
3150 CameraPosition = cAgent.Center; 3503 CameraPosition = cAgent.Center;
3151 CameraAtAxis = cAgent.AtAxis; 3504 CameraAtAxis = cAgent.AtAxis;
@@ -3292,14 +3645,28 @@ namespace OpenSim.Region.Framework.Scenes
3292 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3645 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3293 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 3646 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
3294 // as of this comment the interval is set in AddToPhysicalScene 3647 // as of this comment the interval is set in AddToPhysicalScene
3295 if (Animator != null) 3648 if (Animator!=null)
3296 Animator.UpdateMovementAnimations(); 3649 {
3650 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3651 { // else its will lock out other animation changes, like ground sit.
3652 Animator.UpdateMovementAnimations();
3653 m_updateCount--;
3654 }
3655 }
3297 3656
3298 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3657 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3299 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3658 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3300 3659
3301 CollisionPlane = Vector4.UnitW; 3660 CollisionPlane = Vector4.UnitW;
3302 3661
3662 // No collisions at all means we may be flying. Update always
3663 // to make falling work
3664 if (m_lastColCount != coldata.Count || coldata.Count == 0)
3665 {
3666 m_updateCount = UPDATE_COUNT;
3667 m_lastColCount = coldata.Count;
3668 }
3669
3303 if (coldata.Count != 0 && Animator != null) 3670 if (coldata.Count != 0 && Animator != null)
3304 { 3671 {
3305 switch (Animator.CurrentMovementAnimation) 3672 switch (Animator.CurrentMovementAnimation)
@@ -3329,6 +3696,148 @@ namespace OpenSim.Region.Framework.Scenes
3329 } 3696 }
3330 } 3697 }
3331 3698
3699 List<uint> thisHitColliders = new List<uint>();
3700 List<uint> endedColliders = new List<uint>();
3701 List<uint> startedColliders = new List<uint>();
3702
3703 foreach (uint localid in coldata.Keys)
3704 {
3705 thisHitColliders.Add(localid);
3706 if (!m_lastColliders.Contains(localid))
3707 {
3708 startedColliders.Add(localid);
3709 }
3710 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3711 }
3712
3713 // calculate things that ended colliding
3714 foreach (uint localID in m_lastColliders)
3715 {
3716 if (!thisHitColliders.Contains(localID))
3717 {
3718 endedColliders.Add(localID);
3719 }
3720 }
3721 //add the items that started colliding this time to the last colliders list.
3722 foreach (uint localID in startedColliders)
3723 {
3724 m_lastColliders.Add(localID);
3725 }
3726 // remove things that ended colliding from the last colliders list
3727 foreach (uint localID in endedColliders)
3728 {
3729 m_lastColliders.Remove(localID);
3730 }
3731
3732 // do event notification
3733 if (startedColliders.Count > 0)
3734 {
3735 ColliderArgs StartCollidingMessage = new ColliderArgs();
3736 List<DetectedObject> colliding = new List<DetectedObject>();
3737 foreach (uint localId in startedColliders)
3738 {
3739 if (localId == 0)
3740 continue;
3741
3742 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3743 string data = "";
3744 if (obj != null)
3745 {
3746 DetectedObject detobj = new DetectedObject();
3747 detobj.keyUUID = obj.UUID;
3748 detobj.nameStr = obj.Name;
3749 detobj.ownerUUID = obj.OwnerID;
3750 detobj.posVector = obj.AbsolutePosition;
3751 detobj.rotQuat = obj.GetWorldRotation();
3752 detobj.velVector = obj.Velocity;
3753 detobj.colliderType = 0;
3754 detobj.groupUUID = obj.GroupID;
3755 colliding.Add(detobj);
3756 }
3757 }
3758
3759 if (colliding.Count > 0)
3760 {
3761 StartCollidingMessage.Colliders = colliding;
3762
3763 foreach (SceneObjectGroup att in GetAttachments())
3764 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3765 }
3766 }
3767
3768 if (endedColliders.Count > 0)
3769 {
3770 ColliderArgs EndCollidingMessage = new ColliderArgs();
3771 List<DetectedObject> colliding = new List<DetectedObject>();
3772 foreach (uint localId in endedColliders)
3773 {
3774 if (localId == 0)
3775 continue;
3776
3777 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3778 string data = "";
3779 if (obj != null)
3780 {
3781 DetectedObject detobj = new DetectedObject();
3782 detobj.keyUUID = obj.UUID;
3783 detobj.nameStr = obj.Name;
3784 detobj.ownerUUID = obj.OwnerID;
3785 detobj.posVector = obj.AbsolutePosition;
3786 detobj.rotQuat = obj.GetWorldRotation();
3787 detobj.velVector = obj.Velocity;
3788 detobj.colliderType = 0;
3789 detobj.groupUUID = obj.GroupID;
3790 colliding.Add(detobj);
3791 }
3792 }
3793
3794 if (colliding.Count > 0)
3795 {
3796 EndCollidingMessage.Colliders = colliding;
3797
3798 foreach (SceneObjectGroup att in GetAttachments())
3799 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3800 }
3801 }
3802
3803 if (thisHitColliders.Count > 0)
3804 {
3805 ColliderArgs CollidingMessage = new ColliderArgs();
3806 List<DetectedObject> colliding = new List<DetectedObject>();
3807 foreach (uint localId in thisHitColliders)
3808 {
3809 if (localId == 0)
3810 continue;
3811
3812 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3813 string data = "";
3814 if (obj != null)
3815 {
3816 DetectedObject detobj = new DetectedObject();
3817 detobj.keyUUID = obj.UUID;
3818 detobj.nameStr = obj.Name;
3819 detobj.ownerUUID = obj.OwnerID;
3820 detobj.posVector = obj.AbsolutePosition;
3821 detobj.rotQuat = obj.GetWorldRotation();
3822 detobj.velVector = obj.Velocity;
3823 detobj.colliderType = 0;
3824 detobj.groupUUID = obj.GroupID;
3825 colliding.Add(detobj);
3826 }
3827 }
3828
3829 if (colliding.Count > 0)
3830 {
3831 CollidingMessage.Colliders = colliding;
3832
3833 lock (m_attachments)
3834 {
3835 foreach (SceneObjectGroup att in m_attachments)
3836 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3837 }
3838 }
3839 }
3840
3332 if (Invulnerable) 3841 if (Invulnerable)
3333 return; 3842 return;
3334 3843
@@ -3400,6 +3909,10 @@ namespace OpenSim.Region.Framework.Scenes
3400 { 3909 {
3401 lock (m_attachments) 3910 lock (m_attachments)
3402 { 3911 {
3912 // This may be true when the attachment comes back
3913 // from serialization after login. Clear it.
3914 gobj.IsDeleted = false;
3915
3403 m_attachments.Add(gobj); 3916 m_attachments.Add(gobj);
3404 } 3917 }
3405 } 3918 }
@@ -3763,5 +4276,39 @@ namespace OpenSim.Region.Framework.Scenes
3763 m_reprioritization_called = false; 4276 m_reprioritization_called = false;
3764 } 4277 }
3765 } 4278 }
4279
4280 private Vector3 Quat2Euler(Quaternion rot){
4281 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4282 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4283 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4284 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4285 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4286 return(new Vector3(x,y,z));
4287 }
4288
4289 private void CheckLandingPoint(ref Vector3 pos)
4290 {
4291 // Never constrain lures
4292 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4293 return;
4294
4295 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4296 return;
4297
4298 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4299
4300 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4301 land.LandData.UserLocation != Vector3.Zero &&
4302 land.LandData.OwnerID != m_uuid &&
4303 (!m_scene.Permissions.IsGod(m_uuid)) &&
4304 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4305 {
4306 float curr = Vector3.Distance(AbsolutePosition, pos);
4307 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4308 pos = land.LandData.UserLocation;
4309 else
4310 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4311 }
4312 }
3766 } 4313 }
3767} 4314}
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index 50e1e39..8a0d288 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -126,7 +126,7 @@ namespace OpenSim.Region.Framework.Scenes
126 g.ScheduleFullUpdateToAvatar(m_presence); 126 g.ScheduleFullUpdateToAvatar(m_presence);
127 } 127 }
128 128
129 while (m_partsUpdateQueue.Count > 0) 129 while (m_partsUpdateQueue != null && m_partsUpdateQueue.Count != null && m_partsUpdateQueue.Count > 0)
130 { 130 {
131 SceneObjectPart part = m_partsUpdateQueue.Dequeue(); 131 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
132 132
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index e06a222..11dad6c 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -346,6 +346,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
346 m_SOPXmlProcessors.Add("PayPrice2", ProcessPayPrice2); 346 m_SOPXmlProcessors.Add("PayPrice2", ProcessPayPrice2);
347 m_SOPXmlProcessors.Add("PayPrice3", ProcessPayPrice3); 347 m_SOPXmlProcessors.Add("PayPrice3", ProcessPayPrice3);
348 m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4); 348 m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4);
349
350 m_SOPXmlProcessors.Add("Buoyancy", ProcessBuoyancy);
349 #endregion 351 #endregion
350 352
351 #region TaskInventoryXmlProcessors initialization 353 #region TaskInventoryXmlProcessors initialization
@@ -735,6 +737,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
735 obj.PayPrice[4] = (int)reader.ReadElementContentAsInt("PayPrice4", String.Empty); 737 obj.PayPrice[4] = (int)reader.ReadElementContentAsInt("PayPrice4", String.Empty);
736 } 738 }
737 739
740 private static void ProcessBuoyancy(SceneObjectPart obj, XmlTextReader reader)
741 {
742 obj.Buoyancy = (int)reader.ReadElementContentAsFloat("Buoyancy", String.Empty);
743 }
744
738 #endregion 745 #endregion
739 746
740 #region TaskInventoryXmlProcessors 747 #region TaskInventoryXmlProcessors
@@ -1219,6 +1226,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1219 writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString()); 1226 writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString());
1220 writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString()); 1227 writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString());
1221 1228
1229 writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString());
1230
1222 writer.WriteEndElement(); 1231 writer.WriteEndElement();
1223 } 1232 }
1224 1233
@@ -1503,12 +1512,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1503 { 1512 {
1504 TaskInventoryDictionary tinv = new TaskInventoryDictionary(); 1513 TaskInventoryDictionary tinv = new TaskInventoryDictionary();
1505 1514
1506 if (reader.IsEmptyElement)
1507 {
1508 reader.Read();
1509 return tinv;
1510 }
1511
1512 reader.ReadStartElement(name, String.Empty); 1515 reader.ReadStartElement(name, String.Empty);
1513 1516
1514 while (reader.Name == "TaskInventoryItem") 1517 while (reader.Name == "TaskInventoryItem")
@@ -1551,12 +1554,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1551 1554
1552 PrimitiveBaseShape shape = new PrimitiveBaseShape(); 1555 PrimitiveBaseShape shape = new PrimitiveBaseShape();
1553 1556
1554 if (reader.IsEmptyElement)
1555 {
1556 reader.Read();
1557 return shape;
1558 }
1559
1560 reader.ReadStartElement(name, String.Empty); // Shape 1557 reader.ReadStartElement(name, String.Empty); // Shape
1561 1558
1562 string nodeName = string.Empty; 1559 string nodeName = string.Empty;
@@ -1596,4 +1593,4 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1596 1593
1597 #endregion 1594 #endregion
1598 } 1595 }
1599} 1596} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index d34d8e5..0a30f4b 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -30,12 +30,27 @@ using System.Reflection;
30using log4net; 30using log4net;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using System;
33 34
34namespace OpenSim.Region.Framework.Scenes 35namespace OpenSim.Region.Framework.Scenes
35{ 36{
37 [Flags]
38 public enum UndoType
39 {
40 STATE_PRIM_POSITION = 1,
41 STATE_PRIM_ROTATION = 2,
42 STATE_PRIM_SCALE = 4,
43 STATE_PRIM_ALL = 7,
44 STATE_GROUP_POSITION = 8,
45 STATE_GROUP_ROTATION = 16,
46 STATE_GROUP_SCALE = 32,
47 STATE_GROUP_ALL = 56,
48 STATE_ALL = 63
49 }
50
36 public class UndoState 51 public class UndoState
37 { 52 {
38// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
39 54
40 public Vector3 Position = Vector3.Zero; 55 public Vector3 Position = Vector3.Zero;
41 public Vector3 Scale = Vector3.Zero; 56 public Vector3 Scale = Vector3.Zero;
@@ -57,37 +72,37 @@ namespace OpenSim.Region.Framework.Scenes
57 { 72 {
58 ForGroup = forGroup; 73 ForGroup = forGroup;
59 74
60// if (ForGroup) 75 // if (ForGroup)
61 Position = part.ParentGroup.AbsolutePosition; 76 Position = part.ParentGroup.AbsolutePosition;
62// else 77 // else
63// Position = part.OffsetPosition; 78 // Position = part.OffsetPosition;
64 79
65// m_log.DebugFormat( 80 // m_log.DebugFormat(
66// "[UNDO STATE]: Storing undo position {0} for root part", Position); 81 // "[UNDO STATE]: Storing undo position {0} for root part", Position);
67 82
68 Rotation = part.RotationOffset; 83 Rotation = part.RotationOffset;
69 84
70// m_log.DebugFormat( 85 // m_log.DebugFormat(
71// "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation); 86 // "[UNDO STATE]: Storing undo rotation {0} for root part", Rotation);
72 87
73 Scale = part.Shape.Scale; 88 Scale = part.Shape.Scale;
74 89
75// m_log.DebugFormat( 90 // m_log.DebugFormat(
76// "[UNDO STATE]: Storing undo scale {0} for root part", Scale); 91 // "[UNDO STATE]: Storing undo scale {0} for root part", Scale);
77 } 92 }
78 else 93 else
79 { 94 {
80 Position = part.OffsetPosition; 95 Position = part.OffsetPosition;
81// m_log.DebugFormat( 96 // m_log.DebugFormat(
82// "[UNDO STATE]: Storing undo position {0} for child part", Position); 97 // "[UNDO STATE]: Storing undo position {0} for child part", Position);
83 98
84 Rotation = part.RotationOffset; 99 Rotation = part.RotationOffset;
85// m_log.DebugFormat( 100 // m_log.DebugFormat(
86// "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation); 101 // "[UNDO STATE]: Storing undo rotation {0} for child part", Rotation);
87 102
88 Scale = part.Shape.Scale; 103 Scale = part.Shape.Scale;
89// m_log.DebugFormat( 104 // m_log.DebugFormat(
90// "[UNDO STATE]: Storing undo scale {0} for child part", Scale); 105 // "[UNDO STATE]: Storing undo scale {0} for child part", Scale);
91 } 106 }
92 } 107 }
93 108
@@ -121,9 +136,9 @@ namespace OpenSim.Region.Framework.Scenes
121 136
122 if (part.ParentID == 0) 137 if (part.ParentID == 0)
123 { 138 {
124// m_log.DebugFormat( 139 // m_log.DebugFormat(
125// "[UNDO STATE]: Undoing position to {0} for root part {1} {2}", 140 // "[UNDO STATE]: Undoing position to {0} for root part {1} {2}",
126// Position, part.Name, part.LocalId); 141 // Position, part.Name, part.LocalId);
127 142
128 if (Position != Vector3.Zero) 143 if (Position != Vector3.Zero)
129 { 144 {
@@ -133,9 +148,9 @@ namespace OpenSim.Region.Framework.Scenes
133 part.ParentGroup.UpdateRootPosition(Position); 148 part.ParentGroup.UpdateRootPosition(Position);
134 } 149 }
135 150
136// m_log.DebugFormat( 151 // m_log.DebugFormat(
137// "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}", 152 // "[UNDO STATE]: Undoing rotation {0} to {1} for root part {2} {3}",
138// part.RotationOffset, Rotation, part.Name, part.LocalId); 153 // part.RotationOffset, Rotation, part.Name, part.LocalId);
139 154
140 if (ForGroup) 155 if (ForGroup)
141 part.UpdateRotation(Rotation); 156 part.UpdateRotation(Rotation);
@@ -144,9 +159,9 @@ namespace OpenSim.Region.Framework.Scenes
144 159
145 if (Scale != Vector3.Zero) 160 if (Scale != Vector3.Zero)
146 { 161 {
147// m_log.DebugFormat( 162 // m_log.DebugFormat(
148// "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}", 163 // "[UNDO STATE]: Undoing scale {0} to {1} for root part {2} {3}",
149// part.Shape.Scale, Scale, part.Name, part.LocalId); 164 // part.Shape.Scale, Scale, part.Name, part.LocalId);
150 165
151 if (ForGroup) 166 if (ForGroup)
152 part.ParentGroup.GroupResize(Scale); 167 part.ParentGroup.GroupResize(Scale);
@@ -160,24 +175,24 @@ namespace OpenSim.Region.Framework.Scenes
160 { 175 {
161 if (Position != Vector3.Zero) 176 if (Position != Vector3.Zero)
162 { 177 {
163// m_log.DebugFormat( 178 // m_log.DebugFormat(
164// "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}", 179 // "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}",
165// part.OffsetPosition, Position, part.Name, part.LocalId); 180 // part.OffsetPosition, Position, part.Name, part.LocalId);
166 181
167 part.OffsetPosition = Position; 182 part.OffsetPosition = Position;
168 } 183 }
169 184
170// m_log.DebugFormat( 185 // m_log.DebugFormat(
171// "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}", 186 // "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}",
172// part.RotationOffset, Rotation, part.Name, part.LocalId); 187 // part.RotationOffset, Rotation, part.Name, part.LocalId);
173 188
174 part.UpdateRotation(Rotation); 189 part.UpdateRotation(Rotation);
175 190
176 if (Scale != Vector3.Zero) 191 if (Scale != Vector3.Zero)
177 { 192 {
178// m_log.DebugFormat( 193 // m_log.DebugFormat(
179// "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}", 194 // "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}",
180// part.Shape.Scale, Scale, part.Name, part.LocalId); 195 // part.Shape.Scale, Scale, part.Name, part.LocalId);
181 196
182 part.Resize(Scale); 197 part.Resize(Scale);
183 } 198 }
@@ -249,4 +264,4 @@ namespace OpenSim.Region.Framework.Scenes
249 m_terrainModule.UndoTerrain(m_terrainChannel); 264 m_terrainModule.UndoTerrain(m_terrainChannel);
250 } 265 }
251 } 266 }
252} \ No newline at end of file 267}
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index efb68a2..411e421 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -87,10 +87,6 @@ namespace OpenSim.Region.Framework.Scenes
87 /// <param name="assetUuids">The assets gathered</param> 87 /// <param name="assetUuids">The assets gathered</param>
88 public void GatherAssetUuids(UUID assetUuid, AssetType assetType, IDictionary<UUID, AssetType> assetUuids) 88 public void GatherAssetUuids(UUID assetUuid, AssetType assetType, IDictionary<UUID, AssetType> assetUuids)
89 { 89 {
90 // avoid infinite loops
91 if (assetUuids.ContainsKey(assetUuid))
92 return;
93
94 try 90 try
95 { 91 {
96 assetUuids[assetUuid] = assetType; 92 assetUuids[assetUuid] = assetType;