aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs11
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModule.cs12
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs13
-rw-r--r--OpenSim/Region/Framework/Interfaces/IWorldComm.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs63
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs108
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs27
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs53
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs710
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs55
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs97
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs60
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs6
24 files changed, 818 insertions, 593 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 15060fd..1334905 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -155,6 +155,15 @@ namespace OpenSim.Region.Framework.Interfaces
155 TaskInventoryItem GetInventoryItem(UUID itemId); 155 TaskInventoryItem GetInventoryItem(UUID itemId);
156 156
157 /// <summary> 157 /// <summary>
158 /// Get all inventory items.
159 /// </summary>
160 /// <param name="name"></param>
161 /// <returns>
162 /// If there are no inventory items then an empty list is returned.
163 /// </returns>
164 List<TaskInventoryItem> GetInventoryItems();
165
166 /// <summary>
158 /// Get inventory items by name. 167 /// Get inventory items by name.
159 /// </summary> 168 /// </summary>
160 /// <param name="name"></param> 169 /// <param name="name"></param>
@@ -162,7 +171,7 @@ namespace OpenSim.Region.Framework.Interfaces
162 /// A list of inventory items with that name. 171 /// A list of inventory items with that name.
163 /// If no inventory item has that name then an empty list is returned. 172 /// If no inventory item has that name then an empty list is returned.
164 /// </returns> 173 /// </returns>
165 IList<TaskInventoryItem> GetInventoryItems(string name); 174 List<TaskInventoryItem> GetInventoryItems(string name);
166 175
167 /// <summary> 176 /// <summary>
168 /// Get the scene object referenced by an inventory item. 177 /// Get the scene object referenced by an inventory item.
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index 18c45dd..9cab2e1 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
31 32
32namespace OpenSim.Region.Framework.Interfaces 33namespace OpenSim.Region.Framework.Interfaces
@@ -74,5 +75,14 @@ namespace OpenSim.Region.Framework.Interfaces
74 /// Starts the processing threads. 75 /// Starts the processing threads.
75 /// </summary> 76 /// </summary>
76 void StartProcessing(); 77 void StartProcessing();
78
79 /// <summary>
80 /// Get the execution times of all scripts in each object.
81 /// </summary>
82 /// <returns>
83 /// A dictionary where the key is the root object ID of a linkset
84 /// and the value is a representative execution time in milliseconds of all scripts in that linkset.
85 /// </returns>
86 Dictionary<uint, float> GetObjectScriptsExecutionTimes();
77 } 87 }
78} 88} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
index d7fa316..bfe1e8d 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using OpenMetaverse; 30using OpenMetaverse;
30 31
31namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Region.Framework.Interfaces
@@ -45,6 +46,18 @@ namespace OpenSim.Region.Framework.Interfaces
45 /// </summary> 46 /// </summary>
46 event ScriptCommand OnScriptCommand; 47 event ScriptCommand OnScriptCommand;
47 48
49 void RegisterScriptInvocation(object target, string method);
50 void RegisterScriptInvocation(object target, MethodInfo method);
51 void RegisterScriptInvocation(object target, string[] methods);
52 Delegate[] GetScriptInvocationList();
53
54 Delegate LookupScriptInvocation(string fname);
55 string LookupModInvocation(string fname);
56 Type[] LookupTypeSignature(string fname);
57 Type LookupReturnType(string fname);
58
59 object InvokeOperation(UUID hostId, UUID scriptId, string fname, params object[] parms);
60
48 /// <summary> 61 /// <summary>
49 /// Send a link_message event to an in-world script 62 /// Send a link_message event to an in-world script
50 /// </summary> 63 /// </summary>
diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
index dafbf30..e8e375e 100644
--- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
+++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
@@ -50,6 +50,11 @@ namespace OpenSim.Region.Framework.Interfaces
50 public interface IWorldComm 50 public interface IWorldComm
51 { 51 {
52 /// <summary> 52 /// <summary>
53 /// Total number of listeners
54 /// </summary>
55 int ListenerCount { get; }
56
57 /// <summary>
53 /// Create a listen event callback with the specified filters. 58 /// Create a listen event callback with the specified filters.
54 /// The parameters localID,itemID are needed to uniquely identify 59 /// The parameters localID,itemID are needed to uniquely identify
55 /// the script during 'peek' time. Parameter hostID is needed to 60 /// the script during 'peek' time. Parameter hostID is needed to
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
index 9176d3d..33041e9 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
@@ -27,8 +27,10 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenSim.Framework; 30using System.Reflection;
31using log4net;
31using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Framework;
32 34
33using Animation = OpenSim.Framework.Animation; 35using Animation = OpenSim.Framework.Animation;
34 36
@@ -37,7 +39,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
37 [Serializable] 39 [Serializable]
38 public class AnimationSet 40 public class AnimationSet
39 { 41 {
40 public static AvatarAnimations Animations = new AvatarAnimations(); 42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 43
42 private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation(); 44 private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation();
43 private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>(); 45 private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
@@ -132,9 +134,13 @@ namespace OpenSim.Region.Framework.Scenes.Animation
132 /// </summary> 134 /// </summary>
133 public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID) 135 public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID)
134 { 136 {
135 if (Animations.AnimsUUID.ContainsKey(anim)) 137// m_log.DebugFormat(
138// "[ANIMATION SET]: Setting default animation {0}, sequence number {1}, object id {2}",
139// anim, sequenceNum, objectID);
140
141 if (DefaultAvatarAnimations.AnimsUUID.ContainsKey(anim))
136 { 142 {
137 return SetDefaultAnimation(Animations.AnimsUUID[anim], sequenceNum, objectID); 143 return SetDefaultAnimation(DefaultAvatarAnimations.AnimsUUID[anim], sequenceNum, objectID);
138 } 144 }
139 return false; 145 return false;
140 } 146 }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs b/OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs
deleted file mode 100644
index 659c3a5..0000000
--- a/OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using System.Xml;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Framework.Scenes.Animation
33{
34 public class AvatarAnimations
35 {
36 public Dictionary<string, UUID> AnimsUUID = new Dictionary<string, UUID>();
37 public Dictionary<UUID, string> AnimsNames = new Dictionary<UUID, string>();
38 public Dictionary<UUID, string> AnimStateNames = new Dictionary<UUID, string>();
39
40 public AvatarAnimations()
41 {
42 using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
43 {
44 XmlDocument doc = new XmlDocument();
45 doc.Load(reader);
46 foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
47 {
48 if (nod.Attributes["name"] != null)
49 {
50 string name = (string)nod.Attributes["name"].Value;
51 UUID id = (UUID)nod.InnerText;
52 string animState = (string)nod.Attributes["state"].Value;
53
54 AnimsUUID.Add(name, id);
55 AnimsNames.Add(id, name);
56 if (animState != "")
57 AnimStateNames.Add(id, animState);
58 }
59 }
60 }
61 }
62 }
63}
diff --git a/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
new file mode 100644
index 0000000..c2b0468
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
@@ -0,0 +1,108 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using System.Reflection;
30using System.Xml;
31using log4net;
32using OpenMetaverse;
33
34namespace OpenSim.Region.Framework.Scenes.Animation
35{
36 public class DefaultAvatarAnimations
37 {
38// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
39
40 public static readonly string DefaultAnimationsPath = "data/avataranimations.xml";
41
42 public static Dictionary<string, UUID> AnimsUUID = new Dictionary<string, UUID>();
43 public static Dictionary<UUID, string> AnimsNames = new Dictionary<UUID, string>();
44 public static Dictionary<UUID, string> AnimStateNames = new Dictionary<UUID, string>();
45
46 static DefaultAvatarAnimations()
47 {
48 LoadAnimations(DefaultAnimationsPath);
49 }
50
51 /// <summary>
52 /// Load the default SL avatar animations.
53 /// </summary>
54 /// <returns></returns>
55 private static void LoadAnimations(string path)
56 {
57// Dictionary<string, UUID> animations = new Dictionary<string, UUID>();
58
59 using (XmlTextReader reader = new XmlTextReader(path))
60 {
61 XmlDocument doc = new XmlDocument();
62 doc.Load(reader);
63// if (doc.DocumentElement != null)
64// {
65 foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
66 {
67 if (nod.Attributes["name"] != null)
68 {
69 string name = nod.Attributes["name"].Value;
70 UUID id = (UUID)nod.InnerText;
71 string animState = (string)nod.Attributes["state"].Value;
72
73 AnimsUUID.Add(name, id);
74 AnimsNames.Add(id, name);
75 if (animState != "")
76 AnimStateNames.Add(id, animState);
77
78// m_log.DebugFormat("[AVATAR ANIMATIONS]: Loaded {0} {1} {2}", id, name, animState);
79 }
80 }
81// }
82 }
83
84// return animations;
85 }
86
87 /// <summary>
88 /// Get the default avatar animation with the given name.
89 /// </summary>
90 /// <param name="name"></param>
91 /// <returns></returns>
92 public static UUID GetDefaultAnimation(string name)
93 {
94// m_log.DebugFormat(
95// "[AVATAR ANIMATIONS]: Looking for default avatar animation with name {0}", name);
96
97 if (AnimsUUID.ContainsKey(name))
98 {
99// m_log.DebugFormat(
100// "[AVATAR ANIMATIONS]: Found {0} {1} in GetDefaultAvatarAnimation()", AnimsUUID[name], name);
101
102 return AnimsUUID[name];
103 }
104
105 return UUID.Zero;
106 }
107 }
108} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 3584cda..f5623bd 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -97,7 +97,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
97 if (m_scenePresence.IsChildAgent) 97 if (m_scenePresence.IsChildAgent)
98 return; 98 return;
99 99
100 UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name); 100 // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
101 // are referenced with lower case names!
102 UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
101 if (animID == UUID.Zero) 103 if (animID == UUID.Zero)
102 return; 104 return;
103 105
@@ -121,7 +123,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
121 if (m_scenePresence.IsChildAgent) 123 if (m_scenePresence.IsChildAgent)
122 return; 124 return;
123 125
124 UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name); 126 // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
127 // are referenced with lower case names!
128 UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
125 if (animID == UUID.Zero) 129 if (animID == UUID.Zero)
126 return; 130 return;
127 131
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 569c235..1e1fcb7 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -138,8 +138,11 @@ namespace OpenSim.Region.Framework.Scenes
138 public event OnPermissionErrorDelegate OnPermissionError; 138 public event OnPermissionErrorDelegate OnPermissionError;
139 139
140 /// <summary> 140 /// <summary>
141 /// Fired when a new script is created. 141 /// Fired when a script is run.
142 /// </summary> 142 /// </summary>
143 /// <remarks>
144 /// Occurs after OnNewScript.
145 /// </remarks>
143 public event NewRezScript OnRezScript; 146 public event NewRezScript OnRezScript;
144 public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource); 147 public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource);
145 148
@@ -187,10 +190,16 @@ namespace OpenSim.Region.Framework.Scenes
187 190
188 public event ClientClosed OnClientClosed; 191 public event ClientClosed OnClientClosed;
189 192
190 // Fired when a script is created
191 // The indication that a new script exists in this region.
192 public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID); 193 public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID);
194
195 /// <summary>
196 /// Fired when a script is created.
197 /// </summary>
198 /// <remarks>
199 /// Occurs before OnRezScript
200 /// </remarks>
193 public event NewScript OnNewScript; 201 public event NewScript OnNewScript;
202
194 public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID) 203 public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
195 { 204 {
196 NewScript handlerNewScript = OnNewScript; 205 NewScript handlerNewScript = OnNewScript;
@@ -212,10 +221,16 @@ namespace OpenSim.Region.Framework.Scenes
212 } 221 }
213 } 222 }
214 223
215 //TriggerUpdateScript: triggered after Scene receives client's upload of updated script and stores it as asset
216 // An indication that the script has changed.
217 public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID); 224 public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID);
225
226 /// <summary>
227 /// An indication that the script has changed.
228 /// </summary>
229 /// <remarks>
230 /// Triggered after the scene receives a client's upload of an updated script and has stored it in an asset.
231 /// </remarks>
218 public event UpdateScript OnUpdateScript; 232 public event UpdateScript OnUpdateScript;
233
219 public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) 234 public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)
220 { 235 {
221 UpdateScript handlerUpdateScript = OnUpdateScript; 236 UpdateScript handlerUpdateScript = OnUpdateScript;
@@ -466,6 +481,13 @@ namespace OpenSim.Region.Framework.Scenes
466 public event RegionHeartbeatEnd OnRegionHeartbeatEnd; 481 public event RegionHeartbeatEnd OnRegionHeartbeatEnd;
467 482
468 public delegate void LoginsEnabled(string regionName); 483 public delegate void LoginsEnabled(string regionName);
484
485 /// <summary>
486 /// This should only fire in all circumstances if the RegionReady module is active.
487 /// </summary>
488 /// <remarks>
489 /// TODO: Fire this even when the RegionReady module is not active.
490 /// </remarks>
469 public event LoginsEnabled OnLoginsEnabled; 491 public event LoginsEnabled OnLoginsEnabled;
470 492
471 public delegate void PrimsLoaded(Scene s); 493 public delegate void PrimsLoaded(Scene s);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 23f39a8..5abd74f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -633,7 +633,7 @@ namespace OpenSim.Region.Framework.Scenes
633 { 633 {
634 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 634 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
635 if (invAccess != null) 635 if (invAccess != null)
636 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); 636 Util.FireAndForget(delegate { invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); });
637 } 637 }
638 638
639 if (!Permissions.BypassPermissions()) 639 if (!Permissions.BypassPermissions())
@@ -1210,9 +1210,9 @@ namespace OpenSim.Region.Framework.Scenes
1210 /// <summary> 1210 /// <summary>
1211 /// Copy a task (prim) inventory item to another task (prim) 1211 /// Copy a task (prim) inventory item to another task (prim)
1212 /// </summary> 1212 /// </summary>
1213 /// <param name="destId"></param> 1213 /// <param name="destId">ID of destination part</param>
1214 /// <param name="part"></param> 1214 /// <param name="part">Source part</param>
1215 /// <param name="itemId"></param> 1215 /// <param name="itemId">Source item id to transfer</param>
1216 public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId) 1216 public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId)
1217 { 1217 {
1218 TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId); 1218 TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId);
@@ -1238,24 +1238,21 @@ namespace OpenSim.Region.Framework.Scenes
1238 return; 1238 return;
1239 } 1239 }
1240 1240
1241 // Can't transfer this 1241 if (part.OwnerID != destPart.OwnerID)
1242 //
1243 if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
1244 return;
1245
1246 if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
1247 { 1242 {
1248 // object cannot copy items to an object owned by a different owner 1243 // Source must have transfer permissions
1249 // unless llAllowInventoryDrop has been called 1244 if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1245 return;
1250 1246
1251 return; 1247 // Object cannot copy items to an object owned by a different owner
1248 // unless llAllowInventoryDrop has been called on the destination
1249 if ((destPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
1250 return;
1252 } 1251 }
1253 1252
1254 // must have both move and modify permission to put an item in an object 1253 // must have both move and modify permission to put an item in an object
1255 if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0) 1254 if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0)
1256 {
1257 return; 1255 return;
1258 }
1259 1256
1260 TaskInventoryItem destTaskItem = new TaskInventoryItem(); 1257 TaskInventoryItem destTaskItem = new TaskInventoryItem();
1261 1258
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 3355ebe..87ffc74 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -339,59 +339,6 @@ namespace OpenSim.Region.Framework.Scenes
339 EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg); 339 EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg);
340 } 340 }
341 341
342 public void ProcessAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
343 {
344 //EventManager.TriggerAvatarPickerRequest();
345
346 List<UserAccount> accounts = UserAccountService.GetUserAccounts(RegionInfo.ScopeID, query);
347
348 if (accounts == null)
349 return;
350
351 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
352 // TODO: don't create new blocks if recycling an old packet
353
354 AvatarPickerReplyPacket.DataBlock[] searchData =
355 new AvatarPickerReplyPacket.DataBlock[accounts.Count];
356 AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
357
358 agentData.AgentID = avatarID;
359 agentData.QueryID = RequestID;
360 replyPacket.AgentData = agentData;
361 //byte[] bytes = new byte[AvatarResponses.Count*32];
362
363 int i = 0;
364 foreach (UserAccount item in accounts)
365 {
366 UUID translatedIDtem = item.PrincipalID;
367 searchData[i] = new AvatarPickerReplyPacket.DataBlock();
368 searchData[i].AvatarID = translatedIDtem;
369 searchData[i].FirstName = Utils.StringToBytes((string) item.FirstName);
370 searchData[i].LastName = Utils.StringToBytes((string) item.LastName);
371 i++;
372 }
373 if (accounts.Count == 0)
374 {
375 searchData = new AvatarPickerReplyPacket.DataBlock[0];
376 }
377 replyPacket.Data = searchData;
378
379 AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
380 agent_data.AgentID = replyPacket.AgentData.AgentID;
381 agent_data.QueryID = replyPacket.AgentData.QueryID;
382
383 List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>();
384 for (i = 0; i < replyPacket.Data.Length; i++)
385 {
386 AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
387 data_arg.AvatarID = replyPacket.Data[i].AvatarID;
388 data_arg.FirstName = replyPacket.Data[i].FirstName;
389 data_arg.LastName = replyPacket.Data[i].LastName;
390 data_args.Add(data_arg);
391 }
392 client.SendAvatarPickerReply(agent_data, data_args);
393 }
394
395 public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID, 342 public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID,
396 UUID itemID) 343 UUID itemID)
397 { 344 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 292c81f..0b31e0c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -65,7 +65,16 @@ namespace OpenSim.Region.Framework.Scenes
65 #region Fields 65 #region Fields
66 66
67 public bool EmergencyMonitoring = false; 67 public bool EmergencyMonitoring = false;
68 public bool DEBUG = false; 68
69 /// <summary>
70 /// Show debug information about teleports.
71 /// </summary>
72 public bool DebugTeleporting { get; private set; }
73
74 /// <summary>
75 /// Show debug information about the scene loop.
76 /// </summary>
77 public bool DebugUpdates { get; private set; }
69 78
70 public SynchronizeSceneHandler SynchronizeScene; 79 public SynchronizeSceneHandler SynchronizeScene;
71 public SimStatsReporter StatsReporter; 80 public SimStatsReporter StatsReporter;
@@ -95,6 +104,11 @@ namespace OpenSim.Region.Framework.Scenes
95 public bool m_allowScriptCrossings; 104 public bool m_allowScriptCrossings;
96 public bool m_useFlySlow; 105 public bool m_useFlySlow;
97 106
107 /// <summary>
108 /// Temporarily setting to trigger appearance resends at 60 second intervals.
109 /// </summary>
110 public bool SendPeriodicAppearanceUpdates { get; set; }
111
98 protected float m_defaultDrawDistance = 255.0f; 112 protected float m_defaultDrawDistance = 255.0f;
99 public float DefaultDrawDistance 113 public float DefaultDrawDistance
100 { 114 {
@@ -160,6 +174,11 @@ namespace OpenSim.Region.Framework.Scenes
160 } 174 }
161 175
162 /// <summary> 176 /// <summary>
177 /// Current maintenance run number
178 /// </summary>
179 public uint MaintenanceRun { get; private set; }
180
181 /// <summary>
163 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we 182 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we
164 /// will sleep for the remaining period. 183 /// will sleep for the remaining period.
165 /// </summary> 184 /// </summary>
@@ -169,6 +188,11 @@ namespace OpenSim.Region.Framework.Scenes
169 /// </remarks> 188 /// </remarks>
170 public float MinFrameTime { get; private set; } 189 public float MinFrameTime { get; private set; }
171 190
191 /// <summary>
192 /// The minimum length of time in seconds that will be taken for a maintenance run.
193 /// </summary>
194 public float MinMaintenanceTime { get; private set; }
195
172 private int m_update_physics = 1; 196 private int m_update_physics = 1;
173 private int m_update_entitymovement = 1; 197 private int m_update_entitymovement = 1;
174 private int m_update_objects = 1; 198 private int m_update_objects = 1;
@@ -190,7 +214,16 @@ namespace OpenSim.Region.Framework.Scenes
190 private int backupMS; 214 private int backupMS;
191 private int terrainMS; 215 private int terrainMS;
192 private int landMS; 216 private int landMS;
193 private int lastCompletedFrame; 217
218 /// <summary>
219 /// Tick at which the last frame was processed.
220 /// </summary>
221 private int m_lastFrameTick;
222
223 /// <summary>
224 /// Tick at which the last maintenance run occurred.
225 /// </summary>
226 private int m_lastMaintenanceTick;
194 227
195 /// <summary> 228 /// <summary>
196 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 229 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
@@ -198,14 +231,12 @@ namespace OpenSim.Region.Framework.Scenes
198 /// </summary> 231 /// </summary>
199 private bool m_cleaningTemps = false; 232 private bool m_cleaningTemps = false;
200 233
201 private Object m_heartbeatLock = new Object(); 234// private Object m_heartbeatLock = new Object();
202 235
203 // TODO: Possibly stop other classes being able to manipulate this directly. 236 // TODO: Possibly stop other classes being able to manipulate this directly.
204 private SceneGraph m_sceneGraph; 237 private SceneGraph m_sceneGraph;
205 private volatile int m_bordersLocked; 238 private volatile int m_bordersLocked;
206// private int m_RestartTimerCounter;
207 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing 239 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
208// private int m_incrementsof15seconds;
209 private volatile bool m_backingup; 240 private volatile bool m_backingup;
210 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); 241 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
211 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); 242 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
@@ -213,14 +244,28 @@ namespace OpenSim.Region.Framework.Scenes
213 private bool m_physics_enabled = true; 244 private bool m_physics_enabled = true;
214 private bool m_scripts_enabled = true; 245 private bool m_scripts_enabled = true;
215 private string m_defaultScriptEngine; 246 private string m_defaultScriptEngine;
247
248 /// <summary>
249 /// Tick at which the last login occurred.
250 /// </summary>
216 private int m_LastLogin; 251 private int m_LastLogin;
217 private Thread HeartbeatThread;
218 private volatile bool shuttingdown;
219 252
220 private int m_lastUpdate; 253 /// <summary>
221 private bool m_firstHeartbeat = true; 254 /// Thread that runs the scene loop.
255 /// </summary>
256 private Thread m_heartbeatThread;
222 257
223 private object m_deleting_scene_object = new object(); 258 /// <summary>
259 /// True if these scene is in the process of shutting down or is shutdown.
260 /// </summary>
261 public bool ShuttingDown
262 {
263 get { return m_shuttingDown; }
264 }
265 private volatile bool m_shuttingDown;
266
267// private int m_lastUpdate;
268// private bool m_firstHeartbeat = true;
224 269
225 private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; 270 private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
226 private bool m_reprioritizationEnabled = true; 271 private bool m_reprioritizationEnabled = true;
@@ -466,7 +511,7 @@ namespace OpenSim.Region.Framework.Scenes
466 public int MonitorBackupTime { get { return backupMS; } } 511 public int MonitorBackupTime { get { return backupMS; } }
467 public int MonitorTerrainTime { get { return terrainMS; } } 512 public int MonitorTerrainTime { get { return terrainMS; } }
468 public int MonitorLandTime { get { return landMS; } } 513 public int MonitorLandTime { get { return landMS; } }
469 public int MonitorLastFrameTick { get { return lastCompletedFrame; } } 514 public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
470 515
471 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } 516 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
472 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } 517 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
@@ -535,6 +580,7 @@ namespace OpenSim.Region.Framework.Scenes
535 { 580 {
536 m_config = config; 581 m_config = config;
537 MinFrameTime = 0.089f; 582 MinFrameTime = 0.089f;
583 MinMaintenanceTime = 1;
538 584
539 Random random = new Random(); 585 Random random = new Random();
540 586
@@ -596,7 +642,7 @@ namespace OpenSim.Region.Framework.Scenes
596 642
597 #endregion Region Settings 643 #endregion Region Settings
598 644
599 MainConsole.Instance.Commands.AddCommand("region", false, "reload estate", 645 MainConsole.Instance.Commands.AddCommand("Estates", false, "reload estate",
600 "reload estate", 646 "reload estate",
601 "Reload the estate data", HandleReloadEstate); 647 "Reload the estate data", HandleReloadEstate);
602 648
@@ -628,10 +674,10 @@ namespace OpenSim.Region.Framework.Scenes
628 674
629 #region Region Config 675 #region Region Config
630 676
631 try 677 // Region config overrides global config
678 //
679 if (m_config.Configs["Startup"] != null)
632 { 680 {
633 // Region config overrides global config
634 //
635 IConfig startupConfig = m_config.Configs["Startup"]; 681 IConfig startupConfig = m_config.Configs["Startup"];
636 682
637 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance); 683 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance);
@@ -720,47 +766,42 @@ namespace OpenSim.Region.Framework.Scenes
720 m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences); 766 m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences);
721 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 767 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
722 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 768 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
723 } 769
724 catch 770 SendPeriodicAppearanceUpdates = startupConfig.GetBoolean("SendPeriodicAppearanceUpdates", SendPeriodicAppearanceUpdates);
725 {
726 m_log.Warn("[SCENE]: Failed to load StartupConfig");
727 } 771 }
728 772
729 #endregion Region Config 773 #endregion Region Config
730 774
731 #region Interest Management 775 #region Interest Management
732 776
733 if (m_config != null) 777 IConfig interestConfig = m_config.Configs["InterestManagement"];
778 if (interestConfig != null)
734 { 779 {
735 IConfig interestConfig = m_config.Configs["InterestManagement"]; 780 string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
736 if (interestConfig != null)
737 {
738 string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
739 781
740 try 782 try
741 { 783 {
742 m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true); 784 m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
743 } 785 }
744 catch (Exception) 786 catch (Exception)
745 { 787 {
746 m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time"); 788 m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
747 m_priorityScheme = UpdatePrioritizationSchemes.Time; 789 m_priorityScheme = UpdatePrioritizationSchemes.Time;
748 }
749
750 m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
751 m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
752 m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
753 m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
754 } 790 }
791
792 m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
793 m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
794 m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
795 m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
755 } 796 }
756 797
757 m_log.InfoFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme); 798 m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme);
758 799
759 #endregion Interest Management 800 #endregion Interest Management
760 801
761 StatsReporter = new SimStatsReporter(this); 802 StatsReporter = new SimStatsReporter(this);
762 StatsReporter.OnSendStatsResult += SendSimStatsPackets; 803 StatsReporter.OnSendStatsResult += SendSimStatsPackets;
763 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; 804 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
764 } 805 }
765 806
766 /// <summary> 807 /// <summary>
@@ -797,18 +838,13 @@ namespace OpenSim.Region.Framework.Scenes
797 838
798 m_permissions = new ScenePermissions(this); 839 m_permissions = new ScenePermissions(this);
799 840
800 m_lastUpdate = Util.EnvironmentTickCount(); 841// m_lastUpdate = Util.EnvironmentTickCount();
801 } 842 }
802 843
803 #endregion 844 #endregion
804 845
805 #region Startup / Close Methods 846 #region Startup / Close Methods
806 847
807 public bool ShuttingDown
808 {
809 get { return shuttingdown; }
810 }
811
812 /// <value> 848 /// <value>
813 /// The scene graph for this scene 849 /// The scene graph for this scene
814 /// </value> 850 /// </value>
@@ -1025,44 +1061,72 @@ namespace OpenSim.Region.Framework.Scenes
1025 } 1061 }
1026 } 1062 }
1027 1063
1028 public void SetSceneCoreDebug(bool ScriptEngine, bool CollisionEvents, bool PhysicsEngine) 1064 public void SetSceneCoreDebug(Dictionary<string, string> options)
1029 { 1065 {
1030 if (m_scripts_enabled != !ScriptEngine) 1066 if (options.ContainsKey("scripting"))
1031 { 1067 {
1032 if (ScriptEngine) 1068 bool enableScripts = true;
1069 if (bool.TryParse(options["scripting"], out enableScripts) && m_scripts_enabled != enableScripts)
1033 { 1070 {
1034 m_log.Info("Stopping all Scripts in Scene"); 1071 if (!enableScripts)
1035
1036 EntityBase[] entities = Entities.GetEntities();
1037 foreach (EntityBase ent in entities)
1038 { 1072 {
1039 if (ent is SceneObjectGroup) 1073 m_log.Info("Stopping all Scripts in Scene");
1040 ((SceneObjectGroup)ent).RemoveScriptInstances(false); 1074
1075 EntityBase[] entities = Entities.GetEntities();
1076 foreach (EntityBase ent in entities)
1077 {
1078 if (ent is SceneObjectGroup)
1079 ((SceneObjectGroup)ent).RemoveScriptInstances(false);
1080 }
1041 } 1081 }
1042 } 1082 else
1043 else
1044 {
1045 m_log.Info("Starting all Scripts in Scene");
1046
1047 EntityBase[] entities = Entities.GetEntities();
1048 foreach (EntityBase ent in entities)
1049 { 1083 {
1050 if (ent is SceneObjectGroup) 1084 m_log.Info("Starting all Scripts in Scene");
1085
1086 EntityBase[] entities = Entities.GetEntities();
1087 foreach (EntityBase ent in entities)
1051 { 1088 {
1052 SceneObjectGroup sog = (SceneObjectGroup)ent; 1089 if (ent is SceneObjectGroup)
1053 sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0); 1090 {
1054 sog.ResumeScripts(); 1091 SceneObjectGroup sog = (SceneObjectGroup)ent;
1092 sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
1093 sog.ResumeScripts();
1094 }
1055 } 1095 }
1056 } 1096 }
1097
1098 m_scripts_enabled = enableScripts;
1057 } 1099 }
1100 }
1101
1102 if (options.ContainsKey("physics"))
1103 {
1104 bool enablePhysics;
1105 if (bool.TryParse(options["physics"], out enablePhysics))
1106 m_physics_enabled = enablePhysics;
1107 }
1108
1109// if (options.ContainsKey("collisions"))
1110// {
1111// // TODO: Implement. If false, should stop objects colliding, though possibly should still allow
1112// // the avatar themselves to collide with the ground.
1113// }
1058 1114
1059 m_scripts_enabled = !ScriptEngine; 1115 if (options.ContainsKey("teleport"))
1060 m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine"); 1116 {
1117 bool enableTeleportDebugging;
1118 if (bool.TryParse(options["teleport"], out enableTeleportDebugging))
1119 DebugTeleporting = enableTeleportDebugging;
1061 } 1120 }
1062 1121
1063 if (m_physics_enabled != !PhysicsEngine) 1122 if (options.ContainsKey("updates"))
1064 { 1123 {
1065 m_physics_enabled = !PhysicsEngine; 1124 bool enableUpdateDebugging;
1125 if (bool.TryParse(options["updates"], out enableUpdateDebugging))
1126 {
1127 DebugUpdates = enableUpdateDebugging;
1128 GcNotify.Enabled = DebugUpdates;
1129 }
1066 } 1130 }
1067 } 1131 }
1068 1132
@@ -1076,6 +1140,8 @@ namespace OpenSim.Region.Framework.Scenes
1076 { 1140 {
1077 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); 1141 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
1078 1142
1143 StatsReporter.Close();
1144
1079 m_restartTimer.Stop(); 1145 m_restartTimer.Stop();
1080 m_restartTimer.Close(); 1146 m_restartTimer.Close();
1081 1147
@@ -1097,8 +1163,7 @@ namespace OpenSim.Region.Framework.Scenes
1097 ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); 1163 ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
1098 1164
1099 // Stop updating the scene objects and agents. 1165 // Stop updating the scene objects and agents.
1100 //m_heartbeatTimer.Close(); 1166 m_shuttingDown = true;
1101 shuttingdown = true;
1102 1167
1103 m_log.Debug("[SCENE]: Persisting changed objects"); 1168 m_log.Debug("[SCENE]: Persisting changed objects");
1104 EventManager.TriggerSceneShuttingDown(this); 1169 EventManager.TriggerSceneShuttingDown(this);
@@ -1122,23 +1187,23 @@ namespace OpenSim.Region.Framework.Scenes
1122 } 1187 }
1123 1188
1124 /// <summary> 1189 /// <summary>
1125 /// Start the timer which triggers regular scene updates 1190 /// Start the scene
1126 /// </summary> 1191 /// </summary>
1127 public void StartTimer() 1192 public void Start()
1128 { 1193 {
1129// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1194// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1130 1195
1131 //m_heartbeatTimer.Enabled = true; 1196 //m_heartbeatTimer.Enabled = true;
1132 //m_heartbeatTimer.Interval = (int)(m_timespan * 1000); 1197 //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
1133 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1198 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1134 if (HeartbeatThread != null) 1199 if (m_heartbeatThread != null)
1135 { 1200 {
1136 HeartbeatThread.Abort(); 1201 m_heartbeatThread.Abort();
1137 HeartbeatThread = null; 1202 m_heartbeatThread = null;
1138 } 1203 }
1139 m_lastUpdate = Util.EnvironmentTickCount(); 1204// m_lastUpdate = Util.EnvironmentTickCount();
1140 1205
1141 HeartbeatThread 1206 m_heartbeatThread
1142 = Watchdog.StartThread( 1207 = Watchdog.StartThread(
1143 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); 1208 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
1144 } 1209 }
@@ -1169,222 +1234,296 @@ namespace OpenSim.Region.Framework.Scenes
1169 /// </summary> 1234 /// </summary>
1170 private void Heartbeat() 1235 private void Heartbeat()
1171 { 1236 {
1172 if (!Monitor.TryEnter(m_heartbeatLock)) 1237// if (!Monitor.TryEnter(m_heartbeatLock))
1173 { 1238// {
1174 Watchdog.RemoveThread(); 1239// Watchdog.RemoveThread();
1175 return; 1240// return;
1176 } 1241// }
1177 1242
1178 try 1243// try
1179 { 1244// {
1180 m_eventManager.TriggerOnRegionStarted(this);
1181 1245
1182 // The first frame can take a very long time due to physics actors being added on startup. Therefore, 1246 m_eventManager.TriggerOnRegionStarted(this);
1183 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1184 // alarms for scenes with many objects.
1185 Update();
1186 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1187 1247
1188 while (!shuttingdown) 1248 // The first frame can take a very long time due to physics actors being added on startup. Therefore,
1189 Update(); 1249 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1250 // alarms for scenes with many objects.
1251 Update(1);
1190 1252
1191 m_lastUpdate = Util.EnvironmentTickCount(); 1253 Watchdog.StartThread(
1192 m_firstHeartbeat = false; 1254 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1193 } 1255
1194 catch (ThreadAbortException) 1256 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1195 { 1257 Update(-1);
1196 } 1258
1197 finally 1259// m_lastUpdate = Util.EnvironmentTickCount();
1198 { 1260// m_firstHeartbeat = false;
1199 Monitor.Pulse(m_heartbeatLock); 1261// }
1200 Monitor.Exit(m_heartbeatLock); 1262// finally
1201 } 1263// {
1264// Monitor.Pulse(m_heartbeatLock);
1265// Monitor.Exit(m_heartbeatLock);
1266// }
1202 1267
1203 Watchdog.RemoveThread(); 1268 Watchdog.RemoveThread();
1204 } 1269 }
1205 1270
1206 public override void Update() 1271 private void Maintenance()
1207 { 1272 {
1208 float physicsFPS = 0f; 1273 DoMaintenance(-1);
1209
1210 int maintc = Util.EnvironmentTickCount();
1211 int tmpFrameMS = maintc;
1212 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1213
1214 ++Frame;
1215
1216// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1217 1274
1218 try 1275 Watchdog.RemoveThread();
1219 { 1276 }
1220 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1221 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1222 m_sceneGraph.UpdatePreparePhysics();
1223 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1224
1225 // Apply any pending avatar force input to the avatar's velocity
1226 int tmpAgentMS = Util.EnvironmentTickCount();
1227 if (Frame % m_update_entitymovement == 0)
1228 m_sceneGraph.UpdateScenePresenceMovement();
1229 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
1230
1231 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1232 // velocity
1233 int tmpPhysicsMS = Util.EnvironmentTickCount();
1234 if (Frame % m_update_physics == 0)
1235 {
1236 if (m_physics_enabled)
1237 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1238
1239 if (SynchronizeScene != null)
1240 SynchronizeScene(this);
1241 }
1242 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1243 1277
1244 tmpAgentMS = Util.EnvironmentTickCount(); 1278 public void DoMaintenance(int runs)
1279 {
1280 long? endRun = null;
1281 int runtc;
1282 int previousMaintenanceTick;
1245 1283
1246 // Check if any objects have reached their targets 1284 if (runs >= 0)
1247 CheckAtTargets(); 1285 endRun = MaintenanceRun + runs;
1248 1286
1249 // Update SceneObjectGroups that have scheduled themselves for updates 1287 List<Vector3> coarseLocations;
1250 // Objects queue their updates onto all scene presences 1288 List<UUID> avatarUUIDs;
1251 if (Frame % m_update_objects == 0)
1252 m_sceneGraph.UpdateObjectGroups();
1253 1289
1254 // Run through all ScenePresences looking for updates 1290 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun))
1255 // Presence updates and queued object updates for each presence are sent to clients 1291 {
1256 if (Frame % m_update_presences == 0) 1292 runtc = Util.EnvironmentTickCount();
1257 m_sceneGraph.UpdatePresences(); 1293 ++MaintenanceRun;
1258 1294
1259 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) 1295 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1260 if (Frame % m_update_coarse_locations == 0) 1296 if (MaintenanceRun % (m_update_coarse_locations / 10) == 0)
1261 { 1297 {
1262 List<Vector3> coarseLocations;
1263 List<UUID> avatarUUIDs;
1264 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); 1298 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1265 // Send coarse locations to clients 1299 // Send coarse locations to clients
1266 ForEachScenePresence(delegate(ScenePresence presence) 1300 ForEachScenePresence(delegate(ScenePresence presence)
1267 { 1301 {
1268 presence.SendCoarseLocations(coarseLocations, avatarUUIDs); 1302 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1269 }); 1303 });
1270 } 1304 }
1271 1305
1272 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); 1306 if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0)
1273
1274 // Delete temp-on-rez stuff
1275 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1276 { 1307 {
1277 int tmpTempOnRezMS = Util.EnvironmentTickCount(); 1308// m_log.DebugFormat("[SCENE]: Sending periodic appearance updates");
1278 m_cleaningTemps = true;
1279 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1280 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1281 }
1282 1309
1283 if (Frame % m_update_events == 0) 1310 if (AvatarFactory != null)
1284 { 1311 {
1285 int evMS = Util.EnvironmentTickCount(); 1312 ForEachRootScenePresence(sp => AvatarFactory.SendAppearance(sp.UUID));
1286 UpdateEvents(); 1313 }
1287 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1288 } 1314 }
1289 1315
1290 if (Frame % m_update_backup == 0) 1316 Watchdog.UpdateThread();
1291 {
1292 int backMS = Util.EnvironmentTickCount();
1293 UpdateStorageBackup();
1294 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1295 }
1296 1317
1297 if (Frame % m_update_terrain == 0) 1318 previousMaintenanceTick = m_lastMaintenanceTick;
1298 { 1319 m_lastMaintenanceTick = Util.EnvironmentTickCount();
1299 int terMS = Util.EnvironmentTickCount(); 1320 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
1300 UpdateTerrain(); 1321 runtc = (int)(MinMaintenanceTime * 1000) - runtc;
1301 terrainMS = Util.EnvironmentTickCountSubtract(terMS); 1322
1302 } 1323 if (runtc > 0)
1324 Thread.Sleep(runtc);
1325
1326 // Optionally warn if a frame takes double the amount of time that it should.
1327 if (DebugUpdates
1328 && Util.EnvironmentTickCountSubtract(
1329 m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2))
1330 m_log.WarnFormat(
1331 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
1332 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
1333 MinMaintenanceTime * 1000,
1334 RegionInfo.RegionName);
1335 }
1336 }
1337
1338 public override void Update(int frames)
1339 {
1340 long? endFrame = null;
1341
1342 if (frames >= 0)
1343 endFrame = Frame + frames;
1303 1344
1304 //if (Frame % m_update_land == 0) 1345 float physicsFPS = 0f;
1305 //{ 1346 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
1306 // int ldMS = Util.EnvironmentTickCount(); 1347 int previousFrameTick;
1307 // UpdateLand(); 1348 int maintc;
1308 // landMS = Util.EnvironmentTickCountSubtract(ldMS); 1349
1309 //} 1350 while (!m_shuttingDown && (endFrame == null || Frame < endFrame))
1310 1351 {
1311 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); 1352 maintc = Util.EnvironmentTickCount();
1312 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; 1353 ++Frame;
1313 lastCompletedFrame = Util.EnvironmentTickCount(); 1354
1314 1355// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1315 // if (Frame%m_update_avatars == 0) 1356
1316 // UpdateInWorldTime(); 1357 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1317 StatsReporter.AddPhysicsFPS(physicsFPS); 1358
1318 StatsReporter.AddTimeDilation(TimeDilation); 1359 try
1319 StatsReporter.AddFPS(1);
1320 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1321 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1322 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1323 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1324 StatsReporter.addFrameMS(frameMS);
1325 StatsReporter.addAgentMS(agentMS);
1326 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1327 StatsReporter.addOtherMS(otherMS);
1328 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1329 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1330
1331 if (LoginsDisabled && Frame == 20)
1332 { 1360 {
1333// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); 1361 tmpPhysicsMS2 = Util.EnvironmentTickCount();
1362 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1363 m_sceneGraph.UpdatePreparePhysics();
1364 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1365
1366 // Apply any pending avatar force input to the avatar's velocity
1367 tmpAgentMS = Util.EnvironmentTickCount();
1368 if (Frame % m_update_entitymovement == 0)
1369 m_sceneGraph.UpdateScenePresenceMovement();
1370 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
1371
1372 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1373 // velocity
1374 tmpPhysicsMS = Util.EnvironmentTickCount();
1375 if (Frame % m_update_physics == 0)
1376 {
1377 if (m_physics_enabled)
1378 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1379
1380 if (SynchronizeScene != null)
1381 SynchronizeScene(this);
1382 }
1383 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1334 1384
1335 // In 99.9% of cases it is a bad idea to manually force garbage collection. However, 1385 tmpAgentMS = Util.EnvironmentTickCount();
1336 // this is a rare case where we know we have just went through a long cycle of heap 1386
1337 // allocations, and there is no more work to be done until someone logs in 1387 // Check if any objects have reached their targets
1338 GC.Collect(); 1388 CheckAtTargets();
1389
1390 // Update SceneObjectGroups that have scheduled themselves for updates
1391 // Objects queue their updates onto all scene presences
1392 if (Frame % m_update_objects == 0)
1393 m_sceneGraph.UpdateObjectGroups();
1394
1395 // Run through all ScenePresences looking for updates
1396 // Presence updates and queued object updates for each presence are sent to clients
1397 if (Frame % m_update_presences == 0)
1398 m_sceneGraph.UpdatePresences();
1399
1400 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
1401
1402 // Delete temp-on-rez stuff
1403 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1404 {
1405 tmpTempOnRezMS = Util.EnvironmentTickCount();
1406 m_cleaningTemps = true;
1407 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1408 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1409 }
1410
1411 if (Frame % m_update_events == 0)
1412 {
1413 evMS = Util.EnvironmentTickCount();
1414 UpdateEvents();
1415 eventMS = Util.EnvironmentTickCountSubtract(evMS);
1416 }
1417
1418 if (Frame % m_update_backup == 0)
1419 {
1420 backMS = Util.EnvironmentTickCount();
1421 UpdateStorageBackup();
1422 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1423 }
1424
1425 if (Frame % m_update_terrain == 0)
1426 {
1427 terMS = Util.EnvironmentTickCount();
1428 UpdateTerrain();
1429 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1430 }
1431
1432 //if (Frame % m_update_land == 0)
1433 //{
1434 // int ldMS = Util.EnvironmentTickCount();
1435 // UpdateLand();
1436 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1437 //}
1339 1438
1340 IConfig startupConfig = m_config.Configs["Startup"]; 1439 frameMS = Util.EnvironmentTickCountSubtract(maintc);
1341 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) 1440 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1441
1442 // if (Frame%m_update_avatars == 0)
1443 // UpdateInWorldTime();
1444 StatsReporter.AddPhysicsFPS(physicsFPS);
1445 StatsReporter.AddTimeDilation(TimeDilation);
1446 StatsReporter.AddFPS(1);
1447 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1448 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1449 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1450 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1451
1452 // frameMS currently records work frame times, not total frame times (work + any required sleep to
1453 // reach min frame time.
1454 StatsReporter.addFrameMS(frameMS);
1455
1456 StatsReporter.addAgentMS(agentMS);
1457 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1458 StatsReporter.addOtherMS(otherMS);
1459 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1460 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1461
1462 if (LoginsDisabled && Frame == 20)
1342 { 1463 {
1343 // This handles a case of a region having no scripts for the RegionReady module 1464 // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
1344 if (m_sceneGraph.GetActiveScriptsCount() == 0) 1465
1466 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1467 // this is a rare case where we know we have just went through a long cycle of heap
1468 // allocations, and there is no more work to be done until someone logs in
1469 GC.Collect();
1470
1471 IConfig startupConfig = m_config.Configs["Startup"];
1472 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1345 { 1473 {
1346 // need to be able to tell these have changed in RegionReady 1474 // This handles a case of a region having no scripts for the RegionReady module
1347 LoginLock = false; 1475 if (m_sceneGraph.GetActiveScriptsCount() == 0)
1348 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); 1476 {
1477 // need to be able to tell these have changed in RegionReady
1478 LoginLock = false;
1479 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
1480 }
1481 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1482
1483 // For RegionReady lockouts
1484 if(LoginLock == false)
1485 {
1486 LoginsDisabled = false;
1487 }
1488
1489 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1349 } 1490 }
1350 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); 1491 else
1351
1352 // For RegionReady lockouts
1353 if(LoginLock == false)
1354 { 1492 {
1355 LoginsDisabled = false; 1493 StartDisabled = true;
1494 LoginsDisabled = true;
1356 } 1495 }
1357
1358 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1359 }
1360 else
1361 {
1362 StartDisabled = true;
1363 LoginsDisabled = true;
1364 } 1496 }
1365 } 1497 }
1366 } 1498 catch (Exception e)
1367 catch (NotImplementedException) 1499 {
1368 { 1500 m_log.ErrorFormat(
1369 throw; 1501 "[SCENE]: Failed on region {0} with exception {1}{2}",
1370 } 1502 RegionInfo.RegionName, e.Message, e.StackTrace);
1371 catch (Exception e) 1503 }
1372 { 1504
1373 m_log.ErrorFormat( 1505 EventManager.TriggerRegionHeartbeatEnd(this);
1374 "[SCENE]: Failed on region {0} with exception {1}{2}",
1375 RegionInfo.RegionName, e.Message, e.StackTrace);
1376 }
1377 1506
1378 EventManager.TriggerRegionHeartbeatEnd(this); 1507 Watchdog.UpdateThread();
1379 1508
1380 maintc = Util.EnvironmentTickCountSubtract(maintc); 1509 previousFrameTick = m_lastFrameTick;
1381 maintc = (int)(MinFrameTime * 1000) - maintc; 1510 m_lastFrameTick = Util.EnvironmentTickCount();
1511 maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
1512 maintc = (int)(MinFrameTime * 1000) - maintc;
1382 1513
1383 if (maintc > 0) 1514 if (maintc > 0)
1384 Thread.Sleep(maintc); 1515 Thread.Sleep(maintc);
1385 1516
1386 // Tell the watchdog that this thread is still alive 1517 // Optionally warn if a frame takes double the amount of time that it should.
1387 Watchdog.UpdateThread(); 1518 if (DebugUpdates
1519 && Util.EnvironmentTickCountSubtract(
1520 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
1521 m_log.WarnFormat(
1522 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1523 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1524 MinFrameTime * 1000,
1525 RegionInfo.RegionName);
1526 }
1388 } 1527 }
1389 1528
1390 public void AddGroupTarget(SceneObjectGroup grp) 1529 public void AddGroupTarget(SceneObjectGroup grp)
@@ -1583,8 +1722,15 @@ namespace OpenSim.Region.Framework.Scenes
1583 double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID); 1722 double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID);
1584 if (map == null) 1723 if (map == null)
1585 { 1724 {
1586 m_log.Info("[TERRAIN]: No default terrain. Generating a new terrain."); 1725 // This should be in the Terrain module, but it isn't because
1587 Heightmap = new TerrainChannel(); 1726 // the heightmap is needed _way_ before the modules are initialized...
1727 IConfig terrainConfig = m_config.Configs["Terrain"];
1728 String m_InitialTerrain = "pinhead-island";
1729 if (terrainConfig != null)
1730 m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
1731
1732 m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain);
1733 Heightmap = new TerrainChannel(m_InitialTerrain);
1588 1734
1589 SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1735 SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1590 } 1736 }
@@ -1999,15 +2145,8 @@ namespace OpenSim.Region.Framework.Scenes
1999 public void DeleteSceneObject(SceneObjectGroup group, bool silent) 2145 public void DeleteSceneObject(SceneObjectGroup group, bool silent)
2000 { 2146 {
2001// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); 2147// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
2002
2003 //SceneObjectPart rootPart = group.GetChildPart(group.UUID);
2004 2148
2005 // Serialise calls to RemoveScriptInstances to avoid 2149 group.RemoveScriptInstances(true);
2006 // deadlocking on m_parts inside SceneObjectGroup
2007 lock (m_deleting_scene_object)
2008 {
2009 group.RemoveScriptInstances(true);
2010 }
2011 2150
2012 SceneObjectPart[] partList = group.Parts; 2151 SceneObjectPart[] partList = group.Parts;
2013 2152
@@ -2489,7 +2628,7 @@ namespace OpenSim.Region.Framework.Scenes
2489 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2628 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2490 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2629 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2491 2630
2492 CheckHeartbeat(); 2631// CheckHeartbeat();
2493 2632
2494 ScenePresence sp = GetScenePresence(client.AgentId); 2633 ScenePresence sp = GetScenePresence(client.AgentId);
2495 2634
@@ -2536,6 +2675,14 @@ namespace OpenSim.Region.Framework.Scenes
2536 // Cache the user's name 2675 // Cache the user's name
2537 CacheUserName(sp, aCircuit); 2676 CacheUserName(sp, aCircuit);
2538 2677
2678 // Let's send the Suitcase folder for incoming HG agents
2679 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
2680 {
2681 m_log.DebugFormat("[SCENE]: Sending root folder to viewer...");
2682 InventoryFolderBase suitcase = InventoryService.GetRootFolder(client.AgentId);
2683 client.SendBulkUpdateInventory(suitcase);
2684 }
2685
2539 EventManager.TriggerOnNewClient(client); 2686 EventManager.TriggerOnNewClient(client);
2540 if (vialogin) 2687 if (vialogin)
2541 EventManager.TriggerOnClientLogin(client); 2688 EventManager.TriggerOnClientLogin(client);
@@ -2774,7 +2921,6 @@ namespace OpenSim.Region.Framework.Scenes
2774 { 2921 {
2775 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; 2922 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
2776 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; 2923 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
2777 client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
2778 client.OnSetStartLocationRequest += SetHomeRezPoint; 2924 client.OnSetStartLocationRequest += SetHomeRezPoint;
2779 client.OnRegionHandleRequest += RegionHandleRequest; 2925 client.OnRegionHandleRequest += RegionHandleRequest;
2780 } 2926 }
@@ -2900,7 +3046,6 @@ namespace OpenSim.Region.Framework.Scenes
2900 { 3046 {
2901 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; 3047 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
2902 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; 3048 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
2903 client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest;
2904 client.OnSetStartLocationRequest -= SetHomeRezPoint; 3049 client.OnSetStartLocationRequest -= SetHomeRezPoint;
2905 client.OnRegionHandleRequest -= RegionHandleRequest; 3050 client.OnRegionHandleRequest -= RegionHandleRequest;
2906 } 3051 }
@@ -3067,7 +3212,7 @@ namespace OpenSim.Region.Framework.Scenes
3067 3212
3068 public override void RemoveClient(UUID agentID, bool closeChildAgents) 3213 public override void RemoveClient(UUID agentID, bool closeChildAgents)
3069 { 3214 {
3070 CheckHeartbeat(); 3215// CheckHeartbeat();
3071 bool isChildAgent = false; 3216 bool isChildAgent = false;
3072 ScenePresence avatar = GetScenePresence(agentID); 3217 ScenePresence avatar = GetScenePresence(agentID);
3073 if (avatar != null) 3218 if (avatar != null)
@@ -3540,8 +3685,8 @@ namespace OpenSim.Region.Framework.Scenes
3540 if (!AuthorizationService.IsAuthorizedForRegion( 3685 if (!AuthorizationService.IsAuthorizedForRegion(
3541 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) 3686 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
3542 { 3687 {
3543 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3688 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because {4}",
3544 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3689 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason);
3545 3690
3546 return false; 3691 return false;
3547 } 3692 }
@@ -4156,16 +4301,11 @@ namespace OpenSim.Region.Framework.Scenes
4156 public bool PipeEventsForScript(uint localID) 4301 public bool PipeEventsForScript(uint localID)
4157 { 4302 {
4158 SceneObjectPart part = GetSceneObjectPart(localID); 4303 SceneObjectPart part = GetSceneObjectPart(localID);
4304
4159 if (part != null) 4305 if (part != null)
4160 { 4306 {
4161 // Changed so that child prims of attachments return ScriptDanger for their parent, so that
4162 // their scripts will actually run.
4163 // -- Leaf, Tue Aug 12 14:17:05 EDT 2008
4164 SceneObjectPart parent = part.ParentGroup.RootPart; 4307 SceneObjectPart parent = part.ParentGroup.RootPart;
4165 if (part.ParentGroup.IsAttachment) 4308 return ScriptDanger(parent, parent.GetWorldPosition());
4166 return ScriptDanger(parent, parent.GetWorldPosition());
4167 else
4168 return ScriptDanger(part, part.GetWorldPosition());
4169 } 4309 }
4170 else 4310 else
4171 { 4311 {
@@ -4459,8 +4599,8 @@ namespace OpenSim.Region.Framework.Scenes
4459 // 4599 //
4460 int health=1; // Start at 1, means we're up 4600 int health=1; // Start at 1, means we're up
4461 4601
4462 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4602 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000)
4463 health+=1; 4603 health += 1;
4464 else 4604 else
4465 return health; 4605 return health;
4466 4606
@@ -4471,7 +4611,7 @@ namespace OpenSim.Region.Framework.Scenes
4471 else 4611 else
4472 return health; 4612 return health;
4473 4613
4474 CheckHeartbeat(); 4614// CheckHeartbeat();
4475 4615
4476 return health; 4616 return health;
4477 } 4617 }
@@ -4659,14 +4799,14 @@ namespace OpenSim.Region.Framework.Scenes
4659 return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; 4799 return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z;
4660 } 4800 }
4661 4801
4662 private void CheckHeartbeat() 4802// private void CheckHeartbeat()
4663 { 4803// {
4664 if (m_firstHeartbeat) 4804// if (m_firstHeartbeat)
4665 return; 4805// return;
4666 4806//
4667 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4807// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000)
4668 StartTimer(); 4808// StartTimer();
4669 } 4809// }
4670 4810
4671 public override ISceneObject DeserializeObject(string representation) 4811 public override ISceneObject DeserializeObject(string representation)
4672 { 4812 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 712e094..9c6b884 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -149,9 +149,13 @@ namespace OpenSim.Region.Framework.Scenes
149 #region Update Methods 149 #region Update Methods
150 150
151 /// <summary> 151 /// <summary>
152 /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) 152 /// Called to update the scene loop by a number of frames and until shutdown.
153 /// </summary> 153 /// </summary>
154 public abstract void Update(); 154 /// <param name="frames">
155 /// Number of frames to update. Exits on shutdown even if there are frames remaining.
156 /// If -1 then updates until shutdown.
157 /// </param>
158 public abstract void Update(int frames);
155 159
156 #endregion 160 #endregion
157 161
@@ -472,6 +476,63 @@ namespace OpenSim.Region.Framework.Scenes
472 /// <summary> 476 /// <summary>
473 /// Call this from a region module to add a command to the OpenSim console. 477 /// Call this from a region module to add a command to the OpenSim console.
474 /// </summary> 478 /// </summary>
479 /// <param name="mod">
480 /// The use of IRegionModuleBase is a cheap trick to get a different method signature,
481 /// though all new modules should be using interfaces descended from IRegionModuleBase anyway.
482 /// </param>
483 /// <param name="category">
484 /// Category of the command. This is the section under which it will appear when the user asks for help
485 /// </param>
486 /// <param name="command"></param>
487 /// <param name="shorthelp"></param>
488 /// <param name="longhelp"></param>
489 /// <param name="callback"></param>
490 public void AddCommand(
491 string category, object mod, string command, string shorthelp, string longhelp, CommandDelegate callback)
492 {
493 AddCommand(category, mod, command, shorthelp, longhelp, string.Empty, callback);
494 }
495
496 /// <summary>
497 /// Call this from a region module to add a command to the OpenSim console.
498 /// </summary>
499 /// <param name="mod"></param>
500 /// <param name="command"></param>
501 /// <param name="shorthelp"></param>
502 /// <param name="longhelp"></param>
503 /// <param name="descriptivehelp"></param>
504 /// <param name="callback"></param>
505 public void AddCommand(object mod, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
506 {
507 string moduleName = "";
508
509 if (mod != null)
510 {
511 if (mod is IRegionModule)
512 {
513 IRegionModule module = (IRegionModule)mod;
514 moduleName = module.Name;
515 }
516 else if (mod is IRegionModuleBase)
517 {
518 IRegionModuleBase module = (IRegionModuleBase)mod;
519 moduleName = module.Name;
520 }
521 else
522 {
523 throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase");
524 }
525 }
526
527 AddCommand(moduleName, mod, command, shorthelp, longhelp, descriptivehelp, callback);
528 }
529
530 /// <summary>
531 /// Call this from a region module to add a command to the OpenSim console.
532 /// </summary>
533 /// <param name="category">
534 /// Category of the command. This is the section under which it will appear when the user asks for help
535 /// </param>
475 /// <param name="mod"></param> 536 /// <param name="mod"></param>
476 /// <param name="command"></param> 537 /// <param name="command"></param>
477 /// <param name="shorthelp"></param> 538 /// <param name="shorthelp"></param>
@@ -479,12 +540,12 @@ namespace OpenSim.Region.Framework.Scenes
479 /// <param name="descriptivehelp"></param> 540 /// <param name="descriptivehelp"></param>
480 /// <param name="callback"></param> 541 /// <param name="callback"></param>
481 public void AddCommand( 542 public void AddCommand(
482 object mod, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) 543 string category, object mod, string command,
544 string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
483 { 545 {
484 if (MainConsole.Instance == null) 546 if (MainConsole.Instance == null)
485 return; 547 return;
486 548
487 string modulename = String.Empty;
488 bool shared = false; 549 bool shared = false;
489 550
490 if (mod != null) 551 if (mod != null)
@@ -492,20 +553,20 @@ namespace OpenSim.Region.Framework.Scenes
492 if (mod is IRegionModule) 553 if (mod is IRegionModule)
493 { 554 {
494 IRegionModule module = (IRegionModule)mod; 555 IRegionModule module = (IRegionModule)mod;
495 modulename = module.Name;
496 shared = module.IsSharedModule; 556 shared = module.IsSharedModule;
497 } 557 }
498 else if (mod is IRegionModuleBase) 558 else if (mod is IRegionModuleBase)
499 { 559 {
500 IRegionModuleBase module = (IRegionModuleBase)mod;
501 modulename = module.Name;
502 shared = mod is ISharedRegionModule; 560 shared = mod is ISharedRegionModule;
503 } 561 }
504 else throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase"); 562 else
563 {
564 throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase");
565 }
505 } 566 }
506 567
507 MainConsole.Instance.Commands.AddCommand( 568 MainConsole.Instance.Commands.AddCommand(
508 modulename, shared, command, shorthelp, longhelp, descriptivehelp, callback); 569 category, shared, command, shorthelp, longhelp, descriptivehelp, callback);
509 } 570 }
510 571
511 public virtual ISceneObject DeserializeObject(string representation) 572 public virtual ISceneObject DeserializeObject(string representation)
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 66fb493..5c542d6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -215,27 +215,9 @@ namespace OpenSim.Region.Framework.Scenes
215 if (sp.IsChildAgent) 215 if (sp.IsChildAgent)
216 continue; 216 continue;
217 217
218 if (sp.ParentID != 0) 218 coarseLocations.Add(sp.AbsolutePosition);
219 { 219
220 // sitting avatar 220 avatarUUIDs.Add(sp.UUID);
221 SceneObjectPart sop = m_parentScene.GetSceneObjectPart(sp.ParentID);
222 if (sop != null)
223 {
224 coarseLocations.Add(sop.AbsolutePosition + sp.OffsetPosition);
225 avatarUUIDs.Add(sp.UUID);
226 }
227 else
228 {
229 // we can't find the parent.. ! arg!
230 coarseLocations.Add(sp.AbsolutePosition);
231 avatarUUIDs.Add(sp.UUID);
232 }
233 }
234 else
235 {
236 coarseLocations.Add(sp.AbsolutePosition);
237 avatarUUIDs.Add(sp.UUID);
238 }
239 } 221 }
240 } 222 }
241 223
@@ -751,6 +733,7 @@ namespace OpenSim.Region.Framework.Scenes
751 #endregion 733 #endregion
752 734
753 #region Get Methods 735 #region Get Methods
736
754 /// <summary> 737 /// <summary>
755 /// Get the controlling client for the given avatar, if there is one. 738 /// Get the controlling client for the given avatar, if there is one.
756 /// 739 ///
@@ -1092,36 +1075,6 @@ namespace OpenSim.Region.Framework.Scenes
1092 return Entities.GetEntities(); 1075 return Entities.GetEntities();
1093 } 1076 }
1094 1077
1095 public Dictionary<uint, float> GetTopScripts()
1096 {
1097 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1098
1099 EntityBase[] EntityList = GetEntities();
1100 int limit = 0;
1101 foreach (EntityBase ent in EntityList)
1102 {
1103 if (ent is SceneObjectGroup)
1104 {
1105 SceneObjectGroup grp = (SceneObjectGroup)ent;
1106 if ((grp.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
1107 {
1108 if (grp.scriptScore >= 0.01)
1109 {
1110 topScripts.Add(grp.LocalId, grp.scriptScore);
1111 limit++;
1112 if (limit >= 100)
1113 {
1114 break;
1115 }
1116 }
1117 grp.scriptScore = 0;
1118 }
1119 }
1120 }
1121
1122 return topScripts;
1123 }
1124
1125 #endregion 1078 #endregion
1126 1079
1127 #region Other Methods 1080 #region Other Methods
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 878476e..afb5ccf 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -229,8 +229,6 @@ namespace OpenSim.Region.Framework.Scenes
229 get { return RootPart.VolumeDetectActive; } 229 get { return RootPart.VolumeDetectActive; }
230 } 230 }
231 231
232 public float scriptScore;
233
234 private Vector3 lastPhysGroupPos; 232 private Vector3 lastPhysGroupPos;
235 private Quaternion lastPhysGroupRot; 233 private Quaternion lastPhysGroupRot;
236 234
@@ -1184,12 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes
1184 1182
1185 public void AddScriptLPS(int count) 1183 public void AddScriptLPS(int count)
1186 { 1184 {
1187 if (scriptScore + count >= float.MaxValue - count) 1185 m_scene.SceneGraph.AddToScriptLPS(count);
1188 scriptScore = 0;
1189
1190 scriptScore += (float)count;
1191 SceneGraph d = m_scene.SceneGraph;
1192 d.AddToScriptLPS(count);
1193 } 1186 }
1194 1187
1195 public void AddActiveScriptCount(int count) 1188 public void AddActiveScriptCount(int count)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 65905a0..439b718 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1546,10 +1546,7 @@ namespace OpenSim.Region.Framework.Scenes
1546 if (userExposed) 1546 if (userExposed)
1547 dupe.UUID = UUID.Random(); 1547 dupe.UUID = UUID.Random();
1548 1548
1549 //memberwiseclone means it also clones the physics actor reference 1549 dupe.PhysActor = null;
1550 // This will make physical prim 'bounce' if not set to null.
1551 if (!userExposed)
1552 dupe.PhysActor = null;
1553 1550
1554 dupe.OwnerID = AgentID; 1551 dupe.OwnerID = AgentID;
1555 dupe.GroupID = GroupID; 1552 dupe.GroupID = GroupID;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index f2d1915..71a9084 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -590,9 +590,9 @@ namespace OpenSim.Region.Framework.Scenes
590 /// A list of inventory items with that name. 590 /// A list of inventory items with that name.
591 /// If no inventory item has that name then an empty list is returned. 591 /// If no inventory item has that name then an empty list is returned.
592 /// </returns> 592 /// </returns>
593 public IList<TaskInventoryItem> GetInventoryItems(string name) 593 public List<TaskInventoryItem> GetInventoryItems(string name)
594 { 594 {
595 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 595 List<TaskInventoryItem> items = new List<TaskInventoryItem>();
596 596
597 lock (m_items) 597 lock (m_items)
598 { 598 {
@@ -1100,7 +1100,7 @@ namespace OpenSim.Region.Framework.Scenes
1100 1100
1101 public List<TaskInventoryItem> GetInventoryItems() 1101 public List<TaskInventoryItem> GetInventoryItems()
1102 { 1102 {
1103 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1103 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1104 1104
1105 lock (m_items) 1105 lock (m_items)
1106 ret = new List<TaskInventoryItem>(m_items.Values); 1106 ret = new List<TaskInventoryItem>(m_items.Values);
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ec6bb89..cf60c69 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -432,7 +432,7 @@ namespace OpenSim.Region.Framework.Scenes
432 { 432 {
433 get 433 get
434 { 434 {
435 if (PhysicsActor != null && m_parentID == 0) 435 if (PhysicsActor != null)
436 { 436 {
437 m_pos = PhysicsActor.Position; 437 m_pos = PhysicsActor.Position;
438 438
@@ -455,19 +455,12 @@ namespace OpenSim.Region.Framework.Scenes
455 // in the sim unless the avatar is on a sit target. While 455 // in the sim unless the avatar is on a sit target. While
456 // on a sit target, m_pos will contain the desired offset 456 // on a sit target, m_pos will contain the desired offset
457 // without the parent rotation applied. 457 // without the parent rotation applied.
458 if (ParentID != 0) 458 SceneObjectPart sitPart = ParentPart;
459 { 459
460 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 460 if (sitPart != null)
461 if (part != null) 461 return sitPart.AbsolutePosition + (m_pos * sitPart.GetWorldRotation());
462 {
463 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
464 }
465 else
466 {
467 return ParentPosition + m_pos;
468 }
469 }
470 } 462 }
463
471 return m_pos; 464 return m_pos;
472 } 465 }
473 set 466 set
@@ -484,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes
484 } 477 }
485 } 478 }
486 479
487 // Don't update while sitting 480 // Don't update while sitting. The PhysicsActor above is null whilst sitting.
488 if (ParentID == 0) 481 if (ParentID == 0)
489 { 482 {
490 m_pos = value; 483 m_pos = value;
@@ -511,6 +504,7 @@ namespace OpenSim.Region.Framework.Scenes
511 // There is no offset position when not seated 504 // There is no offset position when not seated
512 if (ParentID == 0) 505 if (ParentID == 0)
513 return; 506 return;
507
514 m_pos = value; 508 m_pos = value;
515 } 509 }
516 } 510 }
@@ -569,12 +563,18 @@ namespace OpenSim.Region.Framework.Scenes
569 563
570 public bool IsChildAgent { get; set; } 564 public bool IsChildAgent { get; set; }
571 565
572 public uint ParentID 566 /// <summary>
573 { 567 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
574 get { return m_parentID; } 568 /// </summary>
575 set { m_parentID = value; } 569 public uint ParentID { get; set; }
576 } 570
577 private uint m_parentID; 571 /// <summary>
572 /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null.
573 /// </summary>
574 /// <remarks>
575 /// If you use this property then you must take a reference since another thread could set it to null.
576 /// </remarks>
577 public SceneObjectPart ParentPart { get; set; }
578 578
579 public float Health 579 public float Health
580 { 580 {
@@ -1751,36 +1751,34 @@ namespace OpenSim.Region.Framework.Scenes
1751 1751
1752 if (ParentID != 0) 1752 if (ParentID != 0)
1753 { 1753 {
1754 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 1754 SceneObjectPart part = ParentPart;
1755 if (part != null) 1755 TaskInventoryDictionary taskIDict = part.TaskInventory;
1756 if (taskIDict != null)
1756 { 1757 {
1757 TaskInventoryDictionary taskIDict = part.TaskInventory; 1758 lock (taskIDict)
1758 if (taskIDict != null)
1759 { 1759 {
1760 lock (taskIDict) 1760 foreach (UUID taskID in taskIDict.Keys)
1761 { 1761 {
1762 foreach (UUID taskID in taskIDict.Keys) 1762 UnRegisterControlEventsToScript(LocalId, taskID);
1763 { 1763 taskIDict[taskID].PermsMask &= ~(
1764 UnRegisterControlEventsToScript(LocalId, taskID); 1764 2048 | //PERMISSION_CONTROL_CAMERA
1765 taskIDict[taskID].PermsMask &= ~( 1765 4); // PERMISSION_TAKE_CONTROLS
1766 2048 | //PERMISSION_CONTROL_CAMERA
1767 4); // PERMISSION_TAKE_CONTROLS
1768 }
1769 } 1766 }
1770 } 1767 }
1768 }
1771 1769
1772 // Reset sit target. 1770 // Reset sit target.
1773 if (part.SitTargetAvatar == UUID) 1771 if (part.SitTargetAvatar == UUID)
1774 part.SitTargetAvatar = UUID.Zero; 1772 part.SitTargetAvatar = UUID.Zero;
1775 1773
1776 ParentPosition = part.GetWorldPosition(); 1774 ParentPosition = part.GetWorldPosition();
1777 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1775 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1778 }
1779 1776
1780 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 1777 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
1781 ParentPosition = Vector3.Zero; 1778 ParentPosition = Vector3.Zero;
1782 1779
1783 ParentID = 0; 1780 ParentID = 0;
1781 ParentPart = null;
1784 SendAvatarDataToAllAgents(); 1782 SendAvatarDataToAllAgents();
1785 m_requestedSitTargetID = 0; 1783 m_requestedSitTargetID = 0;
1786 1784
@@ -2206,19 +2204,16 @@ namespace OpenSim.Region.Framework.Scenes
2206// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2204// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
2207// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2205// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
2208 } 2206 }
2209 }
2210 else
2211 {
2212 return;
2213 }
2214 2207
2215 ParentID = m_requestedSitTargetID; 2208 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2209 ParentID = m_requestedSitTargetID;
2216 2210
2217 Velocity = Vector3.Zero; 2211 Velocity = Vector3.Zero;
2218 RemoveFromPhysicalScene(); 2212 RemoveFromPhysicalScene();
2219 2213
2220 Animator.TrySetMovementAnimation(sitAnimation); 2214 Animator.TrySetMovementAnimation(sitAnimation);
2221 SendAvatarDataToAllAgents(); 2215 SendAvatarDataToAllAgents();
2216 }
2222 } 2217 }
2223 2218
2224 public void HandleAgentSitOnGround() 2219 public void HandleAgentSitOnGround()
@@ -2298,7 +2293,7 @@ namespace OpenSim.Region.Framework.Scenes
2298 { 2293 {
2299 if (direc.Z > 2.0f) 2294 if (direc.Z > 2.0f)
2300 { 2295 {
2301 direc.Z *= 3.0f; 2296 direc.Z *= 2.6f;
2302 2297
2303 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2298 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2304 Animator.TrySetMovementAnimation("PREJUMP"); 2299 Animator.TrySetMovementAnimation("PREJUMP");
@@ -3831,7 +3826,7 @@ namespace OpenSim.Region.Framework.Scenes
3831 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); 3826 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
3832 if (land != null) 3827 if (land != null)
3833 { 3828 {
3834 if (Scene.DEBUG) 3829 if (Scene.DebugTeleporting)
3835 TeleportFlagsDebug(); 3830 TeleportFlagsDebug();
3836 3831
3837 // If we come in via login, landmark or map, we want to 3832 // If we come in via login, landmark or map, we want to
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 35cd025..5c56264 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -178,13 +178,19 @@ namespace OpenSim.Region.Framework.Scenes
178 m_objectCapacity = scene.RegionInfo.ObjectCapacity; 178 m_objectCapacity = scene.RegionInfo.ObjectCapacity;
179 m_report.AutoReset = true; 179 m_report.AutoReset = true;
180 m_report.Interval = statsUpdatesEveryMS; 180 m_report.Interval = statsUpdatesEveryMS;
181 m_report.Elapsed += new ElapsedEventHandler(statsHeartBeat); 181 m_report.Elapsed += statsHeartBeat;
182 m_report.Enabled = true; 182 m_report.Enabled = true;
183 183
184 if (StatsManager.SimExtraStats != null) 184 if (StatsManager.SimExtraStats != null)
185 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket; 185 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
186 } 186 }
187 187
188 public void Close()
189 {
190 m_report.Elapsed -= statsHeartBeat;
191 m_report.Close();
192 }
193
188 public void SetUpdateMS(int ms) 194 public void SetUpdateMS(int ms)
189 { 195 {
190 statsUpdatesEveryMS = ms; 196 statsUpdatesEveryMS = ms;
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index ca6210d..c0ca48e 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -46,23 +46,20 @@ namespace OpenSim.Region.Framework.Scenes
46 public TerrainChannel() 46 public TerrainChannel()
47 { 47 {
48 map = new double[Constants.RegionSize, Constants.RegionSize]; 48 map = new double[Constants.RegionSize, Constants.RegionSize];
49 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; 49 taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16];
50 50
51 int x; 51 PinHeadIsland();
52 for (x = 0; x < Constants.RegionSize; x++) 52 }
53 { 53
54 int y; 54 public TerrainChannel(String type)
55 for (y = 0; y < Constants.RegionSize; y++) 55 {
56 { 56 map = new double[Constants.RegionSize, Constants.RegionSize];
57 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; 57 taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16];
58 double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01; 58
59 double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001; 59 if (type.Equals("flat"))
60 if (map[x, y] < spherFacA) 60 FlatLand();
61 map[x, y] = spherFacA; 61 else
62 if (map[x, y] < spherFacB) 62 PinHeadIsland();
63 map[x, y] = spherFacB;
64 }
65 }
66 } 63 }
67 64
68 public TerrainChannel(double[,] import) 65 public TerrainChannel(double[,] import)
@@ -238,5 +235,36 @@ namespace OpenSim.Region.Framework.Scenes
238 } 235 }
239 } 236 }
240 } 237 }
238
239 private void PinHeadIsland()
240 {
241 int x;
242 for (x = 0; x < Constants.RegionSize; x++)
243 {
244 int y;
245 for (y = 0; y < Constants.RegionSize; y++)
246 {
247 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10;
248 double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01;
249 double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001;
250 if (map[x, y] < spherFacA)
251 map[x, y] = spherFacA;
252 if (map[x, y] < spherFacB)
253 map[x, y] = spherFacB;
254 }
255 }
256 }
257
258 private void FlatLand()
259 {
260 int x;
261 for (x = 0; x < Constants.RegionSize; x++)
262 {
263 int y;
264 for (y = 0; y < Constants.RegionSize; y++)
265 map[x, y] = 21;
266 }
267 }
268
241 } 269 }
242} 270}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
index 442cb8b..cfea10d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
81 // For now, we'll make the scene presence fly to simplify this test, but this needs to change. 81 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
82 sp.Flying = true; 82 sp.Flying = true;
83 83
84 m_scene.Update(); 84 m_scene.Update(1);
85 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos)); 85 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
86 86
87 Vector3 targetPos = startPos + new Vector3(0, 10, 0); 87 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
@@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
91 Assert.That( 91 Assert.That(
92 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); 92 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
93 93
94 m_scene.Update(); 94 m_scene.Update(1);
95 95
96 // We should really check the exact figure. 96 // We should really check the exact figure.
97 Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X)); 97 Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X));
@@ -99,8 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
99 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 99 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
100 Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X)); 100 Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X));
101 101
102 for (int i = 0; i < 10; i++) 102 m_scene.Update(10);
103 m_scene.Update();
104 103
105 double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); 104 double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
106 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move"); 105 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move");
@@ -116,7 +115,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
116 Assert.That( 115 Assert.That(
117 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); 116 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
118 117
119 m_scene.Update(); 118 m_scene.Update(1);
120 119
121 // We should really check the exact figure. 120 // We should really check the exact figure.
122 Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X)); 121 Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X));
@@ -124,8 +123,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
124 Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); 123 Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
125 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 124 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
126 125
127 for (int i = 0; i < 10; i++) 126 m_scene.Update(10);
128 m_scene.Update();
129 127
130 distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); 128 distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
131 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move"); 129 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index c5a76b2..bebc10c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -63,17 +63,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
63 63
64 Thread testThread = new Thread(testClass.run); 64 Thread testThread = new Thread(testClass.run);
65 65
66 try 66 // Seems kind of redundant to start a thread and then join it, however.. We need to protect against
67 { 67 // A thread abort exception in the simulator code.
68 // Seems kind of redundant to start a thread and then join it, however.. We need to protect against 68 testThread.Start();
69 // A thread abort exception in the simulator code. 69 testThread.Join();
70 testThread.Start(); 70
71 testThread.Join();
72 }
73 catch (ThreadAbortException)
74 {
75
76 }
77 Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); 71 Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message);
78 // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); 72 // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod());
79 } 73 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 8b8aea5..5c9a77d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
61 TestHelpers.InMethod(); 61 TestHelpers.InMethod();
62 62
63 Scene scene = SceneHelpers.SetupScene(); 63 Scene scene = SceneHelpers.SetupScene();
64 scene.Update(); 64 scene.Update(1);
65 65
66 Assert.That(scene.Frame, Is.EqualTo(1)); 66 Assert.That(scene.Frame, Is.EqualTo(1));
67 } 67 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index e16903c..55c80f5 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -113,7 +113,7 @@ namespace OpenSim.Region.Framework.Tests
113 } 113 }
114 114
115 /// <summary> 115 /// <summary>
116 /// Test MoveTaskInventoryItem where the item has no parent folder assigned. 116 /// Test MoveTaskInventoryItem from a part inventory to a user inventory where the item has no parent folder assigned.
117 /// </summary> 117 /// </summary>
118 /// <remarks> 118 /// <remarks>
119 /// This should place it in the most suitable user folder. 119 /// This should place it in the most suitable user folder.
@@ -142,9 +142,11 @@ namespace OpenSim.Region.Framework.Tests
142 } 142 }
143 143
144 /// <summary> 144 /// <summary>
145 /// Test MoveTaskInventoryItem where the item has no parent folder assigned. 145 /// Test MoveTaskInventoryItem from a part inventory to a user inventory where the item has no parent folder assigned.
146 /// </summary> 146 /// </summary>
147 /// <remarks>
147 /// This should place it in the most suitable user folder. 148 /// This should place it in the most suitable user folder.
149 /// </remarks>
148 [Test] 150 [Test]
149 public void TestMoveTaskInventoryItemNoParent() 151 public void TestMoveTaskInventoryItemNoParent()
150 { 152 {