aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorRobert Adams2014-01-19 07:38:53 -0800
committerRobert Adams2014-01-19 07:38:53 -0800
commitf127e4b4ee916a429ef1d9922432869d4138e214 (patch)
treebe90e6cea8d61088e8380e7027881a8d13f67849 /OpenSim/Region
parentvarregion: Update Warp3D to properly handle varregions. (diff)
parentFix casting error for float type INI file parameter parsing. (diff)
downloadopensim-SC_OLD-f127e4b4ee916a429ef1d9922432869d4138e214.zip
opensim-SC_OLD-f127e4b4ee916a429ef1d9922432869d4138e214.tar.gz
opensim-SC_OLD-f127e4b4ee916a429ef1d9922432869d4138e214.tar.bz2
opensim-SC_OLD-f127e4b4ee916a429ef1d9922432869d4138e214.tar.xz
Merge branch 'master' into varregion
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs6
-rw-r--r--OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs3
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs157
-rw-r--r--OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs4
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs20
-rw-r--r--OpenSim/Region/Framework/Interfaces/IInterregionComms.cs111
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs88
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs92
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs51
13 files changed, 223 insertions, 329 deletions
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
index f43305f..9b0e1f4 100644
--- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
@@ -194,10 +194,12 @@ namespace OpenSim.Region.CoreModules.Asset
194 194
195 #region IImprovedAssetCache Members 195 #region IImprovedAssetCache Members
196 196
197
198 public bool Check(string id) 197 public bool Check(string id)
199 { 198 {
200 return false; 199 AssetBase asset;
200
201 // XXX:This is probably not an efficient implementation.
202 return m_cache.TryGetValue(id, out asset);
201 } 203 }
202 204
203 /// <summary> 205 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
index 58ce61a..f720748 100644
--- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
@@ -114,7 +114,8 @@ namespace OpenSim.Region.CoreModules.Asset
114 // 114 //
115 public bool Check(string id) 115 public bool Check(string id)
116 { 116 {
117 return false; 117 // XXX This is probably not an efficient implementation.
118 return Get(id) != null;
118 } 119 }
119 120
120 public void Cache(AssetBase asset) 121 public void Cache(AssetBase asset)
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index f1fee63..6a5f8f3 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -248,71 +248,68 @@ namespace OpenSim.Region.CoreModules.Asset
248 248
249 private void UpdateFileCache(string key, AssetBase asset) 249 private void UpdateFileCache(string key, AssetBase asset)
250 { 250 {
251 // TODO: Spawn this off to some seperate thread to do the actual writing 251 string filename = GetFileName(key);
252 if (asset != null)
253 {
254 string filename = GetFileName(key);
255 252
256 try 253 try
254 {
255 // If the file is already cached, don't cache it, just touch it so access time is updated
256 if (File.Exists(filename))
257 { 257 {
258 // If the file is already cached, don't cache it, just touch it so access time is updated 258 // We don't really want to know about sharing
259 if (File.Exists(filename)) 259 // violations here. If the file is locked, then
260 // the other thread has updated the time for us.
261 try
260 { 262 {
261 // We don't really want to know about sharing 263 lock (m_CurrentlyWriting)
262 // violations here. If the file is locked, then
263 // the other thread has updated the time for us.
264 try
265 { 264 {
266 lock (m_CurrentlyWriting) 265 if (!m_CurrentlyWriting.Contains(filename))
267 { 266 File.SetLastAccessTime(filename, DateTime.Now);
268 if (!m_CurrentlyWriting.Contains(filename))
269 File.SetLastAccessTime(filename, DateTime.Now);
270 }
271 } 267 }
272 catch 268 }
269 catch
270 {
271 }
272 }
273 else
274 {
275 // Once we start writing, make sure we flag that we're writing
276 // that object to the cache so that we don't try to write the
277 // same file multiple times.
278 lock (m_CurrentlyWriting)
279 {
280#if WAIT_ON_INPROGRESS_REQUESTS
281 if (m_CurrentlyWriting.ContainsKey(filename))
273 { 282 {
283 return;
274 } 284 }
275 } else { 285 else
276
277 // Once we start writing, make sure we flag that we're writing
278 // that object to the cache so that we don't try to write the
279 // same file multiple times.
280 lock (m_CurrentlyWriting)
281 { 286 {
282#if WAIT_ON_INPROGRESS_REQUESTS 287 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
283 if (m_CurrentlyWriting.ContainsKey(filename)) 288 }
284 {
285 return;
286 }
287 else
288 {
289 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
290 }
291 289
292#else 290#else
293 if (m_CurrentlyWriting.Contains(filename)) 291 if (m_CurrentlyWriting.Contains(filename))
294 { 292 {
295 return; 293 return;
296 }
297 else
298 {
299 m_CurrentlyWriting.Add(filename);
300 }
301#endif
302
303 } 294 }
295 else
296 {
297 m_CurrentlyWriting.Add(filename);
298 }
299#endif
304 300
305 Util.FireAndForget(
306 delegate { WriteFileCache(filename, asset); });
307 } 301 }
308 } 302
309 catch (Exception e) 303 Util.FireAndForget(
310 { 304 delegate { WriteFileCache(filename, asset); });
311 m_log.ErrorFormat(
312 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
313 asset.ID, e.Message, e.StackTrace);
314 } 305 }
315 } 306 }
307 catch (Exception e)
308 {
309 m_log.ErrorFormat(
310 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
311 asset.ID, e.Message, e.StackTrace);
312 }
316 } 313 }
317 314
318 public void Cache(AssetBase asset) 315 public void Cache(AssetBase asset)
@@ -347,15 +344,9 @@ namespace OpenSim.Region.CoreModules.Asset
347 344
348 private bool CheckFromMemoryCache(string id) 345 private bool CheckFromMemoryCache(string id)
349 { 346 {
350 AssetBase asset = null; 347 return m_MemoryCache.Contains(id);
351
352 if (m_MemoryCache.TryGetValue(id, out asset))
353 return true;
354
355 return false;
356 } 348 }
357 349
358
359 /// <summary> 350 /// <summary>
360 /// Try to get an asset from the file cache. 351 /// Try to get an asset from the file cache.
361 /// </summary> 352 /// </summary>
@@ -393,15 +384,16 @@ namespace OpenSim.Region.CoreModules.Asset
393 384
394 if (File.Exists(filename)) 385 if (File.Exists(filename))
395 { 386 {
396 FileStream stream = null;
397 try 387 try
398 { 388 {
399 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 389 using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
400 BinaryFormatter bformatter = new BinaryFormatter(); 390 {
391 BinaryFormatter bformatter = new BinaryFormatter();
401 392
402 asset = (AssetBase)bformatter.Deserialize(stream); 393 asset = (AssetBase)bformatter.Deserialize(stream);
403 394
404 m_DiskHits++; 395 m_DiskHits++;
396 }
405 } 397 }
406 catch (System.Runtime.Serialization.SerializationException e) 398 catch (System.Runtime.Serialization.SerializationException e)
407 { 399 {
@@ -420,12 +412,6 @@ namespace OpenSim.Region.CoreModules.Asset
420 m_log.WarnFormat( 412 m_log.WarnFormat(
421 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 413 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
422 filename, id, e.Message, e.StackTrace); 414 filename, id, e.Message, e.StackTrace);
423
424 }
425 finally
426 {
427 if (stream != null)
428 stream.Close();
429 } 415 }
430 } 416 }
431 417
@@ -437,36 +423,19 @@ namespace OpenSim.Region.CoreModules.Asset
437 bool found = false; 423 bool found = false;
438 424
439 string filename = GetFileName(id); 425 string filename = GetFileName(id);
426
440 if (File.Exists(filename)) 427 if (File.Exists(filename))
441 { 428 {
442 // actually check if we can open it, and so update expire
443 FileStream stream = null;
444 try 429 try
445 { 430 {
446 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 431 using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
447 if (stream != null)
448 { 432 {
449 found = true; 433 if (stream != null)
450 stream.Close(); 434 found = true;
451 } 435 }
452
453 }
454 catch (System.Runtime.Serialization.SerializationException e)
455 {
456 found = false;
457 m_log.ErrorFormat(
458 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
459 filename, id, e.Message, e.StackTrace);
460
461 // If there was a problem deserializing the asset, the asset may
462 // either be corrupted OR was serialized under an old format
463 // {different version of AssetBase} -- we should attempt to
464 // delete it and re-cache
465 File.Delete(filename);
466 } 436 }
467 catch (Exception e) 437 catch (Exception e)
468 { 438 {
469 found = false;
470 m_log.ErrorFormat( 439 m_log.ErrorFormat(
471 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}", 440 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
472 filename, id, e.Message, e.StackTrace); 441 filename, id, e.Message, e.StackTrace);
@@ -518,11 +487,6 @@ namespace OpenSim.Region.CoreModules.Asset
518 return Get(id); 487 return Get(id);
519 } 488 }
520 489
521 public AssetBase CheckCached(string id)
522 {
523 return Get(id);
524 }
525
526 public void Expire(string id) 490 public void Expire(string id)
527 { 491 {
528 if (m_LogLevel >= 2) 492 if (m_LogLevel >= 2)
@@ -1067,11 +1031,6 @@ namespace OpenSim.Region.CoreModules.Asset
1067 return asset.Data; 1031 return asset.Data;
1068 } 1032 }
1069 1033
1070 public bool CheckData(string id)
1071 {
1072 return Check(id); ;
1073 }
1074
1075 public bool Get(string id, object sender, AssetRetrieved handler) 1034 public bool Get(string id, object sender, AssetRetrieved handler)
1076 { 1035 {
1077 AssetBase asset = Get(id); 1036 AssetBase asset = Get(id);
diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
index ce9b546..5f76ac2 100644
--- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
@@ -117,7 +117,7 @@ namespace OpenSim.Region.CoreModules.Asset
117 117
118 public bool Check(string id) 118 public bool Check(string id)
119 { 119 {
120 return false; 120 return m_Cache.Contains(id);
121 } 121 }
122 122
123 public void Cache(AssetBase asset) 123 public void Cache(AssetBase asset)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 4ab36a5..85e8159 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -1433,7 +1433,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1433 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos) 1433 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos)
1434 { 1434 {
1435 version = String.Empty; 1435 version = String.Empty;
1436 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1436 newpos = pos;
1437 1437
1438// m_log.DebugFormat( 1438// m_log.DebugFormat(
1439// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1439// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 678f3dc..4dcb99f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -174,7 +174,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
174 174
175 #endregion 175 #endregion
176 176
177 #region ISimulation 177 #region ISimulationService
178 178
179 public IScene GetScene(UUID regionId) 179 public IScene GetScene(UUID regionId)
180 { 180 {
@@ -353,7 +353,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
353 return false; 353 return false;
354 } 354 }
355 355
356 #endregion /* IInterregionComms */ 356 #endregion
357 357
358 #region Misc 358 #region Misc
359 359
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index f45f560..cc01430 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
146 146
147 #endregion 147 #endregion
148 148
149 #region IInterregionComms 149 #region ISimulationService
150 150
151 public IScene GetScene(UUID regionId) 151 public IScene GetScene(UUID regionId)
152 { 152 {
@@ -279,6 +279,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
279 return false; 279 return false;
280 } 280 }
281 281
282 #endregion /* IInterregionComms */ 282 #endregion
283 } 283 }
284} 284}
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 966916a..709d8fc 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -47,13 +47,33 @@ namespace OpenSim.Region.Framework.Interfaces
47 /// The handle of the destination region. If it's the same as the region currently 47 /// The handle of the destination region. If it's the same as the region currently
48 /// occupied by the agent then the teleport will be within that region. 48 /// occupied by the agent then the teleport will be within that region.
49 /// </param> 49 /// </param>
50 /// <param name='agent'></param>
51 /// <param name='regionHandle'></param>
50 /// <param name='position'></param> 52 /// <param name='position'></param>
51 /// <param name='lookAt'></param> 53 /// <param name='lookAt'></param>
52 /// <param name='teleportFlags'></param> 54 /// <param name='teleportFlags'></param>
53 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags); 55 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags);
54 56
57 /// <summary>
58 /// Teleports the agent for the given client to their home destination.
59 /// </summary>
60 /// <param name='id'></param>
61 /// <param name='client'></param>
55 bool TeleportHome(UUID id, IClientAPI client); 62 bool TeleportHome(UUID id, IClientAPI client);
56 63
64 /// <summary>
65 /// Teleport an agent directly to a given region without checking whether the region should be substituted.
66 /// </summary>
67 /// <remarks>
68 /// Please use Teleport() instead unless you know exactly what you're doing.
69 /// Do not use for same region teleports.
70 /// </remarks>
71 /// <param name='sp'></param>
72 /// <param name='reg'></param>
73 /// <param name='finalDestination'>/param>
74 /// <param name='position'></param>
75 /// <param name='lookAt'></param>
76 /// <param name='teleportFlags'></param>
57 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, 77 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
58 Vector3 position, Vector3 lookAt, uint teleportFlags); 78 Vector3 position, Vector3 lookAt, uint teleportFlags);
59 79
diff --git a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
deleted file mode 100644
index 2d6287f..0000000
--- a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
+++ /dev/null
@@ -1,111 +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 OpenMetaverse;
29using OpenSim.Framework;
30using OpenSim.Region.Framework.Scenes;
31
32namespace OpenSim.Region.Framework.Interfaces
33{
34 public delegate bool ChildAgentUpdateReceived(AgentData data);
35
36 public interface IInterregionCommsOut
37 {
38 #region Agents
39
40 bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit, uint teleportFlags, out string reason);
41
42 /// <summary>
43 /// Full child agent update.
44 /// </summary>
45 /// <param name="regionHandle"></param>
46 /// <param name="data"></param>
47 /// <returns></returns>
48 bool SendChildAgentUpdate(ulong regionHandle, AgentData data);
49
50 /// <summary>
51 /// Short child agent update, mostly for position.
52 /// </summary>
53 /// <param name="regionHandle"></param>
54 /// <param name="data"></param>
55 /// <returns></returns>
56 bool SendChildAgentUpdate(ulong regionHandle, AgentPosition data);
57
58 bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent);
59
60 /// <summary>
61 /// Message from receiving region to departing region, telling it got contacted by the client.
62 /// When sent over REST, it invokes the opaque uri.
63 /// </summary>
64 /// <param name="regionHandle"></param>
65 /// <param name="id"></param>
66 /// <param name="uri"></param>
67 /// <returns></returns>
68 bool SendReleaseAgent(ulong regionHandle, UUID id, string uri);
69
70 /// <summary>
71 /// Close agent.
72 /// </summary>
73 /// <param name="regionHandle"></param>
74 /// <param name="id"></param>
75 /// <returns></returns>
76 bool SendCloseAgent(ulong regionHandle, UUID id);
77
78 #endregion Agents
79
80 #region Objects
81
82 /// <summary>
83 /// Create an object in the destination region. This message is used primarily for prim crossing.
84 /// </summary>
85 /// <param name="regionHandle"></param>
86 /// <param name="sog"></param>
87 /// <param name="isLocalCall"></param>
88 /// <returns></returns>
89 bool SendCreateObject(ulong regionHandle, SceneObjectGroup sog, bool isLocalCall);
90
91 /// <summary>
92 /// Create an object from the user's inventory in the destination region.
93 /// This message is used primarily by clients.
94 /// </summary>
95 /// <param name="regionHandle"></param>
96 /// <param name="userID"></param>
97 /// <param name="itemID"></param>
98 /// <returns></returns>
99 bool SendCreateObject(ulong regionHandle, UUID userID, UUID itemID);
100
101 #endregion Objects
102
103 }
104
105 // This may not be needed, but having it here for now.
106 public interface IInterregionCommsIn
107 {
108 event ChildAgentUpdateReceived OnChildAgentUpdate;
109 }
110
111}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index d8a4ed1..aee621f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4389,18 +4389,6 @@ namespace OpenSim.Region.Framework.Scenes
4389 return sp; 4389 return sp;
4390 } 4390 }
4391 4391
4392 public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
4393 {
4394 agent = null;
4395 ScenePresence sp = GetScenePresence(id);
4396 if ((sp != null) && (!sp.IsChildAgent))
4397 {
4398 sp.IsChildAgent = true;
4399 return sp.CopyAgent(out agent);
4400 }
4401
4402 return false;
4403 }
4404 /// <summary> 4392 /// <summary>
4405 /// Authenticated close (via network) 4393 /// Authenticated close (via network)
4406 /// </summary> 4394 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index d2c7c76..b4274ba 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -110,6 +110,16 @@ namespace OpenSim.Region.Framework.Scenes
110 } 110 }
111 } 111 }
112 112
113 /// <summary>
114 /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and
115 /// the viewer fires these in quick succession.
116 /// </summary>
117 /// <remarks>
118 /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement
119 /// regulation done there.
120 /// </remarks>
121 private object m_completeMovementLock = new object();
122
113// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 123// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
114 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 124 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
115 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 125 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
@@ -980,6 +990,7 @@ namespace OpenSim.Region.Framework.Scenes
980 /// <summary> 990 /// <summary>
981 /// Turns a child agent into a root agent. 991 /// Turns a child agent into a root agent.
982 /// </summary> 992 /// </summary>
993 /// <remarks>
983 /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the 994 /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the
984 /// avatar is actual in the sim. They can perform all actions. 995 /// avatar is actual in the sim. They can perform all actions.
985 /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, 996 /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim,
@@ -987,49 +998,52 @@ namespace OpenSim.Region.Framework.Scenes
987 /// 998 ///
988 /// This method is on the critical path for transferring an avatar from one region to another. Delay here 999 /// This method is on the critical path for transferring an avatar from one region to another. Delay here
989 /// delays that crossing. 1000 /// delays that crossing.
990 /// </summary> 1001 /// </remarks>
991 private void MakeRootAgent(Vector3 pos, bool isFlying) 1002 private bool MakeRootAgent(Vector3 pos, bool isFlying)
992 { 1003 {
993// m_log.InfoFormat( 1004 lock (m_completeMovementLock)
994// "[SCENE]: Upgrading child to root agent for {0} in {1}",
995// Name, m_scene.RegionInfo.RegionName);
996
997 if (ParentUUID != UUID.Zero)
998 { 1005 {
999 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); 1006 if (!IsChildAgent)
1000 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); 1007 return false;
1001 if (part == null) 1008
1009 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
1010
1011 // m_log.InfoFormat(
1012 // "[SCENE]: Upgrading child to root agent for {0} in {1}",
1013 // Name, m_scene.RegionInfo.RegionName);
1014
1015 if (ParentUUID != UUID.Zero)
1002 { 1016 {
1003 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); 1017 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
1018 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
1019 if (part == null)
1020 {
1021 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1022 }
1023 else
1024 {
1025 part.ParentGroup.AddAvatar(UUID);
1026 if (part.SitTargetPosition != Vector3.Zero)
1027 part.SitTargetAvatar = UUID;
1028 // ParentPosition = part.GetWorldPosition();
1029 ParentID = part.LocalId;
1030 ParentPart = part;
1031 m_pos = PrevSitOffset;
1032 // pos = ParentPosition;
1033 pos = part.GetWorldPosition();
1034 }
1035 ParentUUID = UUID.Zero;
1036
1037 // Animator.TrySetMovementAnimation("SIT");
1004 } 1038 }
1005 else 1039 else
1006 { 1040 {
1007 part.ParentGroup.AddAvatar(UUID); 1041 IsLoggingIn = false;
1008 if (part.SitTargetPosition != Vector3.Zero)
1009 part.SitTargetAvatar = UUID;
1010// ParentPosition = part.GetWorldPosition();
1011 ParentID = part.LocalId;
1012 ParentPart = part;
1013 m_pos = PrevSitOffset;
1014// pos = ParentPosition;
1015 pos = part.GetWorldPosition();
1016 } 1042 }
1017 ParentUUID = UUID.Zero;
1018
1019 IsChildAgent = false;
1020 1043
1021// Animator.TrySetMovementAnimation("SIT");
1022 }
1023 else
1024 {
1025 IsChildAgent = false; 1044 IsChildAgent = false;
1026 IsLoggingIn = false;
1027 } 1045 }
1028 1046
1029 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
1030
1031 IsChildAgent = false;
1032
1033 // Must reset this here so that a teleport to a region next to an existing region does not keep the flag 1047 // Must reset this here so that a teleport to a region next to an existing region does not keep the flag
1034 // set and prevent the close of the connection on a subsequent re-teleport. 1048 // set and prevent the close of the connection on a subsequent re-teleport.
1035 // Should not be needed if we are not trying to tell this region to close 1049 // Should not be needed if we are not trying to tell this region to close
@@ -1216,6 +1230,7 @@ namespace OpenSim.Region.Framework.Scenes
1216 1230
1217 m_scene.EventManager.TriggerOnMakeRootAgent(this); 1231 m_scene.EventManager.TriggerOnMakeRootAgent(this);
1218 1232
1233 return true;
1219 } 1234 }
1220 1235
1221 public int GetStateSource() 1236 public int GetStateSource()
@@ -1639,7 +1654,14 @@ namespace OpenSim.Region.Framework.Scenes
1639 } 1654 }
1640 1655
1641 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1656 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1642 MakeRootAgent(AbsolutePosition, flying); 1657 if (!MakeRootAgent(AbsolutePosition, flying))
1658 {
1659 m_log.DebugFormat(
1660 "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root",
1661 Name, Scene.Name);
1662
1663 return;
1664 }
1643 1665
1644 // Tell the client that we're totally ready 1666 // Tell the client that we're totally ready
1645 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1667 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index d1aeaee..1ff1329 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -111,6 +111,45 @@ namespace OpenSim.Region.Framework.Scenes.Tests
111 Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1)); 111 Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1));
112 } 112 }
113 113
114 /// <summary>
115 /// Test that duplicate complete movement calls are ignored.
116 /// </summary>
117 /// <remarks>
118 /// If duplicate calls are not ignored then there is a risk of race conditions or other unexpected effects.
119 /// </remarks>
120 [Test]
121 public void TestDupeCompleteMovementCalls()
122 {
123 TestHelpers.InMethod();
124// TestHelpers.EnableLogging();
125
126 UUID spUuid = TestHelpers.ParseTail(0x1);
127
128 TestScene scene = new SceneHelpers().SetupScene();
129
130 int makeRootAgentEvents = 0;
131 scene.EventManager.OnMakeRootAgent += spi => makeRootAgentEvents++;
132
133 ScenePresence sp = SceneHelpers.AddScenePresence(scene, spUuid);
134
135 Assert.That(makeRootAgentEvents, Is.EqualTo(1));
136
137 // Normally these would be invoked by a CompleteMovement message coming in to the UDP stack. But for
138 // convenience, here we will invoke it manually.
139 sp.CompleteMovement(sp.ControllingClient, true);
140
141 Assert.That(makeRootAgentEvents, Is.EqualTo(1));
142
143 // Check rest of exepcted parameters.
144 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null);
145 Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
146
147 Assert.That(sp.IsChildAgent, Is.False);
148 Assert.That(sp.UUID, Is.EqualTo(spUuid));
149
150 Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1));
151 }
152
114 [Test] 153 [Test]
115 public void TestCreateDuplicateRootScenePresence() 154 public void TestCreateDuplicateRootScenePresence()
116 { 155 {
@@ -249,58 +288,5 @@ namespace OpenSim.Region.Framework.Scenes.Tests
249// Assert.That(childPresence, Is.Not.Null); 288// Assert.That(childPresence, Is.Not.Null);
250// Assert.That(childPresence.IsChildAgent, Is.True); 289// Assert.That(childPresence.IsChildAgent, Is.True);
251 } 290 }
252
253// /// <summary>
254// /// Test adding a root agent to a scene. Doesn't yet actually complete crossing the agent into the scene.
255// /// </summary>
256// [Test]
257// public void T010_TestAddRootAgent()
258// {
259// TestHelpers.InMethod();
260//
261// string firstName = "testfirstname";
262//
263// AgentCircuitData agent = new AgentCircuitData();
264// agent.AgentID = agent1;
265// agent.firstname = firstName;
266// agent.lastname = "testlastname";
267// agent.SessionID = UUID.Random();
268// agent.SecureSessionID = UUID.Random();
269// agent.circuitcode = 123;
270// agent.BaseFolder = UUID.Zero;
271// agent.InventoryFolder = UUID.Zero;
272// agent.startpos = Vector3.Zero;
273// agent.CapsPath = GetRandomCapsObjectPath();
274// agent.ChildrenCapSeeds = new Dictionary<ulong, string>();
275// agent.child = true;
276//
277// scene.PresenceService.LoginAgent(agent.AgentID.ToString(), agent.SessionID, agent.SecureSessionID);
278//
279// string reason;
280// scene.NewUserConnection(agent, (uint)TeleportFlags.ViaLogin, out reason);
281// testclient = new TestClient(agent, scene);
282// scene.AddNewAgent(testclient);
283//
284// ScenePresence presence = scene.GetScenePresence(agent1);
285//
286// Assert.That(presence, Is.Not.Null, "presence is null");
287// Assert.That(presence.Firstname, Is.EqualTo(firstName), "First name not same");
288// acd1 = agent;
289// }
290//
291// /// <summary>
292// /// Test removing an uncrossed root agent from a scene.
293// /// </summary>
294// [Test]
295// public void T011_TestRemoveRootAgent()
296// {
297// TestHelpers.InMethod();
298//
299// scene.RemoveClient(agent1);
300//
301// ScenePresence presence = scene.GetScenePresence(agent1);
302//
303// Assert.That(presence, Is.Null, "presence is not null");
304// }
305 } 291 }
306} \ No newline at end of file 292} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 1d6cb6d..b13a5ae 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -434,6 +434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
434 } 434 }
435 return wl; 435 return wl;
436 } 436 }
437
437 /// <summary> 438 /// <summary>
438 /// Set the current Windlight scene 439 /// Set the current Windlight scene
439 /// </summary> 440 /// </summary>
@@ -446,13 +447,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
446 LSShoutError("LightShare functions are not enabled."); 447 LSShoutError("LightShare functions are not enabled.");
447 return 0; 448 return 0;
448 } 449 }
449 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 450
451 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID))
450 { 452 {
451 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 453 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
452 return 0; 454
455 if (sp == null || sp.GodLevel < 200)
456 {
457 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
458 return 0;
459 }
453 } 460 }
461
454 int success = 0; 462 int success = 0;
455 m_host.AddScriptLPS(1); 463 m_host.AddScriptLPS(1);
464
456 if (LightShareModule.EnableWindlight) 465 if (LightShareModule.EnableWindlight)
457 { 466 {
458 RegionLightShareData wl = getWindlightProfileFromRules(rules); 467 RegionLightShareData wl = getWindlightProfileFromRules(rules);
@@ -465,8 +474,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
465 LSShoutError("Windlight module is disabled"); 474 LSShoutError("Windlight module is disabled");
466 return 0; 475 return 0;
467 } 476 }
477
468 return success; 478 return success;
469 } 479 }
480
470 public void lsClearWindlightScene() 481 public void lsClearWindlightScene()
471 { 482 {
472 if (!m_LSFunctionsEnabled) 483 if (!m_LSFunctionsEnabled)
@@ -474,17 +485,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
474 LSShoutError("LightShare functions are not enabled."); 485 LSShoutError("LightShare functions are not enabled.");
475 return; 486 return;
476 } 487 }
477 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 488
489 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID))
478 { 490 {
479 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 491 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
480 return; 492
493 if (sp == null || sp.GodLevel < 200)
494 {
495 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
496 return;
497 }
481 } 498 }
482 499
483 m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.valid = false; 500 m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.valid = false;
484 if (m_host.ParentGroup.Scene.SimulationDataService != null) 501 if (m_host.ParentGroup.Scene.SimulationDataService != null)
485 m_host.ParentGroup.Scene.SimulationDataService.RemoveRegionWindlightSettings(m_host.ParentGroup.Scene.RegionInfo.RegionID); 502 m_host.ParentGroup.Scene.SimulationDataService.RemoveRegionWindlightSettings(m_host.ParentGroup.Scene.RegionInfo.RegionID);
503
486 m_host.ParentGroup.Scene.EventManager.TriggerOnSaveNewWindlightProfile(); 504 m_host.ParentGroup.Scene.EventManager.TriggerOnSaveNewWindlightProfile();
487 } 505 }
506
488 /// <summary> 507 /// <summary>
489 /// Set the current Windlight scene to a target avatar 508 /// Set the current Windlight scene to a target avatar
490 /// </summary> 509 /// </summary>
@@ -497,13 +516,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
497 LSShoutError("LightShare functions are not enabled."); 516 LSShoutError("LightShare functions are not enabled.");
498 return 0; 517 return 0;
499 } 518 }
500 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 519
520 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID))
501 { 521 {
502 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); 522 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
503 return 0; 523
524 if (sp == null || sp.GodLevel < 200)
525 {
526 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
527 return 0;
528 }
504 } 529 }
530
505 int success = 0; 531 int success = 0;
506 m_host.AddScriptLPS(1); 532 m_host.AddScriptLPS(1);
533
507 if (LightShareModule.EnableWindlight) 534 if (LightShareModule.EnableWindlight)
508 { 535 {
509 RegionLightShareData wl = getWindlightProfileFromRules(rules); 536 RegionLightShareData wl = getWindlightProfileFromRules(rules);
@@ -515,8 +542,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
515 LSShoutError("Windlight module is disabled"); 542 LSShoutError("Windlight module is disabled");
516 return 0; 543 return 0;
517 } 544 }
545
518 return success; 546 return success;
519 } 547 }
520
521 } 548 }
522} 549} \ No newline at end of file