aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-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.cs504
-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.cs228
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs601
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs219
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs795
-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, 3091 insertions, 1060 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 dff43fd..cd5ac6c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -96,6 +96,7 @@ namespace OpenSim.Region.Framework.Scenes
96 // TODO: need to figure out how allow client agents but deny 96 // TODO: need to figure out how allow client agents but deny
97 // root agents when ACL denies access to root agent 97 // root agents when ACL denies access to root agent
98 public bool m_strictAccessControl = true; 98 public bool m_strictAccessControl = true;
99 public bool m_seeIntoBannedRegion = false;
99 public int MaxUndoCount = 5; 100 public int MaxUndoCount = 5;
100 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 101 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
101 public bool LoginLock = false; 102 public bool LoginLock = false;
@@ -111,12 +112,14 @@ namespace OpenSim.Region.Framework.Scenes
111 112
112 protected int m_splitRegionID; 113 protected int m_splitRegionID;
113 protected Timer m_restartWaitTimer = new Timer(); 114 protected Timer m_restartWaitTimer = new Timer();
115 protected Timer m_timerWatchdog = new Timer();
114 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 116 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
115 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 117 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
116 protected string m_simulatorVersion = "OpenSimulator Server"; 118 protected string m_simulatorVersion = "OpenSimulator Server";
117 protected ModuleLoader m_moduleLoader; 119 protected ModuleLoader m_moduleLoader;
118 protected AgentCircuitManager m_authenticateHandler; 120 protected AgentCircuitManager m_authenticateHandler;
119 protected SceneCommunicationService m_sceneGridService; 121 protected SceneCommunicationService m_sceneGridService;
122 protected ISnmpModule m_snmpService = null;
120 123
121 protected ISimulationDataService m_SimulationDataService; 124 protected ISimulationDataService m_SimulationDataService;
122 protected IEstateDataService m_EstateDataService; 125 protected IEstateDataService m_EstateDataService;
@@ -168,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes
168 private int m_update_events = 1; 171 private int m_update_events = 1;
169 private int m_update_backup = 200; 172 private int m_update_backup = 200;
170 private int m_update_terrain = 50; 173 private int m_update_terrain = 50;
171// private int m_update_land = 1; 174 private int m_update_land = 10;
172 private int m_update_coarse_locations = 50; 175 private int m_update_coarse_locations = 50;
173 176
174 private int agentMS; 177 private int agentMS;
@@ -183,6 +186,7 @@ namespace OpenSim.Region.Framework.Scenes
183 private int landMS; 186 private int landMS;
184 private int lastCompletedFrame; 187 private int lastCompletedFrame;
185 188
189 public bool CombineRegions = false;
186 /// <summary> 190 /// <summary>
187 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 191 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
188 /// asynchronously from the update loop. 192 /// asynchronously from the update loop.
@@ -205,10 +209,12 @@ namespace OpenSim.Region.Framework.Scenes
205 private bool m_scripts_enabled = true; 209 private bool m_scripts_enabled = true;
206 private string m_defaultScriptEngine; 210 private string m_defaultScriptEngine;
207 private int m_LastLogin; 211 private int m_LastLogin;
208 private Thread HeartbeatThread; 212 private Thread HeartbeatThread = null;
209 private volatile bool shuttingdown; 213 private volatile bool shuttingdown;
210 214
211 private int m_lastUpdate; 215 private int m_lastUpdate;
216 private int m_lastIncoming;
217 private int m_lastOutgoing;
212 private bool m_firstHeartbeat = true; 218 private bool m_firstHeartbeat = true;
213 219
214 private object m_deleting_scene_object = new object(); 220 private object m_deleting_scene_object = new object();
@@ -256,6 +262,19 @@ namespace OpenSim.Region.Framework.Scenes
256 get { return m_sceneGridService; } 262 get { return m_sceneGridService; }
257 } 263 }
258 264
265 public ISnmpModule SnmpService
266 {
267 get
268 {
269 if (m_snmpService == null)
270 {
271 m_snmpService = RequestModuleInterface<ISnmpModule>();
272 }
273
274 return m_snmpService;
275 }
276 }
277
259 public ISimulationDataService SimulationDataService 278 public ISimulationDataService SimulationDataService
260 { 279 {
261 get 280 get
@@ -537,6 +556,9 @@ namespace OpenSim.Region.Framework.Scenes
537 m_EstateDataService = estateDataService; 556 m_EstateDataService = estateDataService;
538 m_regionHandle = m_regInfo.RegionHandle; 557 m_regionHandle = m_regInfo.RegionHandle;
539 m_regionName = m_regInfo.RegionName; 558 m_regionName = m_regInfo.RegionName;
559 m_lastUpdate = Util.EnvironmentTickCount();
560 m_lastIncoming = 0;
561 m_lastOutgoing = 0;
540 562
541 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); 563 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
542 m_asyncSceneObjectDeleter.Enabled = true; 564 m_asyncSceneObjectDeleter.Enabled = true;
@@ -650,11 +672,13 @@ namespace OpenSim.Region.Framework.Scenes
650 //Animation states 672 //Animation states
651 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 673 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
652 // TODO: Change default to true once the feature is supported 674 // TODO: Change default to true once the feature is supported
653 m_usePreJump = startupConfig.GetBoolean("enableprejump", false); 675 m_usePreJump = startupConfig.GetBoolean("enableprejump", true);
654 676
655 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true); 677 m_physicalPrim = startupConfig.GetBoolean("physical_prim", true);
656 678
657 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); 679 m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
680
681 m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF");
658 if (RegionInfo.NonphysPrimMax > 0) 682 if (RegionInfo.NonphysPrimMax > 0)
659 { 683 {
660 m_maxNonphys = RegionInfo.NonphysPrimMax; 684 m_maxNonphys = RegionInfo.NonphysPrimMax;
@@ -686,6 +710,7 @@ namespace OpenSim.Region.Framework.Scenes
686 m_persistAfter *= 10000000; 710 m_persistAfter *= 10000000;
687 711
688 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); 712 m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
713 m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
689 714
690 IConfig packetConfig = m_config.Configs["PacketPool"]; 715 IConfig packetConfig = m_config.Configs["PacketPool"];
691 if (packetConfig != null) 716 if (packetConfig != null)
@@ -695,6 +720,8 @@ namespace OpenSim.Region.Framework.Scenes
695 } 720 }
696 721
697 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 722 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
723 m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
724 CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
698 725
699 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); 726 m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
700 if (m_generateMaptiles) 727 if (m_generateMaptiles)
@@ -730,9 +757,9 @@ namespace OpenSim.Region.Framework.Scenes
730 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 757 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
731 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 758 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
732 } 759 }
733 catch 760 catch (Exception e)
734 { 761 {
735 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 762 m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
736 } 763 }
737 764
738 #endregion Region Config 765 #endregion Region Config
@@ -1143,7 +1170,9 @@ namespace OpenSim.Region.Framework.Scenes
1143 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1170 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1144 if (HeartbeatThread != null) 1171 if (HeartbeatThread != null)
1145 { 1172 {
1173 m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1146 HeartbeatThread.Abort(); 1174 HeartbeatThread.Abort();
1175 Watchdog.AbortThread(HeartbeatThread.ManagedThreadId);
1147 HeartbeatThread = null; 1176 HeartbeatThread = null;
1148 } 1177 }
1149 m_lastUpdate = Util.EnvironmentTickCount(); 1178 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1186,9 +1215,6 @@ namespace OpenSim.Region.Framework.Scenes
1186 { 1215 {
1187 while (!shuttingdown) 1216 while (!shuttingdown)
1188 Update(); 1217 Update();
1189
1190 m_lastUpdate = Util.EnvironmentTickCount();
1191 m_firstHeartbeat = false;
1192 } 1218 }
1193 catch (ThreadAbortException) 1219 catch (ThreadAbortException)
1194 { 1220 {
@@ -1286,6 +1312,13 @@ namespace OpenSim.Region.Framework.Scenes
1286 eventMS = Util.EnvironmentTickCountSubtract(evMS); ; 1312 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1287 } 1313 }
1288 1314
1315 // if (Frame % m_update_land == 0)
1316 // {
1317 // int ldMS = Util.EnvironmentTickCount();
1318 // UpdateLand();
1319 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1320 // }
1321
1289 if (Frame % m_update_backup == 0) 1322 if (Frame % m_update_backup == 0)
1290 { 1323 {
1291 int backMS = Util.EnvironmentTickCount(); 1324 int backMS = Util.EnvironmentTickCount();
@@ -1387,12 +1420,16 @@ namespace OpenSim.Region.Framework.Scenes
1387 maintc = Util.EnvironmentTickCountSubtract(maintc); 1420 maintc = Util.EnvironmentTickCountSubtract(maintc);
1388 maintc = (int)(MinFrameTime * 1000) - maintc; 1421 maintc = (int)(MinFrameTime * 1000) - maintc;
1389 1422
1423
1424 m_lastUpdate = Util.EnvironmentTickCount();
1425 m_firstHeartbeat = false;
1426
1390 if (maintc > 0) 1427 if (maintc > 0)
1391 Thread.Sleep(maintc); 1428 Thread.Sleep(maintc);
1392 1429
1393 // Tell the watchdog that this thread is still alive 1430 // Tell the watchdog that this thread is still alive
1394 Watchdog.UpdateThread(); 1431 Watchdog.UpdateThread();
1395 } 1432 }
1396 1433
1397 public void AddGroupTarget(SceneObjectGroup grp) 1434 public void AddGroupTarget(SceneObjectGroup grp)
1398 { 1435 {
@@ -1408,9 +1445,9 @@ namespace OpenSim.Region.Framework.Scenes
1408 1445
1409 private void CheckAtTargets() 1446 private void CheckAtTargets()
1410 { 1447 {
1411 Dictionary<UUID, SceneObjectGroup>.ValueCollection objs; 1448 List<SceneObjectGroup> objs = new List<SceneObjectGroup>();
1412 lock (m_groupsWithTargets) 1449 lock (m_groupsWithTargets)
1413 objs = m_groupsWithTargets.Values; 1450 objs = new List<SceneObjectGroup>(m_groupsWithTargets.Values);
1414 1451
1415 foreach (SceneObjectGroup entry in objs) 1452 foreach (SceneObjectGroup entry in objs)
1416 entry.checkAtTargets(); 1453 entry.checkAtTargets();
@@ -1494,7 +1531,7 @@ namespace OpenSim.Region.Framework.Scenes
1494 msg.fromAgentName = "Server"; 1531 msg.fromAgentName = "Server";
1495 msg.dialog = (byte)19; // Object msg 1532 msg.dialog = (byte)19; // Object msg
1496 msg.fromGroup = false; 1533 msg.fromGroup = false;
1497 msg.offline = (byte)0; 1534 msg.offline = (byte)1;
1498 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; 1535 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
1499 msg.Position = Vector3.Zero; 1536 msg.Position = Vector3.Zero;
1500 msg.RegionID = RegionInfo.RegionID.Guid; 1537 msg.RegionID = RegionInfo.RegionID.Guid;
@@ -1729,14 +1766,24 @@ namespace OpenSim.Region.Framework.Scenes
1729 /// <returns></returns> 1766 /// <returns></returns>
1730 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 1767 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
1731 { 1768 {
1769
1770 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
1771 Vector3 wpos = Vector3.Zero;
1772 // Check for water surface intersection from above
1773 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) )
1774 {
1775 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
1776 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
1777 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
1778 wpos.Z = wheight;
1779 }
1780
1732 Vector3 pos = Vector3.Zero; 1781 Vector3 pos = Vector3.Zero;
1733 if (RayEndIsIntersection == (byte)1) 1782 if (RayEndIsIntersection == (byte)1)
1734 { 1783 {
1735 pos = RayEnd; 1784 pos = RayEnd;
1736 return pos;
1737 } 1785 }
1738 1786 else if (RayTargetID != UUID.Zero)
1739 if (RayTargetID != UUID.Zero)
1740 { 1787 {
1741 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 1788 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
1742 1789
@@ -1758,7 +1805,7 @@ namespace OpenSim.Region.Framework.Scenes
1758 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); 1805 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
1759 1806
1760 // Un-comment out the following line to Get Raytrace results printed to the console. 1807 // Un-comment out the following line to Get Raytrace results printed to the console.
1761 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 1808 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
1762 float ScaleOffset = 0.5f; 1809 float ScaleOffset = 0.5f;
1763 1810
1764 // If we hit something 1811 // If we hit something
@@ -1781,13 +1828,10 @@ namespace OpenSim.Region.Framework.Scenes
1781 //pos.Z -= 0.25F; 1828 //pos.Z -= 0.25F;
1782 1829
1783 } 1830 }
1784
1785 return pos;
1786 } 1831 }
1787 else 1832 else
1788 { 1833 {
1789 // We don't have a target here, so we're going to raytrace all the objects in the scene. 1834 // We don't have a target here, so we're going to raytrace all the objects in the scene.
1790
1791 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); 1835 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
1792 1836
1793 // Un-comment the following line to print the raytrace results to the console. 1837 // Un-comment the following line to print the raytrace results to the console.
@@ -1796,13 +1840,12 @@ namespace OpenSim.Region.Framework.Scenes
1796 if (ei.HitTF) 1840 if (ei.HitTF)
1797 { 1841 {
1798 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 1842 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
1799 } else 1843 }
1844 else
1800 { 1845 {
1801 // fall back to our stupid functionality 1846 // fall back to our stupid functionality
1802 pos = RayEnd; 1847 pos = RayEnd;
1803 } 1848 }
1804
1805 return pos;
1806 } 1849 }
1807 } 1850 }
1808 else 1851 else
@@ -1813,8 +1856,12 @@ namespace OpenSim.Region.Framework.Scenes
1813 //increase height so its above the ground. 1856 //increase height so its above the ground.
1814 //should be getting the normal of the ground at the rez point and using that? 1857 //should be getting the normal of the ground at the rez point and using that?
1815 pos.Z += scale.Z / 2f; 1858 pos.Z += scale.Z / 2f;
1816 return pos; 1859// return pos;
1817 } 1860 }
1861
1862 // check against posible water intercept
1863 if (wpos.Z > pos.Z) pos = wpos;
1864 return pos;
1818 } 1865 }
1819 1866
1820 1867
@@ -1898,7 +1945,10 @@ namespace OpenSim.Region.Framework.Scenes
1898 public bool AddRestoredSceneObject( 1945 public bool AddRestoredSceneObject(
1899 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 1946 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
1900 { 1947 {
1901 return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); 1948 bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
1949 if (result)
1950 sceneObject.IsDeleted = false;
1951 return result;
1902 } 1952 }
1903 1953
1904 /// <summary> 1954 /// <summary>
@@ -1988,6 +2038,15 @@ namespace OpenSim.Region.Framework.Scenes
1988 /// </summary> 2038 /// </summary>
1989 public void DeleteAllSceneObjects() 2039 public void DeleteAllSceneObjects()
1990 { 2040 {
2041 DeleteAllSceneObjects(false);
2042 }
2043
2044 /// <summary>
2045 /// Delete every object from the scene. This does not include attachments worn by avatars.
2046 /// </summary>
2047 public void DeleteAllSceneObjects(bool exceptNoCopy)
2048 {
2049 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
1991 lock (Entities) 2050 lock (Entities)
1992 { 2051 {
1993 EntityBase[] entities = Entities.GetEntities(); 2052 EntityBase[] entities = Entities.GetEntities();
@@ -1996,11 +2055,24 @@ namespace OpenSim.Region.Framework.Scenes
1996 if (e is SceneObjectGroup) 2055 if (e is SceneObjectGroup)
1997 { 2056 {
1998 SceneObjectGroup sog = (SceneObjectGroup)e; 2057 SceneObjectGroup sog = (SceneObjectGroup)e;
1999 if (!sog.IsAttachment) 2058 if (sog != null && !sog.IsAttachment)
2000 DeleteSceneObject((SceneObjectGroup)e, false); 2059 {
2060 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2061 {
2062 DeleteSceneObject((SceneObjectGroup)e, false);
2063 }
2064 else
2065 {
2066 toReturn.Add((SceneObjectGroup)e);
2067 }
2068 }
2001 } 2069 }
2002 } 2070 }
2003 } 2071 }
2072 if (toReturn.Count > 0)
2073 {
2074 returnObjects(toReturn.ToArray(), UUID.Zero);
2075 }
2004 } 2076 }
2005 2077
2006 /// <summary> 2078 /// <summary>
@@ -2048,6 +2120,8 @@ namespace OpenSim.Region.Framework.Scenes
2048 } 2120 }
2049 2121
2050 group.DeleteGroupFromScene(silent); 2122 group.DeleteGroupFromScene(silent);
2123 if (!silent)
2124 SendKillObject(new List<uint>() { group.LocalId });
2051 2125
2052// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2126// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2053 } 2127 }
@@ -2402,10 +2476,17 @@ namespace OpenSim.Region.Framework.Scenes
2402 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns> 2476 /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
2403 public bool AddSceneObject(SceneObjectGroup sceneObject) 2477 public bool AddSceneObject(SceneObjectGroup sceneObject)
2404 { 2478 {
2479 if (sceneObject.OwnerID == UUID.Zero)
2480 {
2481 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
2482 return false;
2483 }
2484
2405 // If the user is banned, we won't let any of their objects 2485 // If the user is banned, we won't let any of their objects
2406 // enter. Period. 2486 // enter. Period.
2407 // 2487 //
2408 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) 2488 int flags = GetUserFlags(sceneObject.OwnerID);
2489 if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
2409 { 2490 {
2410 m_log.Info("[INTERREGION]: Denied prim crossing for " + 2491 m_log.Info("[INTERREGION]: Denied prim crossing for " +
2411 "banned avatar"); 2492 "banned avatar");
@@ -2452,12 +2533,23 @@ namespace OpenSim.Region.Framework.Scenes
2452 } 2533 }
2453 else 2534 else
2454 { 2535 {
2536 m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
2455 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2537 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2456 RootPrim.AddFlag(PrimFlags.TemporaryOnRez); 2538 RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
2457 } 2539 }
2540 if (sceneObject.OwnerID == UUID.Zero)
2541 {
2542 m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
2543 return false;
2544 }
2458 } 2545 }
2459 else 2546 else
2460 { 2547 {
2548 if (sceneObject.OwnerID == UUID.Zero)
2549 {
2550 m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
2551 return false;
2552 }
2461 AddRestoredSceneObject(sceneObject, true, false); 2553 AddRestoredSceneObject(sceneObject, true, false);
2462 2554
2463 if (!Permissions.CanObjectEntry(sceneObject.UUID, 2555 if (!Permissions.CanObjectEntry(sceneObject.UUID,
@@ -2487,6 +2579,24 @@ namespace OpenSim.Region.Framework.Scenes
2487 return 2; // StateSource.PrimCrossing 2579 return 2; // StateSource.PrimCrossing
2488 } 2580 }
2489 2581
2582 public int GetUserFlags(UUID user)
2583 {
2584 //Unfortunately the SP approach means that the value is cached until region is restarted
2585 /*
2586 ScenePresence sp;
2587 if (TryGetScenePresence(user, out sp))
2588 {
2589 return sp.UserFlags;
2590 }
2591 else
2592 {
2593 */
2594 UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
2595 if (uac == null)
2596 return 0;
2597 return uac.UserFlags;
2598 //}
2599 }
2490 #endregion 2600 #endregion
2491 2601
2492 #region Add/Remove Avatar Methods 2602 #region Add/Remove Avatar Methods
@@ -2508,6 +2618,7 @@ namespace OpenSim.Region.Framework.Scenes
2508 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2618 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2509 2619
2510 CheckHeartbeat(); 2620 CheckHeartbeat();
2621 ScenePresence presence;
2511 2622
2512 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here 2623 if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
2513 { 2624 {
@@ -2543,7 +2654,14 @@ namespace OpenSim.Region.Framework.Scenes
2543 2654
2544 EventManager.TriggerOnNewClient(client); 2655 EventManager.TriggerOnNewClient(client);
2545 if (vialogin) 2656 if (vialogin)
2657 {
2546 EventManager.TriggerOnClientLogin(client); 2658 EventManager.TriggerOnClientLogin(client);
2659
2660 // Send initial parcel data
2661 Vector3 pos = createdSp.AbsolutePosition;
2662 ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y);
2663 land.SendLandUpdateToClient(client);
2664 }
2547 } 2665 }
2548 } 2666 }
2549 2667
@@ -2632,19 +2750,12 @@ namespace OpenSim.Region.Framework.Scenes
2632 // and the scene presence and the client, if they exist 2750 // and the scene presence and the client, if they exist
2633 try 2751 try
2634 { 2752 {
2635 // We need to wait for the client to make UDP contact first. 2753 ScenePresence sp = GetScenePresence(agentID);
2636 // It's the UDP contact that creates the scene presence 2754 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2637 ScenePresence sp = WaitGetScenePresence(agentID); 2755
2638 if (sp != null) 2756 if (sp != null)
2639 {
2640 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
2641
2642 sp.ControllingClient.Close(); 2757 sp.ControllingClient.Close();
2643 } 2758
2644 else
2645 {
2646 m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
2647 }
2648 // BANG! SLASH! 2759 // BANG! SLASH!
2649 m_authenticateHandler.RemoveCircuit(agentID); 2760 m_authenticateHandler.RemoveCircuit(agentID);
2650 2761
@@ -2744,6 +2855,7 @@ namespace OpenSim.Region.Framework.Scenes
2744 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory; 2855 client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
2745 client.OnUpdateInventoryItem += UpdateInventoryItemAsset; 2856 client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
2746 client.OnCopyInventoryItem += CopyInventoryItem; 2857 client.OnCopyInventoryItem += CopyInventoryItem;
2858 client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
2747 client.OnMoveInventoryItem += MoveInventoryItem; 2859 client.OnMoveInventoryItem += MoveInventoryItem;
2748 client.OnRemoveInventoryItem += RemoveInventoryItem; 2860 client.OnRemoveInventoryItem += RemoveInventoryItem;
2749 client.OnRemoveInventoryFolder += RemoveInventoryFolder; 2861 client.OnRemoveInventoryFolder += RemoveInventoryFolder;
@@ -2921,15 +3033,16 @@ namespace OpenSim.Region.Framework.Scenes
2921 /// </summary> 3033 /// </summary>
2922 /// <param name="agentId">The avatar's Unique ID</param> 3034 /// <param name="agentId">The avatar's Unique ID</param>
2923 /// <param name="client">The IClientAPI for the client</param> 3035 /// <param name="client">The IClientAPI for the client</param>
2924 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 3036 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
2925 { 3037 {
2926 if (m_teleportModule != null) 3038 if (m_teleportModule != null)
2927 m_teleportModule.TeleportHome(agentId, client); 3039 return m_teleportModule.TeleportHome(agentId, client);
2928 else 3040 else
2929 { 3041 {
2930 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3042 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2931 client.SendTeleportFailed("Unable to perform teleports on this simulator."); 3043 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2932 } 3044 }
3045 return false;
2933 } 3046 }
2934 3047
2935 /// <summary> 3048 /// <summary>
@@ -3021,6 +3134,16 @@ namespace OpenSim.Region.Framework.Scenes
3021 /// <param name="flags"></param> 3134 /// <param name="flags"></param>
3022 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 3135 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3023 { 3136 {
3137 //Add half the avatar's height so that the user doesn't fall through prims
3138 ScenePresence presence;
3139 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3140 {
3141 if (presence.Appearance != null)
3142 {
3143 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3144 }
3145 }
3146
3024 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) 3147 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3025 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 3148 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3026 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 3149 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
@@ -3089,8 +3212,9 @@ namespace OpenSim.Region.Framework.Scenes
3089 regions.Remove(RegionInfo.RegionHandle); 3212 regions.Remove(RegionInfo.RegionHandle);
3090 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3213 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3091 } 3214 }
3092 3215 m_log.Debug("[Scene] Beginning ClientClosed");
3093 m_eventManager.TriggerClientClosed(agentID, this); 3216 m_eventManager.TriggerClientClosed(agentID, this);
3217 m_log.Debug("[Scene] Finished ClientClosed");
3094 } 3218 }
3095 catch (NullReferenceException) 3219 catch (NullReferenceException)
3096 { 3220 {
@@ -3098,7 +3222,12 @@ namespace OpenSim.Region.Framework.Scenes
3098 // Avatar is already disposed :/ 3222 // Avatar is already disposed :/
3099 } 3223 }
3100 3224
3225 m_log.Debug("[Scene] Beginning OnRemovePresence");
3101 m_eventManager.TriggerOnRemovePresence(agentID); 3226 m_eventManager.TriggerOnRemovePresence(agentID);
3227 m_log.Debug("[Scene] Finished OnRemovePresence");
3228
3229 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3230 AttachmentsModule.SaveChangedAttachments(avatar);
3102 3231
3103 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3232 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
3104 AttachmentsModule.SaveChangedAttachments(avatar); 3233 AttachmentsModule.SaveChangedAttachments(avatar);
@@ -3107,7 +3236,7 @@ namespace OpenSim.Region.Framework.Scenes
3107 delegate(IClientAPI client) 3236 delegate(IClientAPI client)
3108 { 3237 {
3109 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3238 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3110 try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } 3239 try { client.SendKillObject(avatar.RegionHandle, new List<uint>() { avatar.LocalId}); }
3111 catch (NullReferenceException) { } 3240 catch (NullReferenceException) { }
3112 }); 3241 });
3113 3242
@@ -3118,8 +3247,11 @@ namespace OpenSim.Region.Framework.Scenes
3118 } 3247 }
3119 3248
3120 // Remove the avatar from the scene 3249 // Remove the avatar from the scene
3250 m_log.Debug("[Scene] Begin RemoveScenePresence");
3121 m_sceneGraph.RemoveScenePresence(agentID); 3251 m_sceneGraph.RemoveScenePresence(agentID);
3252 m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager");
3122 m_clientManager.Remove(agentID); 3253 m_clientManager.Remove(agentID);
3254 m_log.Debug("[Scene] Removed the client manager. Firing avatar.close");
3123 3255
3124 try 3256 try
3125 { 3257 {
@@ -3133,9 +3265,10 @@ namespace OpenSim.Region.Framework.Scenes
3133 { 3265 {
3134 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3266 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3135 } 3267 }
3136 3268 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3137 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3269 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3138// CleanDroppedAttachments(); 3270// CleanDroppedAttachments();
3271 m_log.Debug("[Scene] The avatar has left the building");
3139 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3272 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3140 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3273 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3141 } 3274 }
@@ -3166,19 +3299,24 @@ namespace OpenSim.Region.Framework.Scenes
3166 3299
3167 #region Entities 3300 #region Entities
3168 3301
3169 public void SendKillObject(uint localID) 3302 public void SendKillObject(List<uint> localIDs)
3170 { 3303 {
3171 SceneObjectPart part = GetSceneObjectPart(localID); 3304 List<uint> deleteIDs = new List<uint>();
3172 if (part != null) // It is a prim 3305
3306 foreach (uint localID in localIDs)
3173 { 3307 {
3174 if (!part.ParentGroup.IsDeleted) // Valid 3308 SceneObjectPart part = GetSceneObjectPart(localID);
3309 if (part != null) // It is a prim
3175 { 3310 {
3176 if (part.ParentGroup.RootPart != part) // Child part 3311 if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3177 return; 3312 {
3313 if (part.ParentGroup.RootPart != part) // Child part
3314 continue;
3315 }
3178 } 3316 }
3317 deleteIDs.Add(localID);
3179 } 3318 }
3180 3319 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); });
3181 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
3182 } 3320 }
3183 3321
3184 #endregion 3322 #endregion
@@ -3196,7 +3334,6 @@ namespace OpenSim.Region.Framework.Scenes
3196 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; 3334 //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3197 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; 3335 //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
3198 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3336 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3199 m_sceneGridService.KiPrimitive += SendKillObject;
3200 m_sceneGridService.OnGetLandData += GetLandData; 3337 m_sceneGridService.OnGetLandData += GetLandData;
3201 } 3338 }
3202 3339
@@ -3205,7 +3342,6 @@ namespace OpenSim.Region.Framework.Scenes
3205 /// </summary> 3342 /// </summary>
3206 public void UnRegisterRegionWithComms() 3343 public void UnRegisterRegionWithComms()
3207 { 3344 {
3208 m_sceneGridService.KiPrimitive -= SendKillObject;
3209 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; 3345 m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
3210 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; 3346 //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
3211 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; 3347 //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
@@ -3285,13 +3421,16 @@ namespace OpenSim.Region.Framework.Scenes
3285 sp = null; 3421 sp = null;
3286 } 3422 }
3287 3423
3288 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3289 3424
3290 //On login test land permisions 3425 //On login test land permisions
3291 if (vialogin) 3426 if (vialogin)
3292 { 3427 {
3293 if (land != null && !TestLandRestrictions(agent, land, out reason)) 3428 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3429 if (cache != null)
3430 cache.Remove(agent.firstname + " " + agent.lastname);
3431 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y))
3294 { 3432 {
3433 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString());
3295 return false; 3434 return false;
3296 } 3435 }
3297 } 3436 }
@@ -3314,8 +3453,13 @@ namespace OpenSim.Region.Framework.Scenes
3314 3453
3315 try 3454 try
3316 { 3455 {
3317 if (!AuthorizeUser(agent, out reason)) 3456 // Always check estate if this is a login. Always
3318 return false; 3457 // check if banned regions are to be blacked out.
3458 if (vialogin || (!m_seeIntoBannedRegion))
3459 {
3460 if (!AuthorizeUser(agent, out reason))
3461 return false;
3462 }
3319 } 3463 }
3320 catch (Exception e) 3464 catch (Exception e)
3321 { 3465 {
@@ -3417,6 +3561,8 @@ namespace OpenSim.Region.Framework.Scenes
3417 } 3561 }
3418 } 3562 }
3419 // Honor parcel landing type and position. 3563 // Honor parcel landing type and position.
3564 /*
3565 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3420 if (land != null) 3566 if (land != null)
3421 { 3567 {
3422 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 3568 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
@@ -3424,26 +3570,34 @@ namespace OpenSim.Region.Framework.Scenes
3424 agent.startpos = land.LandData.UserLocation; 3570 agent.startpos = land.LandData.UserLocation;
3425 } 3571 }
3426 } 3572 }
3573 */// This is now handled properly in ScenePresence.MakeRootAgent
3427 } 3574 }
3428 3575
3429 return true; 3576 return true;
3430 } 3577 }
3431 3578
3432 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) 3579 private bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
3433 { 3580 {
3434 3581 reason = String.Empty;
3435 bool banned = land.IsBannedFromLand(agent.AgentID); 3582 if (Permissions.IsGod(agentID))
3436 bool restricted = land.IsRestrictedFromLand(agent.AgentID); 3583 return true;
3584
3585 ILandObject land = LandChannel.GetLandObject(posX, posY);
3586 if (land == null)
3587 return false;
3588
3589 bool banned = land.IsBannedFromLand(agentID);
3590 bool restricted = land.IsRestrictedFromLand(agentID);
3437 3591
3438 if (banned || restricted) 3592 if (banned || restricted)
3439 { 3593 {
3440 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); 3594 ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
3441 if (nearestParcel != null) 3595 if (nearestParcel != null)
3442 { 3596 {
3443 //Move agent to nearest allowed 3597 //Move agent to nearest allowed
3444 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); 3598 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3445 agent.startpos.X = newPosition.X; 3599 posX = newPosition.X;
3446 agent.startpos.Y = newPosition.Y; 3600 posY = newPosition.Y;
3447 } 3601 }
3448 else 3602 else
3449 { 3603 {
@@ -3505,7 +3659,7 @@ namespace OpenSim.Region.Framework.Scenes
3505 3659
3506 if (!m_strictAccessControl) return true; 3660 if (!m_strictAccessControl) return true;
3507 if (Permissions.IsGod(agent.AgentID)) return true; 3661 if (Permissions.IsGod(agent.AgentID)) return true;
3508 3662
3509 if (AuthorizationService != null) 3663 if (AuthorizationService != null)
3510 { 3664 {
3511 if (!AuthorizationService.IsAuthorizedForRegion( 3665 if (!AuthorizationService.IsAuthorizedForRegion(
@@ -3513,14 +3667,14 @@ namespace OpenSim.Region.Framework.Scenes
3513 { 3667 {
3514 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3668 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
3515 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3669 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
3516 3670
3517 return false; 3671 return false;
3518 } 3672 }
3519 } 3673 }
3520 3674
3521 if (m_regInfo.EstateSettings != null) 3675 if (m_regInfo.EstateSettings != null)
3522 { 3676 {
3523 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 3677 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID,0))
3524 { 3678 {
3525 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 3679 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
3526 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3680 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
@@ -3710,6 +3864,13 @@ namespace OpenSim.Region.Framework.Scenes
3710 3864
3711 // We have to wait until the viewer contacts this region after receiving EAC. 3865 // We have to wait until the viewer contacts this region after receiving EAC.
3712 // That calls AddNewClient, which finally creates the ScenePresence 3866 // That calls AddNewClient, which finally creates the ScenePresence
3867 int flags = GetUserFlags(cAgentData.AgentID);
3868 if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
3869 {
3870 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
3871 return false;
3872 }
3873
3713 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 3874 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
3714 if (nearestParcel == null) 3875 if (nearestParcel == null)
3715 { 3876 {
@@ -3725,7 +3886,6 @@ namespace OpenSim.Region.Framework.Scenes
3725 return false; 3886 return false;
3726 } 3887 }
3727 3888
3728
3729 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 3889 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
3730 3890
3731 if (childAgentUpdate != null) 3891 if (childAgentUpdate != null)
@@ -3792,12 +3952,22 @@ namespace OpenSim.Region.Framework.Scenes
3792 return false; 3952 return false;
3793 } 3953 }
3794 3954
3955 public bool IncomingCloseAgent(UUID agentID)
3956 {
3957 return IncomingCloseAgent(agentID, false);
3958 }
3959
3960 public bool IncomingCloseChildAgent(UUID agentID)
3961 {
3962 return IncomingCloseAgent(agentID, true);
3963 }
3964
3795 /// <summary> 3965 /// <summary>
3796 /// Tell a single agent to disconnect from the region. 3966 /// Tell a single agent to disconnect from the region.
3797 /// </summary> 3967 /// </summary>
3798 /// <param name="regionHandle"></param>
3799 /// <param name="agentID"></param> 3968 /// <param name="agentID"></param>
3800 public bool IncomingCloseAgent(UUID agentID) 3969 /// <param name="childOnly"></param>
3970 public bool IncomingCloseAgent(UUID agentID, bool childOnly)
3801 { 3971 {
3802 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 3972 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
3803 3973
@@ -3809,7 +3979,7 @@ namespace OpenSim.Region.Framework.Scenes
3809 { 3979 {
3810 m_sceneGraph.removeUserCount(false); 3980 m_sceneGraph.removeUserCount(false);
3811 } 3981 }
3812 else 3982 else if (!childOnly)
3813 { 3983 {
3814 m_sceneGraph.removeUserCount(true); 3984 m_sceneGraph.removeUserCount(true);
3815 } 3985 }
@@ -3825,9 +3995,12 @@ namespace OpenSim.Region.Framework.Scenes
3825 } 3995 }
3826 else 3996 else
3827 presence.ControllingClient.SendShutdownConnectionNotice(); 3997 presence.ControllingClient.SendShutdownConnectionNotice();
3998 presence.ControllingClient.Close(false);
3999 }
4000 else if (!childOnly)
4001 {
4002 presence.ControllingClient.Close(true);
3828 } 4003 }
3829
3830 presence.ControllingClient.Close();
3831 return true; 4004 return true;
3832 } 4005 }
3833 4006
@@ -4428,34 +4601,66 @@ namespace OpenSim.Region.Framework.Scenes
4428 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID); 4601 SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
4429 } 4602 }
4430 4603
4431 public int GetHealth() 4604 public int GetHealth(out int flags, out string message)
4432 { 4605 {
4433 // Returns: 4606 // Returns:
4434 // 1 = sim is up and accepting http requests. The heartbeat has 4607 // 1 = sim is up and accepting http requests. The heartbeat has
4435 // stopped and the sim is probably locked up, but a remote 4608 // stopped and the sim is probably locked up, but a remote
4436 // admin restart may succeed 4609 // admin restart may succeed
4437 // 4610 //
4438 // 2 = Sim is up and the heartbeat is running. The sim is likely 4611 // 2 = Sim is up and the heartbeat is running. The sim is likely
4439 // usable for people within and logins _may_ work 4612 // usable for people within
4440 // 4613 //
4441 // 3 = We have seen a new user enter within the past 4 minutes 4614 // 3 = Sim is up and one packet thread is running. Sim is
4615 // unstable and will not accept new logins
4616 //
4617 // 4 = Sim is up and both packet threads are running. Sim is
4618 // likely usable
4619 //
4620 // 5 = We have seen a new user enter within the past 4 minutes
4442 // which can be seen as positive confirmation of sim health 4621 // which can be seen as positive confirmation of sim health
4443 // 4622 //
4623
4624 flags = 0;
4625 message = String.Empty;
4626
4627 CheckHeartbeat();
4628
4629 if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
4630 {
4631 // We're still starting
4632 // 0 means "in startup", it can't happen another way, since
4633 // to get here, we must be able to accept http connections
4634 return 0;
4635 }
4636
4444 int health=1; // Start at 1, means we're up 4637 int health=1; // Start at 1, means we're up
4445 4638
4446 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4639 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000)
4640 {
4447 health+=1; 4641 health+=1;
4448 else 4642 flags |= 1;
4643 }
4644
4645 if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
4646 {
4647 health+=1;
4648 flags |= 2;
4649 }
4650
4651 if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
4652 {
4653 health+=1;
4654 flags |= 4;
4655 }
4656
4657 if (flags != 7)
4449 return health; 4658 return health;
4450 4659
4451 // A login in the last 4 mins? We can't be doing too badly 4660 // A login in the last 4 mins? We can't be doing too badly
4452 // 4661 //
4453 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000) 4662 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4454 health++; 4663 health++;
4455 else
4456 return health;
4457
4458 CheckHeartbeat();
4459 4664
4460 return health; 4665 return health;
4461 } 4666 }
@@ -4648,7 +4853,7 @@ namespace OpenSim.Region.Framework.Scenes
4648 if (m_firstHeartbeat) 4853 if (m_firstHeartbeat)
4649 return; 4854 return;
4650 4855
4651 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4856 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000)
4652 StartTimer(); 4857 StartTimer();
4653 } 4858 }
4654 4859
@@ -5062,6 +5267,54 @@ namespace OpenSim.Region.Framework.Scenes
5062 } 5267 }
5063 } 5268 }
5064 5269
5270// public void CleanDroppedAttachments()
5271// {
5272// List<SceneObjectGroup> objectsToDelete =
5273// new List<SceneObjectGroup>();
5274//
5275// lock (m_cleaningAttachments)
5276// {
5277// ForEachSOG(delegate (SceneObjectGroup grp)
5278// {
5279// if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5280// {
5281// UUID agentID = grp.OwnerID;
5282// if (agentID == UUID.Zero)
5283// {
5284// objectsToDelete.Add(grp);
5285// return;
5286// }
5287//
5288// ScenePresence sp = GetScenePresence(agentID);
5289// if (sp == null)
5290// {
5291// objectsToDelete.Add(grp);
5292// return;
5293// }
5294// }
5295// });
5296// }
5297//
5298// foreach (SceneObjectGroup grp in objectsToDelete)
5299// {
5300// m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5301// DeleteSceneObject(grp, true);
5302// }
5303// }
5304
5305 public void ThreadAlive(int threadCode)
5306 {
5307 switch(threadCode)
5308 {
5309 case 1: // Incoming
5310 m_lastIncoming = Util.EnvironmentTickCount();
5311 break;
5312 case 2: // Incoming
5313 m_lastOutgoing = Util.EnvironmentTickCount();
5314 break;
5315 }
5316 }
5317
5065 // This method is called across the simulation connector to 5318 // This method is called across the simulation connector to
5066 // determine if a given agent is allowed in this region 5319 // determine if a given agent is allowed in this region
5067 // AS A ROOT AGENT. Returning false here will prevent them 5320 // AS A ROOT AGENT. Returning false here will prevent them
@@ -5070,6 +5323,14 @@ namespace OpenSim.Region.Framework.Scenes
5070 // child agent creation, thereby emulating the SL behavior. 5323 // child agent creation, thereby emulating the SL behavior.
5071 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5324 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5072 { 5325 {
5326 reason = "You are banned from the region";
5327
5328 if (Permissions.IsGod(agentID))
5329 {
5330 reason = String.Empty;
5331 return true;
5332 }
5333
5073 int num = m_sceneGraph.GetNumberOfScenePresences(); 5334 int num = m_sceneGraph.GetNumberOfScenePresences();
5074 5335
5075 if (num >= RegionInfo.RegionSettings.AgentLimit) 5336 if (num >= RegionInfo.RegionSettings.AgentLimit)
@@ -5081,11 +5342,82 @@ namespace OpenSim.Region.Framework.Scenes
5081 } 5342 }
5082 } 5343 }
5083 5344
5345 ScenePresence presence = GetScenePresence(agentID);
5346 IClientAPI client = null;
5347 AgentCircuitData aCircuit = null;
5348
5349 if (presence != null)
5350 {
5351 client = presence.ControllingClient;
5352 if (client != null)
5353 aCircuit = client.RequestClientInfo();
5354 }
5355
5356 // We may be called before there is a presence or a client.
5357 // Fake AgentCircuitData to keep IAuthorizationModule smiling
5358 if (client == null)
5359 {
5360 aCircuit = new AgentCircuitData();
5361 aCircuit.AgentID = agentID;
5362 aCircuit.firstname = String.Empty;
5363 aCircuit.lastname = String.Empty;
5364 }
5365
5366 try
5367 {
5368 if (!AuthorizeUser(aCircuit, out reason))
5369 {
5370 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5371 return false;
5372 }
5373 }
5374 catch (Exception e)
5375 {
5376 m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} "+ e.StackTrace, e.Message);
5377 return false;
5378 }
5379
5380 if (position == Vector3.Zero) // Teleport
5381 {
5382 float posX = 128.0f;
5383 float posY = 128.0f;
5384
5385 if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
5386 {
5387 // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
5388 return false;
5389 }
5390 }
5391 else // Walking
5392 {
5393 ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
5394 if (land == null)
5395 return false;
5396
5397 bool banned = land.IsBannedFromLand(agentID);
5398 bool restricted = land.IsRestrictedFromLand(agentID);
5399
5400 if (banned || restricted)
5401 return false;
5402 }
5403
5084 reason = String.Empty; 5404 reason = String.Empty;
5085 return true; 5405 return true;
5086 } 5406 }
5087 5407
5088 /// <summary> 5408 public void StartTimerWatchdog()
5409 {
5410 m_timerWatchdog.Interval = 1000;
5411 m_timerWatchdog.Elapsed += TimerWatchdog;
5412 m_timerWatchdog.AutoReset = true;
5413 m_timerWatchdog.Start();
5414 }
5415
5416 public void TimerWatchdog(object sender, ElapsedEventArgs e)
5417 {
5418 CheckHeartbeat();
5419 }
5420
5089 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the 5421 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5090 /// autopilot that moves an avatar to a sit target!. 5422 /// autopilot that moves an avatar to a sit target!.
5091 /// </summary> 5423 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index dee2ecb..73e9392 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 82ded28..e1fde64 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
@@ -130,13 +139,18 @@ namespace OpenSim.Region.Framework.Scenes
130 139
131 protected internal void Close() 140 protected internal void Close()
132 { 141 {
133 lock (m_presenceLock) 142 m_scenePresencesLock.EnterWriteLock();
143 try
134 { 144 {
135 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); 145 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
136 List<ScenePresence> newlist = new List<ScenePresence>(); 146 List<ScenePresence> newlist = new List<ScenePresence>();
137 m_scenePresenceMap = newmap; 147 m_scenePresenceMap = newmap;
138 m_scenePresenceArray = newlist; 148 m_scenePresenceArray = newlist;
139 } 149 }
150 finally
151 {
152 m_scenePresencesLock.ExitWriteLock();
153 }
140 154
141 lock (SceneObjectGroupsByFullID) 155 lock (SceneObjectGroupsByFullID)
142 SceneObjectGroupsByFullID.Clear(); 156 SceneObjectGroupsByFullID.Clear();
@@ -275,6 +289,33 @@ namespace OpenSim.Region.Framework.Scenes
275 protected internal bool AddRestoredSceneObject( 289 protected internal bool AddRestoredSceneObject(
276 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 290 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
277 { 291 {
292 if (!m_parentScene.CombineRegions)
293 {
294 // KF: Check for out-of-region, move inside and make static.
295 Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X,
296 sceneObject.RootPart.GroupPosition.Y,
297 sceneObject.RootPart.GroupPosition.Z);
298 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 ||
299 npos.X > Constants.RegionSize ||
300 npos.Y > Constants.RegionSize))
301 {
302 if (npos.X < 0.0) npos.X = 1.0f;
303 if (npos.Y < 0.0) npos.Y = 1.0f;
304 if (npos.Z < 0.0) npos.Z = 0.0f;
305 if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f;
306 if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f;
307
308 foreach (SceneObjectPart part in sceneObject.Parts)
309 {
310 part.GroupPosition = npos;
311 }
312 sceneObject.RootPart.Velocity = Vector3.Zero;
313 sceneObject.RootPart.AngularVelocity = Vector3.Zero;
314 sceneObject.RootPart.Acceleration = Vector3.Zero;
315 sceneObject.RootPart.Velocity = Vector3.Zero;
316 }
317 }
318
278 if (attachToBackup && (!alreadyPersisted)) 319 if (attachToBackup && (!alreadyPersisted))
279 { 320 {
280 sceneObject.ForceInventoryPersistence(); 321 sceneObject.ForceInventoryPersistence();
@@ -492,6 +533,30 @@ namespace OpenSim.Region.Framework.Scenes
492 m_updateList[obj.UUID] = obj; 533 m_updateList[obj.UUID] = obj;
493 } 534 }
494 535
536 public void FireAttachToBackup(SceneObjectGroup obj)
537 {
538 if (OnAttachToBackup != null)
539 {
540 OnAttachToBackup(obj);
541 }
542 }
543
544 public void FireDetachFromBackup(SceneObjectGroup obj)
545 {
546 if (OnDetachFromBackup != null)
547 {
548 OnDetachFromBackup(obj);
549 }
550 }
551
552 public void FireChangeBackup(SceneObjectGroup obj)
553 {
554 if (OnChangeBackup != null)
555 {
556 OnChangeBackup(obj);
557 }
558 }
559
495 /// <summary> 560 /// <summary>
496 /// Process all pending updates 561 /// Process all pending updates
497 /// </summary> 562 /// </summary>
@@ -623,7 +688,8 @@ namespace OpenSim.Region.Framework.Scenes
623 688
624 Entities[presence.UUID] = presence; 689 Entities[presence.UUID] = presence;
625 690
626 lock (m_presenceLock) 691 m_scenePresencesLock.EnterWriteLock();
692 try
627 { 693 {
628 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 694 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
629 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 695 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -647,6 +713,10 @@ namespace OpenSim.Region.Framework.Scenes
647 m_scenePresenceMap = newmap; 713 m_scenePresenceMap = newmap;
648 m_scenePresenceArray = newlist; 714 m_scenePresenceArray = newlist;
649 } 715 }
716 finally
717 {
718 m_scenePresencesLock.ExitWriteLock();
719 }
650 } 720 }
651 721
652 /// <summary> 722 /// <summary>
@@ -661,7 +731,8 @@ namespace OpenSim.Region.Framework.Scenes
661 agentID); 731 agentID);
662 } 732 }
663 733
664 lock (m_presenceLock) 734 m_scenePresencesLock.EnterWriteLock();
735 try
665 { 736 {
666 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); 737 Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
667 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); 738 List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
@@ -683,6 +754,10 @@ namespace OpenSim.Region.Framework.Scenes
683 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); 754 m_log.WarnFormat("[SCENE GRAPH]: Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID);
684 } 755 }
685 } 756 }
757 finally
758 {
759 m_scenePresencesLock.ExitWriteLock();
760 }
686 } 761 }
687 762
688 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) 763 protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F)
@@ -1396,8 +1471,13 @@ namespace OpenSim.Region.Framework.Scenes
1396 { 1471 {
1397 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1472 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1398 { 1473 {
1399 if (m_parentScene.AttachmentsModule != null) 1474 // Set the new attachment point data in the object
1400 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(group, pos); 1475 byte attachmentPoint = group.GetAttachmentPoint();
1476 group.UpdateGroupPosition(pos);
1477 group.IsAttachment = false;
1478 group.AbsolutePosition = group.RootPart.AttachedPos;
1479 group.AttachmentPoint = attachmentPoint;
1480 group.HasGroupChanged = true;
1401 } 1481 }
1402 else 1482 else
1403 { 1483 {
@@ -1661,24 +1741,31 @@ namespace OpenSim.Region.Framework.Scenes
1661 /// <param name="childPrims"></param> 1741 /// <param name="childPrims"></param>
1662 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1742 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1663 { 1743 {
1744 SceneObjectGroup parentGroup = root.ParentGroup;
1745 if (parentGroup == null) return;
1664 Monitor.Enter(m_updateLock); 1746 Monitor.Enter(m_updateLock);
1747
1665 try 1748 try
1666 { 1749 {
1667 SceneObjectGroup parentGroup = root.ParentGroup; 1750 parentGroup.areUpdatesSuspended = true;
1668 1751
1669 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>(); 1752 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1670 1753
1671 // We do this in reverse to get the link order of the prims correct 1754 // We do this in reverse to get the link order of the prims correct
1672 for (int i = children.Count - 1; i >= 0; i--) 1755 for (int i = 0 ; i < children.Count ; i++)
1673 { 1756 {
1674 SceneObjectGroup child = children[i].ParentGroup; 1757 SceneObjectGroup child = children[i].ParentGroup;
1675 1758
1676 // Make sure no child prim is set for sale 1759 // Make sure no child prim is set for sale
1677 // So that, on delink, no prims are unwittingly 1760 // So that, on delink, no prims are unwittingly
1678 // left for sale and sold off 1761 // left for sale and sold off
1679 child.RootPart.ObjectSaleType = 0; 1762
1680 child.RootPart.SalePrice = 10; 1763 if (child != null)
1681 childGroups.Add(child); 1764 {
1765 child.RootPart.ObjectSaleType = 0;
1766 child.RootPart.SalePrice = 10;
1767 childGroups.Add(child);
1768 }
1682 } 1769 }
1683 1770
1684 foreach (SceneObjectGroup child in childGroups) 1771 foreach (SceneObjectGroup child in childGroups)
@@ -1694,12 +1781,19 @@ namespace OpenSim.Region.Framework.Scenes
1694 // occur on link to invoke this elsewhere (such as object selection) 1781 // occur on link to invoke this elsewhere (such as object selection)
1695 parentGroup.RootPart.CreateSelected = true; 1782 parentGroup.RootPart.CreateSelected = true;
1696 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1783 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1697 parentGroup.HasGroupChanged = true;
1698 parentGroup.ScheduleGroupForFullUpdate();
1699
1700 } 1784 }
1701 finally 1785 finally
1702 { 1786 {
1787 lock (SceneObjectGroupsByLocalPartID)
1788 {
1789 foreach (SceneObjectPart part in parentGroup.Parts)
1790 SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup;
1791 }
1792
1793 parentGroup.areUpdatesSuspended = false;
1794 parentGroup.HasGroupChanged = true;
1795 parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
1796 parentGroup.ScheduleGroupForFullUpdate();
1703 Monitor.Exit(m_updateLock); 1797 Monitor.Exit(m_updateLock);
1704 } 1798 }
1705 } 1799 }
@@ -1731,21 +1825,24 @@ namespace OpenSim.Region.Framework.Scenes
1731 1825
1732 SceneObjectGroup group = part.ParentGroup; 1826 SceneObjectGroup group = part.ParentGroup;
1733 if (!affectedGroups.Contains(group)) 1827 if (!affectedGroups.Contains(group))
1828 {
1829 group.areUpdatesSuspended = true;
1734 affectedGroups.Add(group); 1830 affectedGroups.Add(group);
1831 }
1735 } 1832 }
1736 } 1833 }
1737 } 1834 }
1738 1835
1739 foreach (SceneObjectPart child in childParts) 1836 if (childParts.Count > 0)
1740 { 1837 {
1741 // Unlink all child parts from their groups 1838 foreach (SceneObjectPart child in childParts)
1742 // 1839 {
1743 child.ParentGroup.DelinkFromGroup(child, true); 1840 // Unlink all child parts from their groups
1744 1841 //
1745 // These are not in affected groups and will not be 1842 child.ParentGroup.DelinkFromGroup(child, true);
1746 // handled further. Do the honors here. 1843 child.ParentGroup.HasGroupChanged = true;
1747 child.ParentGroup.HasGroupChanged = true; 1844 child.ParentGroup.ScheduleGroupForFullUpdate();
1748 child.ParentGroup.ScheduleGroupForFullUpdate(); 1845 }
1749 } 1846 }
1750 1847
1751 foreach (SceneObjectPart root in rootParts) 1848 foreach (SceneObjectPart root in rootParts)
@@ -1755,56 +1852,68 @@ namespace OpenSim.Region.Framework.Scenes
1755 // However, editing linked parts and unlinking may be different 1852 // However, editing linked parts and unlinking may be different
1756 // 1853 //
1757 SceneObjectGroup group = root.ParentGroup; 1854 SceneObjectGroup group = root.ParentGroup;
1855 group.areUpdatesSuspended = true;
1758 1856
1759 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); 1857 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
1760 int numChildren = newSet.Count; 1858 int numChildren = newSet.Count;
1761 1859
1860 if (numChildren == 1)
1861 break;
1862
1762 // 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
1763 // slated for unlink, we need to do this 1864 // slated for unlink, we need to do this
1865 // Unlink the remaining set
1764 // 1866 //
1765 if (numChildren != 1) 1867 bool sendEventsToRemainder = true;
1766 { 1868 if (numChildren > 1)
1767 // Unlink the remaining set 1869 sendEventsToRemainder = false;
1768 //
1769 bool sendEventsToRemainder = true;
1770 if (numChildren > 1)
1771 sendEventsToRemainder = false;
1772 1870
1773 foreach (SceneObjectPart p in newSet) 1871 foreach (SceneObjectPart p in newSet)
1872 {
1873 if (p != group.RootPart)
1774 { 1874 {
1775 if (p != group.RootPart) 1875 group.DelinkFromGroup(p, sendEventsToRemainder);
1776 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 }
1777 } 1885 }
1886 }
1887
1888 // If there is more than one prim remaining, we
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);
1778 1897
1779 // If there is more than one prim remaining, we 1898 // Preserve link ordering
1780 // need to re-link
1781 // 1899 //
1782 if (numChildren > 2) 1900 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1783 { 1901 {
1784 // Remove old root 1902 return a.LinkNum.CompareTo(b.LinkNum);
1785 // 1903 });
1786 if (newSet.Contains(root))
1787 newSet.Remove(root);
1788
1789 // Preserve link ordering
1790 //
1791 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1792 {
1793 return a.LinkNum.CompareTo(b.LinkNum);
1794 });
1795 1904
1796 // Determine new root 1905 // Determine new root
1797 // 1906 //
1798 SceneObjectPart newRoot = newSet[0]; 1907 SceneObjectPart newRoot = newSet[0];
1799 newSet.RemoveAt(0); 1908 newSet.RemoveAt(0);
1800 1909
1801 foreach (SceneObjectPart newChild in newSet) 1910 foreach (SceneObjectPart newChild in newSet)
1802 newChild.ClearUpdateSchedule(); 1911 newChild.ClearUpdateSchedule();
1803 1912
1804 LinkObjects(newRoot, newSet); 1913 newRoot.ParentGroup.areUpdatesSuspended = true;
1805 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1914 LinkObjects(newRoot, newSet);
1806 affectedGroups.Add(newRoot.ParentGroup); 1915 if (!affectedGroups.Contains(newRoot.ParentGroup))
1807 } 1916 affectedGroups.Add(newRoot.ParentGroup);
1808 } 1917 }
1809 } 1918 }
1810 1919
@@ -1812,8 +1921,14 @@ namespace OpenSim.Region.Framework.Scenes
1812 // 1921 //
1813 foreach (SceneObjectGroup g in affectedGroups) 1922 foreach (SceneObjectGroup g in affectedGroups)
1814 { 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);
1815 g.TriggerScriptChangedEvent(Changed.LINK); 1929 g.TriggerScriptChangedEvent(Changed.LINK);
1816 g.HasGroupChanged = true; // Persist 1930 g.HasGroupChanged = true; // Persist
1931 g.areUpdatesSuspended = false;
1817 g.ScheduleGroupForFullUpdate(); 1932 g.ScheduleGroupForFullUpdate();
1818 } 1933 }
1819 } 1934 }
@@ -1931,9 +2046,6 @@ namespace OpenSim.Region.Framework.Scenes
1931 child.ApplyNextOwnerPermissions(); 2046 child.ApplyNextOwnerPermissions();
1932 } 2047 }
1933 } 2048 }
1934
1935 copy.RootPart.ObjectSaleType = 0;
1936 copy.RootPart.SalePrice = 10;
1937 } 2049 }
1938 2050
1939 // 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 a0a7344..6204b4f 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
@@ -281,6 +344,16 @@ namespace OpenSim.Region.Framework.Scenes
281 get { return m_parts.Count; } 344 get { return m_parts.Count; }
282 } 345 }
283 346
347// protected Quaternion m_rotation = Quaternion.Identity;
348//
349// public virtual Quaternion Rotation
350// {
351// get { return m_rotation; }
352// set {
353// m_rotation = value;
354// }
355// }
356
284 public Quaternion GroupRotation 357 public Quaternion GroupRotation
285 { 358 {
286 get { return m_rootPart.RotationOffset; } 359 get { return m_rootPart.RotationOffset; }
@@ -389,7 +462,11 @@ namespace OpenSim.Region.Framework.Scenes
389 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 462 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
390 } 463 }
391 } 464 }
392 465
466 foreach (SceneObjectPart part in m_parts.GetArray())
467 {
468 part.IgnoreUndoUpdate = true;
469 }
393 if (RootPart.GetStatusSandbox()) 470 if (RootPart.GetStatusSandbox())
394 { 471 {
395 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) 472 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -403,10 +480,29 @@ namespace OpenSim.Region.Framework.Scenes
403 return; 480 return;
404 } 481 }
405 } 482 }
406
407 SceneObjectPart[] parts = m_parts.GetArray(); 483 SceneObjectPart[] parts = m_parts.GetArray();
408 for (int i = 0; i < parts.Length; i++) 484 foreach (SceneObjectPart part in parts)
409 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 }
410 506
411 //if (m_rootPart.PhysActor != null) 507 //if (m_rootPart.PhysActor != null)
412 //{ 508 //{
@@ -565,6 +661,7 @@ namespace OpenSim.Region.Framework.Scenes
565 /// </summary> 661 /// </summary>
566 public SceneObjectGroup() 662 public SceneObjectGroup()
567 { 663 {
664
568 } 665 }
569 666
570 /// <summary> 667 /// <summary>
@@ -581,7 +678,7 @@ namespace OpenSim.Region.Framework.Scenes
581 /// Constructor. This object is added to the scene later via AttachToScene() 678 /// Constructor. This object is added to the scene later via AttachToScene()
582 /// </summary> 679 /// </summary>
583 public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) 680 public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
584 { 681 {
585 SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero)); 682 SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero));
586 } 683 }
587 684
@@ -629,6 +726,9 @@ namespace OpenSim.Region.Framework.Scenes
629 /// </summary> 726 /// </summary>
630 public virtual void AttachToBackup() 727 public virtual void AttachToBackup()
631 { 728 {
729 if (IsAttachment) return;
730 m_scene.SceneGraph.FireAttachToBackup(this);
731
632 if (InSceneBackup) 732 if (InSceneBackup)
633 { 733 {
634 //m_log.DebugFormat( 734 //m_log.DebugFormat(
@@ -671,6 +771,9 @@ namespace OpenSim.Region.Framework.Scenes
671 771
672 ApplyPhysics(m_scene.m_physicalPrim); 772 ApplyPhysics(m_scene.m_physicalPrim);
673 773
774 if (RootPart.PhysActor != null)
775 RootPart.Buoyancy = RootPart.Buoyancy;
776
674 // 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
675 // 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.
676 //ScheduleGroupForFullUpdate(); 779 //ScheduleGroupForFullUpdate();
@@ -716,9 +819,9 @@ namespace OpenSim.Region.Framework.Scenes
716 result.normal = inter.normal; 819 result.normal = inter.normal;
717 result.distance = inter.distance; 820 result.distance = inter.distance;
718 } 821 }
822
719 } 823 }
720 } 824 }
721
722 return result; 825 return result;
723 } 826 }
724 827
@@ -738,17 +841,19 @@ namespace OpenSim.Region.Framework.Scenes
738 minZ = 8192f; 841 minZ = 8192f;
739 842
740 SceneObjectPart[] parts = m_parts.GetArray(); 843 SceneObjectPart[] parts = m_parts.GetArray();
741 for (int i = 0; i < parts.Length; i++) 844 foreach (SceneObjectPart part in parts)
742 { 845 {
743 SceneObjectPart part = parts[i];
744
745 Vector3 worldPos = part.GetWorldPosition(); 846 Vector3 worldPos = part.GetWorldPosition();
746 Vector3 offset = worldPos - AbsolutePosition; 847 Vector3 offset = worldPos - AbsolutePosition;
747 Quaternion worldRot; 848 Quaternion worldRot;
748 if (part.ParentID == 0) 849 if (part.ParentID == 0)
850 {
749 worldRot = part.RotationOffset; 851 worldRot = part.RotationOffset;
852 }
750 else 853 else
854 {
751 worldRot = part.GetWorldRotation(); 855 worldRot = part.GetWorldRotation();
856 }
752 857
753 Vector3 frontTopLeft; 858 Vector3 frontTopLeft;
754 Vector3 frontTopRight; 859 Vector3 frontTopRight;
@@ -760,6 +865,8 @@ namespace OpenSim.Region.Framework.Scenes
760 Vector3 backBottomLeft; 865 Vector3 backBottomLeft;
761 Vector3 backBottomRight; 866 Vector3 backBottomRight;
762 867
868 // Vector3[] corners = new Vector3[8];
869
763 Vector3 orig = Vector3.Zero; 870 Vector3 orig = Vector3.Zero;
764 871
765 frontTopLeft.X = orig.X - (part.Scale.X / 2); 872 frontTopLeft.X = orig.X - (part.Scale.X / 2);
@@ -794,6 +901,38 @@ namespace OpenSim.Region.Framework.Scenes
794 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 901 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
795 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 902 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
796 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
797 frontTopLeft = frontTopLeft * worldRot; 936 frontTopLeft = frontTopLeft * worldRot;
798 frontTopRight = frontTopRight * worldRot; 937 frontTopRight = frontTopRight * worldRot;
799 frontBottomLeft = frontBottomLeft * worldRot; 938 frontBottomLeft = frontBottomLeft * worldRot;
@@ -815,6 +954,15 @@ namespace OpenSim.Region.Framework.Scenes
815 backTopLeft += offset; 954 backTopLeft += offset;
816 backTopRight += offset; 955 backTopRight += offset;
817 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
818 if (frontTopRight.X > maxX) 966 if (frontTopRight.X > maxX)
819 maxX = frontTopRight.X; 967 maxX = frontTopRight.X;
820 if (frontTopLeft.X > maxX) 968 if (frontTopLeft.X > maxX)
@@ -960,15 +1108,20 @@ namespace OpenSim.Region.Framework.Scenes
960 1108
961 public void SaveScriptedState(XmlTextWriter writer) 1109 public void SaveScriptedState(XmlTextWriter writer)
962 { 1110 {
1111 SaveScriptedState(writer, false);
1112 }
1113
1114 public void SaveScriptedState(XmlTextWriter writer, bool oldIDs)
1115 {
963 XmlDocument doc = new XmlDocument(); 1116 XmlDocument doc = new XmlDocument();
964 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 1117 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
965 1118
966 SceneObjectPart[] parts = m_parts.GetArray(); 1119 SceneObjectPart[] parts = m_parts.GetArray();
967 for (int i = 0; i < parts.Length; i++) 1120 for (int i = 0; i < parts.Length; i++)
968 { 1121 {
969 Dictionary<UUID, string> pstates = parts[i].Inventory.GetScriptStates(); 1122 Dictionary<UUID, string> pstates = parts[i].Inventory.GetScriptStates(oldIDs);
970 foreach (KeyValuePair<UUID, string> kvp in pstates) 1123 foreach (KeyValuePair<UUID, string> kvp in pstates)
971 states.Add(kvp.Key, kvp.Value); 1124 states[kvp.Key] = kvp.Value;
972 } 1125 }
973 1126
974 if (states.Count > 0) 1127 if (states.Count > 0)
@@ -988,6 +1141,168 @@ namespace OpenSim.Region.Framework.Scenes
988 } 1141 }
989 1142
990 /// <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>
991 /// 1306 ///
992 /// </summary> 1307 /// </summary>
993 /// <param name="part"></param> 1308 /// <param name="part"></param>
@@ -1037,7 +1352,10 @@ namespace OpenSim.Region.Framework.Scenes
1037 public void AddPart(SceneObjectPart part) 1352 public void AddPart(SceneObjectPart part)
1038 { 1353 {
1039 part.SetParent(this); 1354 part.SetParent(this);
1040 part.LinkNum = m_parts.Add(part.UUID, part); 1355 m_parts.Add(part.UUID, part);
1356
1357 part.LinkNum = m_parts.Count;
1358
1041 if (part.LinkNum == 2) 1359 if (part.LinkNum == 2)
1042 RootPart.LinkNum = 1; 1360 RootPart.LinkNum = 1;
1043 } 1361 }
@@ -1145,6 +1463,11 @@ namespace OpenSim.Region.Framework.Scenes
1145 /// <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>
1146 public void DeleteGroupFromScene(bool silent) 1464 public void DeleteGroupFromScene(bool silent)
1147 { 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
1148 SceneObjectPart[] parts = m_parts.GetArray(); 1471 SceneObjectPart[] parts = m_parts.GetArray();
1149 for (int i = 0; i < parts.Length; i++) 1472 for (int i = 0; i < parts.Length; i++)
1150 { 1473 {
@@ -1162,11 +1485,13 @@ namespace OpenSim.Region.Framework.Scenes
1162 { 1485 {
1163 if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) || 1486 if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) ||
1164 (AttachmentPoint < 31) || (AttachmentPoint > 38)) 1487 (AttachmentPoint < 31) || (AttachmentPoint > 38))
1165 avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1488 avatar.ControllingClient.SendKillObject(m_regionHandle, new List<uint>() {part.LocalId});
1166 } 1489 }
1167 } 1490 }
1168 }); 1491 });
1169 } 1492 }
1493
1494
1170 } 1495 }
1171 1496
1172 public void AddScriptLPS(int count) 1497 public void AddScriptLPS(int count)
@@ -1263,7 +1588,12 @@ namespace OpenSim.Region.Framework.Scenes
1263 1588
1264 public void SetOwnerId(UUID userId) 1589 public void SetOwnerId(UUID userId)
1265 { 1590 {
1266 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1591 ForEachPart(delegate(SceneObjectPart part)
1592 {
1593
1594 part.OwnerID = userId;
1595
1596 });
1267 } 1597 }
1268 1598
1269 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1599 public void ForEachPart(Action<SceneObjectPart> whatToDo)
@@ -1295,11 +1625,17 @@ namespace OpenSim.Region.Framework.Scenes
1295 return; 1625 return;
1296 } 1626 }
1297 1627
1628 if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1629 return;
1630
1298 // 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
1299 // any exception propogate upwards. 1632 // any exception propogate upwards.
1300 try 1633 try
1301 { 1634 {
1302 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
1303 { 1639 {
1304 ILandObject parcel = m_scene.LandChannel.GetLandObject( 1640 ILandObject parcel = m_scene.LandChannel.GetLandObject(
1305 m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); 1641 m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y);
@@ -1326,6 +1662,7 @@ namespace OpenSim.Region.Framework.Scenes
1326 } 1662 }
1327 } 1663 }
1328 } 1664 }
1665
1329 } 1666 }
1330 1667
1331 if (m_scene.UseBackup && HasGroupChanged) 1668 if (m_scene.UseBackup && HasGroupChanged)
@@ -1333,6 +1670,20 @@ namespace OpenSim.Region.Framework.Scenes
1333 // 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.
1334 if (isTimeToPersist() || forcedBackup) 1671 if (isTimeToPersist() || forcedBackup)
1335 { 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 }
1336// m_log.DebugFormat( 1687// m_log.DebugFormat(
1337// "[SCENE]: Storing {0}, {1} in {2}", 1688// "[SCENE]: Storing {0}, {1} in {2}",
1338// Name, UUID, m_scene.RegionInfo.RegionName); 1689// Name, UUID, m_scene.RegionInfo.RegionName);
@@ -1410,7 +1761,7 @@ namespace OpenSim.Region.Framework.Scenes
1410 // This is only necessary when userExposed is false! 1761 // This is only necessary when userExposed is false!
1411 1762
1412 bool previousAttachmentStatus = dupe.IsAttachment; 1763 bool previousAttachmentStatus = dupe.IsAttachment;
1413 1764
1414 if (!userExposed) 1765 if (!userExposed)
1415 dupe.IsAttachment = true; 1766 dupe.IsAttachment = true;
1416 1767
@@ -1428,11 +1779,11 @@ namespace OpenSim.Region.Framework.Scenes
1428 dupe.m_rootPart.TrimPermissions(); 1779 dupe.m_rootPart.TrimPermissions();
1429 1780
1430 List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray()); 1781 List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray());
1431 1782
1432 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1783 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1433 { 1784 {
1434 return p1.LinkNum.CompareTo(p2.LinkNum); 1785 return p1.LinkNum.CompareTo(p2.LinkNum);
1435 } 1786 }
1436 ); 1787 );
1437 1788
1438 foreach (SceneObjectPart part in partList) 1789 foreach (SceneObjectPart part in partList)
@@ -1452,7 +1803,7 @@ namespace OpenSim.Region.Framework.Scenes
1452 if (part.PhysActor != null && userExposed) 1803 if (part.PhysActor != null && userExposed)
1453 { 1804 {
1454 PrimitiveBaseShape pbs = newPart.Shape; 1805 PrimitiveBaseShape pbs = newPart.Shape;
1455 1806
1456 newPart.PhysActor 1807 newPart.PhysActor
1457 = m_scene.PhysicsScene.AddPrimShape( 1808 = m_scene.PhysicsScene.AddPrimShape(
1458 string.Format("{0}/{1}", newPart.Name, newPart.UUID), 1809 string.Format("{0}/{1}", newPart.Name, newPart.UUID),
@@ -1462,11 +1813,11 @@ namespace OpenSim.Region.Framework.Scenes
1462 newPart.RotationOffset, 1813 newPart.RotationOffset,
1463 part.PhysActor.IsPhysical, 1814 part.PhysActor.IsPhysical,
1464 newPart.LocalId); 1815 newPart.LocalId);
1465 1816
1466 newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); 1817 newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
1467 } 1818 }
1468 } 1819 }
1469 1820
1470 if (userExposed) 1821 if (userExposed)
1471 { 1822 {
1472 dupe.UpdateParentIDs(); 1823 dupe.UpdateParentIDs();
@@ -1581,6 +1932,7 @@ namespace OpenSim.Region.Framework.Scenes
1581 return Vector3.Zero; 1932 return Vector3.Zero;
1582 } 1933 }
1583 1934
1935 // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object
1584 public void moveToTarget(Vector3 target, float tau) 1936 public void moveToTarget(Vector3 target, float tau)
1585 { 1937 {
1586 if (IsAttachment) 1938 if (IsAttachment)
@@ -1608,10 +1960,44 @@ namespace OpenSim.Region.Framework.Scenes
1608 RootPart.PhysActor.PIDActive = false; 1960 RootPart.PhysActor.PIDActive = false;
1609 } 1961 }
1610 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
1611 public void stopLookAt() 1990 public void stopLookAt()
1612 { 1991 {
1613 if (RootPart.PhysActor != null) 1992 SceneObjectPart rootpart = m_rootPart;
1614 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
1615 } 2001 }
1616 2002
1617 /// <summary> 2003 /// <summary>
@@ -1669,6 +2055,8 @@ namespace OpenSim.Region.Framework.Scenes
1669 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 2055 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1670 { 2056 {
1671 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
1672 AddPart(newPart); 2060 AddPart(newPart);
1673 2061
1674 SetPartAsNonRoot(newPart); 2062 SetPartAsNonRoot(newPart);
@@ -1815,11 +2203,11 @@ namespace OpenSim.Region.Framework.Scenes
1815 /// Immediately send a full update for this scene object. 2203 /// Immediately send a full update for this scene object.
1816 /// </summary> 2204 /// </summary>
1817 public void SendGroupFullUpdate() 2205 public void SendGroupFullUpdate()
1818 { 2206 {
1819 if (IsDeleted) 2207 if (IsDeleted)
1820 return; 2208 return;
1821 2209
1822// 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);
1823 2211
1824 RootPart.SendFullUpdateToAllClients(); 2212 RootPart.SendFullUpdateToAllClients();
1825 2213
@@ -1963,16 +2351,6 @@ namespace OpenSim.Region.Framework.Scenes
1963 /// <param name="objectGroup">The group of prims which should be linked to this group</param> 2351 /// <param name="objectGroup">The group of prims which should be linked to this group</param>
1964 public void LinkToGroup(SceneObjectGroup objectGroup) 2352 public void LinkToGroup(SceneObjectGroup objectGroup)
1965 { 2353 {
1966 // Make sure we have sent any pending unlinks or stuff.
1967 //if (objectGroup.RootPart.UpdateFlag > 0)
1968 //{
1969 // m_log.WarnFormat(
1970 // "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.",
1971 // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
1972
1973 // objectGroup.RootPart.SendScheduledUpdates();
1974 //}
1975
1976// m_log.DebugFormat( 2354// m_log.DebugFormat(
1977// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", 2355// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
1978// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); 2356// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
@@ -1983,6 +2361,7 @@ namespace OpenSim.Region.Framework.Scenes
1983 Quaternion oldRootRotation = linkPart.RotationOffset; 2361 Quaternion oldRootRotation = linkPart.RotationOffset;
1984 2362
1985 linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition; 2363 linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
2364 linkPart.ParentID = m_rootPart.LocalId;
1986 linkPart.GroupPosition = AbsolutePosition; 2365 linkPart.GroupPosition = AbsolutePosition;
1987 Vector3 axPos = linkPart.OffsetPosition; 2366 Vector3 axPos = linkPart.OffsetPosition;
1988 2367
@@ -1995,42 +2374,27 @@ namespace OpenSim.Region.Framework.Scenes
1995 linkPart.RotationOffset = newRot; 2374 linkPart.RotationOffset = newRot;
1996 2375
1997 linkPart.ParentID = m_rootPart.LocalId; 2376 linkPart.ParentID = m_rootPart.LocalId;
2377
1998 if (m_rootPart.LinkNum == 0) 2378 if (m_rootPart.LinkNum == 0)
1999 m_rootPart.LinkNum = 1; 2379 m_rootPart.LinkNum = 1;
2000 2380
2001 lock (m_parts.SyncRoot) 2381 lock (m_parts.SyncRoot)
2002 { 2382 {
2003 m_parts.Add(linkPart.UUID, linkPart); 2383 int linkNum = PrimCount + 1;
2004
2005 // Insert in terms of link numbers, the new links
2006 // before the current ones (with the exception of
2007 // the root prim. Shuffle the old ones up
2008 SceneObjectPart[] parts = m_parts.GetArray();
2009 for (int i = 0; i < parts.Length; i++)
2010 {
2011 SceneObjectPart part = parts[i];
2012 if (part.LinkNum != 1)
2013 {
2014 // Don't update root prim link number
2015 part.LinkNum += objectGroup.PrimCount;
2016 }
2017 }
2018 2384
2019 linkPart.LinkNum = 2; 2385 m_parts.Add(linkPart.UUID, linkPart);
2020 2386
2021 linkPart.SetParent(this); 2387 linkPart.SetParent(this);
2022 linkPart.CreateSelected = true; 2388 linkPart.CreateSelected = true;
2023 2389
2024 //if (linkPart.PhysActor != null) 2390 linkPart.LinkNum = linkNum++;
2025 //{
2026 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2027
2028 //linkPart.PhysActor = null;
2029 //}
2030 2391
2031 //TODO: rest of parts
2032 int linkNum = 3;
2033 SceneObjectPart[] ogParts = objectGroup.Parts; 2392 SceneObjectPart[] ogParts = objectGroup.Parts;
2393 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b)
2394 {
2395 return a.LinkNum - b.LinkNum;
2396 });
2397
2034 for (int i = 0; i < ogParts.Length; i++) 2398 for (int i = 0; i < ogParts.Length; i++)
2035 { 2399 {
2036 SceneObjectPart part = ogParts[i]; 2400 SceneObjectPart part = ogParts[i];
@@ -2178,6 +2542,7 @@ namespace OpenSim.Region.Framework.Scenes
2178 /// <param name="objectGroup"></param> 2542 /// <param name="objectGroup"></param>
2179 public virtual void DetachFromBackup() 2543 public virtual void DetachFromBackup()
2180 { 2544 {
2545 m_scene.SceneGraph.FireDetachFromBackup(this);
2181 if (m_isBackedUp && Scene != null) 2546 if (m_isBackedUp && Scene != null)
2182 m_scene.EventManager.OnBackup -= ProcessBackup; 2547 m_scene.EventManager.OnBackup -= ProcessBackup;
2183 2548
@@ -2196,7 +2561,8 @@ namespace OpenSim.Region.Framework.Scenes
2196 2561
2197 axPos *= parentRot; 2562 axPos *= parentRot;
2198 part.OffsetPosition = axPos; 2563 part.OffsetPosition = axPos;
2199 part.GroupPosition = oldGroupPosition + part.OffsetPosition; 2564 Vector3 newPos = oldGroupPosition + part.OffsetPosition;
2565 part.GroupPosition = newPos;
2200 part.OffsetPosition = Vector3.Zero; 2566 part.OffsetPosition = Vector3.Zero;
2201 part.RotationOffset = worldRot; 2567 part.RotationOffset = worldRot;
2202 2568
@@ -2207,7 +2573,7 @@ namespace OpenSim.Region.Framework.Scenes
2207 2573
2208 part.LinkNum = linkNum; 2574 part.LinkNum = linkNum;
2209 2575
2210 part.OffsetPosition = part.GroupPosition - AbsolutePosition; 2576 part.OffsetPosition = newPos - AbsolutePosition;
2211 2577
2212 Quaternion rootRotation = m_rootPart.RotationOffset; 2578 Quaternion rootRotation = m_rootPart.RotationOffset;
2213 2579
@@ -2217,7 +2583,7 @@ namespace OpenSim.Region.Framework.Scenes
2217 2583
2218 parentRot = m_rootPart.RotationOffset; 2584 parentRot = m_rootPart.RotationOffset;
2219 oldRot = part.RotationOffset; 2585 oldRot = part.RotationOffset;
2220 Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot; 2586 Quaternion newRot = Quaternion.Inverse(parentRot) * worldRot;
2221 part.RotationOffset = newRot; 2587 part.RotationOffset = newRot;
2222 } 2588 }
2223 2589
@@ -2464,8 +2830,12 @@ namespace OpenSim.Region.Framework.Scenes
2464 } 2830 }
2465 } 2831 }
2466 2832
2833 RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect);
2467 for (int i = 0; i < parts.Length; i++) 2834 for (int i = 0; i < parts.Length; i++)
2468 parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect); 2835 {
2836 if (parts[i] != RootPart)
2837 parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect);
2838 }
2469 } 2839 }
2470 } 2840 }
2471 2841
@@ -2478,6 +2848,17 @@ namespace OpenSim.Region.Framework.Scenes
2478 } 2848 }
2479 } 2849 }
2480 2850
2851
2852
2853 /// <summary>
2854 /// Gets the number of parts
2855 /// </summary>
2856 /// <returns></returns>
2857 public int GetPartCount()
2858 {
2859 return Parts.Count();
2860 }
2861
2481 /// <summary> 2862 /// <summary>
2482 /// Update the texture entry for this part 2863 /// Update the texture entry for this part
2483 /// </summary> 2864 /// </summary>
@@ -2534,7 +2915,6 @@ namespace OpenSim.Region.Framework.Scenes
2534 { 2915 {
2535// m_log.DebugFormat( 2916// m_log.DebugFormat(
2536// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); 2917// "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale);
2537
2538 RootPart.StoreUndoState(true); 2918 RootPart.StoreUndoState(true);
2539 2919
2540 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 2920 scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
@@ -2635,7 +3015,6 @@ namespace OpenSim.Region.Framework.Scenes
2635 prevScale.X *= x; 3015 prevScale.X *= x;
2636 prevScale.Y *= y; 3016 prevScale.Y *= y;
2637 prevScale.Z *= z; 3017 prevScale.Z *= z;
2638
2639// RootPart.IgnoreUndoUpdate = true; 3018// RootPart.IgnoreUndoUpdate = true;
2640 RootPart.Resize(prevScale); 3019 RootPart.Resize(prevScale);
2641// RootPart.IgnoreUndoUpdate = false; 3020// RootPart.IgnoreUndoUpdate = false;
@@ -2666,7 +3045,9 @@ namespace OpenSim.Region.Framework.Scenes
2666 } 3045 }
2667 3046
2668// obPart.IgnoreUndoUpdate = false; 3047// obPart.IgnoreUndoUpdate = false;
2669// obPart.StoreUndoState(); 3048 HasGroupChanged = true;
3049 m_rootPart.TriggerScriptChangedEvent(Changed.SCALE);
3050 ScheduleGroupForTerseUpdate();
2670 } 3051 }
2671 3052
2672// m_log.DebugFormat( 3053// m_log.DebugFormat(
@@ -2726,9 +3107,9 @@ namespace OpenSim.Region.Framework.Scenes
2726 { 3107 {
2727 SceneObjectPart part = GetChildPart(localID); 3108 SceneObjectPart part = GetChildPart(localID);
2728 3109
2729// SceneObjectPart[] parts = m_parts.GetArray(); 3110 SceneObjectPart[] parts = m_parts.GetArray();
2730// for (int i = 0; i < parts.Length; i++) 3111 for (int i = 0; i < parts.Length; i++)
2731// parts[i].StoreUndoState(); 3112 parts[i].StoreUndoState();
2732 3113
2733 if (part != null) 3114 if (part != null)
2734 { 3115 {
@@ -2784,10 +3165,27 @@ namespace OpenSim.Region.Framework.Scenes
2784 obPart.OffsetPosition = obPart.OffsetPosition + diff; 3165 obPart.OffsetPosition = obPart.OffsetPosition + diff;
2785 } 3166 }
2786 3167
2787 AbsolutePosition = newPos; 3168 //We have to set undoing here because otherwise an undo state will be saved
3169 if (!m_rootPart.Undoing)
3170 {
3171 m_rootPart.Undoing = true;
3172 AbsolutePosition = newPos;
3173 m_rootPart.Undoing = false;
3174 }
3175 else
3176 {
3177 AbsolutePosition = newPos;
3178 }
2788 3179
2789 HasGroupChanged = true; 3180 HasGroupChanged = true;
2790 ScheduleGroupForTerseUpdate(); 3181 if (m_rootPart.Undoing)
3182 {
3183 ScheduleGroupForFullUpdate();
3184 }
3185 else
3186 {
3187 ScheduleGroupForTerseUpdate();
3188 }
2791 } 3189 }
2792 3190
2793 #endregion 3191 #endregion
@@ -2864,10 +3262,7 @@ namespace OpenSim.Region.Framework.Scenes
2864 public void UpdateSingleRotation(Quaternion rot, uint localID) 3262 public void UpdateSingleRotation(Quaternion rot, uint localID)
2865 { 3263 {
2866 SceneObjectPart part = GetChildPart(localID); 3264 SceneObjectPart part = GetChildPart(localID);
2867
2868 SceneObjectPart[] parts = m_parts.GetArray(); 3265 SceneObjectPart[] parts = m_parts.GetArray();
2869 for (int i = 0; i < parts.Length; i++)
2870 parts[i].StoreUndoState();
2871 3266
2872 if (part != null) 3267 if (part != null)
2873 { 3268 {
@@ -2905,7 +3300,16 @@ namespace OpenSim.Region.Framework.Scenes
2905 if (part.UUID == m_rootPart.UUID) 3300 if (part.UUID == m_rootPart.UUID)
2906 { 3301 {
2907 UpdateRootRotation(rot); 3302 UpdateRootRotation(rot);
2908 AbsolutePosition = pos; 3303 if (!m_rootPart.Undoing)
3304 {
3305 m_rootPart.Undoing = true;
3306 AbsolutePosition = pos;
3307 m_rootPart.Undoing = false;
3308 }
3309 else
3310 {
3311 AbsolutePosition = pos;
3312 }
2909 } 3313 }
2910 else 3314 else
2911 { 3315 {
@@ -2929,9 +3333,10 @@ namespace OpenSim.Region.Framework.Scenes
2929 3333
2930 Quaternion axRot = rot; 3334 Quaternion axRot = rot;
2931 Quaternion oldParentRot = m_rootPart.RotationOffset; 3335 Quaternion oldParentRot = m_rootPart.RotationOffset;
2932
2933 m_rootPart.StoreUndoState(); 3336 m_rootPart.StoreUndoState();
2934 m_rootPart.UpdateRotation(rot); 3337
3338 //Don't use UpdateRotation because it schedules an update prematurely
3339 m_rootPart.RotationOffset = rot;
2935 if (m_rootPart.PhysActor != null) 3340 if (m_rootPart.PhysActor != null)
2936 { 3341 {
2937 m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; 3342 m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset;
@@ -2945,15 +3350,18 @@ namespace OpenSim.Region.Framework.Scenes
2945 if (prim.UUID != m_rootPart.UUID) 3350 if (prim.UUID != m_rootPart.UUID)
2946 { 3351 {
2947 prim.IgnoreUndoUpdate = true; 3352 prim.IgnoreUndoUpdate = true;
3353
3354 Quaternion NewRot = oldParentRot * prim.RotationOffset;
3355 NewRot = Quaternion.Inverse(axRot) * NewRot;
3356 prim.RotationOffset = NewRot;
3357
2948 Vector3 axPos = prim.OffsetPosition; 3358 Vector3 axPos = prim.OffsetPosition;
3359
2949 axPos *= oldParentRot; 3360 axPos *= oldParentRot;
2950 axPos *= Quaternion.Inverse(axRot); 3361 axPos *= Quaternion.Inverse(axRot);
2951 prim.OffsetPosition = axPos; 3362 prim.OffsetPosition = axPos;
2952 Quaternion primsRot = prim.RotationOffset; 3363
2953 Quaternion newRot = primsRot * oldParentRot; 3364 prim.IgnoreUndoUpdate = false;
2954 newRot *= Quaternion.Inverse(axRot);
2955 prim.RotationOffset = newRot;
2956 prim.ScheduleTerseUpdate();
2957 prim.IgnoreUndoUpdate = false; 3365 prim.IgnoreUndoUpdate = false;
2958 } 3366 }
2959 } 3367 }
@@ -2967,8 +3375,8 @@ namespace OpenSim.Region.Framework.Scenes
2967//// childpart.StoreUndoState(); 3375//// childpart.StoreUndoState();
2968// } 3376// }
2969// } 3377// }
2970 3378 HasGroupChanged = true;
2971 m_rootPart.ScheduleTerseUpdate(); 3379 ScheduleGroupForFullUpdate();
2972 3380
2973// m_log.DebugFormat( 3381// m_log.DebugFormat(
2974// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", 3382// "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}",
@@ -3196,7 +3604,6 @@ namespace OpenSim.Region.Framework.Scenes
3196 public float GetMass() 3604 public float GetMass()
3197 { 3605 {
3198 float retmass = 0f; 3606 float retmass = 0f;
3199
3200 SceneObjectPart[] parts = m_parts.GetArray(); 3607 SceneObjectPart[] parts = m_parts.GetArray();
3201 for (int i = 0; i < parts.Length; i++) 3608 for (int i = 0; i < parts.Length; i++)
3202 retmass += parts[i].GetMass(); 3609 retmass += parts[i].GetMass();
@@ -3290,6 +3697,14 @@ namespace OpenSim.Region.Framework.Scenes
3290 SetFromItemID(uuid); 3697 SetFromItemID(uuid);
3291 } 3698 }
3292 3699
3700 public void ResetOwnerChangeFlag()
3701 {
3702 ForEachPart(delegate(SceneObjectPart part)
3703 {
3704 part.ResetOwnerChangeFlag();
3705 });
3706 }
3707
3293 #endregion 3708 #endregion
3294 } 3709 }
3295} 3710}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 44f822c..948518a 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.
@@ -184,6 +185,15 @@ namespace OpenSim.Region.Framework.Scenes
184 185
185 public UUID FromFolderID; 186 public UUID FromFolderID;
186 187
188 // The following two are to hold the attachment data
189 // while an object is inworld
190 [XmlIgnore]
191 public byte AttachPoint = 0;
192
193 [XmlIgnore]
194 public Vector3 AttachOffset = Vector3.Zero;
195
196 [XmlIgnore]
187 public int STATUS_ROTATE_X; 197 public int STATUS_ROTATE_X;
188 198
189 public int STATUS_ROTATE_Y; 199 public int STATUS_ROTATE_Y;
@@ -253,6 +263,7 @@ namespace OpenSim.Region.Framework.Scenes
253 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 263 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
254 private Vector3 m_sitTargetPosition; 264 private Vector3 m_sitTargetPosition;
255 private string m_sitAnimation = "SIT"; 265 private string m_sitAnimation = "SIT";
266 private bool m_occupied; // KF if any av is sitting on this prim
256 private string m_text = String.Empty; 267 private string m_text = String.Empty;
257 private string m_touchName = String.Empty; 268 private string m_touchName = String.Empty;
258 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5); 269 private readonly Stack<UndoState> m_undo = new Stack<UndoState>(5);
@@ -288,6 +299,7 @@ namespace OpenSim.Region.Framework.Scenes
288 protected Vector3 m_lastAcceleration; 299 protected Vector3 m_lastAcceleration;
289 protected Vector3 m_lastAngularVelocity; 300 protected Vector3 m_lastAngularVelocity;
290 protected int m_lastTerseSent; 301 protected int m_lastTerseSent;
302 protected float m_buoyancy = 0.0f;
291 303
292 /// <summary> 304 /// <summary>
293 /// Stores media texture data 305 /// Stores media texture data
@@ -340,7 +352,7 @@ namespace OpenSim.Region.Framework.Scenes
340 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 352 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
341 Quaternion rotationOffset, Vector3 offsetPosition) 353 Quaternion rotationOffset, Vector3 offsetPosition)
342 { 354 {
343 m_name = "Primitive"; 355 m_name = "Object";
344 356
345 Rezzed = DateTime.UtcNow; 357 Rezzed = DateTime.UtcNow;
346 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 358 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
@@ -395,7 +407,7 @@ namespace OpenSim.Region.Framework.Scenes
395 private uint _ownerMask = (uint)PermissionMask.All; 407 private uint _ownerMask = (uint)PermissionMask.All;
396 private uint _groupMask = (uint)PermissionMask.None; 408 private uint _groupMask = (uint)PermissionMask.None;
397 private uint _everyoneMask = (uint)PermissionMask.None; 409 private uint _everyoneMask = (uint)PermissionMask.None;
398 private uint _nextOwnerMask = (uint)PermissionMask.All; 410 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
399 private PrimFlags _flags = PrimFlags.None; 411 private PrimFlags _flags = PrimFlags.None;
400 private DateTime m_expires; 412 private DateTime m_expires;
401 private DateTime m_rezzed; 413 private DateTime m_rezzed;
@@ -494,12 +506,16 @@ namespace OpenSim.Region.Framework.Scenes
494 } 506 }
495 507
496 /// <value> 508 /// <value>
497 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 509 /// Get the inventory list
498 /// </value> 510 /// </value>
499 public TaskInventoryDictionary TaskInventory 511 public TaskInventoryDictionary TaskInventory
500 { 512 {
501 get { return m_inventory.Items; } 513 get {
502 set { m_inventory.Items = value; } 514 return m_inventory.Items;
515 }
516 set {
517 m_inventory.Items = value;
518 }
503 } 519 }
504 520
505 /// <summary> 521 /// <summary>
@@ -640,14 +656,12 @@ namespace OpenSim.Region.Framework.Scenes
640 set { m_LoopSoundSlavePrims = value; } 656 set { m_LoopSoundSlavePrims = value; }
641 } 657 }
642 658
643
644 public Byte[] TextureAnimation 659 public Byte[] TextureAnimation
645 { 660 {
646 get { return m_TextureAnimation; } 661 get { return m_TextureAnimation; }
647 set { m_TextureAnimation = value; } 662 set { m_TextureAnimation = value; }
648 } 663 }
649 664
650
651 public Byte[] ParticleSystem 665 public Byte[] ParticleSystem
652 { 666 {
653 get { return m_particleSystem; } 667 get { return m_particleSystem; }
@@ -684,9 +698,11 @@ namespace OpenSim.Region.Framework.Scenes
684 { 698 {
685 // If this is a linkset, we don't want the physics engine mucking up our group position here. 699 // If this is a linkset, we don't want the physics engine mucking up our group position here.
686 PhysicsActor actor = PhysActor; 700 PhysicsActor actor = PhysActor;
687 if (actor != null && _parentID == 0) 701 if (_parentID == 0)
688 { 702 {
689 m_groupPosition = actor.Position; 703 if (actor != null)
704 m_groupPosition = actor.Position;
705 return m_groupPosition;
690 } 706 }
691 707
692 if (m_parentGroup.IsAttachment) 708 if (m_parentGroup.IsAttachment)
@@ -696,12 +712,14 @@ namespace OpenSim.Region.Framework.Scenes
696 return sp.AbsolutePosition; 712 return sp.AbsolutePosition;
697 } 713 }
698 714
715 // use root prim's group position. Physics may have updated it
716 if (ParentGroup.RootPart != this)
717 m_groupPosition = ParentGroup.RootPart.GroupPosition;
699 return m_groupPosition; 718 return m_groupPosition;
700 } 719 }
701 set 720 set
702 { 721 {
703 m_groupPosition = value; 722 m_groupPosition = value;
704
705 PhysicsActor actor = PhysActor; 723 PhysicsActor actor = PhysActor;
706 if (actor != null) 724 if (actor != null)
707 { 725 {
@@ -721,22 +739,13 @@ namespace OpenSim.Region.Framework.Scenes
721 739
722 // Tell the physics engines that this prim changed. 740 // Tell the physics engines that this prim changed.
723 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 741 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
742
724 } 743 }
725 catch (Exception e) 744 catch (Exception e)
726 { 745 {
727 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 746 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
728 } 747 }
729 } 748 }
730
731 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
732 if (m_sitTargetAvatar != UUID.Zero)
733 {
734 ScenePresence avatar;
735 if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar))
736 {
737 avatar.ParentPosition = GetWorldPosition();
738 }
739 }
740 } 749 }
741 } 750 }
742 751
@@ -745,7 +754,7 @@ namespace OpenSim.Region.Framework.Scenes
745 get { return m_offsetPosition; } 754 get { return m_offsetPosition; }
746 set 755 set
747 { 756 {
748// StoreUndoState(); 757 Vector3 oldpos = m_offsetPosition;
749 m_offsetPosition = value; 758 m_offsetPosition = value;
750 759
751 if (ParentGroup != null && !ParentGroup.IsDeleted) 760 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -760,7 +769,22 @@ namespace OpenSim.Region.Framework.Scenes
760 if (m_parentGroup.Scene != null) 769 if (m_parentGroup.Scene != null)
761 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 770 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
762 } 771 }
772
773 if (!m_parentGroup.m_dupeInProgress)
774 {
775 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
776 foreach (ScenePresence av in avs)
777 {
778 if (av.ParentID == m_localId)
779 {
780 Vector3 offset = (m_offsetPosition - oldpos);
781 av.AbsolutePosition += offset;
782 av.SendAvatarDataToAllAgents();
783 }
784 }
785 }
763 } 786 }
787 TriggerScriptChangedEvent(Changed.POSITION);
764 } 788 }
765 } 789 }
766 790
@@ -909,7 +933,16 @@ namespace OpenSim.Region.Framework.Scenes
909 /// <summary></summary> 933 /// <summary></summary>
910 public Vector3 Acceleration 934 public Vector3 Acceleration
911 { 935 {
912 get { return m_acceleration; } 936 get
937 {
938 PhysicsActor actor = PhysActor;
939 if (actor != null)
940 {
941 m_acceleration = actor.Acceleration;
942 }
943 return m_acceleration;
944 }
945
913 set { m_acceleration = value; } 946 set { m_acceleration = value; }
914 } 947 }
915 948
@@ -1240,6 +1273,13 @@ namespace OpenSim.Region.Framework.Scenes
1240 _flags = value; 1273 _flags = value;
1241 } 1274 }
1242 } 1275 }
1276
1277 [XmlIgnore]
1278 public bool IsOccupied // KF If an av is sittingon this prim
1279 {
1280 get { return m_occupied; }
1281 set { m_occupied = value; }
1282 }
1243 1283
1244 /// <summary> 1284 /// <summary>
1245 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero 1285 /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
@@ -1299,6 +1339,19 @@ namespace OpenSim.Region.Framework.Scenes
1299 set { m_collisionSoundVolume = value; } 1339 set { m_collisionSoundVolume = value; }
1300 } 1340 }
1301 1341
1342 public float Buoyancy
1343 {
1344 get { return m_buoyancy; }
1345 set
1346 {
1347 m_buoyancy = value;
1348 if (PhysActor != null)
1349 {
1350 PhysActor.Buoyancy = value;
1351 }
1352 }
1353 }
1354
1302 #endregion Public Properties with only Get 1355 #endregion Public Properties with only Get
1303 1356
1304 private uint ApplyMask(uint val, bool set, uint mask) 1357 private uint ApplyMask(uint val, bool set, uint mask)
@@ -1670,6 +1723,9 @@ namespace OpenSim.Region.Framework.Scenes
1670 1723
1671 // Move afterwards ResetIDs as it clears the localID 1724 // Move afterwards ResetIDs as it clears the localID
1672 dupe.LocalId = localID; 1725 dupe.LocalId = localID;
1726 if(dupe.PhysActor != null)
1727 dupe.PhysActor.LocalID = localID;
1728
1673 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1729 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1674 dupe._lastOwnerID = OwnerID; 1730 dupe._lastOwnerID = OwnerID;
1675 1731
@@ -2031,19 +2087,17 @@ namespace OpenSim.Region.Framework.Scenes
2031 public Vector3 GetWorldPosition() 2087 public Vector3 GetWorldPosition()
2032 { 2088 {
2033 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 2089 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
2034
2035 Vector3 axPos = OffsetPosition; 2090 Vector3 axPos = OffsetPosition;
2036
2037 axPos *= parentRot; 2091 axPos *= parentRot;
2038 Vector3 translationOffsetPosition = axPos; 2092 Vector3 translationOffsetPosition = axPos;
2039 2093 if(_parentID == 0)
2040// m_log.DebugFormat("[SCENE OBJECT PART]: Found group pos {0} for part {1}", GroupPosition, Name); 2094 {
2041 2095 return GroupPosition;
2042 Vector3 worldPos = GroupPosition + translationOffsetPosition; 2096 }
2043 2097 else
2044// m_log.DebugFormat("[SCENE OBJECT PART]: Found world pos {0} for part {1}", worldPos, Name); 2098 {
2045 2099 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
2046 return worldPos; 2100 }
2047 } 2101 }
2048 2102
2049 /// <summary> 2103 /// <summary>
@@ -2683,17 +2737,18 @@ namespace OpenSim.Region.Framework.Scenes
2683 //Trys to fetch sound id from prim's inventory. 2737 //Trys to fetch sound id from prim's inventory.
2684 //Prim's inventory doesn't support non script items yet 2738 //Prim's inventory doesn't support non script items yet
2685 2739
2686 lock (TaskInventory) 2740 TaskInventory.LockItemsForRead(true);
2741
2742 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2687 { 2743 {
2688 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2744 if (item.Value.Name == sound)
2689 { 2745 {
2690 if (item.Value.Name == sound) 2746 soundID = item.Value.ItemID;
2691 { 2747 break;
2692 soundID = item.Value.ItemID;
2693 break;
2694 }
2695 } 2748 }
2696 } 2749 }
2750
2751 TaskInventory.LockItemsForRead(false);
2697 } 2752 }
2698 2753
2699 m_parentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp) 2754 m_parentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2776,7 +2831,7 @@ namespace OpenSim.Region.Framework.Scenes
2776 2831
2777 public void RotLookAt(Quaternion target, float strength, float damping) 2832 public void RotLookAt(Quaternion target, float strength, float damping)
2778 { 2833 {
2779 rotLookAt(target, strength, damping); 2834 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup.
2780 } 2835 }
2781 2836
2782 public void rotLookAt(Quaternion target, float strength, float damping) 2837 public void rotLookAt(Quaternion target, float strength, float damping)
@@ -3022,8 +3077,8 @@ namespace OpenSim.Region.Framework.Scenes
3022 { 3077 {
3023 const float ROTATION_TOLERANCE = 0.01f; 3078 const float ROTATION_TOLERANCE = 0.01f;
3024 const float VELOCITY_TOLERANCE = 0.001f; 3079 const float VELOCITY_TOLERANCE = 0.001f;
3025 const float POSITION_TOLERANCE = 0.05f; 3080 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
3026 const int TIME_MS_TOLERANCE = 3000; 3081 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
3027 3082
3028 switch (UpdateFlag) 3083 switch (UpdateFlag)
3029 { 3084 {
@@ -3086,17 +3141,16 @@ namespace OpenSim.Region.Framework.Scenes
3086 if (!UUID.TryParse(sound, out soundID)) 3141 if (!UUID.TryParse(sound, out soundID))
3087 { 3142 {
3088 // search sound file from inventory 3143 // search sound file from inventory
3089 lock (TaskInventory) 3144 TaskInventory.LockItemsForRead(true);
3145 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
3090 { 3146 {
3091 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3147 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
3092 { 3148 {
3093 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3149 soundID = item.Value.ItemID;
3094 { 3150 break;
3095 soundID = item.Value.ItemID;
3096 break;
3097 }
3098 } 3151 }
3099 } 3152 }
3153 TaskInventory.LockItemsForRead(false);
3100 } 3154 }
3101 3155
3102 if (soundID == UUID.Zero) 3156 if (soundID == UUID.Zero)
@@ -3507,7 +3561,7 @@ namespace OpenSim.Region.Framework.Scenes
3507 3561
3508 public void StopLookAt() 3562 public void StopLookAt()
3509 { 3563 {
3510 m_parentGroup.stopLookAt(); 3564 m_parentGroup.stopLookAt(); // This calls method in SceneObjectGroup.
3511 3565
3512 m_parentGroup.ScheduleGroupForTerseUpdate(); 3566 m_parentGroup.ScheduleGroupForTerseUpdate();
3513 } 3567 }
@@ -3558,45 +3612,45 @@ namespace OpenSim.Region.Framework.Scenes
3558 // TODO: May need to fix for group comparison 3612 // TODO: May need to fix for group comparison
3559 if (last.Compare(this)) 3613 if (last.Compare(this))
3560 { 3614 {
3561 // m_log.DebugFormat( 3615 // m_log.DebugFormat(
3562 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", 3616 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3563 // Name, LocalId, m_undo.Count); 3617 // Name, LocalId, m_undo.Count);
3564 3618
3565 return; 3619 return;
3566 } 3620 }
3567 } 3621 }
3568 } 3622 }
3569 3623
3570 // m_log.DebugFormat( 3624 // m_log.DebugFormat(
3571 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", 3625 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3572 // Name, LocalId, forGroup, m_undo.Count); 3626 // Name, LocalId, forGroup, m_undo.Count);
3573 3627
3574 if (m_parentGroup.GetSceneMaxUndo() > 0) 3628 if (m_parentGroup.GetSceneMaxUndo() > 0)
3575 { 3629 {
3576 UndoState nUndo = new UndoState(this, forGroup); 3630 UndoState nUndo = new UndoState(this, forGroup);
3577 3631
3578 m_undo.Push(nUndo); 3632 m_undo.Push(nUndo);
3579 3633
3580 if (m_redo.Count > 0) 3634 if (m_redo.Count > 0)
3581 m_redo.Clear(); 3635 m_redo.Clear();
3582 3636
3583 // m_log.DebugFormat( 3637 // m_log.DebugFormat(
3584 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", 3638 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3585 // Name, LocalId, forGroup, m_undo.Count); 3639 // Name, LocalId, forGroup, m_undo.Count);
3586 } 3640 }
3587 } 3641 }
3588 } 3642 }
3589 } 3643 }
3590// else 3644 // else
3591// { 3645 // {
3592// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); 3646 // m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3593// } 3647 // }
3594 } 3648 }
3595// else 3649 // else
3596// { 3650 // {
3597// m_log.DebugFormat( 3651 // m_log.DebugFormat(
3598// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); 3652 // "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3599// } 3653 // }
3600 } 3654 }
3601 3655
3602 /// <summary> 3656 /// <summary>
@@ -4644,8 +4698,9 @@ namespace OpenSim.Region.Framework.Scenes
4644 { 4698 {
4645 m_shape.TextureEntry = textureEntry; 4699 m_shape.TextureEntry = textureEntry;
4646 TriggerScriptChangedEvent(Changed.TEXTURE); 4700 TriggerScriptChangedEvent(Changed.TEXTURE);
4647 4701 UpdateFlag = UpdateRequired.FULL;
4648 ParentGroup.HasGroupChanged = true; 4702 ParentGroup.HasGroupChanged = true;
4703
4649 //This is madness.. 4704 //This is madness..
4650 //ParentGroup.ScheduleGroupForFullUpdate(); 4705 //ParentGroup.ScheduleGroupForFullUpdate();
4651 //This is sparta 4706 //This is sparta
@@ -4842,5 +4897,17 @@ namespace OpenSim.Region.Framework.Scenes
4842 Color color = Color; 4897 Color color = Color;
4843 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 4898 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4844 } 4899 }
4900
4901 public void ResetOwnerChangeFlag()
4902 {
4903 List<UUID> inv = Inventory.GetInventoryList();
4904
4905 foreach (UUID itemID in inv)
4906 {
4907 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
4908 item.OwnerChanged = false;
4909 Inventory.UpdateInventoryItem(item, false, false);
4910 }
4911 }
4845 } 4912 }
4846} 4913}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 9446741..07e303f 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,125 @@ 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 Items.LockItemsForRead(false);
1037 return;
1038 }
1039
1040 if (!changed)
1041 {
1042 if (m_inventoryFileData.Length > 2)
801 { 1043 {
802 foreach (TaskInventoryItem item in m_items.Values) 1044 xferManager.AddNewFile(m_inventoryFileName,
803 { 1045 m_inventoryFileData);
804// m_log.DebugFormat( 1046 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
805// "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", 1047 Util.StringToBytes256(m_inventoryFileName));
806// item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId);
807 1048
808 UUID ownerID = item.OwnerID; 1049 Items.LockItemsForRead(false);
809 uint everyoneMask = 0; 1050 return;
810 uint baseMask = item.BasePermissions; 1051 }
811 uint ownerMask = item.CurrentPermissions; 1052 }
812 uint groupMask = item.GroupPermissions;
813 1053
814 invString.AddItemStart(); 1054 m_inventoryPrivileged = includeAssets;
815 invString.AddNameValueLine("item_id", item.ItemID.ToString());
816 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
817 1055
818 invString.AddPermissionsStart(); 1056 foreach (TaskInventoryItem item in m_items.Values)
1057 {
1058 UUID ownerID = item.OwnerID;
1059 uint everyoneMask = 0;
1060 uint baseMask = item.BasePermissions;
1061 uint ownerMask = item.CurrentPermissions;
1062 uint groupMask = item.GroupPermissions;
819 1063
820 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 1064 invString.AddItemStart();
821 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 1065 invString.AddNameValueLine("item_id", item.ItemID.ToString());
822 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); 1066 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 1067
826 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 1068 invString.AddPermissionsStart();
827 invString.AddNameValueLine("owner_id", ownerID.ToString());
828 1069
829 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 1070 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1071 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1072 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1073 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1074 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
830 1075
831 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 1076 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
832 invString.AddSectionEnd(); 1077 invString.AddNameValueLine("owner_id", ownerID.ToString());
833 1078
834 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 1079 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 1080
839 invString.AddSaleStart(); 1081 invString.AddNameValueLine("group_id", item.GroupID.ToString());
840 invString.AddNameValueLine("sale_type", "not"); 1082 invString.AddSectionEnd();
841 invString.AddNameValueLine("sale_price", "0");
842 invString.AddSectionEnd();
843 1083
844 invString.AddNameValueLine("name", item.Name + "|"); 1084 if (includeAssets)
845 invString.AddNameValueLine("desc", item.Description + "|"); 1085 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1086 else
1087 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1088 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
1089 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
1090 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
846 1091
847 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 1092 invString.AddSaleStart();
848 invString.AddSectionEnd(); 1093 invString.AddNameValueLine("sale_type", "not");
849 } 1094 invString.AddNameValueLine("sale_price", "0");
850 } 1095 invString.AddSectionEnd();
851 1096
852 m_inventoryFileData = Utils.StringToBytes(invString.BuildString); 1097 invString.AddNameValueLine("name", item.Name + "|");
1098 invString.AddNameValueLine("desc", item.Description + "|");
853 1099
854 return true; 1100 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1101 invString.AddSectionEnd();
855 } 1102 }
856 1103
857 // No need to recreate, the existing file is fine 1104 Items.LockItemsForRead(false);
858 return false;
859 }
860 1105
861 /// <summary> 1106 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 1107
877 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1108 if (m_inventoryFileData.Length > 2)
878 return; 1109 {
879 } 1110 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
880 1111 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
881 CreateInventoryFile(); 1112 Util.StringToBytes256(m_inventoryFileName));
882 1113 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 } 1114 }
1115
1116 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
904 } 1117 }
905 1118
906 /// <summary> 1119 /// <summary>
@@ -911,10 +1124,11 @@ namespace OpenSim.Region.Framework.Scenes
911 { 1124 {
912 if (HasInventoryChanged) 1125 if (HasInventoryChanged)
913 { 1126 {
914 HasInventoryChanged = false; 1127 Items.LockItemsForRead(true);
915 List<TaskInventoryItem> items = GetInventoryItems(); 1128 datastore.StorePrimInventory(m_part.UUID, Items.Values);
916 datastore.StorePrimInventory(m_part.UUID, items); 1129 Items.LockItemsForRead(false);
917 1130
1131 HasInventoryChanged = false;
918 } 1132 }
919 } 1133 }
920 1134
@@ -981,82 +1195,63 @@ namespace OpenSim.Region.Framework.Scenes
981 { 1195 {
982 uint mask=0x7fffffff; 1196 uint mask=0x7fffffff;
983 1197
984 lock (m_items) 1198 foreach (TaskInventoryItem item in m_items.Values)
985 { 1199 {
986 foreach (TaskInventoryItem item in m_items.Values) 1200 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1201 mask &= ~((uint)PermissionMask.Copy >> 13);
1202 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1203 mask &= ~((uint)PermissionMask.Transfer >> 13);
1204 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1205 mask &= ~((uint)PermissionMask.Modify >> 13);
1206
1207 if (item.InvType == (int)InventoryType.Object)
987 { 1208 {
988 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1209 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
989 mask &= ~((uint)PermissionMask.Copy >> 13); 1210 mask &= ~((uint)PermissionMask.Copy >> 13);
990 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1211 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
991 mask &= ~((uint)PermissionMask.Transfer >> 13); 1212 mask &= ~((uint)PermissionMask.Transfer >> 13);
992 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1213 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
993 mask &= ~((uint)PermissionMask.Modify >> 13); 1214 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 } 1215 }
1216
1217 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1218 mask &= ~(uint)PermissionMask.Copy;
1219 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1220 mask &= ~(uint)PermissionMask.Transfer;
1221 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1222 mask &= ~(uint)PermissionMask.Modify;
1021 } 1223 }
1022
1023 return mask; 1224 return mask;
1024 } 1225 }
1025 1226
1026 public void ApplyNextOwnerPermissions() 1227 public void ApplyNextOwnerPermissions()
1027 { 1228 {
1028 lock (m_items) 1229 foreach (TaskInventoryItem item in m_items.Values)
1029 { 1230 {
1030 foreach (TaskInventoryItem item in m_items.Values) 1231 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
1031 { 1232 {
1032 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1233 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1033 { 1234 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1034 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1235 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1035 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1236 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1036 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1237 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1037 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1238 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 } 1239 }
1240 item.OwnerChanged = true;
1241 item.CurrentPermissions &= item.NextPermissions;
1242 item.BasePermissions &= item.NextPermissions;
1243 item.EveryonePermissions &= item.NextPermissions;
1244 item.PermsMask = 0;
1245 item.PermsGranter = UUID.Zero;
1048 } 1246 }
1049 } 1247 }
1050 1248
1051 public void ApplyGodPermissions(uint perms) 1249 public void ApplyGodPermissions(uint perms)
1052 { 1250 {
1053 lock (m_items) 1251 foreach (TaskInventoryItem item in m_items.Values)
1054 { 1252 {
1055 foreach (TaskInventoryItem item in m_items.Values) 1253 item.CurrentPermissions = perms;
1056 { 1254 item.BasePermissions = perms;
1057 item.CurrentPermissions = perms;
1058 item.BasePermissions = perms;
1059 }
1060 } 1255 }
1061 1256
1062 m_inventorySerial++; 1257 m_inventorySerial++;
@@ -1069,17 +1264,13 @@ namespace OpenSim.Region.Framework.Scenes
1069 /// <returns></returns> 1264 /// <returns></returns>
1070 public bool ContainsScripts() 1265 public bool ContainsScripts()
1071 { 1266 {
1072 lock (m_items) 1267 foreach (TaskInventoryItem item in m_items.Values)
1073 { 1268 {
1074 foreach (TaskInventoryItem item in m_items.Values) 1269 if (item.InvType == (int)InventoryType.LSL)
1075 { 1270 {
1076 if (item.InvType == (int)InventoryType.LSL) 1271 return true;
1077 {
1078 return true;
1079 }
1080 } 1272 }
1081 } 1273 }
1082
1083 return false; 1274 return false;
1084 } 1275 }
1085 1276
@@ -1087,11 +1278,8 @@ namespace OpenSim.Region.Framework.Scenes
1087 { 1278 {
1088 List<UUID> ret = new List<UUID>(); 1279 List<UUID> ret = new List<UUID>();
1089 1280
1090 lock (m_items) 1281 foreach (TaskInventoryItem item in m_items.Values)
1091 { 1282 ret.Add(item.ItemID);
1092 foreach (TaskInventoryItem item in m_items.Values)
1093 ret.Add(item.ItemID);
1094 }
1095 1283
1096 return ret; 1284 return ret;
1097 } 1285 }
@@ -1122,6 +1310,11 @@ namespace OpenSim.Region.Framework.Scenes
1122 1310
1123 public Dictionary<UUID, string> GetScriptStates() 1311 public Dictionary<UUID, string> GetScriptStates()
1124 { 1312 {
1313 return GetScriptStates(false);
1314 }
1315
1316 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1317 {
1125 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1318 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1126 1319
1127 if (m_part.ParentGroup.Scene == null) // Group not in a scene 1320 if (m_part.ParentGroup.Scene == null) // Group not in a scene
@@ -1132,25 +1325,35 @@ namespace OpenSim.Region.Framework.Scenes
1132 if (engines == null) // No engine at all 1325 if (engines == null) // No engine at all
1133 return ret; 1326 return ret;
1134 1327
1135 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1328 Items.LockItemsForRead(true);
1136 1329 foreach (TaskInventoryItem item in m_items.Values)
1137 foreach (TaskInventoryItem item in scripts)
1138 { 1330 {
1139 foreach (IScriptModule e in engines) 1331 if (item.InvType == (int)InventoryType.LSL)
1140 { 1332 {
1141 if (e != null) 1333 foreach (IScriptModule e in engines)
1142 { 1334 {
1143 string n = e.GetXMLState(item.ItemID); 1335 if (e != null)
1144 if (n != String.Empty)
1145 { 1336 {
1146 if (!ret.ContainsKey(item.ItemID)) 1337 string n = e.GetXMLState(item.ItemID);
1147 ret[item.ItemID] = n; 1338 if (n != String.Empty)
1148 break; 1339 {
1340 if (oldIDs)
1341 {
1342 if (!ret.ContainsKey(item.OldItemID))
1343 ret[item.OldItemID] = n;
1344 }
1345 else
1346 {
1347 if (!ret.ContainsKey(item.ItemID))
1348 ret[item.ItemID] = n;
1349 }
1350 break;
1351 }
1149 } 1352 }
1150 } 1353 }
1151 } 1354 }
1152 } 1355 }
1153 1356 Items.LockItemsForRead(false);
1154 return ret; 1357 return ret;
1155 } 1358 }
1156 1359
@@ -1160,21 +1363,27 @@ namespace OpenSim.Region.Framework.Scenes
1160 if (engines == null) 1363 if (engines == null)
1161 return; 1364 return;
1162 1365
1163 List<TaskInventoryItem> scripts = GetInventoryScripts();
1164 1366
1165 foreach (TaskInventoryItem item in scripts) 1367 Items.LockItemsForRead(true);
1368
1369 foreach (TaskInventoryItem item in m_items.Values)
1166 { 1370 {
1167 foreach (IScriptModule engine in engines) 1371 if (item.InvType == (int)InventoryType.LSL)
1168 { 1372 {
1169 if (engine != null) 1373 foreach (IScriptModule engine in engines)
1170 { 1374 {
1171 if (item.OwnerChanged) 1375 if (engine != null)
1172 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1376 {
1173 item.OwnerChanged = false; 1377 if (item.OwnerChanged)
1174 engine.ResumeScript(item.ItemID); 1378 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1379 item.OwnerChanged = false;
1380 engine.ResumeScript(item.ItemID);
1381 }
1175 } 1382 }
1176 } 1383 }
1177 } 1384 }
1385
1386 Items.LockItemsForRead(false);
1178 } 1387 }
1179 } 1388 }
1180} 1389}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 1d77b06..aa1c15e 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 {
@@ -529,8 +556,10 @@ namespace OpenSim.Region.Framework.Scenes
529 } 556 }
530 } 557 }
531 558
532 m_pos = value; 559// Changed this to update unconditionally to make npose work
533 ParentPosition = Vector3.Zero; 560// if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting!
561 m_pos = value;
562 m_parentPosition = Vector3.Zero;
534 563
535// m_log.DebugFormat( 564// m_log.DebugFormat(
536// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 565// "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
@@ -587,15 +616,39 @@ namespace OpenSim.Region.Framework.Scenes
587 } 616 }
588 } 617 }
589 618
619 public Quaternion OffsetRotation
620 {
621 get { return m_offsetRotation; }
622 set { m_offsetRotation = value; }
623 }
590 private Quaternion m_bodyRot = Quaternion.Identity; 624 private Quaternion m_bodyRot = Quaternion.Identity;
591 625
592 public Quaternion Rotation 626 public Quaternion Rotation
593 { 627 {
594 get { return m_bodyRot; } 628 get {
595 set 629 if (m_parentID != 0)
596 { 630 {
631 if (m_offsetRotation != null)
632 {
633 return m_offsetRotation;
634 }
635 else
636 {
637 return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
638 }
639
640 }
641 else
642 {
643 return m_bodyRot;
644 }
645 }
646 set {
597 m_bodyRot = value; 647 m_bodyRot = value;
598// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); 648 if (m_parentID != 0)
649 {
650 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
651 }
599 } 652 }
600 } 653 }
601 654
@@ -613,12 +666,15 @@ namespace OpenSim.Region.Framework.Scenes
613 set { m_isChildAgent = value; } 666 set { m_isChildAgent = value; }
614 } 667 }
615 668
669 private uint m_parentID;
670
671
616 public uint ParentID 672 public uint ParentID
617 { 673 {
618 get { return m_parentID; } 674 get { return m_parentID; }
619 set { m_parentID = value; } 675 set { m_parentID = value; }
620 } 676 }
621 private uint m_parentID; 677
622 678
623 public float Health 679 public float Health
624 { 680 {
@@ -751,6 +807,7 @@ namespace OpenSim.Region.Framework.Scenes
751 m_localId = m_scene.AllocateLocalId(); 807 m_localId = m_scene.AllocateLocalId();
752 808
753 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); 809 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
810 m_userFlags = account.UserFlags;
754 811
755 if (account != null) 812 if (account != null)
756 UserLevel = account.UserLevel; 813 UserLevel = account.UserLevel;
@@ -769,10 +826,7 @@ namespace OpenSim.Region.Framework.Scenes
769 m_reprioritization_timer.AutoReset = false; 826 m_reprioritization_timer.AutoReset = false;
770 827
771 AdjustKnownSeeds(); 828 AdjustKnownSeeds();
772
773 // TODO: I think, this won't send anything, as we are still a child here...
774 Animator.TrySetMovementAnimation("STAND"); 829 Animator.TrySetMovementAnimation("STAND");
775
776 // we created a new ScenePresence (a new child agent) in a fresh region. 830 // we created a new ScenePresence (a new child agent) in a fresh region.
777 // Request info about all the (root) agents in this region 831 // Request info about all the (root) agents in this region
778 // Note: This won't send data *to* other clients in that region (children don't send) 832 // Note: This won't send data *to* other clients in that region (children don't send)
@@ -813,26 +867,30 @@ namespace OpenSim.Region.Framework.Scenes
813 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT 867 Dir_Vectors[3] = -Vector3.UnitY; //RIGHT
814 Dir_Vectors[4] = Vector3.UnitZ; //UP 868 Dir_Vectors[4] = Vector3.UnitZ; //UP
815 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN 869 Dir_Vectors[5] = -Vector3.UnitZ; //DOWN
816 Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge 870 Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE
817 Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD 871 Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE
818 Dir_Vectors[7] = -Vector3.UnitX; //BACK 872 Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE
873 Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE
874 Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge
819 } 875 }
820 876
821 private Vector3[] GetWalkDirectionVectors() 877 private Vector3[] GetWalkDirectionVectors()
822 { 878 {
823 Vector3[] vector = new Vector3[9]; 879 Vector3[] vector = new Vector3[11];
824 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z); //FORWARD 880 vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD
825 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK 881 vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK
826 vector[2] = Vector3.UnitY; //LEFT 882 vector[2] = Vector3.UnitY; //LEFT
827 vector[3] = -Vector3.UnitY; //RIGHT 883 vector[3] = -Vector3.UnitY; //RIGHT
828 vector[4] = new Vector3(CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP 884 vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP
829 vector[5] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN 885 vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN
830 vector[8] = new Vector3(-CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge 886 vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE
831 vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -CameraAtAxis.Z) * 2); //FORWARD Nudge 887 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE
832 vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, CameraAtAxis.Z); //BACK Nudge 888 vector[8] = Vector3.UnitY; //LEFT_NUDGE
889 vector[9] = -Vector3.UnitY; //RIGHT_NUDGE
890 vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE
833 return vector; 891 return vector;
834 } 892 }
835 893
836 #endregion 894 #endregion
837 895
838 public uint GenerateClientFlags(UUID ObjectID) 896 public uint GenerateClientFlags(UUID ObjectID)
@@ -847,6 +905,8 @@ namespace OpenSim.Region.Framework.Scenes
847 /// </summary> 905 /// </summary>
848 public void SendPrimUpdates() 906 public void SendPrimUpdates()
849 { 907 {
908 m_sceneViewer.SendPrimUpdates();
909
850 SceneViewer.SendPrimUpdates(); 910 SceneViewer.SendPrimUpdates();
851 } 911 }
852 912
@@ -892,6 +952,62 @@ namespace OpenSim.Region.Framework.Scenes
892 pos.Y = crossedBorder.BorderLine.Z - 1; 952 pos.Y = crossedBorder.BorderLine.Z - 1;
893 } 953 }
894 954
955 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
956 if (land != null)
957 {
958 // If we come in via login, landmark or map, we want to
959 // honor landing points. If we come in via Lure, we want
960 // to ignore them.
961 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
962 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
963 (m_teleportFlags & TeleportFlags.ViaLocation) != 0)
964 {
965 // Don't restrict gods, estate managers, or land owners to
966 // the TP point. This behaviour mimics agni.
967 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
968 land.LandData.UserLocation != Vector3.Zero &&
969 GodLevel < 200 &&
970 ((land.LandData.OwnerID != m_uuid &&
971 (!m_scene.Permissions.IsGod(m_uuid)) &&
972 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0))
973 {
974 pos = land.LandData.UserLocation;
975 }
976 }
977
978 land.SendLandUpdateToClient(ControllingClient);
979 }
980
981 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
982 {
983 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
984
985 if (pos.X < 0)
986 {
987 emergencyPos.X = (int)Constants.RegionSize + pos.X;
988 if (!(pos.Y < 0))
989 emergencyPos.Y = pos.Y;
990 if (!(pos.Z < 0))
991 emergencyPos.Z = pos.Z;
992 }
993 if (pos.Y < 0)
994 {
995 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
996 if (!(pos.X < 0))
997 emergencyPos.X = pos.X;
998 if (!(pos.Z < 0))
999 emergencyPos.Z = pos.Z;
1000 }
1001 if (pos.Z < 0)
1002 {
1003 emergencyPos.Z = 128;
1004 if (!(pos.Y < 0))
1005 emergencyPos.Y = pos.Y;
1006 if (!(pos.X < 0))
1007 emergencyPos.X = pos.X;
1008 }
1009 }
1010
895 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1011 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
896 { 1012 {
897 m_log.WarnFormat( 1013 m_log.WarnFormat(
@@ -1024,16 +1140,21 @@ namespace OpenSim.Region.Framework.Scenes
1024 /// <summary> 1140 /// <summary>
1025 /// Removes physics plugin scene representation of this agent if it exists. 1141 /// Removes physics plugin scene representation of this agent if it exists.
1026 /// </summary> 1142 /// </summary>
1027 private void RemoveFromPhysicalScene() 1143 public void RemoveFromPhysicalScene()
1028 { 1144 {
1029 if (PhysicsActor != null) 1145 if (PhysicsActor != null)
1030 { 1146 {
1031 PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; 1147 try
1032 PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; 1148 {
1033 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); 1149 m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
1034 PhysicsActor.UnSubscribeEvents(); 1150 m_physicsActor.OnOutOfBounds -= OutOfBoundsCall;
1035 PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; 1151 m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
1036 PhysicsActor = null; 1152 m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
1153 m_physicsActor.UnSubscribeEvents();
1154 PhysicsActor = null;
1155 }
1156 catch
1157 { }
1037 } 1158 }
1038 } 1159 }
1039 1160
@@ -1049,10 +1170,12 @@ namespace OpenSim.Region.Framework.Scenes
1049 1170
1050 RemoveFromPhysicalScene(); 1171 RemoveFromPhysicalScene();
1051 Velocity = Vector3.Zero; 1172 Velocity = Vector3.Zero;
1173 CheckLandingPoint(ref pos);
1052 AbsolutePosition = pos; 1174 AbsolutePosition = pos;
1053 AddToPhysicalScene(isFlying); 1175 AddToPhysicalScene(isFlying);
1054 1176
1055 SendTerseUpdateToAllClients(); 1177 SendTerseUpdateToAllClients();
1178
1056 } 1179 }
1057 1180
1058 public void TeleportWithMomentum(Vector3 pos) 1181 public void TeleportWithMomentum(Vector3 pos)
@@ -1062,6 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes
1062 isFlying = PhysicsActor.Flying; 1185 isFlying = PhysicsActor.Flying;
1063 1186
1064 RemoveFromPhysicalScene(); 1187 RemoveFromPhysicalScene();
1188 CheckLandingPoint(ref pos);
1065 AbsolutePosition = pos; 1189 AbsolutePosition = pos;
1066 AddToPhysicalScene(isFlying); 1190 AddToPhysicalScene(isFlying);
1067 1191
@@ -1269,11 +1393,12 @@ namespace OpenSim.Region.Framework.Scenes
1269 /// <summary> 1393 /// <summary>
1270 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1394 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1271 /// </summary> 1395 /// </summary>
1396 /// <summary>
1397 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1398 /// </summary>
1272 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1399 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1273 { 1400 {
1274// m_log.DebugFormat( 1401 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1275// "[SCENE PRESENCE]: In {0} received agent update from {1}",
1276// Scene.RegionInfo.RegionName, remoteClient.Name);
1277 1402
1278 //if (IsChildAgent) 1403 //if (IsChildAgent)
1279 //{ 1404 //{
@@ -1348,6 +1473,10 @@ namespace OpenSim.Region.Framework.Scenes
1348 1473
1349 #endregion Inputs 1474 #endregion Inputs
1350 1475
1476 // Make anims work for client side autopilot
1477 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
1478 m_updateCount = UPDATE_COUNT;
1479
1351 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) 1480 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
1352 { 1481 {
1353 StandUp(); 1482 StandUp();
@@ -1378,6 +1507,9 @@ namespace OpenSim.Region.Framework.Scenes
1378 1507
1379 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1508 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1380 { 1509 {
1510 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1511 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1512
1381 // TODO: This doesn't prevent the user from walking yet. 1513 // TODO: This doesn't prevent the user from walking yet.
1382 // Setting parent ID would fix this, if we knew what value 1514 // Setting parent ID would fix this, if we knew what value
1383 // to use. Or we could add a m_isSitting variable. 1515 // to use. Or we could add a m_isSitting variable.
@@ -1467,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes
1467 1599
1468 if ((MovementFlag & (byte)(uint)DCF) == 0) 1600 if ((MovementFlag & (byte)(uint)DCF) == 0)
1469 { 1601 {
1470 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1602 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1471 { 1603 {
1472 MovementFlag |= (byte)nudgehack; 1604 MovementFlag |= (byte)nudgehack;
1473 } 1605 }
@@ -1479,13 +1611,13 @@ namespace OpenSim.Region.Framework.Scenes
1479 } 1611 }
1480 else 1612 else
1481 { 1613 {
1482 if ((MovementFlag & (byte)(uint)DCF) != 0 || 1614 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1483 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) 1615 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1484 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1616 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1485 ) // This or is for Nudge forward 1617 ) // This or is for Nudge forward
1486 { 1618 {
1487// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1619 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1488 MovementFlag -= ((byte)(uint)DCF); 1620 m_movementflag -= ((byte)(uint)DCF);
1489 update_movementflag = true; 1621 update_movementflag = true;
1490 1622
1491 /* 1623 /*
@@ -1546,21 +1678,21 @@ namespace OpenSim.Region.Framework.Scenes
1546 // which occurs later in the main scene loop 1678 // which occurs later in the main scene loop
1547 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1679 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1548 { 1680 {
1549// m_log.DebugFormat( 1681 // m_log.DebugFormat(
1550// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1682 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1551// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1683 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1552 1684
1553 AddNewMovement(agent_control_v3); 1685 AddNewMovement(agent_control_v3);
1554 } 1686 }
1555// else 1687 // else
1556// { 1688 // {
1557// if (!update_movementflag) 1689 // if (!update_movementflag)
1558// { 1690 // {
1559// m_log.DebugFormat( 1691 // m_log.DebugFormat(
1560// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1692 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1561// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1693 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1562// } 1694 // }
1563// } 1695 // }
1564 1696
1565 if (update_movementflag && ParentID == 0) 1697 if (update_movementflag && ParentID == 0)
1566 Animator.UpdateMovementAnimations(); 1698 Animator.UpdateMovementAnimations();
@@ -1579,20 +1711,20 @@ namespace OpenSim.Region.Framework.Scenes
1579 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1711 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1580 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1712 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1581 { 1713 {
1582// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1714 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1583 1715
1584 bool updated = false; 1716 bool updated = false;
1585 1717
1586// m_log.DebugFormat( 1718 // m_log.DebugFormat(
1587// "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", 1719 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1588// allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); 1720 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1589 1721
1590 if (!m_autopilotMoving) 1722 if (!m_autopilotMoving)
1591 { 1723 {
1592 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1724 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1593// m_log.DebugFormat( 1725 // m_log.DebugFormat(
1594// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1726 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1595// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1727 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1596 1728
1597 // Check the error term of the current position in relation to the target position 1729 // Check the error term of the current position in relation to the target position
1598 if (distanceToTarget <= 1) 1730 if (distanceToTarget <= 1)
@@ -1615,7 +1747,7 @@ namespace OpenSim.Region.Framework.Scenes
1615 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1747 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1616 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1748 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1617 // Ignore z component of vector 1749 // Ignore z component of vector
1618// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1750 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1619 LocalVectorToTarget3D.Normalize(); 1751 LocalVectorToTarget3D.Normalize();
1620 1752
1621 // update avatar movement flags. the avatar coordinate system is as follows: 1753 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1681,9 +1813,9 @@ namespace OpenSim.Region.Framework.Scenes
1681 updated = true; 1813 updated = true;
1682 } 1814 }
1683 1815
1684// m_log.DebugFormat( 1816 // m_log.DebugFormat(
1685// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1817 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1686// LocalVectorToTarget3D, agent_control_v3, Name); 1818 // LocalVectorToTarget3D, agent_control_v3, Name);
1687 1819
1688 agent_control_v3 += LocalVectorToTarget3D; 1820 agent_control_v3 += LocalVectorToTarget3D;
1689 } 1821 }
@@ -1712,9 +1844,12 @@ namespace OpenSim.Region.Framework.Scenes
1712 /// </param> 1844 /// </param>
1713 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) 1845 public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget)
1714 { 1846 {
1715 m_log.DebugFormat( 1847 if (SitGround)
1716 "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}", 1848 StandUp();
1717 Name, pos, m_scene.RegionInfo.RegionName); 1849
1850// m_log.DebugFormat(
1851// "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
1852// Name, pos, m_scene.RegionInfo.RegionName);
1718 1853
1719 if (pos.X < 0 || pos.X >= Constants.RegionSize 1854 if (pos.X < 0 || pos.X >= Constants.RegionSize
1720 || pos.Y < 0 || pos.Y >= Constants.RegionSize 1855 || pos.Y < 0 || pos.Y >= Constants.RegionSize
@@ -1740,9 +1875,9 @@ namespace OpenSim.Region.Framework.Scenes
1740 if (pos.Z - terrainHeight < 0.2) 1875 if (pos.Z - terrainHeight < 0.2)
1741 pos.Z = terrainHeight; 1876 pos.Z = terrainHeight;
1742 1877
1743 m_log.DebugFormat( 1878// m_log.DebugFormat(
1744 "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", 1879// "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
1745 Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); 1880// Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
1746 1881
1747 if (noFly) 1882 if (noFly)
1748 PhysicsActor.Flying = false; 1883 PhysicsActor.Flying = false;
@@ -1778,7 +1913,7 @@ namespace OpenSim.Region.Framework.Scenes
1778 /// </summary> 1913 /// </summary>
1779 public void ResetMoveToTarget() 1914 public void ResetMoveToTarget()
1780 { 1915 {
1781 m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); 1916// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
1782 1917
1783 MovingToTarget = false; 1918 MovingToTarget = false;
1784 MoveToPositionTarget = Vector3.Zero; 1919 MoveToPositionTarget = Vector3.Zero;
@@ -1804,7 +1939,7 @@ namespace OpenSim.Region.Framework.Scenes
1804 Velocity = Vector3.Zero; 1939 Velocity = Vector3.Zero;
1805 SendAvatarDataToAllAgents(); 1940 SendAvatarDataToAllAgents();
1806 1941
1807 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1942 HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ??
1808 } 1943 }
1809 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); 1944 //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false);
1810 m_requestedSitTargetUUID = UUID.Zero; 1945 m_requestedSitTargetUUID = UUID.Zero;
@@ -1841,24 +1976,22 @@ namespace OpenSim.Region.Framework.Scenes
1841 1976
1842 if (ParentID != 0) 1977 if (ParentID != 0)
1843 { 1978 {
1844 m_log.Debug("StandupCode Executed"); 1979 SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
1845 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID);
1846 if (part != null) 1980 if (part != null)
1847 { 1981 {
1982 part.TaskInventory.LockItemsForRead(true);
1848 TaskInventoryDictionary taskIDict = part.TaskInventory; 1983 TaskInventoryDictionary taskIDict = part.TaskInventory;
1849 if (taskIDict != null) 1984 if (taskIDict != null)
1850 { 1985 {
1851 lock (taskIDict) 1986 foreach (UUID taskID in taskIDict.Keys)
1852 { 1987 {
1853 foreach (UUID taskID in taskIDict.Keys) 1988 UnRegisterControlEventsToScript(LocalId, taskID);
1854 { 1989 taskIDict[taskID].PermsMask &= ~(
1855 UnRegisterControlEventsToScript(LocalId, taskID); 1990 2048 | //PERMISSION_CONTROL_CAMERA
1856 taskIDict[taskID].PermsMask &= ~( 1991 4); // PERMISSION_TAKE_CONTROLS
1857 2048 | //PERMISSION_CONTROL_CAMERA
1858 4); // PERMISSION_TAKE_CONTROLS
1859 }
1860 } 1992 }
1861 } 1993 }
1994 part.TaskInventory.LockItemsForRead(false);
1862 1995
1863 // Reset sit target. 1996 // Reset sit target.
1864 if (part.SitTargetAvatar == UUID) 1997 if (part.SitTargetAvatar == UUID)
@@ -1869,21 +2002,59 @@ namespace OpenSim.Region.Framework.Scenes
1869 ParentPosition = part.GetWorldPosition(); 2002 ParentPosition = part.GetWorldPosition();
1870 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 2003 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1871 } 2004 }
1872 2005 // part.GetWorldRotation() is the rotation of the object being sat on
1873 if (PhysicsActor == null) 2006 // Rotation is the sittiing Av's rotation
2007
2008 Quaternion partRot;
2009// if (part.LinkNum == 1)
2010// { // Root prim of linkset
2011// partRot = part.ParentGroup.RootPart.RotationOffset;
2012// }
2013// else
2014// { // single or child prim
2015
2016// }
2017 if (part == null) //CW: Part may be gone. llDie() for example.
1874 { 2018 {
1875 AddToPhysicalScene(false); 2019 partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
2020 }
2021 else
2022 {
2023 partRot = part.GetWorldRotation();
1876 } 2024 }
1877 2025
1878 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); 2026 Quaternion partIRot = Quaternion.Inverse(partRot);
1879 ParentPosition = Vector3.Zero;
1880 2027
1881 ParentID = 0; 2028 Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av
2029 Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av
2030
2031
2032 if (m_physicsActor == null)
2033 {
2034 AddToPhysicalScene(false);
2035 }
2036 //CW: If the part isn't null then we can set the current position
2037 if (part != null)
2038 {
2039 Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset!
2040 AbsolutePosition = avWorldStandUp; //KF: Fix stand up.
2041 part.IsOccupied = false;
2042 part.ParentGroup.DeleteAvatar(ControllingClient.AgentId);
2043 }
2044 else
2045 {
2046 //CW: Since the part doesn't exist, a coarse standup position isn't an issue
2047 AbsolutePosition = m_lastWorldPosition;
2048 }
2049
2050 m_parentPosition = Vector3.Zero;
2051 m_parentID = 0;
2052 m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f);
1882 SendAvatarDataToAllAgents(); 2053 SendAvatarDataToAllAgents();
1883 m_requestedSitTargetID = 0; 2054 m_requestedSitTargetID = 0;
1884 } 2055 }
1885 2056
1886 Animator.TrySetMovementAnimation("STAND"); 2057 Animator.UpdateMovementAnimations();
1887 } 2058 }
1888 2059
1889 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) 2060 private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
@@ -1915,9 +2086,7 @@ namespace OpenSim.Region.Framework.Scenes
1915 UUID avOnTargetAlready = part.SitTargetAvatar; 2086 UUID avOnTargetAlready = part.SitTargetAvatar;
1916 2087
1917 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); 2088 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1918 bool SitTargetisSet = 2089 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
1919 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f &&
1920 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f));
1921 2090
1922 if (SitTargetisSet && SitTargetUnOccupied) 2091 if (SitTargetisSet && SitTargetUnOccupied)
1923 { 2092 {
@@ -1933,87 +2102,168 @@ namespace OpenSim.Region.Framework.Scenes
1933 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2102 private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation)
1934 { 2103 {
1935 bool autopilot = true; 2104 bool autopilot = true;
2105 Vector3 autopilotTarget = new Vector3();
2106 Quaternion sitOrientation = Quaternion.Identity;
1936 Vector3 pos = new Vector3(); 2107 Vector3 pos = new Vector3();
1937 Quaternion sitOrientation = pSitOrientation;
1938 Vector3 cameraEyeOffset = Vector3.Zero; 2108 Vector3 cameraEyeOffset = Vector3.Zero;
1939 Vector3 cameraAtOffset = Vector3.Zero; 2109 Vector3 cameraAtOffset = Vector3.Zero;
1940 bool forceMouselook = false; 2110 bool forceMouselook = false;
1941 2111
1942 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 2112 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1943 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 2113 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1944 if (part != null) 2114 if (part == null) return;
2115
2116 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2117 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2118
2119 // part is the prim to sit on
2120 // offset is the world-ref vector distance from that prim center to the click-spot
2121 // UUID is the UUID of the Avatar doing the clicking
2122
2123 m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation
2124
2125 // Is a sit target available?
2126 Vector3 avSitOffSet = part.SitTargetPosition;
2127 Quaternion avSitOrientation = part.SitTargetOrientation;
2128
2129 bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored.
2130 // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation());
2131 Quaternion partRot;
2132// if (part.LinkNum == 1)
2133// { // Root prim of linkset
2134// partRot = part.ParentGroup.RootPart.RotationOffset;
2135// }
2136// else
2137// { // single or child prim
2138 partRot = part.GetWorldRotation();
2139// }
2140 Quaternion partIRot = Quaternion.Inverse(partRot);
2141//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet);
2142 // Sit analysis rewritten by KF 091125
2143 if (SitTargetisSet) // scipted sit
1945 { 2144 {
1946 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2145 if (!part.IsOccupied)
1947 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2146 {
1948 2147//Console.WriteLine("Scripted, unoccupied");
1949 // Is a sit target available? 2148 part.SitTargetAvatar = UUID; // set that Av will be on it
1950 Vector3 avSitOffSet = part.SitTargetPosition; 2149 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one
1951 Quaternion avSitOrientation = part.SitTargetOrientation; 2150
1952 UUID avOnTargetAlready = part.SitTargetAvatar; 2151 Quaternion nrot = avSitOrientation;
1953 2152 if (!part.IsRoot)
1954 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
1955 bool SitTargetisSet =
1956 (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f &&
1957 (
1958 avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion
1959 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
1960 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
1961 )
1962 ));
1963
1964// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
1965
1966 if (SitTargetisSet && SitTargetUnOccupied)
1967 {
1968 part.SitTargetAvatar = UUID;
1969 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
1970 sitOrientation = avSitOrientation;
1971 autopilot = false;
1972 }
1973 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1974
1975 pos = part.AbsolutePosition + offset;
1976 //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1)
1977 //{
1978 // offset = pos;
1979 //autopilot = false;
1980 //}
1981 if (PhysicsActor != null)
1982 {
1983 // If we're not using the client autopilot, we're immediately warping the avatar to the location
1984 // We can remove the physicsActor until they stand up.
1985 m_sitAvatarHeight = PhysicsActor.Size.Z;
1986
1987 if (autopilot)
1988 { 2153 {
1989 if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) 2154 nrot = part.RotationOffset * avSitOrientation;
1990 {
1991 autopilot = false;
1992
1993 RemoveFromPhysicalScene();
1994 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
1995 }
1996 } 2155 }
1997 else 2156 sitOrientation = nrot; // Change rotatione to the scripted one
2157 OffsetRotation = nrot;
2158 autopilot = false; // Jump direct to scripted llSitPos()
2159 }
2160 else
2161 {
2162//Console.WriteLine("Scripted, occupied");
2163 return;
2164 }
2165 }
2166 else // Not Scripted
2167 {
2168 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
2169 {
2170 // large prim & offset, ignore if other Avs sitting
2171// offset.Z -= 0.05f;
2172 m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked
2173 autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point
2174
2175//Console.WriteLine(" offset ={0}", offset);
2176//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos);
2177//Console.WriteLine(" autopilotTarget={0}", autopilotTarget);
2178
2179 }
2180 else // small offset
2181 {
2182//Console.WriteLine("Small offset");
2183 if (!part.IsOccupied)
2184 {
2185 m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center
2186 autopilotTarget = part.AbsolutePosition;
2187//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget);
2188 }
2189 else return; // occupied small
2190 } // end large/small
2191 } // end Scripted/not
2192
2193 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2194
2195 cameraAtOffset = part.GetCameraAtOffset();
2196 cameraEyeOffset = part.GetCameraEyeOffset();
2197 forceMouselook = part.GetForceMouselook();
2198 if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); //
2199 if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); //
2200
2201 if (m_physicsActor != null)
2202 {
2203 // If we're not using the client autopilot, we're immediately warping the avatar to the location
2204 // We can remove the physicsActor until they stand up.
2205 m_sitAvatarHeight = m_physicsActor.Size.Z;
2206 if (autopilot)
2207 { // its not a scripted sit
2208// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5)
2209 if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) )
1998 { 2210 {
2211 autopilot = false; // close enough
2212 m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2213 Not using the part's position because returning the AV to the last known standing
2214 position is likely to be more friendly, isn't it? */
1999 RemoveFromPhysicalScene(); 2215 RemoveFromPhysicalScene();
2000 } 2216 Velocity = Vector3.Zero;
2217 AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target
2218 } // else the autopilot will get us close
2219 }
2220 else
2221 { // its a scripted sit
2222 m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup.
2223 I *am* using the part's position this time because we have no real idea how far away
2224 the avatar is from the sit target. */
2225 RemoveFromPhysicalScene();
2226 Velocity = Vector3.Zero;
2001 } 2227 }
2002
2003 cameraAtOffset = part.GetCameraAtOffset();
2004 cameraEyeOffset = part.GetCameraEyeOffset();
2005 forceMouselook = part.GetForceMouselook();
2006 } 2228 }
2007 2229 else return; // physactor is null!
2008 ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); 2230
2009 m_requestedSitTargetUUID = targetID; 2231 Vector3 offsetr; // = offset * partIRot;
2232 // KF: In a linkset, offsetr needs to be relative to the group root! 091208
2233 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot);
2234 // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error.
2235 // { // Single, or Root prim of linkset, target is ClickOffset * RootRot
2236 //offsetr = offset * partIRot;
2237//
2238 // }
2239 // else
2240 // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot)
2241 // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) +
2242 // (offset * partRot);
2243 // }
2244
2245//Console.WriteLine(" ");
2246//Console.WriteLine("link number ={0}", part.LinkNum);
2247//Console.WriteLine("Prim offset ={0}", part.OffsetPosition );
2248//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset);
2249//Console.WriteLine("Click offst ={0}", offset);
2250//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation());
2251//Console.WriteLine("offsetr ={0}", offsetr);
2252//Console.WriteLine("Camera At ={0}", cameraAtOffset);
2253//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2254
2255 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2256 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2257
2258 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2010 // This calls HandleAgentSit twice, once from here, and the client calls 2259 // This calls HandleAgentSit twice, once from here, and the client calls
2011 // HandleAgentSit itself after it gets to the location 2260 // HandleAgentSit itself after it gets to the location
2012 // It doesn't get to the location until we've moved them there though 2261 // It doesn't get to the location until we've moved them there though
2013 // which happens in HandleAgentSit :P 2262 // which happens in HandleAgentSit :P
2014 m_autopilotMoving = autopilot; 2263 m_autopilotMoving = autopilot;
2015 m_autoPilotTarget = pos; 2264 m_autoPilotTarget = autopilotTarget;
2016 m_sitAtAutoTarget = autopilot; 2265 m_sitAtAutoTarget = autopilot;
2266 m_initialSitTarget = autopilotTarget;
2017 if (!autopilot) 2267 if (!autopilot)
2018 HandleAgentSit(remoteClient, UUID); 2268 HandleAgentSit(remoteClient, UUID);
2019 } 2269 }
@@ -2279,45 +2529,127 @@ namespace OpenSim.Region.Framework.Scenes
2279 { 2529 {
2280 if (part.SitTargetAvatar == UUID) 2530 if (part.SitTargetAvatar == UUID)
2281 { 2531 {
2532//Console.WriteLine("Scripted Sit");
2533 // Scripted sit
2282 Vector3 sitTargetPos = part.SitTargetPosition; 2534 Vector3 sitTargetPos = part.SitTargetPosition;
2283 Quaternion sitTargetOrient = part.SitTargetOrientation; 2535 Quaternion sitTargetOrient = part.SitTargetOrientation;
2284
2285 //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0);
2286 //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w);
2287
2288 //Quaternion result = (sitTargetOrient * vq) * nq;
2289
2290 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); 2536 m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z);
2291 m_pos += SIT_TARGET_ADJUSTMENT; 2537 m_pos += SIT_TARGET_ADJUSTMENT;
2292 Rotation = sitTargetOrient; 2538 if (!part.IsRoot)
2293 //Rotation = sitTargetOrient; 2539 {
2294 ParentPosition = part.AbsolutePosition; 2540 m_pos *= part.RotationOffset;
2295 2541 }
2296 //SendTerseUpdateToAllClients(); 2542 m_bodyRot = sitTargetOrient;
2543 m_parentPosition = part.AbsolutePosition;
2544 part.IsOccupied = true;
2545 part.ParentGroup.AddAvatar(agentID);
2297 } 2546 }
2298 else 2547 else
2299 { 2548 {
2300 m_pos -= part.AbsolutePosition; 2549 // if m_avUnscriptedSitPos is zero then Av sits above center
2301 ParentPosition = part.AbsolutePosition; 2550 // Else Av sits at m_avUnscriptedSitPos
2302 } 2551
2552 // Non-scripted sit by Kitto Flora 21Nov09
2553 // Calculate angle of line from prim to Av
2554 Quaternion partIRot;
2555// if (part.LinkNum == 1)
2556// { // Root prim of linkset
2557// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2558// }
2559// else
2560// { // single or child prim
2561 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2562// }
2563 Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos;
2564 float y_diff = (m_avInitialPos.Y - sitTargetPos.Y);
2565 float x_diff = ( m_avInitialPos.X - sitTargetPos.X);
2566 if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0
2567 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0
2568 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff);
2569 // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'.
2570 // Av sits at world euler <0,0, z>, translated by part rotation
2571 m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click
2572
2573 m_parentPosition = part.AbsolutePosition;
2574 part.IsOccupied = true;
2575 part.ParentGroup.AddAvatar(agentID);
2576 m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation
2577 (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center
2578 (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) +
2579 m_avUnscriptedSitPos; // adds click offset, if any
2580 //Set up raytrace to find top surface of prim
2581 Vector3 size = part.Scale;
2582 float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z));
2583 Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag);
2584 Vector3 down = new Vector3(0f, 0f, -1f);
2585//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag);
2586 m_scene.PhysicsScene.RaycastWorld(
2587 start, // Vector3 position,
2588 down, // Vector3 direction,
2589 mag, // float length,
2590 SitAltitudeCallback); // retMethod
2591 } // end scripted/not
2303 } 2592 }
2304 else 2593 else // no Av
2305 { 2594 {
2306 return; 2595 return;
2307 } 2596 }
2308 } 2597 }
2309 ParentID = m_requestedSitTargetID; 2598 ParentID = m_requestedSitTargetID;
2310 2599
2600 //We want our offsets to reference the root prim, not the child we may have sat on
2601 if (!part.IsRoot)
2602 {
2603 m_parentID = part.ParentGroup.RootPart.LocalId;
2604 m_pos += part.OffsetPosition;
2605 }
2606 else
2607 {
2608 m_parentID = m_requestedSitTargetID;
2609 }
2610
2611 if (part.SitTargetAvatar != UUID)
2612 {
2613 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2614 }
2311 Velocity = Vector3.Zero; 2615 Velocity = Vector3.Zero;
2312 RemoveFromPhysicalScene(); 2616 RemoveFromPhysicalScene();
2313
2314 Animator.TrySetMovementAnimation(sitAnimation); 2617 Animator.TrySetMovementAnimation(sitAnimation);
2315 SendAvatarDataToAllAgents(); 2618 SendAvatarDataToAllAgents();
2316 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2317 // So we're also sending a terse update (which has avatar rotation)
2318 // [Update] We do now.
2319 //SendTerseUpdateToAllClients(); 2619 //SendTerseUpdateToAllClients();
2320 } 2620 }
2621
2622 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
2623 {
2624 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
2625 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
2626 if(hitYN)
2627 {
2628 // m_pos = Av offset from prim center to make look like on center
2629 // m_parentPosition = Actual center pos of prim
2630 // collisionPoint = spot on prim where we want to sit
2631 // collisionPoint.Z = global sit surface height
2632 SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
2633 Quaternion partIRot;
2634// if (part.LinkNum == 1)
2635/// { // Root prim of linkset
2636// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset);
2637// }
2638// else
2639// { // single or child prim
2640 partIRot = Quaternion.Inverse(part.GetWorldRotation());
2641// }
2642 if (m_initialSitTarget != null)
2643 {
2644 float offZ = collisionPoint.Z - m_initialSitTarget.Z;
2645 Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction
2646 //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset);
2647 m_pos += offset;
2648 // ControllingClient.SendClearFollowCamProperties(part.UUID);
2649 }
2650
2651 }
2652 } // End SitAltitudeCallback KF.
2321 2653
2322 /// <summary> 2654 /// <summary>
2323 /// Event handler for the 'Always run' setting on the client 2655 /// Event handler for the 'Always run' setting on the client
@@ -2347,6 +2679,19 @@ namespace OpenSim.Region.Framework.Scenes
2347 Vector3 direc = vec * Rotation; 2679 Vector3 direc = vec * Rotation;
2348 direc.Normalize(); 2680 direc.Normalize();
2349 2681
2682 if (PhysicsActor.Flying != m_flyingOld) // add for fly velocity control
2683 {
2684 m_flyingOld = PhysicsActor.Flying; // add for fly velocity control
2685 if (!PhysicsActor.Flying)
2686 m_wasFlying = true; // add for fly velocity control
2687 }
2688
2689 if (PhysicsActor.IsColliding == true)
2690 m_wasFlying = false; // add for fly velocity control
2691
2692 if ((vec.Z == 0f) && !PhysicsActor.Flying)
2693 direc.Z = 0f; // Prevent camera WASD up.
2694
2350 direc *= 0.03f * 128f * SpeedModifier; 2695 direc *= 0.03f * 128f * SpeedModifier;
2351 2696
2352 if (PhysicsActor != null) 2697 if (PhysicsActor != null)
@@ -2365,6 +2710,10 @@ namespace OpenSim.Region.Framework.Scenes
2365 // m_log.Info("[AGENT]: Stop Flying"); 2710 // m_log.Info("[AGENT]: Stop Flying");
2366 //} 2711 //}
2367 } 2712 }
2713 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2714 {
2715 direc *= 0.0f;
2716 }
2368 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding) 2717 else if (!PhysicsActor.Flying && PhysicsActor.IsColliding)
2369 { 2718 {
2370 if (direc.Z > 2.0f) 2719 if (direc.Z > 2.0f)
@@ -2425,6 +2774,9 @@ namespace OpenSim.Region.Framework.Scenes
2425 2774
2426 CheckForSignificantMovement(); // sends update to the modules. 2775 CheckForSignificantMovement(); // sends update to the modules.
2427 } 2776 }
2777
2778 //Sending prim updates AFTER the avatar terse updates are sent
2779 SendPrimUpdates();
2428 } 2780 }
2429 2781
2430 #endregion 2782 #endregion
@@ -3145,6 +3497,7 @@ namespace OpenSim.Region.Framework.Scenes
3145 m_callbackURI = cAgent.CallbackURI; 3497 m_callbackURI = cAgent.CallbackURI;
3146 3498
3147 m_pos = cAgent.Position; 3499 m_pos = cAgent.Position;
3500
3148 m_velocity = cAgent.Velocity; 3501 m_velocity = cAgent.Velocity;
3149 CameraPosition = cAgent.Center; 3502 CameraPosition = cAgent.Center;
3150 CameraAtAxis = cAgent.AtAxis; 3503 CameraAtAxis = cAgent.AtAxis;
@@ -3291,14 +3644,28 @@ namespace OpenSim.Region.Framework.Scenes
3291 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) 3644 //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f))
3292 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( 3645 // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents(
3293 // as of this comment the interval is set in AddToPhysicalScene 3646 // as of this comment the interval is set in AddToPhysicalScene
3294 if (Animator != null) 3647 if (Animator!=null)
3295 Animator.UpdateMovementAnimations(); 3648 {
3649 if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper,
3650 { // else its will lock out other animation changes, like ground sit.
3651 Animator.UpdateMovementAnimations();
3652 m_updateCount--;
3653 }
3654 }
3296 3655
3297 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3656 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3298 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3657 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3299 3658
3300 CollisionPlane = Vector4.UnitW; 3659 CollisionPlane = Vector4.UnitW;
3301 3660
3661 // No collisions at all means we may be flying. Update always
3662 // to make falling work
3663 if (m_lastColCount != coldata.Count || coldata.Count == 0)
3664 {
3665 m_updateCount = UPDATE_COUNT;
3666 m_lastColCount = coldata.Count;
3667 }
3668
3302 if (coldata.Count != 0 && Animator != null) 3669 if (coldata.Count != 0 && Animator != null)
3303 { 3670 {
3304 switch (Animator.CurrentMovementAnimation) 3671 switch (Animator.CurrentMovementAnimation)
@@ -3328,6 +3695,148 @@ namespace OpenSim.Region.Framework.Scenes
3328 } 3695 }
3329 } 3696 }
3330 3697
3698 List<uint> thisHitColliders = new List<uint>();
3699 List<uint> endedColliders = new List<uint>();
3700 List<uint> startedColliders = new List<uint>();
3701
3702 foreach (uint localid in coldata.Keys)
3703 {
3704 thisHitColliders.Add(localid);
3705 if (!m_lastColliders.Contains(localid))
3706 {
3707 startedColliders.Add(localid);
3708 }
3709 //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
3710 }
3711
3712 // calculate things that ended colliding
3713 foreach (uint localID in m_lastColliders)
3714 {
3715 if (!thisHitColliders.Contains(localID))
3716 {
3717 endedColliders.Add(localID);
3718 }
3719 }
3720 //add the items that started colliding this time to the last colliders list.
3721 foreach (uint localID in startedColliders)
3722 {
3723 m_lastColliders.Add(localID);
3724 }
3725 // remove things that ended colliding from the last colliders list
3726 foreach (uint localID in endedColliders)
3727 {
3728 m_lastColliders.Remove(localID);
3729 }
3730
3731 // do event notification
3732 if (startedColliders.Count > 0)
3733 {
3734 ColliderArgs StartCollidingMessage = new ColliderArgs();
3735 List<DetectedObject> colliding = new List<DetectedObject>();
3736 foreach (uint localId in startedColliders)
3737 {
3738 if (localId == 0)
3739 continue;
3740
3741 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3742 string data = "";
3743 if (obj != null)
3744 {
3745 DetectedObject detobj = new DetectedObject();
3746 detobj.keyUUID = obj.UUID;
3747 detobj.nameStr = obj.Name;
3748 detobj.ownerUUID = obj.OwnerID;
3749 detobj.posVector = obj.AbsolutePosition;
3750 detobj.rotQuat = obj.GetWorldRotation();
3751 detobj.velVector = obj.Velocity;
3752 detobj.colliderType = 0;
3753 detobj.groupUUID = obj.GroupID;
3754 colliding.Add(detobj);
3755 }
3756 }
3757
3758 if (colliding.Count > 0)
3759 {
3760 StartCollidingMessage.Colliders = colliding;
3761
3762 foreach (SceneObjectGroup att in GetAttachments())
3763 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3764 }
3765 }
3766
3767 if (endedColliders.Count > 0)
3768 {
3769 ColliderArgs EndCollidingMessage = new ColliderArgs();
3770 List<DetectedObject> colliding = new List<DetectedObject>();
3771 foreach (uint localId in endedColliders)
3772 {
3773 if (localId == 0)
3774 continue;
3775
3776 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3777 string data = "";
3778 if (obj != null)
3779 {
3780 DetectedObject detobj = new DetectedObject();
3781 detobj.keyUUID = obj.UUID;
3782 detobj.nameStr = obj.Name;
3783 detobj.ownerUUID = obj.OwnerID;
3784 detobj.posVector = obj.AbsolutePosition;
3785 detobj.rotQuat = obj.GetWorldRotation();
3786 detobj.velVector = obj.Velocity;
3787 detobj.colliderType = 0;
3788 detobj.groupUUID = obj.GroupID;
3789 colliding.Add(detobj);
3790 }
3791 }
3792
3793 if (colliding.Count > 0)
3794 {
3795 EndCollidingMessage.Colliders = colliding;
3796
3797 foreach (SceneObjectGroup att in GetAttachments())
3798 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
3799 }
3800 }
3801
3802 if (thisHitColliders.Count > 0)
3803 {
3804 ColliderArgs CollidingMessage = new ColliderArgs();
3805 List<DetectedObject> colliding = new List<DetectedObject>();
3806 foreach (uint localId in thisHitColliders)
3807 {
3808 if (localId == 0)
3809 continue;
3810
3811 SceneObjectPart obj = Scene.GetSceneObjectPart(localId);
3812 string data = "";
3813 if (obj != null)
3814 {
3815 DetectedObject detobj = new DetectedObject();
3816 detobj.keyUUID = obj.UUID;
3817 detobj.nameStr = obj.Name;
3818 detobj.ownerUUID = obj.OwnerID;
3819 detobj.posVector = obj.AbsolutePosition;
3820 detobj.rotQuat = obj.GetWorldRotation();
3821 detobj.velVector = obj.Velocity;
3822 detobj.colliderType = 0;
3823 detobj.groupUUID = obj.GroupID;
3824 colliding.Add(detobj);
3825 }
3826 }
3827
3828 if (colliding.Count > 0)
3829 {
3830 CollidingMessage.Colliders = colliding;
3831
3832 lock (m_attachments)
3833 {
3834 foreach (SceneObjectGroup att in m_attachments)
3835 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3836 }
3837 }
3838 }
3839
3331 if (Invulnerable) 3840 if (Invulnerable)
3332 return; 3841 return;
3333 3842
@@ -3399,6 +3908,10 @@ namespace OpenSim.Region.Framework.Scenes
3399 { 3908 {
3400 lock (m_attachments) 3909 lock (m_attachments)
3401 { 3910 {
3911 // This may be true when the attachment comes back
3912 // from serialization after login. Clear it.
3913 gobj.IsDeleted = false;
3914
3402 m_attachments.Add(gobj); 3915 m_attachments.Add(gobj);
3403 } 3916 }
3404 } 3917 }
@@ -3762,5 +4275,39 @@ namespace OpenSim.Region.Framework.Scenes
3762 m_reprioritization_called = false; 4275 m_reprioritization_called = false;
3763 } 4276 }
3764 } 4277 }
4278
4279 private Vector3 Quat2Euler(Quaternion rot){
4280 float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) ,
4281 (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z)));
4282 float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W)));
4283 float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) ,
4284 (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z)));
4285 return(new Vector3(x,y,z));
4286 }
4287
4288 private void CheckLandingPoint(ref Vector3 pos)
4289 {
4290 // Never constrain lures
4291 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
4292 return;
4293
4294 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
4295 return;
4296
4297 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
4298
4299 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
4300 land.LandData.UserLocation != Vector3.Zero &&
4301 land.LandData.OwnerID != m_uuid &&
4302 (!m_scene.Permissions.IsGod(m_uuid)) &&
4303 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
4304 {
4305 float curr = Vector3.Distance(AbsolutePosition, pos);
4306 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
4307 pos = land.LandData.UserLocation;
4308 else
4309 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
4310 }
4311 }
3765 } 4312 }
3766} 4313}
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index d6bb81c..2c3084c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -123,7 +123,7 @@ namespace OpenSim.Region.Framework.Scenes
123 g.ScheduleFullUpdateToAvatar(m_presence); 123 g.ScheduleFullUpdateToAvatar(m_presence);
124 } 124 }
125 125
126 while (m_partsUpdateQueue.Count > 0) 126 while (m_partsUpdateQueue != null && m_partsUpdateQueue.Count != null && m_partsUpdateQueue.Count > 0)
127 { 127 {
128 SceneObjectPart part = m_partsUpdateQueue.Dequeue(); 128 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
129 129
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 60cc788..680a6fa 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -345,6 +345,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
345 m_SOPXmlProcessors.Add("PayPrice2", ProcessPayPrice2); 345 m_SOPXmlProcessors.Add("PayPrice2", ProcessPayPrice2);
346 m_SOPXmlProcessors.Add("PayPrice3", ProcessPayPrice3); 346 m_SOPXmlProcessors.Add("PayPrice3", ProcessPayPrice3);
347 m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4); 347 m_SOPXmlProcessors.Add("PayPrice4", ProcessPayPrice4);
348
349 m_SOPXmlProcessors.Add("Buoyancy", ProcessBuoyancy);
348 #endregion 350 #endregion
349 351
350 #region TaskInventoryXmlProcessors initialization 352 #region TaskInventoryXmlProcessors initialization
@@ -729,6 +731,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
729 obj.PayPrice[4] = (int)reader.ReadElementContentAsInt("PayPrice4", String.Empty); 731 obj.PayPrice[4] = (int)reader.ReadElementContentAsInt("PayPrice4", String.Empty);
730 } 732 }
731 733
734 private static void ProcessBuoyancy(SceneObjectPart obj, XmlTextReader reader)
735 {
736 obj.Buoyancy = (int)reader.ReadElementContentAsFloat("Buoyancy", String.Empty);
737 }
738
732 #endregion 739 #endregion
733 740
734 #region TaskInventoryXmlProcessors 741 #region TaskInventoryXmlProcessors
@@ -1212,6 +1219,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1212 writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString()); 1219 writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString());
1213 writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString()); 1220 writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString());
1214 1221
1222 writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString());
1223
1215 writer.WriteEndElement(); 1224 writer.WriteEndElement();
1216 } 1225 }
1217 1226
@@ -1496,12 +1505,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1496 { 1505 {
1497 TaskInventoryDictionary tinv = new TaskInventoryDictionary(); 1506 TaskInventoryDictionary tinv = new TaskInventoryDictionary();
1498 1507
1499 if (reader.IsEmptyElement)
1500 {
1501 reader.Read();
1502 return tinv;
1503 }
1504
1505 reader.ReadStartElement(name, String.Empty); 1508 reader.ReadStartElement(name, String.Empty);
1506 1509
1507 while (reader.Name == "TaskInventoryItem") 1510 while (reader.Name == "TaskInventoryItem")
@@ -1544,12 +1547,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1544 1547
1545 PrimitiveBaseShape shape = new PrimitiveBaseShape(); 1548 PrimitiveBaseShape shape = new PrimitiveBaseShape();
1546 1549
1547 if (reader.IsEmptyElement)
1548 {
1549 reader.Read();
1550 return shape;
1551 }
1552
1553 reader.ReadStartElement(name, String.Empty); // Shape 1550 reader.ReadStartElement(name, String.Empty); // Shape
1554 1551
1555 string nodeName = string.Empty; 1552 string nodeName = string.Empty;
@@ -1589,4 +1586,4 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1589 1586
1590 #endregion 1587 #endregion
1591 } 1588 }
1592} 1589} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 860172c..5ed3c79 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);
@@ -161,24 +176,24 @@ namespace OpenSim.Region.Framework.Scenes
161 // Note: Updating these properties on sop automatically schedules an update if needed 176 // Note: Updating these properties on sop automatically schedules an update if needed
162 if (Position != Vector3.Zero) 177 if (Position != Vector3.Zero)
163 { 178 {
164// m_log.DebugFormat( 179 // m_log.DebugFormat(
165// "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}", 180 // "[UNDO STATE]: Undoing position {0} to {1} for child part {2} {3}",
166// part.OffsetPosition, Position, part.Name, part.LocalId); 181 // part.OffsetPosition, Position, part.Name, part.LocalId);
167 182
168 part.OffsetPosition = Position; 183 part.OffsetPosition = Position;
169 } 184 }
170 185
171// m_log.DebugFormat( 186 // m_log.DebugFormat(
172// "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}", 187 // "[UNDO STATE]: Undoing rotation {0} to {1} for child part {2} {3}",
173// part.RotationOffset, Rotation, part.Name, part.LocalId); 188 // part.RotationOffset, Rotation, part.Name, part.LocalId);
174 189
175 part.UpdateRotation(Rotation); 190 part.UpdateRotation(Rotation);
176 191
177 if (Scale != Vector3.Zero) 192 if (Scale != Vector3.Zero)
178 { 193 {
179// m_log.DebugFormat( 194 // m_log.DebugFormat(
180// "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}", 195 // "[UNDO STATE]: Undoing scale {0} to {1} for child part {2} {3}",
181// part.Shape.Scale, Scale, part.Name, part.LocalId); 196 // part.Shape.Scale, Scale, part.Name, part.LocalId);
182 197
183 part.Resize(Scale); 198 part.Resize(Scale);
184 } 199 }
@@ -247,4 +262,4 @@ namespace OpenSim.Region.Framework.Scenes
247 m_terrainModule.UndoTerrain(m_terrainChannel); 262 m_terrainModule.UndoTerrain(m_terrainChannel);
248 } 263 }
249 } 264 }
250} \ No newline at end of file 265}
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;