2007-07-16 15:40:11 +00:00
/ *
2008-03-18 05:16:43 +00:00
* Copyright ( c ) Contributors , http : //opensimulator.org/
* See CONTRIBUTORS . TXT for a full list of copyright holders .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
2008-12-19 17:57:03 +00:00
* * Redistributions in binary form must reproduce the above copyrightD
2008-03-18 05:16:43 +00:00
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ` ` AS IS ' ' AND ANY
* EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
2007-07-16 15:40:11 +00:00
using System ;
using System.Collections.Generic ;
2007-12-27 21:41:48 +00:00
using System.Drawing ;
using System.Drawing.Imaging ;
2008-08-15 07:20:38 +00:00
using System.IO ;
2009-02-12 09:53:12 +00:00
using System.Text ;
2007-07-16 15:40:11 +00:00
using System.Threading ;
using System.Timers ;
2009-02-12 09:53:12 +00:00
using System.Xml ;
using Nini.Config ;
2008-09-06 07:52:41 +00:00
using OpenMetaverse ;
using OpenMetaverse.Imaging ;
2007-07-16 15:40:11 +00:00
using OpenSim.Framework ;
2009-05-11 21:04:27 +00:00
using OpenSim.Services.Interfaces ;
2007-07-16 15:40:11 +00:00
using OpenSim.Framework.Communications ;
2007-09-24 05:15:13 +00:00
using OpenSim.Framework.Communications.Cache ;
2009-04-14 19:35:35 +00:00
using OpenSim.Framework.Communications.Clients ;
2009-02-12 09:53:12 +00:00
using OpenSim.Framework.Console ;
2009-02-06 16:55:34 +00:00
using OpenSim.Region.Framework.Interfaces ;
using OpenSim.Region.Framework.Scenes.Scripting ;
2009-05-08 18:05:54 +00:00
using OpenSim.Region.Framework.Scenes.Serialization ;
2007-09-19 00:30:55 +00:00
using OpenSim.Region.Physics.Manager ;
2009-02-12 09:53:12 +00:00
using Timer = System . Timers . Timer ;
2008-10-04 18:46:34 +00:00
using TPFlags = OpenSim . Framework . Constants . TeleportFlags ;
2007-07-16 18:45:19 +00:00
2009-02-06 16:55:34 +00:00
namespace OpenSim.Region.Framework.Scenes
2007-07-16 15:40:11 +00:00
{
2007-11-03 19:14:22 +00:00
public delegate bool FilterAvatarList ( ScenePresence avatar ) ;
2007-08-10 17:22:54 +00:00
public partial class Scene : SceneBase
2007-07-16 15:40:11 +00:00
{
2008-05-01 16:35:00 +00:00
public delegate void SynchronizeSceneHandler ( Scene scene ) ;
2008-05-01 18:04:42 +00:00
public SynchronizeSceneHandler SynchronizeScene = null ;
2009-04-15 04:07:41 +00:00
/* Used by the loadbalancer plugin on GForge */
protected int m_splitRegionID = 0 ;
public int SplitRegionID
{
get { return m_splitRegionID ; }
set { m_splitRegionID = value ; }
}
2007-11-27 13:46:52 +00:00
2008-11-15 17:52:00 +00:00
private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L ;
private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L ;
2008-05-01 18:04:42 +00:00
#region Fields
2007-12-12 06:58:55 +00:00
2008-05-01 18:04:42 +00:00
protected Timer m_restartWaitTimer = new Timer ( ) ;
2007-11-03 19:14:22 +00:00
2009-02-23 06:55:42 +00:00
protected Thread m_updateEntitiesThread ;
2009-01-03 03:30:03 +00:00
public SimStatsReporter StatsReporter ;
2008-05-01 18:04:42 +00:00
protected List < RegionInfo > m_regionRestartNotifyList = new List < RegionInfo > ( ) ;
protected List < RegionInfo > m_neighbours = new List < RegionInfo > ( ) ;
2008-11-12 20:16:46 +00:00
/// <value>
/// The scene graph for this scene
/// </value>
/// TODO: Possibly stop other classes being able to manipulate this directly.
2009-02-20 17:18:07 +00:00
private SceneGraph m_sceneGraph ;
2007-09-19 00:30:55 +00:00
2008-06-17 17:23:00 +00:00
/// <summary>
/// Are we applying physics to any of the prims in this scene?
/// </summary>
2008-05-01 18:04:42 +00:00
public bool m_physicalPrim ;
2009-03-11 09:31:02 +00:00
public float m_maxNonphys = 256 ;
2008-07-23 13:24:25 +00:00
public float m_maxPhys = 10 ;
2008-11-11 03:10:28 +00:00
public bool m_clampPrimSize = false ;
2008-11-29 14:26:42 +00:00
public bool m_trustBinaries = false ;
public bool m_allowScriptCrossings = false ;
2009-04-06 18:02:12 +00:00
public bool m_useFlySlow = false ;
public bool m_usePreJump = false ;
2008-05-01 18:04:42 +00:00
public bool m_seeIntoRegionFromNeighbor ;
2009-05-11 07:46:12 +00:00
// TODO: need to figure out how allow client agents but deny
// root agents when ACL denies access to root agent
public bool m_strictAccessControl = true ;
2008-05-01 18:04:42 +00:00
public int MaxUndoCount = 5 ;
private int m_RestartTimerCounter ;
private readonly Timer m_restartTimer = new Timer ( 15000 ) ; // Wait before firing
private int m_incrementsof15seconds = 0 ;
2008-05-21 21:47:03 +00:00
private volatile bool m_backingup = false ;
2008-05-01 18:04:42 +00:00
2008-10-18 05:51:36 +00:00
private Dictionary < UUID , ReturnInfo > m_returns = new Dictionary < UUID , ReturnInfo > ( ) ;
2008-09-25 14:57:40 +00:00
protected string m_simulatorVersion = "OpenSimulator Server" ;
2008-05-01 18:04:42 +00:00
protected ModuleLoader m_moduleLoader ;
protected StorageManager m_storageManager ;
2008-05-01 16:35:00 +00:00
protected AgentCircuitManager m_authenticateHandler ;
2008-05-01 18:04:42 +00:00
public CommunicationsManager CommsManager ;
2008-05-22 22:31:42 +00:00
2008-05-01 18:04:42 +00:00
protected SceneCommunicationService m_sceneGridService ;
2007-07-16 15:40:11 +00:00
2008-06-25 19:33:19 +00:00
public SceneCommunicationService SceneGridService
{
get { return m_sceneGridService ; }
}
2008-05-01 18:04:42 +00:00
public IXfer XferManager ;
2009-05-11 21:04:27 +00:00
protected IAssetService m_AssetService = null ;
public IAssetService AssetService
{
get
{
if ( m_AssetService = = null )
m_AssetService = RequestModuleInterface < IAssetService > ( ) ;
return m_AssetService ;
}
}
2008-05-01 18:04:42 +00:00
protected IXMLRPC m_xmlrpcModule ;
protected IWorldComm m_worldCommModule ;
protected IAvatarFactory m_AvatarFactory ;
2008-05-14 23:15:25 +00:00
protected IConfigSource m_config ;
2008-12-19 19:07:11 +00:00
protected IRegionSerialiserModule m_serialiser ;
2008-12-29 22:22:05 +00:00
protected IInterregionCommsOut m_interregionCommsOut ;
protected IInterregionCommsIn m_interregionCommsIn ;
2009-01-07 20:29:09 +00:00
protected IDialogModule m_dialogModule ;
2009-02-06 16:55:34 +00:00
protected ICapabilitiesModule m_capsModule ;
public ICapabilitiesModule CapsModule
{
get { return m_capsModule ; }
}
2009-05-02 17:31:49 +00:00
2009-05-04 01:57:18 +00:00
protected override IConfigSource GetConfig ( )
2009-05-02 17:31:49 +00:00
{
2009-05-04 01:57:18 +00:00
return m_config ;
2009-05-02 17:31:49 +00:00
}
2009-02-04 00:01:36 +00:00
2007-09-24 15:46:03 +00:00
// Central Update Loop
protected int m_fps = 10 ;
2008-05-01 18:04:42 +00:00
protected int m_frame = 0 ;
protected float m_timespan = 0.089f ;
2007-09-24 15:46:03 +00:00
protected DateTime m_lastupdate = DateTime . Now ;
2008-05-01 18:04:42 +00:00
private int m_update_physics = 1 ;
private int m_update_entitymovement = 1 ;
2008-03-02 09:31:39 +00:00
private int m_update_entities = 1 ; // Run through all objects checking for updates
private int m_update_entitiesquick = 200 ; // Run through objects that have scheduled updates checking for updates
2008-05-01 16:35:00 +00:00
private int m_update_presences = 1 ; // Update scene presence movements
2008-05-01 18:04:42 +00:00
private int m_update_events = 1 ;
private int m_update_backup = 200 ;
2008-05-01 16:35:00 +00:00
private int m_update_terrain = 50 ;
2008-05-01 18:04:42 +00:00
private int m_update_land = 1 ;
2008-05-16 01:22:11 +00:00
2008-05-01 18:04:42 +00:00
private int frameMS = 0 ;
private int physicsMS2 = 0 ;
private int physicsMS = 0 ;
private int otherMS = 0 ;
private bool m_physics_enabled = true ;
private bool m_scripts_enabled = true ;
2008-09-21 21:47:00 +00:00
private string m_defaultScriptEngine ;
2008-10-10 01:10:33 +00:00
private int m_LastLogin = 0 ;
2008-10-11 11:43:42 +00:00
private Thread HeartbeatThread ;
private volatile bool shuttingdown = false ;
2008-05-01 18:04:42 +00:00
2009-04-15 20:16:18 +00:00
private int m_lastUpdate = Environment . TickCount ;
2009-05-01 19:33:18 +00:00
private int m_maxPrimsPerFrame = 200 ;
2009-04-15 20:16:18 +00:00
2008-11-10 18:10:00 +00:00
private object m_deleting_scene_object = new object ( ) ;
2008-11-10 12:42:22 +00:00
2008-11-15 17:52:00 +00:00
// the minimum time that must elapse before a changed object will be considered for persisted
public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L ;
// the maximum time that must elapse before a changed object will be considered for persisted
public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L ;
2007-11-03 19:14:22 +00:00
# endregion
2007-09-24 15:46:03 +00:00
2007-07-16 15:40:11 +00:00
#region Properties
2007-07-17 17:47:23 +00:00
2007-08-09 12:59:42 +00:00
public AgentCircuitManager AuthenticateHandler
{
2007-11-04 13:48:15 +00:00
get { return m_authenticateHandler ; }
2007-08-09 12:59:42 +00:00
}
2007-09-19 00:30:55 +00:00
2009-01-22 01:50:00 +00:00
public SceneGraph SceneContents
{
get { return m_sceneGraph ; }
}
2007-12-10 21:12:38 +00:00
// an instance to the physics plugin's Scene object.
2007-11-29 15:27:57 +00:00
public PhysicsScene PhysicsScene
2007-11-03 19:14:22 +00:00
{
2008-11-20 16:58:40 +00:00
get { return m_sceneGraph . PhysicsScene ; }
2008-12-26 12:58:02 +00:00
set
{
// If we're not doing the initial set
// Then we've got to remove the previous
// event handler
if ( PhysicsScene ! = null & & PhysicsScene . SupportsNINJAJoints )
{
PhysicsScene . OnJointMoved - = jointMoved ;
PhysicsScene . OnJointDeactivated - = jointDeactivated ;
PhysicsScene . OnJointErrorMessage - = jointErrorMessage ;
}
m_sceneGraph . PhysicsScene = value ;
if ( PhysicsScene ! = null & & m_sceneGraph . PhysicsScene . SupportsNINJAJoints )
{
// register event handlers to respond to joint movement/deactivation
PhysicsScene . OnJointMoved + = jointMoved ;
PhysicsScene . OnJointDeactivated + = jointDeactivated ;
PhysicsScene . OnJointErrorMessage + = jointErrorMessage ;
}
}
2007-09-20 23:28:08 +00:00
}
2007-12-27 21:41:48 +00:00
2007-12-10 21:12:38 +00:00
// This gets locked so things stay thread safe.
2007-11-04 22:22:53 +00:00
public object SyncRoot
{
2008-11-12 20:16:46 +00:00
get { return m_sceneGraph . m_syncRoot ; }
2007-11-04 22:22:53 +00:00
}
2009-05-01 19:33:18 +00:00
public int MaxPrimsPerFrame
{
get { return m_maxPrimsPerFrame ; }
set { m_maxPrimsPerFrame = value ; }
}
2008-10-16 13:17:31 +00:00
/// <summary>
/// This is for llGetRegionFPS
/// </summary>
public float SimulatorFPS
{
2009-01-03 03:30:03 +00:00
get { return StatsReporter . getLastReportedSimFPS ( ) ; }
2008-10-16 13:17:31 +00:00
}
2008-09-21 21:47:00 +00:00
public string DefaultScriptEngine
{
get { return m_defaultScriptEngine ; }
}
2007-12-10 21:12:38 +00:00
// Reference to all of the agents in the scene (root and child)
2008-09-06 07:52:41 +00:00
protected Dictionary < UUID , ScenePresence > m_scenePresences
2007-08-19 13:35:20 +00:00
{
2008-11-12 20:16:46 +00:00
get { return m_sceneGraph . ScenePresences ; }
set { m_sceneGraph . ScenePresences = value ; }
2007-11-03 19:14:22 +00:00
}
2008-11-24 14:45:05 +00:00
public EntityManager Entities
{
get { return m_sceneGraph . Entities ; }
}
2008-05-16 01:22:11 +00:00
2008-09-06 07:52:41 +00:00
public Dictionary < UUID , ScenePresence > m_restorePresences
2008-03-04 05:31:54 +00:00
{
2008-11-12 20:16:46 +00:00
get { return m_sceneGraph . RestorePresences ; }
set { m_sceneGraph . RestorePresences = value ; }
2008-03-04 05:31:54 +00:00
}
2008-03-18 15:30:38 +00:00
2008-05-01 18:04:42 +00:00
public int objectCapacity = 45000 ;
2009-02-04 00:01:36 +00:00
2007-07-16 15:40:11 +00:00
# endregion
#region Constructors
2007-07-17 17:47:23 +00:00
2008-05-05 20:14:53 +00:00
public Scene ( RegionInfo regInfo , AgentCircuitManager authen ,
2007-12-27 21:41:48 +00:00
CommunicationsManager commsMan , SceneCommunicationService sceneGridService ,
2009-02-16 19:15:16 +00:00
StorageManager storeManager ,
2008-05-25 23:27:38 +00:00
ModuleLoader moduleLoader , bool dumpAssetsToFile , bool physicalPrim ,
2008-05-22 00:18:33 +00:00
bool SeeIntoRegionFromNeighbor , IConfigSource config , string simulatorVersion )
2007-07-16 15:40:11 +00:00
{
2008-05-14 23:15:25 +00:00
m_config = config ;
2008-10-14 09:40:05 +00:00
2008-11-29 13:17:21 +00:00
Random random = new Random ( ) ;
m_lastAllocatedLocalId = ( uint ) ( random . NextDouble ( ) * ( double ) ( uint . MaxValue / 2 ) ) + ( uint ) ( uint . MaxValue / 4 ) ;
2007-08-28 14:21:17 +00:00
m_moduleLoader = moduleLoader ;
2007-11-04 13:48:15 +00:00
m_authenticateHandler = authen ;
CommsManager = commsMan ;
2007-11-03 19:14:22 +00:00
m_sceneGridService = sceneGridService ;
2007-11-04 13:48:15 +00:00
m_storageManager = storeManager ;
2007-07-16 15:40:11 +00:00
m_regInfo = regInfo ;
m_regionHandle = m_regInfo . RegionHandle ;
m_regionName = m_regInfo . RegionName ;
2007-07-17 17:47:23 +00:00
m_datastore = m_regInfo . DataStore ;
2007-12-12 17:15:37 +00:00
2007-11-11 00:08:18 +00:00
m_physicalPrim = physicalPrim ;
2008-02-11 05:19:54 +00:00
m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor ;
2007-07-16 15:40:11 +00:00
2007-12-17 03:49:13 +00:00
m_eventManager = new EventManager ( ) ;
2008-11-21 22:14:57 +00:00
m_permissions = new ScenePermissions ( this ) ;
2009-02-04 00:01:36 +00:00
2008-10-14 09:40:05 +00:00
m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter ( this ) ;
2008-11-11 20:33:29 +00:00
m_asyncSceneObjectDeleter . Enabled = true ;
2007-12-17 03:49:13 +00:00
2008-06-30 14:09:19 +00:00
// Load region settings
m_regInfo . RegionSettings = m_storageManager . DataStore . LoadRegionSettings ( m_regInfo . RegionID ) ;
2008-07-23 13:24:25 +00:00
if ( m_storageManager . EstateDataStore ! = null )
2008-07-18 02:40:47 +00:00
m_regInfo . EstateSettings = m_storageManager . EstateDataStore . LoadEstateSettings ( m_regInfo . RegionID ) ;
2007-12-17 03:49:13 +00:00
//Bind Storage Manager functions to some land manager functions for this scene
2007-12-27 21:41:48 +00:00
EventManager . OnLandObjectAdded + =
2008-05-01 18:04:42 +00:00
new EventManager . LandObjectAdded ( m_storageManager . DataStore . StoreLandObject ) ;
2007-12-27 21:41:48 +00:00
EventManager . OnLandObjectRemoved + =
2008-05-01 18:04:42 +00:00
new EventManager . LandObjectRemoved ( m_storageManager . DataStore . RemoveLandObject ) ;
2007-12-27 21:41:48 +00:00
2008-11-12 20:16:46 +00:00
m_sceneGraph = new SceneGraph ( this , m_regInfo ) ;
2007-12-12 17:15:37 +00:00
2008-11-12 20:16:46 +00:00
// If the scene graph has an Unrecoverable error, restart this sim.
2007-11-28 06:18:07 +00:00
// Currently the only thing that causes it to happen is two kinds of specific
// Physics based crashes.
/ /
// Out of memory
// Operating system has killed the plugin
2008-11-12 20:16:46 +00:00
m_sceneGraph . UnRecoverableError + = RestartNow ;
2007-11-28 06:18:07 +00:00
2007-11-18 11:11:44 +00:00
RegisterDefaultSceneEvents ( ) ;
2007-08-15 14:10:26 +00:00
2009-01-21 21:14:17 +00:00
DumpAssetsToFile = dumpAssetsToFile ;
2007-12-12 06:58:55 +00:00
2008-07-14 01:27:47 +00:00
m_scripts_enabled = ! RegionInfo . RegionSettings . DisableScripts ;
m_physics_enabled = ! RegionInfo . RegionSettings . DisablePhysics ;
2008-02-06 09:38:14 +00:00
2009-01-03 03:30:03 +00:00
StatsReporter = new SimStatsReporter ( this ) ;
StatsReporter . OnSendStatsResult + = SendSimStatsPackets ;
2009-01-06 00:07:24 +00:00
StatsReporter . OnStatsIncorrect + = m_sceneGraph . RecalculateStats ;
2008-04-10 09:36:55 +00:00
2009-01-03 03:30:03 +00:00
StatsReporter . SetObjectCapacity ( objectCapacity ) ;
2008-04-10 09:36:55 +00:00
2008-05-22 00:32:04 +00:00
m_simulatorVersion = simulatorVersion
2008-11-11 17:02:46 +00:00
+ " (OS " + Util . GetOperatingSystemInformation ( ) + ")"
2008-05-25 23:27:38 +00:00
+ " ChilTasks:" + m_seeIntoRegionFromNeighbor . ToString ( )
2008-05-22 00:18:33 +00:00
+ " PhysPrim:" + m_physicalPrim . ToString ( ) ;
2008-07-20 15:19:26 +00:00
2008-07-23 13:24:25 +00:00
try
{
2009-01-02 17:41:12 +00:00
// Region config overrides global config
/ /
2008-07-23 13:24:25 +00:00
IConfig startupConfig = m_config . Configs [ "Startup" ] ;
2009-04-06 18:02:12 +00:00
//Animation states
m_useFlySlow = startupConfig . GetBoolean ( "enableflyslow" , false ) ;
// TODO: Change default to true once the feature is supported
m_usePreJump = startupConfig . GetBoolean ( "enableprejump" , false ) ;
2009-03-11 09:31:02 +00:00
m_maxNonphys = startupConfig . GetFloat ( "NonPhysicalPrimMax" , m_maxNonphys ) ;
2009-01-02 17:41:12 +00:00
if ( RegionInfo . NonphysPrimMax > 0 )
m_maxNonphys = RegionInfo . NonphysPrimMax ;
2009-03-11 09:31:02 +00:00
m_maxPhys = startupConfig . GetFloat ( "PhysicalPrimMax" , m_maxPhys ) ;
2009-01-02 17:41:12 +00:00
if ( RegionInfo . PhysPrimMax > 0 )
m_maxPhys = RegionInfo . PhysPrimMax ;
// Here, if clamping is requested in either global or
// local config, it will be used
/ /
2009-03-11 09:31:02 +00:00
m_clampPrimSize = startupConfig . GetBoolean ( "ClampPrimSize" , m_clampPrimSize ) ;
2009-01-02 17:41:12 +00:00
if ( RegionInfo . ClampPrimSize )
m_clampPrimSize = true ;
2009-03-11 09:31:02 +00:00
m_trustBinaries = startupConfig . GetBoolean ( "TrustBinaries" , m_trustBinaries ) ;
m_allowScriptCrossings = startupConfig . GetBoolean ( "AllowScriptCrossing" , m_allowScriptCrossings ) ;
2008-11-15 17:52:00 +00:00
m_dontPersistBefore =
2008-11-15 18:00:34 +00:00
startupConfig . GetLong ( "MinimumTimeBeforePersistenceConsidered" , DEFAULT_MIN_TIME_FOR_PERSISTENCE ) ;
2008-11-15 17:52:00 +00:00
m_dontPersistBefore * = 10000000 ;
m_persistAfter =
2008-11-15 18:00:34 +00:00
startupConfig . GetLong ( "MaximumTimeBeforePersistenceConsidered" , DEFAULT_MAX_TIME_FOR_PERSISTENCE ) ;
2008-11-15 17:52:00 +00:00
m_persistAfter * = 10000000 ;
2008-09-21 21:47:00 +00:00
m_defaultScriptEngine = startupConfig . GetString ( "DefaultScriptEngine" , "DotNetEngine" ) ;
2009-05-01 19:33:18 +00:00
m_maxPrimsPerFrame = startupConfig . GetInt ( "MaxPrimsPerFrame" , 200 ) ;
2009-05-02 13:16:41 +00:00
IConfig packetConfig = m_config . Configs [ "PacketPool" ] ;
if ( packetConfig ! = null )
{
PacketPool . Instance . RecyclePackets = packetConfig . GetBoolean ( "RecyclePackets" , true ) ;
PacketPool . Instance . RecycleDataBlocks = packetConfig . GetBoolean ( "RecycleDataBlocks" , true ) ;
}
2009-05-11 07:46:12 +00:00
m_strictAccessControl = startupConfig . GetBoolean ( "StrictAccessControl" , m_strictAccessControl ) ;
2008-07-23 13:24:25 +00:00
}
2008-11-06 20:38:04 +00:00
catch
2008-07-23 13:24:25 +00:00
{
2008-11-06 20:38:04 +00:00
m_log . Warn ( "[SCENE]: Failed to load StartupConfig" ) ;
2008-07-23 13:24:25 +00:00
}
2007-07-16 15:40:11 +00:00
}
2007-07-17 17:47:23 +00:00
2009-01-11 18:24:16 +00:00
/// <summary>
/// Mock constructor for scene group persistency unit tests.
/// SceneObjectGroup RegionId property is delegated to Scene.
/// </summary>
/// <param name="regInfo"></param>
public Scene ( RegionInfo regInfo )
{
m_regInfo = regInfo ;
m_eventManager = new EventManager ( ) ;
}
2007-07-16 15:40:11 +00:00
# endregion
2007-11-03 19:14:22 +00:00
#region Startup / Close Methods
2007-11-18 11:11:44 +00:00
2008-11-15 17:52:00 +00:00
public bool ShuttingDown
{
get { return shuttingdown ; }
}
2009-02-20 17:18:07 +00:00
/// <value>
/// The scene graph for this scene
/// </value>
/// TODO: Possibly stop other classes being able to manipulate this directly.
public SceneGraph SceneGraph
{
get { return m_sceneGraph ; }
}
2007-11-18 11:11:44 +00:00
protected virtual void RegisterDefaultSceneEvents ( )
{
2009-01-07 20:09:37 +00:00
IDialogModule dm = RequestModuleInterface < IDialogModule > ( ) ;
2009-02-04 00:01:36 +00:00
2009-01-07 20:09:37 +00:00
if ( dm ! = null )
m_eventManager . OnPermissionError + = dm . SendAlertToUser ;
2007-11-18 11:11:44 +00:00
}
2008-02-09 07:53:01 +00:00
public override string GetSimulatorVersion ( )
{
return m_simulatorVersion ;
}
2008-10-14 09:40:05 +00:00
/// <summary>
/// Another region is up. Gets called from Grid Comms:
/// (OGS1 -> LocalBackEnd -> RegionListened -> SceneCommunicationService)
/// We have to tell all our ScenePresences about it, and add it to the
/// neighbor list.
///
/// We only add it to the neighbor list if it's within 1 region from here.
/// Agents may have draw distance values that cross two regions though, so
/// we add it to the notify list regardless of distance. We'll check
/// the agent's draw distance before notifying them though.
/// </summary>
/// <param name="otherRegion">RegionInfo handle for the new region.</param>
/// <returns>True after all operations complete, throws exceptions otherwise.</returns>
2007-11-26 05:02:18 +00:00
public override bool OtherRegionUp ( RegionInfo otherRegion )
2007-11-25 04:52:14 +00:00
{
2009-02-14 16:37:55 +00:00
m_log . InfoFormat ( "[SCENE]: Region {0} up in coords {1}-{2}" , otherRegion . RegionName , otherRegion . RegionLocX , otherRegion . RegionLocY ) ;
2007-11-27 13:46:52 +00:00
if ( RegionInfo . RegionHandle ! = otherRegion . RegionHandle )
2007-11-25 04:52:14 +00:00
{
2007-12-27 21:41:48 +00:00
for ( int i = 0 ; i < m_neighbours . Count ; i + + )
{
2008-05-16 01:22:11 +00:00
// The purpose of this loop is to re-update the known neighbors
2007-12-27 21:41:48 +00:00
// when another region comes up on top of another one.
2008-05-16 01:22:11 +00:00
// The latest region in that location ends up in the
2007-12-27 21:41:48 +00:00
// 'known neighbors list'
// Additionally, the commFailTF property gets reset to false.
if ( m_neighbours [ i ] . RegionHandle = = otherRegion . RegionHandle )
2007-12-10 00:46:56 +00:00
{
2007-12-27 21:41:48 +00:00
lock ( m_neighbours )
2007-12-10 00:46:56 +00:00
{
2007-12-27 21:41:48 +00:00
m_neighbours [ i ] = otherRegion ;
2009-02-14 17:17:48 +00:00
2007-12-10 00:46:56 +00:00
}
}
2007-12-27 21:41:48 +00:00
}
2007-12-10 00:46:56 +00:00
2007-12-27 21:41:48 +00:00
// If the value isn't in the neighbours, add it.
2008-05-16 01:22:11 +00:00
// If the RegionInfo isn't exact but is for the same XY World location,
2007-12-27 21:41:48 +00:00
// then the above loop will fix that.
2007-12-10 00:46:56 +00:00
2008-05-13 06:05:45 +00:00
if ( ! ( CheckNeighborRegion ( otherRegion ) ) )
2007-12-27 21:41:48 +00:00
{
lock ( m_neighbours )
2007-12-10 00:46:56 +00:00
{
2007-12-27 21:41:48 +00:00
m_neighbours . Add ( otherRegion ) ;
2008-05-13 06:05:45 +00:00
//m_log.Info("[UP]: " + otherRegion.RegionHandle.ToString());
2007-12-10 00:46:56 +00:00
}
2007-12-27 21:41:48 +00:00
}
2008-01-20 05:51:38 +00:00
2008-10-14 09:40:05 +00:00
// If these are cast to INT because long + negative values + abs returns invalid data
2008-05-01 18:04:42 +00:00
int resultX = Math . Abs ( ( int ) otherRegion . RegionLocX - ( int ) RegionInfo . RegionLocX ) ;
int resultY = Math . Abs ( ( int ) otherRegion . RegionLocY - ( int ) RegionInfo . RegionLocY ) ;
2008-08-28 14:41:54 +00:00
if ( resultX < = 1 & & resultY < = 1 )
2007-12-11 21:43:17 +00:00
{
2007-12-12 00:38:57 +00:00
try
2007-11-29 02:07:19 +00:00
{
2007-12-12 00:38:57 +00:00
ForEachScenePresence ( delegate ( ScenePresence agent )
2008-05-01 18:04:42 +00:00
{
// If agent is a root agent.
if ( ! agent . IsChildAgent )
2007-12-27 21:41:48 +00:00
{
2008-05-01 18:04:42 +00:00
//agent.ControllingClient.new
//this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
2009-02-14 17:17:48 +00:00
List < ulong > old = new List < ulong > ( ) ;
old . Add ( otherRegion . RegionHandle ) ;
agent . DropOldNeighbours ( old ) ;
2008-05-01 18:04:42 +00:00
InformClientOfNeighbor ( agent , otherRegion ) ;
2007-12-27 21:41:48 +00:00
}
2008-05-01 18:04:42 +00:00
}
2007-12-27 21:41:48 +00:00
) ;
2007-12-12 00:38:57 +00:00
}
2007-12-27 21:41:48 +00:00
catch ( NullReferenceException )
2007-12-12 00:38:57 +00:00
{
// This means that we're not booted up completely yet.
// This shouldn't happen too often anymore.
2008-02-05 19:44:27 +00:00
m_log . Error ( "[SCENE]: Couldn't inform client of regionup because we got a null reference exception" ) ;
2007-11-29 02:07:19 +00:00
}
}
else
{
2008-05-01 18:04:42 +00:00
m_log . Info ( "[INTERGRID]: Got notice about far away Region: " + otherRegion . RegionName . ToString ( ) +
" at (" + otherRegion . RegionLocX . ToString ( ) + ", " +
otherRegion . RegionLocY . ToString ( ) + ")" ) ;
2007-11-25 04:52:14 +00:00
}
2007-12-08 17:25:34 +00:00
}
2007-11-26 05:02:18 +00:00
return true ;
2007-11-25 04:52:14 +00:00
}
2007-11-28 12:36:09 +00:00
2008-05-13 06:05:45 +00:00
public void AddNeighborRegion ( RegionInfo region )
{
lock ( m_neighbours )
{
if ( ! CheckNeighborRegion ( region ) )
{
m_neighbours . Add ( region ) ;
}
}
}
2007-12-10 21:12:38 +00:00
2008-05-13 06:05:45 +00:00
public bool CheckNeighborRegion ( RegionInfo region )
{
bool found = false ;
lock ( m_neighbours )
{
foreach ( RegionInfo reg in m_neighbours )
{
if ( reg . RegionHandle = = region . RegionHandle )
{
found = true ;
break ;
}
}
}
return found ;
}
2008-06-18 03:50:39 +00:00
2009-02-14 16:37:55 +00:00
// Alias IncomingHelloNeighbour OtherRegionUp, for now
public bool IncomingHelloNeighbour ( RegionInfo neighbour )
{
return OtherRegionUp ( neighbour ) ;
}
2008-10-14 09:40:05 +00:00
/// <summary>
/// Given float seconds, this will restart the region.
/// </summary>
/// <param name="seconds">float indicating duration before restart.</param>
2007-11-25 04:52:14 +00:00
public virtual void Restart ( float seconds )
{
2007-12-10 21:12:38 +00:00
// notifications are done in 15 second increments
// so .. if the number of seconds is less then 15 seconds, it's not really a restart request
// It's a 'Cancel restart' request.
// RestartNow() does immediate restarting.
2007-11-27 13:46:52 +00:00
if ( seconds < 15 )
2007-11-25 04:52:14 +00:00
{
2007-11-29 15:27:57 +00:00
m_restartTimer . Stop ( ) ;
2009-01-07 20:29:09 +00:00
m_dialogModule . SendGeneralAlert ( "Restart Aborted" ) ;
2007-11-25 04:52:14 +00:00
}
else
{
2007-12-10 21:12:38 +00:00
// Now we figure out what to set the timer to that does the notifications and calls, RestartNow()
2007-11-29 15:27:57 +00:00
m_restartTimer . Interval = 15000 ;
2008-05-01 18:04:42 +00:00
m_incrementsof15seconds = ( int ) seconds / 15 ;
2007-11-25 04:52:14 +00:00
m_RestartTimerCounter = 0 ;
2007-11-29 15:27:57 +00:00
m_restartTimer . AutoReset = true ;
2009-02-04 00:01:36 +00:00
m_restartTimer . Elapsed + = new ElapsedEventHandler ( RestartTimer_Elapsed ) ;
2009-01-08 18:50:46 +00:00
m_log . Info ( "[REGION]: Restarting Region in " + ( seconds / 60 ) + " minutes" ) ;
2007-11-29 15:27:57 +00:00
m_restartTimer . Start ( ) ;
2009-01-08 18:50:46 +00:00
m_dialogModule . SendNotificationToUsersInRegion (
UUID . Random ( ) , String . Empty , RegionInfo . RegionName + ": Restarting in 2 Minutes" ) ;
2007-11-25 04:52:14 +00:00
}
}
2007-11-28 12:36:09 +00:00
2008-05-16 01:22:11 +00:00
// The Restart timer has occured.
// We have to figure out if this is a notification or if the number of seconds specified in Restart
2007-12-10 21:12:38 +00:00
// have elapsed.
// If they have elapsed, call RestartNow()
2007-11-29 15:27:57 +00:00
public void RestartTimer_Elapsed ( object sender , ElapsedEventArgs e )
2007-11-25 04:52:14 +00:00
{
m_RestartTimerCounter + + ;
if ( m_RestartTimerCounter < = m_incrementsof15seconds )
{
if ( m_RestartTimerCounter = = 4 | | m_RestartTimerCounter = = 6 | | m_RestartTimerCounter = = 7 )
2009-01-08 18:50:46 +00:00
m_dialogModule . SendNotificationToUsersInRegion (
2009-02-04 00:01:36 +00:00
UUID . Random ( ) ,
String . Empty ,
2009-01-08 18:50:46 +00:00
RegionInfo . RegionName + ": Restarting in " + ( ( 8 - m_RestartTimerCounter ) * 15 ) + " seconds" ) ;
2007-11-25 04:52:14 +00:00
}
else
{
2007-11-29 15:27:57 +00:00
m_restartTimer . Stop ( ) ;
m_restartTimer . AutoReset = false ;
RestartNow ( ) ;
2007-11-25 04:52:14 +00:00
}
}
2007-11-28 12:36:09 +00:00
2007-12-10 21:12:38 +00:00
// This causes the region to restart immediatley.
2007-11-29 15:27:57 +00:00
public void RestartNow ( )
2007-11-28 06:18:07 +00:00
{
2008-02-11 22:54:51 +00:00
if ( PhysicsScene ! = null )
{
PhysicsScene . Dispose ( ) ;
}
2008-02-05 19:44:27 +00:00
m_log . Error ( "[REGION]: Closing" ) ;
2007-11-28 06:18:07 +00:00
Close ( ) ;
2008-02-05 19:44:27 +00:00
m_log . Error ( "[REGION]: Firing Region Restart Message" ) ;
2007-11-28 06:18:07 +00:00
base . Restart ( 0 ) ;
}
2007-11-28 12:36:09 +00:00
2007-12-10 21:12:38 +00:00
// This is a helper function that notifies root agents in this region that a new sim near them has come up
2008-05-16 01:22:11 +00:00
// This is in the form of a timer because when an instance of OpenSim.exe is started,
2007-12-10 21:12:38 +00:00
// Even though the sims initialize, they don't listen until 'all of the sims are initialized'
// If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
// subsequently the agent will never see the region come back online.
2007-11-29 15:27:57 +00:00
public void RestartNotifyWaitElapsed ( object sender , ElapsedEventArgs e )
2007-12-12 17:15:37 +00:00
{
2007-11-27 13:46:52 +00:00
m_restartWaitTimer . Stop ( ) ;
2007-12-11 21:43:17 +00:00
lock ( m_regionRestartNotifyList )
2007-11-27 13:46:52 +00:00
{
2007-12-11 21:43:17 +00:00
foreach ( RegionInfo region in m_regionRestartNotifyList )
2007-11-29 07:25:58 +00:00
{
2007-12-11 21:43:17 +00:00
try
2007-11-29 07:25:58 +00:00
{
2007-12-11 21:43:17 +00:00
ForEachScenePresence ( delegate ( ScenePresence agent )
2008-05-01 18:04:42 +00:00
{
// If agent is a root agent.
if ( ! agent . IsChildAgent )
2007-12-27 21:41:48 +00:00
{
2008-05-01 18:04:42 +00:00
//agent.ControllingClient.new
//this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
InformClientOfNeighbor ( agent , region ) ;
2007-12-27 21:41:48 +00:00
}
2008-05-01 18:04:42 +00:00
}
2007-12-27 21:41:48 +00:00
) ;
2007-12-11 21:43:17 +00:00
}
2007-12-27 21:41:48 +00:00
catch ( NullReferenceException )
2007-12-11 21:43:17 +00:00
{
// This means that we're not booted up completely yet.
// This shouldn't happen too often anymore.
}
2007-11-29 07:25:58 +00:00
}
2007-12-10 21:12:38 +00:00
2007-12-11 21:43:17 +00:00
// Reset list to nothing.
m_regionRestartNotifyList . Clear ( ) ;
}
2007-11-27 13:46:52 +00:00
}
2007-11-28 12:36:09 +00:00
2008-02-02 17:43:21 +00:00
public void SetSceneCoreDebug ( bool ScriptEngine , bool CollisionEvents , bool PhysicsEngine )
{
if ( m_scripts_enabled ! = ! ScriptEngine )
{
// Tedd! Here's the method to disable the scripting engine!
2008-02-06 09:38:14 +00:00
if ( ScriptEngine )
{
m_log . Info ( "Stopping all Scripts in Scene" ) ;
2008-11-24 15:14:33 +00:00
foreach ( EntityBase ent in Entities )
2008-02-06 09:38:14 +00:00
{
2008-11-24 15:14:33 +00:00
if ( ent is SceneObjectGroup )
2008-02-06 09:38:14 +00:00
{
2008-11-24 15:14:33 +00:00
( ( SceneObjectGroup ) ent ) . RemoveScriptInstances ( ) ;
2008-02-06 09:38:14 +00:00
}
}
}
else
{
m_log . Info ( "Starting all Scripts in Scene" ) ;
lock ( Entities )
{
2008-11-24 14:45:05 +00:00
foreach ( EntityBase ent in Entities )
2008-02-06 09:38:14 +00:00
{
if ( ent is SceneObjectGroup )
{
2008-11-09 19:30:40 +00:00
( ( SceneObjectGroup ) ent ) . CreateScriptInstances ( 0 , false , DefaultScriptEngine , 0 ) ;
2008-02-06 09:38:14 +00:00
}
}
}
}
m_scripts_enabled = ! ScriptEngine ;
2008-02-05 19:44:27 +00:00
m_log . Info ( "[TOTEDD]: Here is the method to trigger disabling of the scripting engine" ) ;
2008-02-02 17:43:21 +00:00
}
2008-05-28 03:44:49 +00:00
2008-02-02 17:43:21 +00:00
if ( m_physics_enabled ! = ! PhysicsEngine )
{
m_physics_enabled = ! PhysicsEngine ;
}
}
2008-05-28 03:44:49 +00:00
2008-05-13 06:05:45 +00:00
public int GetInaccurateNeighborCount ( )
{
lock ( m_neighbours )
2008-08-28 14:41:54 +00:00
{
2008-05-13 06:05:45 +00:00
return m_neighbours . Count ;
2008-08-28 14:41:54 +00:00
}
2008-05-13 06:05:45 +00:00
}
2008-05-28 03:44:49 +00:00
2007-12-10 21:12:38 +00:00
// This is the method that shuts down the scene.
2007-11-03 19:14:22 +00:00
public override void Close ( )
2007-08-28 14:21:17 +00:00
{
2008-07-13 00:21:23 +00:00
m_log . InfoFormat ( "[SCENE]: Closing down the single simulator: {0}" , RegionInfo . RegionName ) ;
2008-08-18 00:39:10 +00:00
2007-12-10 21:12:38 +00:00
// Kick all ROOT agents with the message, 'The simulator is going down'
2007-11-13 12:23:05 +00:00
ForEachScenePresence ( delegate ( ScenePresence avatar )
2008-05-01 18:04:42 +00:00
{
2008-12-14 02:17:12 +00:00
if ( avatar . KnownChildRegionHandles . Contains ( RegionInfo . RegionHandle ) )
avatar . KnownChildRegionHandles . Remove ( RegionInfo . RegionHandle ) ;
2007-11-25 04:52:14 +00:00
2008-05-01 18:04:42 +00:00
if ( ! avatar . IsChildAgent )
avatar . ControllingClient . Kick ( "The simulator is going down." ) ;
2007-11-25 04:52:14 +00:00
2008-05-10 13:11:09 +00:00
avatar . ControllingClient . SendShutdownConnectionNotice ( ) ;
2008-05-01 18:04:42 +00:00
} ) ;
2007-12-10 21:12:38 +00:00
// Wait here, or the kick messages won't actually get to the agents before the scene terminates.
2007-11-25 04:52:14 +00:00
Thread . Sleep ( 500 ) ;
2007-12-10 21:12:38 +00:00
// Stop all client threads.
2007-12-27 21:41:48 +00:00
ForEachScenePresence ( delegate ( ScenePresence avatar ) { avatar . ControllingClient . Close ( true ) ; } ) ;
2009-02-04 00:01:36 +00:00
2007-12-10 21:12:38 +00:00
// Stop updating the scene objects and agents.
2008-10-11 11:43:42 +00:00
//m_heartbeatTimer.Close();
shuttingdown = true ;
2008-11-12 20:16:46 +00:00
2008-11-13 04:23:31 +00:00
m_log . Debug ( "[SCENE]: Persisting changed objects" ) ;
List < EntityBase > entities = GetEntities ( ) ;
foreach ( EntityBase entity in entities )
{
if ( ! entity . IsDeleted & & entity is SceneObjectGroup & & ( ( SceneObjectGroup ) entity ) . HasGroupChanged )
{
2009-02-04 16:00:39 +00:00
( ( SceneObjectGroup ) entity ) . ProcessBackup ( m_storageManager . DataStore , false ) ;
2008-11-13 04:23:31 +00:00
}
}
2008-11-12 20:16:46 +00:00
m_sceneGraph . Close ( ) ;
2009-02-04 00:01:36 +00:00
2007-12-10 21:12:38 +00:00
// De-register with region communications (events cleanup)
2008-09-18 15:44:05 +00:00
UnRegisterRegionWithComms ( ) ;
2007-07-16 15:40:11 +00:00
2007-12-10 21:12:38 +00:00
// call the base class Close method.
2007-11-03 19:14:22 +00:00
base . Close ( ) ;
2007-07-16 15:40:11 +00:00
}
/// <summary>
2008-03-13 18:42:57 +00:00
/// Start the timer which triggers regular scene updates
2007-07-16 15:40:11 +00:00
/// </summary>
public void StartTimer ( )
{
2008-10-11 11:43:42 +00:00
//m_log.Debug("[SCENE]: Starting timer");
//m_heartbeatTimer.Enabled = true;
//m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
//m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
HeartbeatThread = new Thread ( new ParameterizedThreadStart ( Heartbeat ) ) ;
HeartbeatThread . SetApartmentState ( ApartmentState . MTA ) ;
2009-03-12 20:37:15 +00:00
HeartbeatThread . Name = string . Format ( "Heartbeat for region {0}" , RegionInfo . RegionName ) ;
2008-10-11 11:43:42 +00:00
HeartbeatThread . Priority = ThreadPriority . AboveNormal ;
ThreadTracker . Add ( HeartbeatThread ) ;
HeartbeatThread . Start ( ) ;
2007-07-16 15:40:11 +00:00
}
2008-05-05 20:14:53 +00:00
/// <summary>
2008-05-22 22:21:58 +00:00
/// Sets up references to modules required by the scene
2008-05-05 20:14:53 +00:00
/// </summary>
2007-11-03 19:14:22 +00:00
public void SetModuleInterfaces ( )
{
m_xmlrpcModule = RequestModuleInterface < IXMLRPC > ( ) ;
m_worldCommModule = RequestModuleInterface < IWorldComm > ( ) ;
XferManager = RequestModuleInterface < IXfer > ( ) ;
2007-12-01 14:20:37 +00:00
m_AvatarFactory = RequestModuleInterface < IAvatarFactory > ( ) ;
2008-12-19 19:07:11 +00:00
m_serialiser = RequestModuleInterface < IRegionSerialiserModule > ( ) ;
2008-12-29 22:22:05 +00:00
m_interregionCommsOut = RequestModuleInterface < IInterregionCommsOut > ( ) ;
m_interregionCommsIn = RequestModuleInterface < IInterregionCommsIn > ( ) ;
2009-01-07 20:29:09 +00:00
m_dialogModule = RequestModuleInterface < IDialogModule > ( ) ;
2009-02-06 16:55:34 +00:00
m_capsModule = RequestModuleInterface < ICapabilitiesModule > ( ) ;
2007-11-03 19:14:22 +00:00
}
# endregion
2007-07-16 15:40:11 +00:00
#region Update Methods
/// <summary>
/// Performs per-frame updates regularly
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
2008-10-11 11:43:42 +00:00
private void Heartbeat ( object sender )
2007-07-16 15:40:11 +00:00
{
2007-07-17 17:47:23 +00:00
Update ( ) ;
2009-04-15 20:16:18 +00:00
m_lastUpdate = Environment . TickCount ;
2007-07-16 15:40:11 +00:00
}
/// <summary>
2007-08-06 13:40:45 +00:00
/// Performs per-frame updates on the scene, this should be the central scene loop
2007-07-16 15:40:11 +00:00
/// </summary>
public override void Update ( )
{
2008-10-11 11:43:42 +00:00
int maintc = 0 ;
while ( ! shuttingdown )
2008-02-07 08:15:38 +00:00
{
2009-02-12 09:53:12 +00:00
maintc = Environment . TickCount ;
2008-10-11 11:43:42 +00:00
TimeSpan SinceLastFrame = DateTime . Now - m_lastupdate ;
// Aquire a lock so only one update call happens at once
//updateLock.WaitOne();
float physicsFPS = 0 ;
//m_log.Info("sadfadf" + m_neighbours.Count.ToString());
2008-11-12 20:16:46 +00:00
int agentsInScene = m_sceneGraph . GetRootAgentCount ( ) + m_sceneGraph . GetChildAgentCount ( ) ;
2008-10-11 11:43:42 +00:00
if ( agentsInScene > 21 )
2008-02-07 08:15:38 +00:00
{
2008-10-11 11:43:42 +00:00
if ( m_update_entities = = 1 )
{
m_update_entities = 5 ;
2009-01-03 03:30:03 +00:00
StatsReporter . SetUpdateMS ( 6000 ) ;
2008-10-11 11:43:42 +00:00
}
2008-02-07 08:15:38 +00:00
}
2008-10-11 11:43:42 +00:00
else
2008-02-07 08:15:38 +00:00
{
2008-10-11 11:43:42 +00:00
if ( m_update_entities = = 5 )
{
m_update_entities = 1 ;
2009-01-03 03:30:03 +00:00
StatsReporter . SetUpdateMS ( 3000 ) ;
2008-10-11 11:43:42 +00:00
}
2008-02-07 08:15:38 +00:00
}
2009-02-12 09:53:12 +00:00
frameMS = Environment . TickCount ;
2008-10-11 11:43:42 +00:00
try
2008-03-04 05:31:54 +00:00
{
2008-10-11 11:43:42 +00:00
// Increment the frame counter
m_frame + + ;
// Loop it
if ( m_frame = = Int32 . MaxValue )
m_frame = 0 ;
2008-05-16 01:22:11 +00:00
2009-02-12 09:53:12 +00:00
physicsMS2 = Environment . TickCount ;
2008-10-11 11:43:42 +00:00
if ( ( m_frame % m_update_physics = = 0 ) & & m_physics_enabled )
2008-11-12 20:16:46 +00:00
m_sceneGraph . UpdatePreparePhysics ( ) ;
2009-02-12 09:53:12 +00:00
physicsMS2 = Environment . TickCount - physicsMS2 ;
2008-10-11 11:43:42 +00:00
if ( m_frame % m_update_entitymovement = = 0 )
2008-11-12 20:16:46 +00:00
m_sceneGraph . UpdateEntityMovement ( ) ;
2008-10-11 11:43:42 +00:00
2009-02-12 09:53:12 +00:00
physicsMS = Environment . TickCount ;
2008-10-11 11:43:42 +00:00
if ( ( m_frame % m_update_physics = = 0 ) & & m_physics_enabled )
2008-11-12 20:16:46 +00:00
physicsFPS = m_sceneGraph . UpdatePhysics (
2008-10-11 11:43:42 +00:00
Math . Max ( SinceLastFrame . TotalSeconds , m_timespan )
) ;
if ( m_frame % m_update_physics = = 0 & & SynchronizeScene ! = null )
SynchronizeScene ( this ) ;
2009-02-12 09:53:12 +00:00
physicsMS = Environment . TickCount - physicsMS ;
2008-10-11 11:43:42 +00:00
physicsMS + = physicsMS2 ;
2009-02-12 09:53:12 +00:00
otherMS = Environment . TickCount ;
2008-10-11 11:43:42 +00:00
// run through all entities looking for updates (slow)
if ( m_frame % m_update_entities = = 0 )
2009-02-23 06:55:42 +00:00
{
2009-02-23 07:57:54 +00:00
/ * // Adam Experimental
2009-02-23 06:55:42 +00:00
if ( m_updateEntitiesThread = = null )
{
m_updateEntitiesThread = new Thread ( m_sceneGraph . UpdateEntities ) ;
2009-02-23 07:31:13 +00:00
2009-02-23 06:55:42 +00:00
ThreadTracker . Add ( m_updateEntitiesThread ) ;
}
2009-02-23 10:36:16 +00:00
if ( m_updateEntitiesThread . ThreadState = = ThreadState . Stopped )
2009-02-23 06:55:42 +00:00
m_updateEntitiesThread . Start ( ) ;
2009-02-23 07:57:54 +00:00
* /
2009-03-04 02:29:51 +00:00
2009-02-23 07:57:54 +00:00
m_sceneGraph . UpdateEntities ( ) ;
2009-02-23 06:55:42 +00:00
}
2008-10-11 11:43:42 +00:00
// run through entities that have scheduled themselves for
// updates looking for updates(faster)
if ( m_frame % m_update_entitiesquick = = 0 )
2008-11-12 20:16:46 +00:00
m_sceneGraph . ProcessUpdates ( ) ;
2008-10-11 11:43:42 +00:00
// Run through scenepresences looking for updates
if ( m_frame % m_update_presences = = 0 )
2008-11-12 20:16:46 +00:00
m_sceneGraph . UpdatePresences ( ) ;
2008-10-11 11:43:42 +00:00
// Delete temp-on-rez stuff
2008-03-12 18:11:08 +00:00
if ( m_frame % m_update_backup = = 0 )
2008-10-11 11:43:42 +00:00
CleanTempObjects ( ) ;
2009-04-15 04:15:47 +00:00
if ( RegionStatus ! = RegionStatus . SlaveScene )
2008-07-09 12:02:01 +00:00
{
2008-10-11 11:43:42 +00:00
if ( m_frame % m_update_events = = 0 )
UpdateEvents ( ) ;
2008-05-16 01:22:11 +00:00
2008-10-11 11:43:42 +00:00
if ( m_frame % m_update_backup = = 0 )
UpdateStorageBackup ( ) ;
2007-09-24 16:39:26 +00:00
2008-10-11 11:43:42 +00:00
if ( m_frame % m_update_terrain = = 0 )
UpdateTerrain ( ) ;
if ( m_frame % m_update_land = = 0 )
UpdateLand ( ) ;
2009-02-13 16:43:20 +00:00
2009-02-12 09:53:12 +00:00
otherMS = Environment . TickCount - otherMS ;
2008-10-11 11:43:42 +00:00
// if (m_frame%m_update_avatars == 0)
// UpdateInWorldTime();
2009-01-03 03:30:03 +00:00
StatsReporter . AddPhysicsFPS ( physicsFPS ) ;
StatsReporter . AddTimeDilation ( m_timedilation ) ;
StatsReporter . AddFPS ( 1 ) ;
StatsReporter . AddInPackets ( 0 ) ;
StatsReporter . SetRootAgents ( m_sceneGraph . GetRootAgentCount ( ) ) ;
StatsReporter . SetChildAgents ( m_sceneGraph . GetChildAgentCount ( ) ) ;
StatsReporter . SetObjects ( m_sceneGraph . GetTotalObjectsCount ( ) ) ;
StatsReporter . SetActiveObjects ( m_sceneGraph . GetActiveObjectsCount ( ) ) ;
2009-02-12 09:53:12 +00:00
frameMS = Environment . TickCount - frameMS ;
2009-01-03 03:30:03 +00:00
StatsReporter . addFrameMS ( frameMS ) ;
StatsReporter . addPhysicsMS ( physicsMS ) ;
StatsReporter . addOtherMS ( otherMS ) ;
StatsReporter . SetActiveScripts ( m_sceneGraph . GetActiveScriptsCount ( ) ) ;
StatsReporter . addScriptLines ( m_sceneGraph . GetScriptLPS ( ) ) ;
2008-10-11 11:43:42 +00:00
}
}
catch ( NotImplementedException )
2008-02-12 04:27:20 +00:00
{
2008-10-11 11:43:42 +00:00
throw ;
2008-02-12 04:27:20 +00:00
}
2009-04-11 00:12:57 +00:00
catch ( AccessViolationException e )
{
m_log . Error ( "[Scene]: Failed with exception " + e . ToString ( ) + " On Region: " + RegionInfo . RegionName ) ;
}
2008-12-29 22:22:05 +00:00
//catch (NullReferenceException e)
//{
// m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
//}
2008-10-11 11:43:42 +00:00
catch ( InvalidOperationException e )
{
m_log . Error ( "[Scene]: Failed with exception " + e . ToString ( ) + " On Region: " + RegionInfo . RegionName ) ;
}
2009-04-11 00:12:57 +00:00
catch ( Exception e )
{
m_log . Error ( "[Scene]: Failed with exception " + e . ToString ( ) + " On Region: " + RegionInfo . RegionName ) ;
}
2008-10-11 11:43:42 +00:00
finally
{
//updateLock.ReleaseMutex();
// Get actual time dilation
float tmpval = ( m_timespan / ( float ) SinceLastFrame . TotalSeconds ) ;
// If actual time dilation is greater then one, we're catching up, so subtract
// the amount that's greater then 1 from the time dilation
if ( tmpval > 1.0 )
{
tmpval = tmpval - ( tmpval - 1.0f ) ;
}
m_timedilation = tmpval ;
2008-05-16 01:22:11 +00:00
2008-10-11 11:43:42 +00:00
m_lastupdate = DateTime . Now ;
}
2009-02-12 09:53:12 +00:00
maintc = Environment . TickCount - maintc ;
2008-10-11 11:43:42 +00:00
maintc = ( int ) ( m_timespan * 1000 ) - maintc ;
2008-10-14 09:40:05 +00:00
2008-10-11 11:43:42 +00:00
if ( ( maintc < ( m_timespan * 1000 ) ) & & maintc > 0 )
Thread . Sleep ( maintc ) ;
2007-09-24 15:46:03 +00:00
}
}
2007-12-27 21:41:48 +00:00
2008-10-06 19:52:54 +00:00
private void SendSimStatsPackets ( SimStats stats )
2007-12-12 06:58:55 +00:00
{
List < ScenePresence > StatSendAgents = GetScenePresences ( ) ;
foreach ( ScenePresence agent in StatSendAgents )
{
if ( ! agent . IsChildAgent )
{
2008-10-06 19:52:54 +00:00
agent . ControllingClient . SendSimStats ( stats ) ;
2007-12-12 06:58:55 +00:00
}
}
}
2007-12-27 21:41:48 +00:00
2007-09-24 15:46:03 +00:00
private void UpdateLand ( )
{
2008-03-22 23:10:22 +00:00
if ( LandChannel ! = null )
2007-09-24 15:46:03 +00:00
{
2008-05-06 04:56:48 +00:00
if ( LandChannel . IsLandPrimCountTainted ( ) )
2008-03-22 23:10:22 +00:00
{
2008-05-23 15:12:15 +00:00
EventManager . TriggerParcelPrimCountUpdate ( ) ;
2008-03-22 23:10:22 +00:00
}
2007-09-24 15:46:03 +00:00
}
}
2007-08-08 20:47:44 +00:00
2007-09-24 15:46:03 +00:00
private void UpdateTerrain ( )
{
2008-03-06 15:49:53 +00:00
EventManager . TriggerTerrainTick ( ) ;
2008-02-05 15:03:08 +00:00
}
2007-09-24 15:46:03 +00:00
private void UpdateStorageBackup ( )
{
2008-05-21 21:22:56 +00:00
if ( ! m_backingup )
{
m_backingup = true ;
Thread backupthread = new Thread ( Backup ) ;
backupthread . Name = "BackupWriter" ;
backupthread . IsBackground = true ;
backupthread . Start ( ) ;
}
2007-09-24 15:46:03 +00:00
}
2007-08-19 13:35:20 +00:00
2007-09-24 15:46:03 +00:00
private void UpdateEvents ( )
{
m_eventManager . TriggerOnFrame ( ) ;
}
2007-09-20 13:04:51 +00:00
2007-09-21 06:00:34 +00:00
/// <summary>
/// Perform delegate action on all clients subscribing to updates from this region.
/// </summary>
/// <returns></returns>
2009-02-06 16:55:34 +00:00
public void Broadcast ( Action < IClientAPI > whatToDo )
2007-09-21 04:58:40 +00:00
{
2007-10-30 09:05:31 +00:00
ForEachScenePresence ( delegate ( ScenePresence presence ) { whatToDo ( presence . ControllingClient ) ; } ) ;
2007-09-21 04:58:40 +00:00
}
2008-05-16 01:22:11 +00:00
2007-07-16 15:40:11 +00:00
/// <summary>
2008-06-16 15:36:01 +00:00
/// Backup the scene. This acts as the main method of the backup thread.
2007-07-16 15:40:11 +00:00
/// </summary>
/// <returns></returns>
2008-05-21 21:22:56 +00:00
public void Backup ( )
2007-07-16 15:40:11 +00:00
{
2008-11-21 18:44:48 +00:00
lock ( m_returns )
2008-10-18 05:51:36 +00:00
{
2008-11-21 07:33:13 +00:00
EventManager . TriggerOnBackup ( m_storageManager . DataStore ) ;
m_backingup = false ;
2008-10-18 05:51:36 +00:00
2008-11-21 07:33:13 +00:00
foreach ( KeyValuePair < UUID , ReturnInfo > ret in m_returns )
{
UUID transaction = UUID . Random ( ) ;
GridInstantMessage msg = new GridInstantMessage ( ) ;
msg . fromAgentID = new Guid ( UUID . Zero . ToString ( ) ) ; // From server
msg . toAgentID = new Guid ( ret . Key . ToString ( ) ) ;
msg . imSessionID = new Guid ( transaction . ToString ( ) ) ;
msg . timestamp = ( uint ) Util . UnixTimeSinceEpoch ( ) ;
msg . fromAgentName = "Server" ;
msg . dialog = ( byte ) 19 ; // Object msg
msg . fromGroup = false ;
msg . offline = ( byte ) 1 ;
msg . ParentEstateID = RegionInfo . EstateSettings . ParentEstateID ;
msg . Position = Vector3 . Zero ;
msg . RegionID = RegionInfo . RegionID . Guid ;
msg . binaryBucket = new byte [ 0 ] ;
if ( ret . Value . count > 1 )
msg . message = string . Format ( "Your {0} objects were returned from {1} in region {2} due to {3}" , ret . Value . count , ret . Value . location . ToString ( ) , RegionInfo . RegionName , ret . Value . reason ) ;
else
msg . message = string . Format ( "Your object {0} was returned from {1} in region {2} due to {3}" , ret . Value . objectName , ret . Value . location . ToString ( ) , RegionInfo . RegionName , ret . Value . reason ) ;
IMessageTransferModule tr = RequestModuleInterface < IMessageTransferModule > ( ) ;
if ( tr ! = null )
tr . SendInstantMessage ( msg , delegate ( bool success ) { } ) ;
}
m_returns . Clear ( ) ;
2008-10-18 05:51:36 +00:00
}
}
2009-02-04 16:00:39 +00:00
public void ForceSceneObjectBackup ( SceneObjectGroup group )
{
if ( group ! = null )
{
group . ProcessBackup ( m_storageManager . DataStore , true ) ;
}
}
2008-11-21 07:33:13 +00:00
public void AddReturn ( UUID agentID , string objectName , Vector3 location , string reason )
2008-10-18 05:51:36 +00:00
{
2008-11-21 18:44:48 +00:00
lock ( m_returns )
2008-10-18 05:51:36 +00:00
{
2008-11-21 07:33:13 +00:00
if ( m_returns . ContainsKey ( agentID ) )
{
ReturnInfo info = m_returns [ agentID ] ;
info . count + + ;
m_returns [ agentID ] = info ;
}
else
{
ReturnInfo info = new ReturnInfo ( ) ;
info . count = 1 ;
info . objectName = objectName ;
info . location = location ;
info . reason = reason ;
m_returns [ agentID ] = info ;
}
2008-10-18 05:51:36 +00:00
}
2007-07-16 15:40:11 +00:00
}
2007-07-17 17:47:23 +00:00
2007-07-16 15:40:11 +00:00
# endregion
#region Load Terrain
2007-07-17 17:47:23 +00:00
2008-03-06 15:49:53 +00:00
public void SaveTerrain ( )
2008-01-12 03:17:28 +00:00
{
2008-03-06 15:49:53 +00:00
m_storageManager . DataStore . StoreTerrain ( Heightmap . GetDoubles ( ) , RegionInfo . RegionID ) ;
2008-01-12 03:17:28 +00:00
}
2007-07-16 15:40:11 +00:00
/// <summary>
/// Loads the World heightmap
/// </summary>
public override void LoadWorldMap ( )
{
try
{
2007-11-04 13:48:15 +00:00
double [ , ] map = m_storageManager . DataStore . LoadTerrain ( RegionInfo . RegionID ) ;
2007-07-16 15:40:11 +00:00
if ( map = = null )
{
2008-03-06 15:49:53 +00:00
m_log . Info ( "[TERRAIN]: No default terrain. Generating a new terrain." ) ;
2008-04-21 07:09:17 +00:00
Heightmap = new TerrainChannel ( ) ;
2007-07-16 15:40:11 +00:00
2008-03-06 15:49:53 +00:00
m_storageManager . DataStore . StoreTerrain ( Heightmap . GetDoubles ( ) , RegionInfo . RegionID ) ;
2007-07-16 15:40:11 +00:00
}
else
{
2008-04-21 07:09:17 +00:00
Heightmap = new TerrainChannel ( map ) ;
2007-07-16 15:40:11 +00:00
}
}
catch ( Exception e )
{
2008-11-28 19:39:46 +00:00
m_log . Warn ( "[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception " + e . ToString ( ) ) ;
2007-07-16 15:40:11 +00:00
}
}
2008-05-12 16:57:56 +00:00
/// <summary>
/// Register this region with a grid service
/// </summary>
/// <exception cref="System.Exception">Thrown if registration of the region itself fails.</exception>
2007-11-28 12:36:09 +00:00
public void RegisterRegionWithGrid ( )
{
RegisterCommsEvents ( ) ;
2008-05-16 01:22:11 +00:00
2007-11-28 12:36:09 +00:00
// These two 'commands' *must be* next to each other or sim rebooting fails.
2008-12-29 22:22:05 +00:00
m_sceneGridService . RegisterRegion ( m_interregionCommsOut , RegionInfo ) ;
2007-11-28 12:36:09 +00:00
m_sceneGridService . InformNeighborsThatRegionisUp ( RegionInfo ) ;
2008-05-16 01:22:11 +00:00
2007-12-20 06:31:03 +00:00
Dictionary < string , string > dGridSettings = m_sceneGridService . GetGridSettings ( ) ;
2008-05-16 01:22:11 +00:00
2007-12-20 06:31:03 +00:00
if ( dGridSettings . ContainsKey ( "allow_forceful_banlines" ) )
{
2007-12-20 16:50:16 +00:00
if ( dGridSettings [ "allow_forceful_banlines" ] ! = "TRUE" )
{
2008-02-05 19:44:27 +00:00
m_log . Info ( "[GRID]: Grid is disabling forceful parcel banlists" ) ;
2008-05-23 15:12:15 +00:00
EventManager . TriggerSetAllowForcefulBan ( false ) ;
2007-12-20 16:50:16 +00:00
}
else
{
2008-02-05 19:44:27 +00:00
m_log . Info ( "[GRID]: Grid is allowing forceful parcel banlists" ) ;
2008-05-23 15:12:15 +00:00
EventManager . TriggerSetAllowForcefulBan ( true ) ;
2007-12-20 16:50:16 +00:00
}
2007-12-20 06:31:03 +00:00
}
2007-11-28 12:36:09 +00:00
}
2007-07-16 15:40:11 +00:00
/// <summary>
2009-02-13 17:15:49 +00:00
/// Create a terrain texture for this scene
2007-07-16 15:40:11 +00:00
/// </summary>
2007-11-28 12:36:09 +00:00
public void CreateTerrainTexture ( bool temporary )
2007-07-16 15:40:11 +00:00
{
2008-05-16 01:22:11 +00:00
//create a texture asset of the terrain
2008-04-15 03:07:31 +00:00
IMapImageGenerator terrain = RequestModuleInterface < IMapImageGenerator > ( ) ;
2008-04-10 13:37:39 +00:00
2008-04-15 03:07:31 +00:00
// Cannot create a map for a nonexistant heightmap yet.
if ( Heightmap = = null )
return ;
2008-06-13 00:21:53 +00:00
2008-04-15 03:07:31 +00:00
if ( terrain = = null )
2009-02-13 17:15:49 +00:00
return ;
2008-06-14 02:39:27 +00:00
2009-02-13 17:15:49 +00:00
byte [ ] data = terrain . WriteJpeg2000Image ( "defaultstripe.png" ) ;
if ( data ! = null )
2008-08-17 18:59:58 +00:00
{
2009-02-13 17:40:52 +00:00
IWorldMapModule mapModule = RequestModuleInterface < IWorldMapModule > ( ) ;
if ( mapModule ! = null )
mapModule . LazySaveGeneratedMaptile ( data , temporary ) ;
2008-08-17 18:59:58 +00:00
}
2007-07-16 15:40:11 +00:00
}
2008-08-28 14:41:54 +00:00
2007-07-16 15:40:11 +00:00
# endregion
2007-12-17 03:49:13 +00:00
#region Load Land
2008-09-06 07:52:41 +00:00
public void loadAllLandObjectsFromStorage ( UUID regionID )
2007-12-17 03:49:13 +00:00
{
2008-02-10 14:27:21 +00:00
m_log . Info ( "[SCENE]: Loading land objects from storage" ) ;
2008-03-04 05:31:54 +00:00
List < LandData > landData = m_storageManager . DataStore . LoadLandObjects ( regionID ) ;
2008-01-19 19:49:08 +00:00
2008-05-13 16:22:57 +00:00
if ( LandChannel ! = null )
2008-02-10 14:27:21 +00:00
{
2008-05-13 16:22:57 +00:00
if ( landData . Count = = 0 )
{
2008-05-23 15:12:15 +00:00
EventManager . TriggerNoticeNoLandDataFromStorage ( ) ;
2008-05-13 16:22:57 +00:00
}
else
{
2008-05-23 15:12:15 +00:00
EventManager . TriggerIncomingLandDataFromStorage ( landData ) ;
2008-05-13 16:22:57 +00:00
}
2008-02-10 14:27:21 +00:00
}
else
{
2008-05-13 16:22:57 +00:00
m_log . Error ( "[SCENE]: Land Channel is not defined. Cannot load from storage!" ) ;
2008-02-10 14:27:21 +00:00
}
2007-12-17 03:49:13 +00:00
}
2007-12-27 21:41:48 +00:00
2007-12-17 03:49:13 +00:00
# endregion
2007-07-16 15:40:11 +00:00
#region Primitives Methods
/// <summary>
/// Loads the World's objects
/// </summary>
2008-09-06 07:52:41 +00:00
public virtual void LoadPrimsFromStorage ( UUID regionID )
2007-07-16 15:40:11 +00:00
{
2008-02-05 19:44:27 +00:00
m_log . Info ( "[SCENE]: Loading objects from datastore" ) ;
2008-02-10 14:27:21 +00:00
2008-03-04 05:31:54 +00:00
List < SceneObjectGroup > PrimsFromDB = m_storageManager . DataStore . LoadObjects ( regionID ) ;
2008-01-07 02:12:06 +00:00
foreach ( SceneObjectGroup group in PrimsFromDB )
2007-07-19 00:42:59 +00:00
{
2008-10-11 17:48:37 +00:00
if ( group . RootPart = = null )
{
m_log . ErrorFormat ( "[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children" ,
group . Children = = null ? 0 : group . Children . Count ) ;
}
2009-02-04 00:01:36 +00:00
2008-07-13 00:18:29 +00:00
AddRestoredSceneObject ( group , true , true ) ;
2008-01-07 02:12:06 +00:00
SceneObjectPart rootPart = group . GetChildPart ( group . UUID ) ;
2008-09-06 07:52:41 +00:00
rootPart . ObjectFlags & = ~ ( uint ) PrimFlags . Scripted ;
2008-01-22 15:07:30 +00:00
rootPart . TrimPermissions ( ) ;
2008-05-09 07:50:00 +00:00
group . CheckSculptAndLoad ( ) ;
2008-01-15 04:14:27 +00:00
//rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
2007-07-19 00:42:59 +00:00
}
2008-02-10 14:27:21 +00:00
2008-05-01 18:04:42 +00:00
m_log . Info ( "[SCENE]: Loaded " + PrimsFromDB . Count . ToString ( ) + " SceneObject(s)" ) ;
2007-07-16 15:40:11 +00:00
}
2008-09-06 07:52:41 +00:00
public Vector3 GetNewRezLocation ( Vector3 RayStart , Vector3 RayEnd , UUID RayTargetID , Quaternion rot , byte bypassRayCast , byte RayEndIsIntersection , bool frontFacesOnly , Vector3 scale , bool FaceCenter )
2007-07-16 15:40:11 +00:00
{
2008-09-06 07:52:41 +00:00
Vector3 pos = Vector3 . Zero ;
2008-05-01 18:04:42 +00:00
if ( RayEndIsIntersection = = ( byte ) 1 )
2007-08-26 17:57:25 +00:00
{
2007-12-28 05:25:21 +00:00
pos = RayEnd ;
return pos ;
}
2008-08-28 14:41:54 +00:00
2008-09-06 07:52:41 +00:00
if ( RayTargetID ! = UUID . Zero )
2007-12-28 05:25:21 +00:00
{
SceneObjectPart target = GetSceneObjectPart ( RayTargetID ) ;
2008-05-16 01:22:11 +00:00
2008-09-06 07:52:41 +00:00
Vector3 direction = Vector3 . Normalize ( RayEnd - RayStart ) ;
2008-03-23 06:24:59 +00:00
Vector3 AXOrigin = new Vector3 ( RayStart . X , RayStart . Y , RayStart . Z ) ;
Vector3 AXdirection = new Vector3 ( direction . X , direction . Y , direction . Z ) ;
2007-12-28 05:25:21 +00:00
if ( target ! = null )
2007-12-12 17:15:37 +00:00
{
2007-12-28 05:25:21 +00:00
pos = target . AbsolutePosition ;
2008-03-21 05:54:56 +00:00
//m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
2008-05-16 01:22:11 +00:00
2008-03-23 06:24:59 +00:00
// TODO: Raytrace better here
2008-05-16 01:22:11 +00:00
2008-11-12 20:16:46 +00:00
//EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
2008-03-23 06:24:59 +00:00
Ray NewRay = new Ray ( AXOrigin , AXdirection ) ;
// Ray Trace against target here
2008-09-06 07:52:41 +00:00
EntityIntersection ei = target . TestIntersectionOBB ( NewRay , Quaternion . Identity , frontFacesOnly , FaceCenter ) ;
2008-03-23 06:24:59 +00:00
// Un-comment out the following line to Get Raytrace results printed to the console.
2008-05-01 18:04:42 +00:00
// m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
2008-05-01 06:31:12 +00:00
float ScaleOffset = 0.5f ;
2008-03-23 06:24:59 +00:00
// If we hit something
if ( ei . HitTF )
2008-03-21 05:54:56 +00:00
{
2008-09-06 07:52:41 +00:00
Vector3 scaleComponent = new Vector3 ( ei . AAfaceNormal . X , ei . AAfaceNormal . Y , ei . AAfaceNormal . Z ) ;
2008-05-01 06:31:12 +00:00
if ( scaleComponent . X ! = 0 ) ScaleOffset = scale . X ;
if ( scaleComponent . Y ! = 0 ) ScaleOffset = scale . Y ;
if ( scaleComponent . Z ! = 0 ) ScaleOffset = scale . Z ;
ScaleOffset = Math . Abs ( ScaleOffset ) ;
2008-09-06 07:52:41 +00:00
Vector3 intersectionpoint = new Vector3 ( ei . ipoint . X , ei . ipoint . Y , ei . ipoint . Z ) ;
Vector3 normal = new Vector3 ( ei . normal . X , ei . normal . Y , ei . normal . Z ) ;
2008-03-23 06:24:59 +00:00
// Set the position to the intersection point
2008-09-06 07:52:41 +00:00
Vector3 offset = ( normal * ( ScaleOffset / 2f ) ) ;
2008-05-01 04:58:15 +00:00
pos = ( intersectionpoint + offset ) ;
2008-05-16 01:22:11 +00:00
2008-03-25 17:28:09 +00:00
// Un-offset the prim (it gets offset later by the consumer method)
pos . Z - = 0.25F ;
2008-05-16 01:22:11 +00:00
}
2007-12-28 05:25:21 +00:00
return pos ;
2007-11-23 05:56:35 +00:00
}
2007-11-25 17:53:16 +00:00
else
{
2008-03-23 06:24:59 +00:00
// We don't have a target here, so we're going to raytrace all the objects in the scene.
2008-11-12 20:16:46 +00:00
EntityIntersection ei = m_sceneGraph . GetClosestIntersectingPrim ( new Ray ( AXOrigin , AXdirection ) , true , false ) ;
2008-03-23 06:24:59 +00:00
// Un-comment the following line to print the raytrace results to the console.
//m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
if ( ei . HitTF )
{
2008-09-06 07:52:41 +00:00
pos = new Vector3 ( ei . ipoint . X , ei . ipoint . Y , ei . ipoint . Z ) ;
2008-09-30 14:42:25 +00:00
} else
{
// fall back to our stupid functionality
pos = RayEnd ;
2008-05-16 01:22:11 +00:00
}
2007-12-28 05:25:21 +00:00
return pos ;
}
}
else
{
// fall back to our stupid functionality
pos = RayEnd ;
return pos ;
}
}
2008-11-17 23:43:46 +00:00
public virtual void AddNewPrim ( UUID ownerID , UUID groupID , Vector3 RayEnd , Quaternion rot , PrimitiveBaseShape shape ,
2008-09-06 07:52:41 +00:00
byte bypassRaycast , Vector3 RayStart , UUID RayTargetID ,
2008-02-05 19:44:27 +00:00
byte RayEndIsIntersection )
2008-02-10 14:27:21 +00:00
{
2008-09-06 07:52:41 +00:00
Vector3 pos = GetNewRezLocation ( RayStart , RayEnd , RayTargetID , rot , bypassRaycast , RayEndIsIntersection , true , new Vector3 ( 0.5f , 0.5f , 0.5f ) , false ) ;
2008-05-16 01:22:11 +00:00
2008-11-21 22:14:57 +00:00
if ( Permissions . CanRezObject ( 1 , ownerID , pos ) )
2007-12-28 05:25:21 +00:00
{
2007-12-30 16:00:55 +00:00
// rez ON the ground, not IN the ground
2008-02-10 14:27:21 +00:00
pos . Z + = 0.25F ;
2007-12-30 16:00:55 +00:00
2008-11-17 23:43:46 +00:00
AddNewPrim ( ownerID , groupID , pos , rot , shape ) ;
2007-12-30 16:00:55 +00:00
}
}
2008-12-19 17:57:03 +00:00
public virtual SceneObjectGroup AddNewPrim (
UUID ownerID , UUID groupID , Vector3 pos , Quaternion rot , PrimitiveBaseShape shape )
2007-12-30 16:00:55 +00:00
{
2008-06-17 20:36:21 +00:00
//m_log.DebugFormat(
2008-12-19 17:57:03 +00:00
// "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
2009-02-04 00:01:36 +00:00
2008-12-19 17:57:03 +00:00
// If an entity creator has been registered for this prim type then use that
if ( m_entityCreators . ContainsKey ( ( PCode ) shape . PCode ) )
return m_entityCreators [ ( PCode ) shape . PCode ] . CreateEntity ( ownerID , groupID , pos , rot , shape ) ;
2008-06-18 03:50:39 +00:00
2008-12-19 17:57:03 +00:00
// Otherwise, use this default creation code;
2008-11-07 21:07:14 +00:00
SceneObjectGroup sceneObject = new SceneObjectGroup ( ownerID , pos , rot , shape ) ;
AddNewSceneObject ( sceneObject , true ) ;
2008-11-18 17:21:33 +00:00
sceneObject . SetGroup ( groupID , null ) ;
2008-02-04 10:39:30 +00:00
2008-11-07 21:07:14 +00:00
return sceneObject ;
2007-07-16 15:40:11 +00:00
}
2008-05-24 22:10:14 +00:00
/// <summary>
/// Add an object into the scene that has come from storage
/// </summary>
2009-02-05 18:36:53 +00:00
///
2008-05-25 23:27:38 +00:00
/// <param name="sceneObject"></param>
2008-07-13 00:18:29 +00:00
/// <param name="attachToBackup">
/// If true, changes to the object will be reflected in its persisted data
/// If false, the persisted data will not be changed even if the object in the scene is changed
/// </param>
/// <param name="alreadyPersisted">
/// If true, we won't persist this object until it changes
/// If false, we'll persist this object immediately
/// </param>
/// <returns>
/// true if the object was added, false if an object with the same uuid was already in the scene
2008-08-18 00:39:10 +00:00
/// </returns>
2008-07-13 00:18:29 +00:00
public bool AddRestoredSceneObject (
SceneObjectGroup sceneObject , bool attachToBackup , bool alreadyPersisted )
2007-08-10 13:59:19 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . AddRestoredSceneObject ( sceneObject , attachToBackup , alreadyPersisted ) ;
2007-08-10 13:59:19 +00:00
}
2008-05-24 22:10:14 +00:00
/// <summary>
2008-06-27 14:25:36 +00:00
/// Add a newly created object to the scene
2008-05-24 22:10:14 +00:00
/// </summary>
/// <param name="sceneObject"></param>
2008-06-12 17:49:08 +00:00
/// <param name="attachToBackup">
2008-06-13 00:21:53 +00:00
/// If true, the object is made persistent into the scene.
2008-06-12 17:49:08 +00:00
/// If false, the object will not persist over server restarts
/// </param>
2008-07-12 22:14:38 +00:00
public bool AddNewSceneObject ( SceneObjectGroup sceneObject , bool attachToBackup )
2007-07-16 15:40:11 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . AddNewSceneObject ( sceneObject , attachToBackup ) ;
2008-05-25 23:27:38 +00:00
}
2007-07-16 15:40:11 +00:00
2008-07-14 16:23:59 +00:00
/// <summary>
/// Delete every object from the scene
/// </summary>
public void DeleteAllSceneObjects ( )
{
lock ( Entities )
{
2008-11-24 14:45:05 +00:00
ICollection < EntityBase > entities = new List < EntityBase > ( Entities ) ;
2008-08-18 00:39:10 +00:00
2008-07-14 16:23:59 +00:00
foreach ( EntityBase e in entities )
{
if ( e is SceneObjectGroup )
2008-11-07 05:48:44 +00:00
DeleteSceneObject ( ( SceneObjectGroup ) e , false ) ;
2008-07-14 16:23:59 +00:00
}
2008-08-18 00:39:10 +00:00
}
2008-07-14 16:23:59 +00:00
}
2008-08-18 00:39:10 +00:00
2008-05-24 22:10:14 +00:00
/// <summary>
2008-11-12 20:35:35 +00:00
/// Synchronously delete the given object from the scene.
2008-05-24 22:10:14 +00:00
/// </summary>
2009-02-02 14:57:01 +00:00
/// <param name="group">Object Id</param>
/// <param name="silent">Suppress broadcasting changes to other clients.</param>
2008-11-07 05:48:44 +00:00
public void DeleteSceneObject ( SceneObjectGroup group , bool silent )
2007-07-16 15:40:11 +00:00
{
2008-08-30 18:09:38 +00:00
//SceneObjectPart rootPart = group.GetChildPart(group.UUID);
2008-05-25 23:27:38 +00:00
2008-11-11 00:52:47 +00:00
// Serialise calls to RemoveScriptInstances to avoid
// deadlocking on m_parts inside SceneObjectGroup
lock ( m_deleting_scene_object )
{
group . RemoveScriptInstances ( ) ;
}
2008-09-17 22:00:56 +00:00
2008-08-27 19:06:07 +00:00
foreach ( SceneObjectPart part in group . Children . Values )
2008-05-24 23:11:07 +00:00
{
2008-12-26 12:58:02 +00:00
if ( part . IsJoint ( ) & & ( ( part . ObjectFlags & ( uint ) PrimFlags . Physics ) ! = 0 ) )
{
PhysicsScene . RequestJointDeletion ( part . Name ) ; // FIXME: what if the name changed?
}
else if ( part . PhysActor ! = null )
2008-08-27 19:06:07 +00:00
{
PhysicsScene . RemovePrim ( part . PhysActor ) ;
part . PhysActor = null ;
}
2008-05-25 23:27:38 +00:00
}
2008-08-27 19:06:07 +00:00
// if (rootPart.PhysActor != null)
// {
// PhysicsScene.RemovePrim(rootPart.PhysActor);
// rootPart.PhysActor = null;
// }
2008-05-24 23:11:07 +00:00
2008-06-07 00:24:43 +00:00
if ( UnlinkSceneObject ( group . UUID , false ) )
2007-07-16 15:40:11 +00:00
{
2008-05-24 23:11:07 +00:00
EventManager . TriggerObjectBeingRemovedFromScene ( group ) ;
2008-05-23 15:12:15 +00:00
EventManager . TriggerParcelPrimCountTainted ( ) ;
2008-05-25 23:27:38 +00:00
}
2008-05-25 00:09:08 +00:00
2008-11-07 05:48:44 +00:00
group . DeleteGroup ( silent ) ;
2008-05-25 23:27:38 +00:00
}
2008-05-25 00:09:08 +00:00
/// <summary>
/// Unlink the given object from the scene. Unlike delete, this just removes the record of the object - the
/// object itself is not destroyed.
/// </summary>
2009-02-02 14:57:01 +00:00
/// <param name="uuid">Id of object.</param>
2008-05-25 00:09:08 +00:00
/// <returns>true if the object was in the scene, false if it was not</returns>
2009-02-02 14:57:01 +00:00
/// <param name="softDelete">If true, only deletes from scene, but keeps object in database.</param>
public bool UnlinkSceneObject ( UUID uuid , bool softDelete )
2008-05-25 23:27:38 +00:00
{
2009-02-02 14:57:01 +00:00
if ( m_sceneGraph . DeleteSceneObject ( uuid , softDelete ) )
2008-05-25 00:09:08 +00:00
{
2009-02-02 14:57:01 +00:00
if ( ! softDelete )
{
2008-10-22 03:32:45 +00:00
m_storageManager . DataStore . RemoveObject ( uuid ,
2009-02-02 14:57:01 +00:00
m_regInfo . RegionID ) ;
}
2008-05-25 00:09:08 +00:00
return true ;
}
2008-05-25 23:27:38 +00:00
2008-05-25 00:09:08 +00:00
return false ;
}
2007-07-16 15:40:11 +00:00
2008-04-25 21:41:55 +00:00
/// <summary>
2008-10-14 09:40:05 +00:00
/// Move the given scene object into a new region depending on which region its absolute position has moved
/// into.
///
2008-09-12 00:37:59 +00:00
/// This method locates the new region handle and offsets the prim position for the new region
2008-04-25 21:41:55 +00:00
/// </summary>
2008-09-12 00:37:59 +00:00
/// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
/// <param name="grp">the scene object that we're crossing</param>
2008-11-07 05:48:44 +00:00
public void CrossPrimGroupIntoNewRegion ( Vector3 attemptedPosition , SceneObjectGroup grp , bool silent )
2008-02-11 01:43:54 +00:00
{
2008-05-04 22:55:52 +00:00
if ( grp = = null )
return ;
2008-11-17 15:40:27 +00:00
if ( grp . IsDeleted )
2008-05-04 22:55:52 +00:00
return ;
if ( grp . RootPart . DIE_AT_EDGE )
{
// We remove the object here
try
{
2008-11-07 05:48:44 +00:00
DeleteSceneObject ( grp , false ) ;
2008-05-04 22:55:52 +00:00
}
catch ( Exception )
{
m_log . Warn ( "[DATABASE]: exception when trying to remove the prim that crossed the border." ) ;
}
return ;
}
2008-10-14 09:40:05 +00:00
2008-05-01 18:04:42 +00:00
int thisx = ( int ) RegionInfo . RegionLocX ;
int thisy = ( int ) RegionInfo . RegionLocY ;
2008-03-30 08:01:47 +00:00
2008-02-11 01:43:54 +00:00
ulong newRegionHandle = 0 ;
2008-09-12 00:37:59 +00:00
Vector3 pos = attemptedPosition ;
2008-02-11 01:43:54 +00:00
2008-09-12 00:37:59 +00:00
if ( attemptedPosition . X > Constants . RegionSize + 0.1f )
2008-02-11 01:43:54 +00:00
{
2008-02-14 12:16:33 +00:00
pos . X = ( ( pos . X - Constants . RegionSize ) ) ;
2008-10-14 09:40:05 +00:00
newRegionHandle
2008-09-12 00:37:59 +00:00
= Util . UIntsToLong ( ( uint ) ( ( thisx + 1 ) * Constants . RegionSize ) , ( uint ) ( thisy * Constants . RegionSize ) ) ;
2008-02-11 01:43:54 +00:00
// x + 1
}
2008-09-12 00:37:59 +00:00
else if ( attemptedPosition . X < - 0.1f )
2008-02-11 01:43:54 +00:00
{
2008-02-14 12:16:33 +00:00
pos . X = ( ( pos . X + Constants . RegionSize ) ) ;
2008-10-14 09:40:05 +00:00
newRegionHandle
2008-09-12 00:37:59 +00:00
= Util . UIntsToLong ( ( uint ) ( ( thisx - 1 ) * Constants . RegionSize ) , ( uint ) ( thisy * Constants . RegionSize ) ) ;
2008-02-11 01:43:54 +00:00
// x - 1
}
2008-09-12 00:37:59 +00:00
if ( attemptedPosition . Y > Constants . RegionSize + 0.1f )
2008-02-11 01:43:54 +00:00
{
2008-02-14 12:16:33 +00:00
pos . Y = ( ( pos . Y - Constants . RegionSize ) ) ;
2008-10-14 09:40:05 +00:00
newRegionHandle
2008-09-12 00:37:59 +00:00
= Util . UIntsToLong ( ( uint ) ( thisx * Constants . RegionSize ) , ( uint ) ( ( thisy + 1 ) * Constants . RegionSize ) ) ;
2008-03-18 15:30:38 +00:00
// y + 1
2008-02-11 01:43:54 +00:00
}
2008-10-05 20:06:42 +00:00
else if ( attemptedPosition . Y < - 0.1f )
2008-02-11 01:43:54 +00:00
{
2008-02-14 12:16:33 +00:00
pos . Y = ( ( pos . Y + Constants . RegionSize ) ) ;
2008-10-14 09:40:05 +00:00
newRegionHandle
2008-09-12 00:37:59 +00:00
= Util . UIntsToLong ( ( uint ) ( thisx * Constants . RegionSize ) , ( uint ) ( ( thisy - 1 ) * Constants . RegionSize ) ) ;
2008-02-11 01:43:54 +00:00
// y - 1
}
// Offset the positions for the new region across the border
2008-09-12 00:37:59 +00:00
Vector3 oldGroupPosition = grp . RootPart . GroupPosition ;
2008-02-11 01:43:54 +00:00
grp . OffsetForNewRegion ( pos ) ;
2008-05-16 01:22:11 +00:00
2008-09-12 00:37:59 +00:00
// If we fail to cross the border, then reset the position of the scene object on that border.
2008-11-07 05:48:44 +00:00
if ( ! CrossPrimGroupIntoNewRegion ( newRegionHandle , grp , silent ) )
2008-10-14 09:40:05 +00:00
{
grp . OffsetForNewRegion ( oldGroupPosition ) ;
2008-11-30 09:03:55 +00:00
grp . ScheduleGroupForFullUpdate ( ) ;
2008-09-12 00:37:59 +00:00
}
2008-05-01 18:04:42 +00:00
}
2008-06-04 09:59:27 +00:00
2008-09-12 00:37:59 +00:00
/// <summary>
/// Move the given scene object into a new region
/// </summary>
/// <param name="newRegionHandle"></param>
2008-10-14 09:40:05 +00:00
/// <param name="grp">Scene Object Group that we're crossing</param>
2008-09-12 00:37:59 +00:00
/// <returns>
/// true if the crossing itself was successful, false on failure
/// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
/// </returns>
2008-11-07 05:48:44 +00:00
public bool CrossPrimGroupIntoNewRegion ( ulong newRegionHandle , SceneObjectGroup grp , bool silent )
2008-04-25 21:41:55 +00:00
{
2009-02-22 20:52:55 +00:00
//m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
2009-02-09 22:27:27 +00:00
2008-10-14 09:40:05 +00:00
bool successYN = false ;
2008-11-10 05:21:51 +00:00
grp . RootPart . UpdateFlag = 0 ;
2009-02-09 22:27:27 +00:00
//int primcrossingXMLmethod = 0;
2008-10-14 09:40:05 +00:00
2008-02-11 01:43:54 +00:00
if ( newRegionHandle ! = 0 )
{
2009-02-09 22:27:27 +00:00
//string objectState = grp.GetStateSnapshot();
2008-12-05 20:30:00 +00:00
2009-02-09 22:27:27 +00:00
//successYN
// = m_sceneGridService.PrimCrossToNeighboringRegion(
// newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod);
//if (successYN && (objectState != "") && m_allowScriptCrossings)
//{
// successYN = m_sceneGridService.PrimCrossToNeighboringRegion(
// newRegionHandle, grp.UUID, objectState, 100);
//}
// And the new channel...
2009-02-09 23:12:49 +00:00
if ( m_interregionCommsOut ! = null )
2009-02-13 00:49:58 +00:00
successYN = m_interregionCommsOut . SendCreateObject ( newRegionHandle , grp , true ) ;
2008-06-04 09:59:27 +00:00
2008-02-11 01:43:54 +00:00
if ( successYN )
{
// We remove the object here
try
{
2008-11-07 05:48:44 +00:00
DeleteSceneObject ( grp , silent ) ;
2008-02-11 01:43:54 +00:00
}
2008-09-12 00:37:59 +00:00
catch ( Exception e )
2008-02-11 01:43:54 +00:00
{
2008-09-12 00:37:59 +00:00
m_log . ErrorFormat (
2008-10-14 09:40:05 +00:00
"[INTERREGION]: Exception deleting the old object left behind on a border crossing for {0}, {1}" ,
2008-09-12 00:37:59 +00:00
grp , e ) ;
2008-02-11 01:43:54 +00:00
}
}
else
{
2008-11-17 15:40:27 +00:00
if ( ! grp . IsDeleted )
2008-02-14 00:39:08 +00:00
{
if ( grp . RootPart . PhysActor ! = null )
{
grp . RootPart . PhysActor . CrossingFailure ( ) ;
}
}
2008-10-14 09:40:05 +00:00
2008-09-12 00:37:59 +00:00
m_log . ErrorFormat ( "[INTERREGION]: Prim crossing failed for {0}" , grp ) ;
2008-02-11 01:43:54 +00:00
}
}
2008-09-12 00:37:59 +00:00
else
{
m_log . Error ( "[INTERREGION]: region handle was unexpectedly 0 in Scene.CrossPrimGroupIntoNewRegion()" ) ;
}
2008-10-14 09:40:05 +00:00
2008-09-12 00:37:59 +00:00
return successYN ;
2008-02-11 01:43:54 +00:00
}
2008-03-18 15:30:38 +00:00
2008-09-12 00:37:59 +00:00
/// <summary>
/// Handle a scene object that is crossing into this region from another.
2009-02-09 22:27:27 +00:00
/// NOTE: Unused as of 2009-02-09. Soon to be deleted.
2008-09-12 00:37:59 +00:00
/// </summary>
/// <param name="regionHandle"></param>
/// <param name="primID"></param>
/// <param name="objXMLData"></param>
/// <param name="XMLMethod"></param>
/// <returns></returns>
2008-11-12 19:12:33 +00:00
public bool IncomingInterRegionPrimGroup ( UUID primID , string objXMLData , int XMLMethod )
2008-02-11 01:43:54 +00:00
{
2009-02-04 00:01:36 +00:00
2008-03-30 08:01:47 +00:00
if ( XMLMethod = = 0 )
{
2008-12-05 20:30:00 +00:00
m_log . DebugFormat ( "[INTERREGION]: A new prim {0} arrived from a neighbor" , primID ) ;
2008-08-18 00:39:10 +00:00
SceneObjectGroup sceneObject = m_serialiser . DeserializeGroupFromXml2 ( objXMLData ) ;
2008-11-22 00:23:48 +00:00
2009-02-09 22:27:27 +00:00
return AddSceneObject ( primID , sceneObject ) ;
2008-11-29 13:17:21 +00:00
2008-03-30 08:01:47 +00:00
}
2008-12-05 20:30:00 +00:00
else if ( ( XMLMethod = = 100 ) & & m_allowScriptCrossings )
{
m_log . Warn ( "[INTERREGION]: Prim state data arrived from a neighbor" ) ;
2009-02-09 22:27:27 +00:00
2008-12-05 20:30:00 +00:00
XmlDocument doc = new XmlDocument ( ) ;
doc . LoadXml ( objXMLData ) ;
XmlNodeList rootL = doc . GetElementsByTagName ( "ScriptData" ) ;
if ( rootL . Count = = 1 )
{
XmlNode rootNode = rootL [ 0 ] ;
if ( rootNode ! = null )
{
XmlNodeList partL = rootNode . ChildNodes ;
foreach ( XmlNode part in partL )
{
XmlNodeList nodeL = part . ChildNodes ;
switch ( part . Name )
{
case "Assemblies" :
foreach ( XmlNode asm in nodeL )
{
string fn = asm . Attributes . GetNamedItem ( "Filename" ) . Value ;
Byte [ ] filedata = Convert . FromBase64String ( asm . InnerText ) ;
string path = Path . Combine ( "ScriptEngines" , RegionInfo . RegionID . ToString ( ) ) ;
path = Path . Combine ( path , fn ) ;
if ( ! File . Exists ( path ) )
{
FileStream fs = File . Create ( path ) ;
fs . Write ( filedata , 0 , filedata . Length ) ;
fs . Close ( ) ;
}
}
break ;
case "ScriptStates" :
foreach ( XmlNode st in nodeL )
{
string id = st . Attributes . GetNamedItem ( "UUID" ) . Value ;
UUID uuid = new UUID ( id ) ;
XmlNode state = st . ChildNodes [ 0 ] ;
XmlDocument sdoc = new XmlDocument ( ) ;
XmlNode sxmlnode = sdoc . CreateNode (
XmlNodeType . XmlDeclaration ,
"" , "" ) ;
sdoc . AppendChild ( sxmlnode ) ;
XmlNode newnode = sdoc . ImportNode ( state , true ) ;
sdoc . AppendChild ( newnode ) ;
string spath = Path . Combine ( "ScriptEngines" , RegionInfo . RegionID . ToString ( ) ) ;
spath = Path . Combine ( spath , uuid . ToString ( ) ) ;
FileStream sfs = File . Create ( spath + ".state" ) ;
2009-02-12 09:53:12 +00:00
ASCIIEncoding enc = new ASCIIEncoding ( ) ;
2008-12-05 20:30:00 +00:00
Byte [ ] buf = enc . GetBytes ( sdoc . InnerXml ) ;
sfs . Write ( buf , 0 , buf . Length ) ;
sfs . Close ( ) ;
}
break ;
}
}
}
}
SceneObjectPart RootPrim = GetSceneObjectPart ( primID ) ;
RootPrim . ParentGroup . CreateScriptInstances ( 0 , false , DefaultScriptEngine , 1 ) ;
return true ;
}
2008-11-29 01:33:10 +00:00
return true ;
2008-02-11 01:43:54 +00:00
}
2008-03-18 15:30:38 +00:00
2009-02-09 22:27:27 +00:00
public bool IncomingCreateObject ( ISceneObject sog )
{
2009-02-22 20:52:55 +00:00
//m_log.Debug(" >>> IncomingCreateObject <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted);
2009-02-09 22:27:27 +00:00
SceneObjectGroup newObject ;
try
{
newObject = ( SceneObjectGroup ) sog ;
}
catch ( Exception e )
{
m_log . WarnFormat ( "[SCENE]: Problem casting object: {0}" , e . Message ) ;
return false ;
}
if ( ! AddSceneObject ( newObject . UUID , newObject ) )
{
m_log . DebugFormat ( "[SCENE]: Problem adding scene object {0} in {1} " , sog . UUID , RegionInfo . RegionName ) ;
return false ;
}
newObject . RootPart . ParentGroup . CreateScriptInstances ( 0 , false , DefaultScriptEngine , 1 ) ;
return true ;
}
2009-04-05 03:27:50 +00:00
public virtual bool IncomingCreateObject ( UUID userID , UUID itemID )
{
ScenePresence sp = GetScenePresence ( userID ) ;
if ( sp ! = null )
{
uint attPt = ( uint ) sp . Appearance . GetAttachpoint ( itemID ) ;
2009-04-07 20:24:09 +00:00
m_sceneGraph . RezSingleAttachment ( sp . ControllingClient , itemID , attPt ) ;
2009-04-05 03:27:50 +00:00
}
2009-04-07 20:24:09 +00:00
2009-04-05 03:27:50 +00:00
return false ;
}
2009-02-09 22:27:27 +00:00
public bool AddSceneObject ( UUID primID , SceneObjectGroup sceneObject )
{
// If the user is banned, we won't let any of their objects
// enter. Period.
/ /
if ( m_regInfo . EstateSettings . IsBanned ( sceneObject . OwnerID ) )
{
m_log . Info ( "[INTERREGION]: Denied prim crossing for " +
"banned avatar" ) ;
return false ;
}
// Force allocation of new LocalId
/ /
foreach ( SceneObjectPart p in sceneObject . Children . Values )
p . LocalId = 0 ;
if ( sceneObject . RootPart . Shape . PCode = = ( byte ) PCode . Prim )
{
2009-02-10 22:54:05 +00:00
if ( sceneObject . RootPart . Shape . State ! = 0 ) // Attchment
2009-02-09 22:27:27 +00:00
{
2009-02-10 22:54:05 +00:00
sceneObject . RootPart . AddFlag ( PrimFlags . TemporaryOnRez ) ;
AddRestoredSceneObject ( sceneObject , false , false ) ;
// Handle attachment special case
/ /
//SceneObjectPart RootPrim = GetSceneObjectPart(primID);
SceneObjectPart RootPrim = sceneObject . RootPart ;
2009-02-09 22:27:27 +00:00
// Fix up attachment Parent Local ID
/ /
ScenePresence sp = GetScenePresence ( sceneObject . OwnerID ) ;
2009-02-11 20:36:17 +00:00
//uint parentLocalID = 0;
2009-02-09 22:27:27 +00:00
if ( sp ! = null )
2009-02-10 22:54:05 +00:00
{
2009-02-11 20:36:17 +00:00
//parentLocalID = sp.LocalId;
2009-02-09 22:27:27 +00:00
2009-02-10 22:54:05 +00:00
//sceneObject.RootPart.IsAttachment = true;
//sceneObject.RootPart.SetParentLocalId(parentLocalID);
2009-02-09 22:27:27 +00:00
2009-02-10 22:54:05 +00:00
SceneObjectGroup grp = sceneObject ;
2009-02-09 22:27:27 +00:00
2009-02-10 22:54:05 +00:00
//RootPrim.SetParentLocalId(parentLocalID);
2009-02-09 22:27:27 +00:00
2009-02-10 22:54:05 +00:00
m_log . DebugFormat ( "[ATTACHMENT]: Received " +
2009-02-09 22:27:27 +00:00
"attachment {0}, inworld asset id {1}" ,
//grp.RootPart.LastOwnerID.ToString(),
grp . GetFromAssetID ( ) ,
grp . UUID . ToString ( ) ) ;
2009-02-10 22:54:05 +00:00
//grp.SetFromAssetID(grp.RootPart.LastOwnerID);
m_log . DebugFormat ( "[ATTACHMENT]: Attach " +
"to avatar {0} at position {1}" ,
sp . UUID . ToString ( ) , grp . AbsolutePosition ) ;
AttachObject ( sp . ControllingClient ,
grp . LocalId , ( uint ) 0 ,
grp . GroupRotation ,
grp . AbsolutePosition , false ) ;
RootPrim . RemFlag ( PrimFlags . TemporaryOnRez ) ;
grp . SendGroupFullUpdate ( ) ;
}
else
{
RootPrim . RemFlag ( PrimFlags . TemporaryOnRez ) ;
RootPrim . AddFlag ( PrimFlags . TemporaryOnRez ) ;
2009-02-09 22:27:27 +00:00
}
2009-02-10 22:54:05 +00:00
2009-02-09 22:27:27 +00:00
}
else
{
AddRestoredSceneObject ( sceneObject , true , false ) ;
if ( ! Permissions . CanObjectEntry ( sceneObject . UUID ,
true , sceneObject . AbsolutePosition ) )
{
// Deny non attachments based on parcel settings
/ /
m_log . Info ( "[INTERREGION]: Denied prim crossing " +
"because of parcel settings" ) ;
DeleteSceneObject ( sceneObject , false ) ;
return false ;
}
}
}
return true ;
}
2007-07-16 15:40:11 +00:00
# endregion
#region Add/Remove Avatar Methods
2008-11-28 20:11:17 +00:00
public override void AddNewClient ( IClientAPI client )
2007-07-16 15:40:11 +00:00
{
2009-05-05 16:17:52 +00:00
SubscribeToClientEvents ( client ) ;
ScenePresence presence ;
if ( m_restorePresences . ContainsKey ( client . AgentId ) )
{
m_log . DebugFormat ( "[SCENE]: Restoring agent {0} {1} in {2}" , client . Name , client . AgentId , RegionInfo . RegionName ) ;
presence = m_restorePresences [ client . AgentId ] ;
m_restorePresences . Remove ( client . AgentId ) ;
// This is one of two paths to create avatars that are
// used. This tends to get called more in standalone
// than grid, not really sure why, but as such needs
// an explicity appearance lookup here.
AvatarAppearance appearance = null ;
GetAvatarAppearance ( client , out appearance ) ;
presence . Appearance = appearance ;
presence . initializeScenePresence ( client , RegionInfo , this ) ;
m_sceneGraph . AddScenePresence ( presence ) ;
lock ( m_restorePresences )
2009-02-11 21:07:41 +00:00
{
2009-05-05 16:17:52 +00:00
Monitor . PulseAll ( m_restorePresences ) ;
2008-03-18 15:30:38 +00:00
}
}
2008-03-04 05:31:54 +00:00
else
{
2009-05-05 16:17:52 +00:00
m_log . DebugFormat (
"[SCENE]: Adding new child agent for {0} in {1}" ,
client . Name , RegionInfo . RegionName ) ;
CommsManager . UserProfileCacheService . AddNewUser ( client . AgentId ) ;
CreateAndAddScenePresence ( client ) ;
2008-03-04 05:31:54 +00:00
}
2009-05-05 16:17:52 +00:00
m_LastLogin = Environment . TickCount ;
EventManager . TriggerOnNewClient ( client ) ;
2007-07-16 15:40:11 +00:00
}
protected virtual void SubscribeToClientEvents ( IClientAPI client )
{
2007-07-17 17:47:23 +00:00
client . OnRegionHandShakeReply + = SendLayerData ;
client . OnAddPrim + = AddNewPrim ;
2008-11-12 20:16:46 +00:00
client . OnUpdatePrimGroupPosition + = m_sceneGraph . UpdatePrimPosition ;
client . OnUpdatePrimSinglePosition + = m_sceneGraph . UpdatePrimSinglePosition ;
client . OnUpdatePrimGroupRotation + = m_sceneGraph . UpdatePrimRotation ;
client . OnUpdatePrimGroupMouseRotation + = m_sceneGraph . UpdatePrimRotation ;
client . OnUpdatePrimSingleRotation + = m_sceneGraph . UpdatePrimSingleRotation ;
client . OnUpdatePrimScale + = m_sceneGraph . UpdatePrimScale ;
client . OnUpdatePrimGroupScale + = m_sceneGraph . UpdatePrimGroupScale ;
client . OnUpdateExtraParams + = m_sceneGraph . UpdateExtraParam ;
client . OnUpdatePrimShape + = m_sceneGraph . UpdatePrimShape ;
client . OnUpdatePrimTexture + = m_sceneGraph . UpdatePrimTexture ;
2007-07-17 17:47:23 +00:00
client . OnTeleportLocationRequest + = RequestTeleportLocation ;
2008-04-16 14:10:54 +00:00
client . OnTeleportLandmarkRequest + = RequestTeleportLandmark ;
2007-07-17 17:47:23 +00:00
client . OnObjectSelect + = SelectPrim ;
client . OnObjectDeselect + = DeselectPrim ;
2008-11-12 20:16:46 +00:00
client . OnGrabUpdate + = m_sceneGraph . MoveObject ;
2009-04-10 06:39:52 +00:00
client . OnSpinStart + = m_sceneGraph . SpinStart ;
client . OnSpinUpdate + = m_sceneGraph . SpinObject ;
2007-07-29 13:05:57 +00:00
client . OnDeRezObject + = DeRezObject ;
2007-08-16 16:31:32 +00:00
client . OnRezObject + = RezObject ;
2008-08-19 02:12:40 +00:00
client . OnRezSingleAttachmentFromInv + = RezSingleAttachment ;
2009-04-07 17:46:23 +00:00
client . OnRezMultipleAttachmentsFromInv + = RezMultipleAttachments ;
2008-08-19 02:12:40 +00:00
client . OnDetachAttachmentIntoInv + = DetachSingleAttachmentToInv ;
2008-11-12 20:16:46 +00:00
client . OnObjectAttach + = m_sceneGraph . AttachObject ;
client . OnObjectDetach + = m_sceneGraph . DetachObject ;
client . OnObjectDrop + = m_sceneGraph . DropObject ;
2007-11-04 13:48:15 +00:00
client . OnNameFromUUIDRequest + = CommsManager . HandleUUIDNameRequest ;
2008-11-12 20:16:46 +00:00
client . OnObjectDescription + = m_sceneGraph . PrimDescription ;
client . OnObjectName + = m_sceneGraph . PrimName ;
client . OnObjectClickAction + = m_sceneGraph . PrimClickAction ;
client . OnObjectMaterial + = m_sceneGraph . PrimMaterial ;
client . OnLinkObjects + = m_sceneGraph . LinkObjects ;
client . OnDelinkObjects + = m_sceneGraph . DelinkObjects ;
client . OnObjectDuplicate + = m_sceneGraph . DuplicateObject ;
2008-05-01 15:17:49 +00:00
client . OnObjectDuplicateOnRay + = doObjectDuplicateOnRay ;
2008-11-12 20:16:46 +00:00
client . OnUpdatePrimFlags + = m_sceneGraph . UpdatePrimFlags ;
2009-03-30 18:20:41 +00:00
client . OnRequestObjectPropertiesFamily + = m_sceneGraph . RequestObjectPropertiesFamily ;
2007-12-05 06:44:32 +00:00
client . OnObjectPermissions + = HandleObjectPermissionsUpdate ;
2007-08-14 17:48:25 +00:00
client . OnCreateNewInventoryItem + = CreateNewInventoryItem ;
2008-12-10 19:12:59 +00:00
client . OnCreateNewInventoryFolder + = HandleCreateInventoryFolder ;
client . OnUpdateInventoryFolder + = HandleUpdateInventoryFolder ;
client . OnMoveInventoryFolder + = HandleMoveInventoryFolder ;
client . OnFetchInventoryDescendents + = HandleFetchInventoryDescendents ;
client . OnPurgeInventoryDescendents + = HandlePurgeInventoryDescendents ;
client . OnFetchInventory + = HandleFetchInventory ;
2007-12-03 20:06:01 +00:00
client . OnUpdateInventoryItem + = UpdateInventoryItemAsset ;
2007-11-18 13:50:46 +00:00
client . OnCopyInventoryItem + = CopyInventoryItem ;
2007-12-08 19:13:10 +00:00
client . OnMoveInventoryItem + = MoveInventoryItem ;
2008-02-18 03:25:14 +00:00
client . OnRemoveInventoryItem + = RemoveInventoryItem ;
client . OnRemoveInventoryFolder + = RemoveInventoryFolder ;
2007-08-21 21:03:18 +00:00
client . OnRezScript + = RezScript ;
2007-12-27 21:41:48 +00:00
client . OnRequestTaskInventory + = RequestTaskInventory ;
2007-08-22 18:36:47 +00:00
client . OnRemoveTaskItem + = RemoveTaskInventory ;
2007-12-22 02:52:35 +00:00
client . OnUpdateTaskInventory + = UpdateTaskInventory ;
2008-06-24 23:55:33 +00:00
client . OnMoveTaskItem + = ClientMoveTaskInventoryItem ;
2007-08-13 20:11:35 +00:00
client . OnGrabObject + = ProcessObjectGrab ;
2008-04-27 22:15:38 +00:00
client . OnDeGrabObject + = ProcessObjectDeGrab ;
2008-02-04 10:39:30 +00:00
client . OnMoneyTransferRequest + = ProcessMoneyTransferRequest ;
2008-04-14 17:13:38 +00:00
client . OnParcelBuy + = ProcessParcelBuy ;
2007-11-13 22:48:19 +00:00
client . OnAvatarPickerRequest + = ProcessAvatarPickerRequest ;
2008-11-12 20:16:46 +00:00
client . OnObjectIncludeInSearch + = m_sceneGraph . MakeObjectSearchable ;
2008-04-17 05:07:14 +00:00
client . OnTeleportHomeRequest + = TeleportClientHome ;
client . OnSetStartLocationRequest + = SetHomeRezPoint ;
2008-11-12 20:16:46 +00:00
client . OnUndo + = m_sceneGraph . HandleUndo ;
client . OnObjectGroupRequest + = m_sceneGraph . HandleObjectGroupUpdate ;
2008-05-24 11:10:21 +00:00
client . OnParcelReturnObjectsRequest + = LandChannel . ReturnObjectsInParcel ;
2008-10-18 05:51:36 +00:00
client . OnParcelSetOtherCleanTime + = LandChannel . SetParcelOtherCleanTime ;
2008-08-24 00:51:21 +00:00
client . OnObjectSaleInfo + = ObjectSaleInfo ;
2008-05-26 16:16:48 +00:00
client . OnScriptReset + = ProcessScriptReset ;
2008-06-28 16:08:12 +00:00
client . OnGetScriptRunning + = GetScriptRunning ;
client . OnSetScriptRunning + = SetScriptRunning ;
2008-08-16 19:20:14 +00:00
client . OnRegionHandleRequest + = RegionHandleRequest ;
2008-07-21 15:13:34 +00:00
client . OnUnackedTerrain + = TerrainUnAcked ;
2008-10-06 00:09:49 +00:00
client . OnObjectOwner + = ObjectOwner ;
2009-02-04 00:01:36 +00:00
2009-04-03 17:14:51 +00:00
IGodsModule godsModule = RequestModuleInterface < IGodsModule > ( ) ;
2009-03-30 18:20:41 +00:00
client . OnGodKickUser + = godsModule . KickUser ;
client . OnRequestGodlikePowers + = godsModule . RequestGodlikePowers ;
2009-04-03 17:14:51 +00:00
client . OnNetworkStatsUpdate + = StatsReporter . AddPacketsStats ;
2008-10-06 00:09:49 +00:00
2008-05-23 16:07:47 +00:00
// EventManager.TriggerOnNewClient(client);
2007-07-16 15:40:11 +00:00
}
2008-05-16 13:33:57 +00:00
2008-10-04 18:46:34 +00:00
/// <summary>
/// Teleport an avatar to their home region
/// </summary>
/// <param name="agentId"></param>
/// <param name="client"></param>
2008-09-06 07:52:41 +00:00
public virtual void TeleportClientHome ( UUID agentId , IClientAPI client )
2008-04-17 05:07:14 +00:00
{
2008-08-16 19:34:12 +00:00
UserProfileData UserProfile = CommsManager . UserService . GetUserProfile ( agentId ) ;
2008-04-17 05:07:14 +00:00
if ( UserProfile ! = null )
{
2008-10-04 18:46:34 +00:00
RegionInfo regionInfo = CommsManager . GridService . RequestNeighbourInfo ( UserProfile . HomeRegionID ) ;
if ( regionInfo = = null )
2008-08-14 00:04:37 +00:00
{
2008-10-04 18:46:34 +00:00
regionInfo = CommsManager . GridService . RequestNeighbourInfo ( UserProfile . HomeRegion ) ;
2008-11-21 18:44:48 +00:00
if ( regionInfo ! = null ) // home region can be away temporarily, too
2008-11-16 23:53:00 +00:00
{
UserProfile . HomeRegionID = regionInfo . RegionID ;
CommsManager . UserService . UpdateUserProfile ( UserProfile ) ;
}
2008-08-14 00:04:37 +00:00
}
2008-10-04 18:46:34 +00:00
if ( regionInfo = = null )
2008-08-14 00:04:37 +00:00
{
2008-10-04 18:46:34 +00:00
// can't find the Home region: Tell viewer and abort
client . SendTeleportFailed ( "Your home-region could not be found." ) ;
return ;
2008-08-14 00:04:37 +00:00
}
2008-10-04 18:46:34 +00:00
RequestTeleportLocation (
2008-10-14 09:40:05 +00:00
client , regionInfo . RegionHandle , UserProfile . HomeLocation , UserProfile . HomeLookAt ,
2008-10-04 18:46:34 +00:00
( uint ) ( TPFlags . SetLastToTarget | TPFlags . ViaHome ) ) ;
2008-04-17 05:07:14 +00:00
}
2008-05-01 18:04:42 +00:00
}
2008-05-16 01:22:11 +00:00
2008-09-06 07:52:41 +00:00
public void doObjectDuplicateOnRay ( uint localID , uint dupeFlags , UUID AgentID , UUID GroupID ,
UUID RayTargetObj , Vector3 RayEnd , Vector3 RayStart ,
2008-06-13 00:21:53 +00:00
bool BypassRaycast , bool RayEndIsIntersection , bool CopyCenters , bool CopyRotates )
2008-05-16 01:22:11 +00:00
{
2008-09-06 07:52:41 +00:00
Vector3 pos ;
2008-05-02 18:36:41 +00:00
const bool frontFacesOnly = true ;
2008-06-10 00:18:00 +00:00
//m_log.Info("HITTARGET: " + RayTargetObj.ToString() + ", COPYTARGET: " + localID.ToString());
2008-05-01 15:17:49 +00:00
SceneObjectPart target = GetSceneObjectPart ( localID ) ;
2008-05-02 02:31:22 +00:00
SceneObjectPart target2 = GetSceneObjectPart ( RayTargetObj ) ;
2008-05-01 15:17:49 +00:00
2008-05-02 02:31:22 +00:00
if ( target ! = null & & target2 ! = null )
2008-05-01 15:17:49 +00:00
{
2008-09-06 07:52:41 +00:00
Vector3 direction = Vector3 . Normalize ( RayEnd - RayStart ) ;
2008-05-01 15:17:49 +00:00
Vector3 AXOrigin = new Vector3 ( RayStart . X , RayStart . Y , RayStart . Z ) ;
2008-05-16 01:22:11 +00:00
Vector3 AXdirection = new Vector3 ( direction . X , direction . Y , direction . Z ) ;
2008-05-02 02:31:22 +00:00
if ( target2 . ParentGroup ! = null )
2008-05-01 15:17:49 +00:00
{
2008-05-02 02:31:22 +00:00
pos = target2 . AbsolutePosition ;
//m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
2008-05-01 15:17:49 +00:00
2008-05-02 02:31:22 +00:00
// TODO: Raytrace better here
2008-05-01 15:17:49 +00:00
2008-11-12 20:16:46 +00:00
//EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
2008-05-02 02:31:22 +00:00
Ray NewRay = new Ray ( AXOrigin , AXdirection ) ;
2008-05-01 15:17:49 +00:00
2008-05-02 02:31:22 +00:00
// Ray Trace against target here
2008-09-06 07:52:41 +00:00
EntityIntersection ei = target2 . TestIntersectionOBB ( NewRay , Quaternion . Identity , frontFacesOnly , CopyCenters ) ;
2008-05-01 15:17:49 +00:00
2008-05-02 02:31:22 +00:00
// Un-comment out the following line to Get Raytrace results printed to the console.
2008-06-10 00:18:00 +00:00
//m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
2008-05-02 02:31:22 +00:00
float ScaleOffset = 0.5f ;
2008-05-01 15:17:49 +00:00
2008-05-02 02:31:22 +00:00
// If we hit something
if ( ei . HitTF )
{
2008-09-06 07:52:41 +00:00
Vector3 scale = target . Scale ;
Vector3 scaleComponent = new Vector3 ( ei . AAfaceNormal . X , ei . AAfaceNormal . Y , ei . AAfaceNormal . Z ) ;
2008-05-02 02:31:22 +00:00
if ( scaleComponent . X ! = 0 ) ScaleOffset = scale . X ;
if ( scaleComponent . Y ! = 0 ) ScaleOffset = scale . Y ;
if ( scaleComponent . Z ! = 0 ) ScaleOffset = scale . Z ;
ScaleOffset = Math . Abs ( ScaleOffset ) ;
2008-09-06 07:52:41 +00:00
Vector3 intersectionpoint = new Vector3 ( ei . ipoint . X , ei . ipoint . Y , ei . ipoint . Z ) ;
Vector3 normal = new Vector3 ( ei . normal . X , ei . normal . Y , ei . normal . Z ) ;
Vector3 offset = normal * ( ScaleOffset / 2f ) ;
2008-06-13 00:21:53 +00:00
pos = intersectionpoint + offset ;
2008-05-16 01:22:11 +00:00
2008-06-10 00:18:00 +00:00
// stick in offset format from the original prim
pos = pos - target . ParentGroup . AbsolutePosition ;
if ( CopyRotates )
2008-05-01 15:17:49 +00:00
{
2008-09-06 07:52:41 +00:00
Quaternion worldRot = target2 . GetWorldRotation ( ) ;
2008-05-01 15:17:49 +00:00
2008-11-12 20:16:46 +00:00
// SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
m_sceneGraph . DuplicateObject ( localID , pos , target . GetEffectiveObjectFlags ( ) , AgentID , GroupID , worldRot ) ;
2008-09-06 07:52:41 +00:00
//obj.Rotation = worldRot;
2008-06-10 00:18:00 +00:00
//obj.UpdateGroupRotation(worldRot);
}
else
{
2008-11-12 20:16:46 +00:00
m_sceneGraph . DuplicateObject ( localID , pos , target . GetEffectiveObjectFlags ( ) , AgentID , GroupID ) ;
2008-06-10 00:18:00 +00:00
}
2008-05-01 15:17:49 +00:00
}
2008-05-02 02:31:22 +00:00
2008-05-01 15:17:49 +00:00
return ;
}
2008-05-16 01:22:11 +00:00
2008-05-16 13:33:57 +00:00
return ;
2008-05-01 15:17:49 +00:00
}
2008-05-01 18:04:42 +00:00
}
2008-05-16 13:33:57 +00:00
2008-09-06 07:52:41 +00:00
public virtual void SetHomeRezPoint ( IClientAPI remoteClient , ulong regionHandle , Vector3 position , Vector3 lookAt , uint flags )
2008-04-17 05:07:14 +00:00
{
UserProfileData UserProfile = CommsManager . UserService . GetUserProfile ( remoteClient . AgentId ) ;
if ( UserProfile ! = null )
{
// I know I'm ignoring the regionHandle provided by the teleport location request.
// reusing the TeleportLocationRequest delegate, so regionHandle isn't valid
2008-08-14 00:04:37 +00:00
UserProfile . HomeRegionID = RegionInfo . RegionID ;
// TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around.
// TODO: The HomeRegion property can be removed then, too
2008-04-17 05:07:14 +00:00
UserProfile . HomeRegion = RegionInfo . RegionHandle ;
2008-08-16 19:34:12 +00:00
UserProfile . HomeLocation = position ;
UserProfile . HomeLookAt = lookAt ;
2008-09-15 19:02:34 +00:00
CommsManager . UserService . UpdateUserProfile ( UserProfile ) ;
2008-05-16 01:22:11 +00:00
2008-09-21 13:31:30 +00:00
// FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
2009-01-07 20:46:28 +00:00
m_dialogModule . SendAlertToUser ( remoteClient , "Home position set." ) ;
2008-04-17 05:07:14 +00:00
}
else
{
2009-01-07 20:46:28 +00:00
m_dialogModule . SendAlertToUser ( remoteClient , "Set Home request Failed." ) ;
2008-04-17 05:07:14 +00:00
}
2008-05-01 18:04:42 +00:00
}
2008-05-16 01:22:11 +00:00
2008-10-28 15:46:30 +00:00
/// <summary>
2008-11-28 20:11:17 +00:00
/// Create a child agent scene presence and add it to this scene.
2008-10-28 15:46:30 +00:00
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
2008-11-28 20:11:17 +00:00
protected virtual ScenePresence CreateAndAddScenePresence ( IClientAPI client )
2007-07-16 15:40:11 +00:00
{
2009-02-17 00:35:52 +00:00
AvatarAppearance appearance = null ;
GetAvatarAppearance ( client , out appearance ) ;
2007-10-26 14:08:36 +00:00
2008-11-28 20:11:17 +00:00
ScenePresence avatar = m_sceneGraph . CreateAndAddChildScenePresence ( client , appearance ) ;
2008-12-15 16:23:34 +00:00
//avatar.KnownRegions = GetChildrenSeeds(avatar.UUID);
2007-11-29 06:07:48 +00:00
return avatar ;
2007-07-16 15:40:11 +00:00
}
2008-06-19 17:03:59 +00:00
/// <summary>
/// Get the avatar apperance for the given client.
/// </summary>
/// <param name="client"></param>
/// <param name="appearance"></param>
2008-05-19 20:33:54 +00:00
public void GetAvatarAppearance ( IClientAPI client , out AvatarAppearance appearance )
2008-05-19 19:08:59 +00:00
{
2009-02-17 00:35:52 +00:00
AgentCircuitData aCircuit = m_authenticateHandler . GetAgentCircuitData ( client . CircuitCode ) ;
2009-02-22 12:39:46 +00:00
2009-02-23 10:36:16 +00:00
if ( aCircuit = = null )
2009-02-22 12:39:46 +00:00
{
m_log . DebugFormat ( "[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance." ) ;
appearance = new AvatarAppearance ( client . AgentId ) ;
return ;
}
2009-02-17 00:35:52 +00:00
appearance = aCircuit . Appearance ;
if ( appearance = = null )
2008-06-19 17:03:59 +00:00
{
2009-02-17 00:35:52 +00:00
m_log . DebugFormat ( "[APPEARANCE]: Appearance not found in {0}, returning default" , RegionInfo . RegionName ) ;
2009-02-22 01:26:11 +00:00
appearance = new AvatarAppearance ( client . AgentId ) ;
2008-08-18 00:39:10 +00:00
}
2009-02-17 00:35:52 +00:00
2008-05-19 19:08:59 +00:00
}
2007-12-01 14:20:37 +00:00
2007-07-16 15:40:11 +00:00
/// <summary>
2008-03-25 17:08:20 +00:00
/// Remove the given client from the scene.
2007-07-16 15:40:11 +00:00
/// </summary>
/// <param name="agentID"></param>
2008-09-06 07:52:41 +00:00
public override void RemoveClient ( UUID agentID )
2007-07-16 15:40:11 +00:00
{
2008-02-27 17:41:42 +00:00
bool childagentYN = false ;
2007-09-20 13:04:51 +00:00
ScenePresence avatar = GetScenePresence ( agentID ) ;
2008-02-27 17:41:42 +00:00
if ( avatar ! = null )
{
childagentYN = avatar . IsChildAgent ;
}
2008-08-18 00:39:10 +00:00
2009-04-27 14:04:01 +00:00
if ( avatar . ParentID ! = 0 )
{
avatar . StandUp ( ) ;
}
2007-12-12 18:03:37 +00:00
try
2007-12-12 06:58:55 +00:00
{
2008-08-01 20:05:26 +00:00
m_log . DebugFormat (
2008-08-18 00:39:10 +00:00
"[SCENE]: Removing {0} agent {1} from region {2}" ,
2008-08-01 20:05:26 +00:00
( childagentYN ? "child" : "root" ) , agentID , RegionInfo . RegionName ) ;
2008-08-18 00:39:10 +00:00
2008-12-14 02:17:12 +00:00
m_sceneGraph . removeUserCount ( ! childagentYN ) ;
2009-01-21 21:14:17 +00:00
CapsModule . RemoveCapsHandler ( agentID ) ;
2008-12-14 02:17:12 +00:00
2008-12-15 20:45:40 +00:00
if ( avatar . Scene . NeedSceneCacheClear ( avatar . UUID ) )
{
CommsManager . UserProfileCacheService . RemoveUser ( agentID ) ;
}
2008-12-14 02:17:12 +00:00
if ( ! avatar . IsChildAgent )
2007-12-12 18:03:37 +00:00
{
2008-10-04 18:46:34 +00:00
m_sceneGridService . LogOffUser ( agentID , RegionInfo . RegionID , RegionInfo . RegionHandle , avatar . AbsolutePosition , avatar . Lookat ) ;
2008-12-14 02:17:12 +00:00
//List<ulong> childknownRegions = new List<ulong>();
//List<ulong> ckn = avatar.KnownChildRegionHandles;
//for (int i = 0; i < ckn.Count; i++)
//{
// childknownRegions.Add(ckn[i]);
//}
2008-12-22 06:56:47 +00:00
List < ulong > regions = new List < ulong > ( avatar . KnownChildRegionHandles ) ;
regions . Remove ( RegionInfo . RegionHandle ) ;
m_sceneGridService . SendCloseChildAgentConnections ( agentID , regions ) ;
2008-05-16 01:22:11 +00:00
2007-12-12 18:03:37 +00:00
}
2008-02-05 05:26:18 +00:00
m_eventManager . TriggerClientClosed ( agentID ) ;
2007-12-12 06:58:55 +00:00
}
2007-12-27 21:41:48 +00:00
catch ( NullReferenceException )
2007-12-12 06:58:55 +00:00
{
2007-12-12 18:03:37 +00:00
// We don't know which count to remove it from
// Avatar is already disposed :/
2007-12-12 06:58:55 +00:00
}
2008-08-18 00:39:10 +00:00
2007-12-12 18:03:37 +00:00
m_eventManager . TriggerOnRemovePresence ( agentID ) ;
2007-12-06 04:01:56 +00:00
Broadcast ( delegate ( IClientAPI client )
2008-05-01 18:04:42 +00:00
{
try
{
2008-10-14 14:43:46 +00:00
client . SendKillObject ( avatar . RegionHandle , avatar . LocalId ) ;
2008-05-01 18:04:42 +00:00
}
catch ( NullReferenceException )
2007-12-06 04:01:56 +00:00
{
2008-05-01 18:04:42 +00:00
//We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
}
} ) ;
2007-07-16 15:40:11 +00:00
2007-07-17 17:47:23 +00:00
ForEachScenePresence (
2007-10-30 09:05:31 +00:00
delegate ( ScenePresence presence ) { presence . CoarseLocationChange ( ) ; } ) ;
2008-05-16 01:22:11 +00:00
2008-05-01 18:04:42 +00:00
IAgentAssetTransactions agentTransactions = this . RequestModuleInterface < IAgentAssetTransactions > ( ) ;
2008-02-16 13:01:42 +00:00
if ( agentTransactions ! = null )
{
agentTransactions . RemoveAgentAssetTransactions ( agentID ) ;
}
2007-07-16 15:40:11 +00:00
2008-11-12 20:16:46 +00:00
m_sceneGraph . RemoveScenePresence ( agentID ) ;
2007-09-21 05:23:17 +00:00
2007-11-18 07:16:17 +00:00
try
{
avatar . Close ( ) ;
}
2007-12-27 21:41:48 +00:00
catch ( NullReferenceException )
2007-11-25 04:33:18 +00:00
{
//We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
2007-12-12 17:15:37 +00:00
}
2007-11-18 07:16:17 +00:00
catch ( Exception e )
{
2008-05-01 18:04:42 +00:00
m_log . Error ( "[SCENE] Scene.cs:RemoveClient exception: " + e . ToString ( ) ) ;
2007-11-18 07:16:17 +00:00
}
2007-08-14 17:29:15 +00:00
2007-07-31 14:42:50 +00:00
// Remove client agent from profile, so new logins will work
2008-02-27 17:41:42 +00:00
if ( ! childagentYN )
2008-02-27 11:52:02 +00:00
{
m_sceneGridService . ClearUserAgent ( agentID ) ;
}
2008-02-10 14:27:21 +00:00
2009-04-14 02:21:40 +00:00
m_authenticateHandler . RemoveCircuit ( avatar . ControllingClient . CircuitCode ) ;
2008-02-10 01:57:59 +00:00
//m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
2008-05-16 01:22:11 +00:00
//m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
2007-07-16 15:40:11 +00:00
}
2008-03-31 18:41:24 +00:00
2008-09-06 07:52:41 +00:00
public void HandleRemoveKnownRegionsFromAvatar ( UUID avatarID , List < ulong > regionslst )
2008-02-20 01:17:21 +00:00
{
ScenePresence av = GetScenePresence ( avatarID ) ;
if ( av ! = null )
{
lock ( av )
{
for ( int i = 0 ; i < regionslst . Count ; i + + )
{
2008-12-14 02:17:12 +00:00
av . KnownChildRegionHandles . Remove ( regionslst [ i ] ) ;
2008-02-20 01:17:21 +00:00
}
}
}
}
2007-12-27 21:41:48 +00:00
public override void CloseAllAgents ( uint circuitcode )
2007-12-18 00:34:42 +00:00
{
// Called by ClientView to kill all circuit codes
ClientManager . CloseAllAgents ( circuitcode ) ;
}
2007-12-27 21:41:48 +00:00
2007-11-03 19:14:22 +00:00
public void NotifyMyCoarseLocationChange ( )
2007-10-22 17:55:49 +00:00
{
2007-11-03 19:14:22 +00:00
ForEachScenePresence ( delegate ( ScenePresence presence ) { presence . CoarseLocationChange ( ) ; } ) ;
2007-07-16 15:40:11 +00:00
}
2007-12-27 21:41:48 +00:00
2007-07-17 17:47:23 +00:00
# endregion
2007-07-16 15:40:11 +00:00
2007-11-03 19:14:22 +00:00
#region Entities
2007-12-27 21:41:48 +00:00
2008-10-14 14:43:46 +00:00
public void SendKillObject ( uint localID )
2007-08-21 18:11:45 +00:00
{
2008-09-03 19:28:46 +00:00
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
if ( part ! = null ) // It is a prim
{
2008-11-17 15:40:27 +00:00
if ( part . ParentGroup ! = null & & ! part . ParentGroup . IsDeleted ) // Valid
2008-09-03 19:28:46 +00:00
{
if ( part . ParentGroup . RootPart ! = part ) // Child part
return ;
}
}
2008-10-14 14:43:46 +00:00
Broadcast ( delegate ( IClientAPI client ) { client . SendKillObject ( m_regionHandle , localID ) ; } ) ;
2007-08-21 18:11:45 +00:00
}
2007-11-03 19:14:22 +00:00
# endregion
2007-07-16 15:40:11 +00:00
2007-11-03 19:14:22 +00:00
#region RegionComms
2007-07-16 15:40:11 +00:00
/// <summary>
2008-09-07 03:22:33 +00:00
/// Register the methods that should be invoked when this scene receives various incoming events
2007-07-16 15:40:11 +00:00
/// </summary>
2007-11-28 12:36:09 +00:00
public void RegisterCommsEvents ( )
2007-07-16 15:40:11 +00:00
{
2009-03-03 15:41:21 +00:00
m_sceneGridService . OnExpectUser + = HandleNewUserConnection ;
2007-11-03 19:14:22 +00:00
m_sceneGridService . OnAvatarCrossingIntoRegion + = AgentCrossing ;
2009-01-01 19:42:24 +00:00
m_sceneGridService . OnCloseAgentConnection + = IncomingCloseAgent ;
2007-11-26 05:02:18 +00:00
m_sceneGridService . OnRegionUp + = OtherRegionUp ;
2008-12-29 22:22:05 +00:00
//m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
2008-02-11 01:43:54 +00:00
m_sceneGridService . OnExpectPrim + = IncomingInterRegionPrimGroup ;
2008-12-20 18:15:02 +00:00
//m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
2008-05-31 12:18:29 +00:00
m_sceneGridService . OnLogOffUser + = HandleLogOffUserFromGrid ;
2008-10-14 14:43:46 +00:00
m_sceneGridService . KiPrimitive + = SendKillObject ;
2008-08-16 19:20:14 +00:00
m_sceneGridService . OnGetLandData + = GetLandData ;
2008-12-29 22:22:05 +00:00
if ( m_interregionCommsIn ! = null )
{
m_log . Debug ( "[SCENE]: Registering with InterregionCommsIn" ) ;
m_interregionCommsIn . OnChildAgentUpdate + = IncomingChildAgentDataUpdate ;
}
else
m_log . Debug ( "[SCENE]: Unable to register with InterregionCommsIn" ) ;
2007-07-16 15:40:11 +00:00
}
2007-11-28 12:36:09 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2008-11-14 20:06:44 +00:00
/// Deregister this scene from receiving incoming region events
2007-12-06 04:01:56 +00:00
/// </summary>
2008-09-18 15:44:05 +00:00
public void UnRegisterRegionWithComms ( )
2007-12-27 21:41:48 +00:00
{
2008-10-14 14:43:46 +00:00
m_sceneGridService . KiPrimitive - = SendKillObject ;
2008-05-31 12:18:29 +00:00
m_sceneGridService . OnLogOffUser - = HandleLogOffUserFromGrid ;
2008-12-20 18:15:02 +00:00
//m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
2008-02-11 01:43:54 +00:00
m_sceneGridService . OnExpectPrim - = IncomingInterRegionPrimGroup ;
2008-12-29 22:22:05 +00:00
//m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
2007-11-26 05:02:18 +00:00
m_sceneGridService . OnRegionUp - = OtherRegionUp ;
2009-03-03 15:41:21 +00:00
m_sceneGridService . OnExpectUser - = HandleNewUserConnection ;
2007-11-25 04:52:14 +00:00
m_sceneGridService . OnAvatarCrossingIntoRegion - = AgentCrossing ;
2009-01-01 19:42:24 +00:00
m_sceneGridService . OnCloseAgentConnection - = IncomingCloseAgent ;
2008-08-16 19:20:14 +00:00
m_sceneGridService . OnGetLandData - = GetLandData ;
2007-12-27 21:41:48 +00:00
2008-12-29 22:22:05 +00:00
if ( m_interregionCommsIn ! = null )
m_interregionCommsIn . OnChildAgentUpdate - = IncomingChildAgentDataUpdate ;
2007-11-25 04:52:14 +00:00
m_sceneGridService . Close ( ) ;
}
2007-12-27 21:41:48 +00:00
2009-03-03 15:41:21 +00:00
/// <summary>
/// A handler for the SceneCommunicationService event, to match that events return type of void.
/// Use NewUserConnection() directly if possible so the return type can refuse connections.
/// At the moment nothing actually seems to use this event,
/// as everything is switching to calling the NewUserConnection method directly.
/// </summary>
/// <param name="agent"></param>
public void HandleNewUserConnection ( AgentCircuitData agent )
{
2009-05-05 16:17:52 +00:00
string reason ;
NewUserConnection ( agent , out reason ) ;
2009-03-03 15:41:21 +00:00
}
2007-07-16 15:40:11 +00:00
/// <summary>
2008-09-07 03:22:33 +00:00
/// Do the work necessary to initiate a new user connection for a particular scene.
2008-03-19 19:25:10 +00:00
/// At the moment, this consists of setting up the caps infrastructure
2009-03-03 15:41:21 +00:00
/// The return bool should allow for connections to be refused, but as not all calling paths
/// take proper notice of it let, we allowed banned users in still.
2007-07-16 15:40:11 +00:00
/// </summary>
/// <param name="regionHandle"></param>
/// <param name="agent"></param>
2009-05-05 16:17:52 +00:00
/// <param name="reason"></param>
public bool NewUserConnection ( AgentCircuitData agent , out string reason )
2007-07-16 15:40:11 +00:00
{
2009-05-06 20:02:49 +00:00
// Don't disable this log message - it's too helpful
m_log . InfoFormat (
"[CONNECTION BEGIN]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5})" ,
RegionInfo . RegionName , ( agent . child ? "child" : "root" ) , agent . firstname , agent . lastname ,
agent . AgentID , agent . circuitcode ) ;
2008-12-14 02:17:12 +00:00
2009-05-05 16:17:52 +00:00
reason = String . Empty ;
2009-05-06 20:02:49 +00:00
if ( ! AuthenticateUser ( agent , out reason ) )
return false ;
2009-05-05 16:17:52 +00:00
2009-05-06 20:02:49 +00:00
if ( ! AuthorizeUser ( agent , out reason ) )
return false ;
2009-05-05 16:17:52 +00:00
2009-05-11 07:46:12 +00:00
m_log . InfoFormat (
"[CONNECTION BEGIN]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})" ,
RegionInfo . RegionName , ( agent . child ? "child" : "root" ) , agent . firstname , agent . lastname ,
agent . AgentID , agent . circuitcode ) ;
2009-05-06 20:02:49 +00:00
CapsModule . NewUserConnection ( agent ) ;
2009-05-05 16:17:52 +00:00
2009-05-06 20:02:49 +00:00
ScenePresence sp = m_sceneGraph . GetScenePresence ( agent . AgentID ) ;
if ( sp ! = null )
2009-02-04 00:01:36 +00:00
{
2009-05-06 20:02:49 +00:00
m_log . DebugFormat (
"[SCENE]: Adjusting known seeds for existing agent {0} in {1}" ,
agent . AgentID , RegionInfo . RegionName ) ;
sp . AdjustKnownSeeds ( ) ;
return true ;
}
CapsModule . AddCapsHandler ( agent . AgentID ) ;
if ( ! agent . child )
{
// Honor parcel landing type and position.
ILandObject land = LandChannel . GetLandObject ( agent . startpos . X , agent . startpos . Y ) ;
if ( land ! = null )
2008-11-12 19:12:33 +00:00
{
2009-05-06 20:02:49 +00:00
if ( land . landData . LandingType = = ( byte ) 1 & & land . landData . UserLocation ! = Vector3 . Zero )
2008-04-05 09:47:05 +00:00
{
2009-05-06 20:02:49 +00:00
agent . startpos = land . landData . UserLocation ;
2008-04-05 09:47:05 +00:00
}
2007-07-16 15:40:11 +00:00
}
2009-05-06 20:02:49 +00:00
}
m_authenticateHandler . AddNewCircuit ( agent . circuitcode , agent ) ;
// rewrite session_id
CachedUserInfo userinfo = CommsManager . UserProfileCacheService . GetUserDetails ( agent . AgentID ) ;
if ( userinfo ! = null )
{
userinfo . SessionID = agent . SessionID ;
2007-07-16 15:40:11 +00:00
}
2008-02-08 17:49:53 +00:00
else
{
2009-05-06 20:02:49 +00:00
m_log . WarnFormat (
"[CONNECTION BEGIN]: We couldn't find a User Info record for {0}. This is usually an indication that the UUID we're looking up is invalid" , agent . AgentID ) ;
2008-02-08 17:49:53 +00:00
}
2009-05-06 20:02:49 +00:00
return true ;
2009-04-14 19:35:35 +00:00
}
2009-03-03 15:41:21 +00:00
2009-05-06 20:02:49 +00:00
public virtual bool AuthenticateUser ( AgentCircuitData agent , out string reason )
2009-04-14 19:35:35 +00:00
{
2009-05-06 20:02:49 +00:00
reason = String . Empty ;
2009-04-14 19:35:35 +00:00
bool result = CommsManager . UserService . VerifySession ( agent . AgentID , agent . SessionID ) ;
m_log . Debug ( "[CONNECTION BEGIN]: User authentication returned " + result ) ;
2009-05-06 20:02:49 +00:00
if ( ! result )
reason = String . Format ( "Failed to authenticate user {0} {1}, access denied." , agent . firstname , agent . lastname ) ;
2009-04-14 19:35:35 +00:00
return result ;
2008-08-25 07:35:17 +00:00
}
2009-05-06 20:02:49 +00:00
protected virtual bool AuthorizeUser ( AgentCircuitData agent , out string reason )
{
reason = String . Empty ;
2009-05-11 07:46:12 +00:00
if ( ! m_strictAccessControl ) return true ;
if ( Permissions . IsGod ( agent . AgentID ) ) return true ;
if ( m_regInfo . EstateSettings . IsBanned ( agent . AgentID ) )
2009-05-06 20:02:49 +00:00
{
m_log . WarnFormat ( "[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist" ,
agent . AgentID , agent . firstname , agent . lastname , RegionInfo . RegionName ) ;
reason = String . Format ( "Denied access to region {0}: You have been banned from that region." ,
RegionInfo . RegionName ) ;
return false ;
}
if ( ! m_regInfo . EstateSettings . PublicAccess & &
2009-05-11 07:46:12 +00:00
! m_regInfo . EstateSettings . HasAccess ( agent . AgentID ) )
2009-05-06 20:02:49 +00:00
{
2009-05-11 07:46:12 +00:00
m_log . WarnFormat ( "[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate" ,
2009-05-06 20:02:49 +00:00
agent . AgentID , agent . firstname , agent . lastname , RegionInfo . RegionName ) ;
reason = String . Format ( "Denied access to private region {0}: You are not on the access list for that region." ,
RegionInfo . RegionName ) ;
return false ;
}
2009-05-11 07:46:12 +00:00
// TODO: estate/region settings are not properly hooked up
// to ILandObject.isRestrictedFromLand()
// if (null != LandChannel)
// {
// // region seems to have local Id of 1
// ILandObject land = LandChannel.GetLandObject(1);
// if (null != land)
// {
// if (land.isBannedFromLand(agent.AgentID))
// {
// m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user has been banned from land",
// agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
// reason = String.Format("Denied access to private region {0}: You are banned from that region.",
// RegionInfo.RegionName);
// return false;
// }
// if (land.isRestrictedFromLand(agent.AgentID))
// {
// m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
// agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
// reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
// RegionInfo.RegionName);
// return false;
// }
// }
// }
2009-05-06 20:02:49 +00:00
return true ;
}
2008-08-25 07:35:17 +00:00
public void UpdateCircuitData ( AgentCircuitData data )
{
m_authenticateHandler . UpdateAgentData ( data ) ;
}
public bool ChangeCircuitCode ( uint oldcc , uint newcc )
{
return m_authenticateHandler . TryChangeCiruitCode ( oldcc , newcc ) ;
2008-05-16 01:22:11 +00:00
}
2008-03-20 20:04:45 +00:00
2009-03-03 15:41:21 +00:00
public void HandleLogOffUserFromGrid ( UUID AvatarID , UUID RegionSecret , string message )
2008-05-31 12:18:29 +00:00
{
2008-11-12 19:12:33 +00:00
ScenePresence loggingOffUser = null ;
loggingOffUser = GetScenePresence ( AvatarID ) ;
if ( loggingOffUser ! = null )
2008-05-31 12:18:29 +00:00
{
2009-01-13 23:25:47 +00:00
UUID localRegionSecret = UUID . Zero ;
bool parsedsecret = UUID . TryParse ( m_regInfo . regionSecret , out localRegionSecret ) ;
// Region Secret is used here in case a new sessionid overwrites an old one on the user server.
// Will update the user server in a few revisions to use it.
if ( RegionSecret = = loggingOffUser . ControllingClient . SecureSessionId | | ( parsedsecret & & RegionSecret = = localRegionSecret ) )
2008-05-31 12:18:29 +00:00
{
2008-12-17 17:44:00 +00:00
m_sceneGridService . SendCloseChildAgentConnections ( loggingOffUser . UUID , new List < ulong > ( loggingOffUser . KnownRegions . Keys ) ) ;
2008-11-12 19:12:33 +00:00
loggingOffUser . ControllingClient . Kick ( message ) ;
// Give them a second to receive the message!
2009-02-12 09:53:12 +00:00
Thread . Sleep ( 1000 ) ;
2008-11-12 19:12:33 +00:00
loggingOffUser . ControllingClient . Close ( true ) ;
2008-05-31 12:18:29 +00:00
}
else
{
2008-11-12 19:12:33 +00:00
m_log . Info ( "[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate" ) ;
2008-05-31 12:18:29 +00:00
}
}
2008-11-12 19:12:33 +00:00
else
{
m_log . InfoFormat ( "[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out" , AvatarID . ToString ( ) ) ;
}
2008-05-31 12:18:29 +00:00
}
2008-08-28 14:41:54 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2008-11-12 18:12:18 +00:00
/// Triggered when an agent crosses into this sim. Also happens on initial login.
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="agentID"></param>
/// <param name="position"></param>
/// <param name="isFlying"></param>
2008-11-12 19:12:33 +00:00
public virtual void AgentCrossing ( UUID agentID , Vector3 position , bool isFlying )
2007-07-16 15:40:11 +00:00
{
2008-11-12 19:12:33 +00:00
ScenePresence presence ;
2009-02-04 00:01:36 +00:00
2008-11-12 19:12:33 +00:00
lock ( m_scenePresences )
2007-07-16 15:40:11 +00:00
{
2008-11-12 19:12:33 +00:00
m_scenePresences . TryGetValue ( agentID , out presence ) ;
}
2009-02-04 00:01:36 +00:00
2008-11-12 19:12:33 +00:00
if ( presence ! = null )
{
try
2007-07-16 15:40:11 +00:00
{
2008-11-12 19:12:33 +00:00
presence . MakeRootAgent ( position , isFlying ) ;
2008-11-12 18:12:18 +00:00
}
2008-11-12 19:12:33 +00:00
catch ( Exception e )
2008-11-12 18:12:18 +00:00
{
2008-11-12 19:12:33 +00:00
m_log . ErrorFormat ( "[SCENE]: Unable to do agent crossing, exception {0}" , e ) ;
2008-11-12 18:12:18 +00:00
}
2007-07-16 15:40:11 +00:00
}
2008-11-12 19:12:33 +00:00
else
{
m_log . ErrorFormat (
"[SCENE]: Could not find presence for agent {0} crossing into scene {1}" ,
agentID , RegionInfo . RegionName ) ;
}
2007-07-16 15:40:11 +00:00
}
2008-12-29 22:22:05 +00:00
public virtual bool IncomingChildAgentDataUpdate ( AgentData cAgentData )
2007-12-10 00:46:56 +00:00
{
2009-01-16 21:56:13 +00:00
// m_log.DebugFormat(
// "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
2009-02-04 00:01:36 +00:00
2009-02-04 16:31:48 +00:00
// We have to wait until the viewer contacts this region after receiving EAC.
// That calls AddNewClient, which finally creates the ScenePresence
ScenePresence childAgentUpdate = WaitGetScenePresence ( cAgentData . AgentID ) ;
2009-01-03 02:29:49 +00:00
if ( childAgentUpdate ! = null )
{
childAgentUpdate . ChildAgentDataUpdate ( cAgentData ) ;
return true ;
}
2009-02-04 00:01:36 +00:00
2009-01-03 02:29:49 +00:00
return false ;
}
public virtual bool IncomingChildAgentDataUpdate ( AgentPosition cAgentData )
{
2009-02-22 20:52:55 +00:00
//m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName);
2008-12-29 22:22:05 +00:00
ScenePresence childAgentUpdate = GetScenePresence ( cAgentData . AgentID ) ;
2008-01-22 08:52:51 +00:00
if ( childAgentUpdate ! = null )
2007-12-10 00:46:56 +00:00
{
2008-05-16 01:22:11 +00:00
// I can't imagine *yet* why we would get an update if the agent is a root agent..
// however to avoid a race condition crossing borders..
2007-12-10 00:46:56 +00:00
if ( childAgentUpdate . IsChildAgent )
{
2008-12-29 22:22:05 +00:00
uint rRegionX = ( uint ) ( cAgentData . RegionHandle > > 40 ) ;
uint rRegionY = ( ( ( uint ) ( cAgentData . RegionHandle ) ) > > 8 ) ;
2008-01-22 08:52:51 +00:00
uint tRegionX = RegionInfo . RegionLocX ;
uint tRegionY = RegionInfo . RegionLocY ;
2007-12-10 00:46:56 +00:00
//Send Data to ScenePresence
2008-01-22 08:52:51 +00:00
childAgentUpdate . ChildAgentDataUpdate ( cAgentData , tRegionX , tRegionY , rRegionX , rRegionY ) ;
2007-12-10 00:46:56 +00:00
// Not Implemented:
//TODO: Do we need to pass the message on to one of our neighbors?
}
2009-02-04 00:01:36 +00:00
2008-01-22 08:52:51 +00:00
return true ;
2007-12-10 00:46:56 +00:00
}
2009-02-04 00:01:36 +00:00
2008-01-22 08:52:51 +00:00
return false ;
2007-12-10 00:46:56 +00:00
}
2007-12-27 21:41:48 +00:00
2009-02-04 16:31:48 +00:00
protected virtual ScenePresence WaitGetScenePresence ( UUID agentID )
{
int ntimes = 10 ;
ScenePresence childAgentUpdate = null ;
while ( ( childAgentUpdate = GetScenePresence ( agentID ) ) = = null & & ( ntimes - - > 0 ) )
Thread . Sleep ( 1000 ) ;
return childAgentUpdate ;
}
2009-03-23 02:37:19 +00:00
public virtual bool IncomingRetrieveRootAgent ( UUID id , out IAgentData agent )
{
agent = null ;
ScenePresence sp = GetScenePresence ( id ) ;
if ( ( sp ! = null ) & & ( ! sp . IsChildAgent ) )
{
sp . IsChildAgent = true ;
return sp . CopyAgent ( out agent ) ;
}
return false ;
}
2009-01-01 19:42:24 +00:00
public virtual bool IncomingReleaseAgent ( UUID id )
{
return m_sceneGridService . ReleaseAgent ( id ) ;
}
public void SendReleaseAgent ( ulong regionHandle , UUID id , string uri )
{
m_interregionCommsOut . SendReleaseAgent ( regionHandle , id , uri ) ;
}
2007-12-06 04:01:56 +00:00
/// <summary>
2007-12-10 21:12:38 +00:00
/// Tell a single agent to disconnect from the region.
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="regionHandle"></param>
/// <param name="agentID"></param>
2009-01-01 19:42:24 +00:00
public bool IncomingCloseAgent ( UUID agentID )
2007-11-05 13:58:44 +00:00
{
2009-01-16 21:56:13 +00:00
//m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
2009-02-04 00:01:36 +00:00
2008-11-12 20:16:46 +00:00
ScenePresence presence = m_sceneGraph . GetScenePresence ( agentID ) ;
2008-11-12 19:12:33 +00:00
if ( presence ! = null )
2007-11-05 13:58:44 +00:00
{
2008-11-12 19:12:33 +00:00
// Nothing is removed here, so down count it as such
2009-01-03 03:30:03 +00:00
if ( presence . IsChildAgent )
{
m_sceneGraph . removeUserCount ( false ) ;
}
else
{
m_sceneGraph . removeUserCount ( true ) ;
}
2008-08-18 00:39:10 +00:00
2008-12-16 19:44:32 +00:00
// Don't do this to root agents on logout, it's not nice for the viewer
2009-02-04 00:01:36 +00:00
if ( presence . IsChildAgent )
2008-12-14 02:17:12 +00:00
{
2008-12-16 19:44:32 +00:00
// Tell a single agent to disconnect from the region.
IEventQueue eq = RequestModuleInterface < IEventQueue > ( ) ;
if ( eq ! = null )
{
2009-02-06 16:55:34 +00:00
eq . DisableSimulator ( RegionInfo . RegionHandle , agentID ) ;
2008-12-16 19:44:32 +00:00
}
else
presence . ControllingClient . SendShutdownConnectionNotice ( ) ;
2008-12-14 02:17:12 +00:00
}
2009-02-04 00:01:36 +00:00
2008-11-12 19:12:33 +00:00
presence . ControllingClient . Close ( true ) ;
2009-01-01 19:42:24 +00:00
return true ;
2007-11-05 13:58:44 +00:00
}
2009-02-04 00:01:36 +00:00
2009-01-01 19:42:24 +00:00
// Agent not here
return false ;
2007-11-05 13:58:44 +00:00
}
2007-07-16 15:40:11 +00:00
/// <summary>
2007-12-10 21:12:38 +00:00
/// Tell neighboring regions about this agent
2008-05-16 01:22:11 +00:00
/// When the regions respond with a true value,
2007-12-10 21:12:38 +00:00
/// tell the agents about the region.
2008-05-16 01:22:11 +00:00
///
2007-12-10 21:12:38 +00:00
/// We have to tell the regions about the agents first otherwise it'll deny them access
2008-05-16 01:22:11 +00:00
///
2007-07-16 15:40:11 +00:00
/// </summary>
2007-12-06 04:01:56 +00:00
/// <param name="presence"></param>
2007-11-03 19:14:22 +00:00
public void InformClientOfNeighbours ( ScenePresence presence )
2007-07-16 15:40:11 +00:00
{
2007-12-10 19:16:50 +00:00
m_sceneGridService . EnableNeighbourChildAgents ( presence , m_neighbours ) ;
2007-07-16 15:40:11 +00:00
}
2007-12-03 07:26:27 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2007-12-10 21:12:38 +00:00
/// Tell a neighboring region about this agent
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="presence"></param>
/// <param name="region"></param>
2007-11-25 04:52:14 +00:00
public void InformClientOfNeighbor ( ScenePresence presence , RegionInfo region )
{
2009-02-14 17:17:48 +00:00
m_sceneGridService . EnableNeighbourChildAgents ( presence , m_neighbours ) ;
2007-11-25 04:52:14 +00:00
}
2007-07-16 15:40:11 +00:00
/// <summary>
2007-12-10 21:12:38 +00:00
/// Requests information about this region from gridcomms
2007-07-16 15:40:11 +00:00
/// </summary>
/// <param name="regionHandle"></param>
/// <returns></returns>
public RegionInfo RequestNeighbouringRegionInfo ( ulong regionHandle )
{
2007-11-03 19:14:22 +00:00
return m_sceneGridService . RequestNeighbouringRegionInfo ( regionHandle ) ;
2007-07-16 15:40:11 +00:00
}
/// <summary>
2007-12-10 21:12:38 +00:00
/// Requests textures for map from minimum region to maximum region in world cordinates
2007-07-16 15:40:11 +00:00
/// </summary>
2007-12-06 04:01:56 +00:00
/// <param name="remoteClient"></param>
2007-07-16 15:40:11 +00:00
/// <param name="minX"></param>
/// <param name="minY"></param>
/// <param name="maxX"></param>
/// <param name="maxY"></param>
public void RequestMapBlocks ( IClientAPI remoteClient , int minX , int minY , int maxX , int maxY )
{
2009-03-30 18:20:41 +00:00
m_log . DebugFormat ( "[MAPBLOCK]: {0}-{1}, {2}-{3}" , minX , minY , maxX , maxY ) ;
2008-06-12 20:19:42 +00:00
m_sceneGridService . RequestMapBlocks ( remoteClient , minX , minY , maxX , maxY ) ;
2007-07-16 15:40:11 +00:00
}
2008-08-16 19:34:12 +00:00
/// <summary>
/// Tries to teleport agent to other region.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="regionName"></param>
/// <param name="position"></param>
/// <param name="lookAt"></param>
2008-10-04 18:46:34 +00:00
/// <param name="teleportFlags"></param>
2008-09-06 07:52:41 +00:00
public void RequestTeleportLocation ( IClientAPI remoteClient , string regionName , Vector3 position ,
2008-10-04 18:46:34 +00:00
Vector3 lookat , uint teleportFlags )
2008-08-16 19:34:12 +00:00
{
RegionInfo regionInfo = m_sceneGridService . RequestClosestRegion ( regionName ) ;
if ( regionInfo = = null )
{
// can't find the region: Tell viewer and abort
remoteClient . SendTeleportFailed ( "The region '" + regionName + "' could not be found." ) ;
return ;
}
2009-02-04 00:01:36 +00:00
2008-10-04 18:46:34 +00:00
RequestTeleportLocation ( remoteClient , regionInfo . RegionHandle , position , lookat , teleportFlags ) ;
2008-08-16 19:34:12 +00:00
}
2007-07-16 15:40:11 +00:00
/// <summary>
2007-12-10 21:12:38 +00:00
/// Tries to teleport agent to other region.
2007-07-16 15:40:11 +00:00
/// </summary>
/// <param name="remoteClient"></param>
2007-12-06 04:01:56 +00:00
/// <param name="regionHandle"></param>
2007-07-16 15:40:11 +00:00
/// <param name="position"></param>
/// <param name="lookAt"></param>
2008-10-04 18:46:34 +00:00
/// <param name="teleportFlags"></param>
2008-09-06 07:52:41 +00:00
public void RequestTeleportLocation ( IClientAPI remoteClient , ulong regionHandle , Vector3 position ,
2008-10-04 18:46:34 +00:00
Vector3 lookAt , uint teleportFlags )
2007-07-16 15:40:11 +00:00
{
2009-01-14 04:18:28 +00:00
ScenePresence sp = null ;
2008-05-07 22:59:30 +00:00
lock ( m_scenePresences )
2007-07-16 15:40:11 +00:00
{
2008-05-07 22:59:30 +00:00
if ( m_scenePresences . ContainsKey ( remoteClient . AgentId ) )
2009-01-14 04:18:28 +00:00
sp = m_scenePresences [ remoteClient . AgentId ] ;
}
2009-02-04 00:01:36 +00:00
2009-01-15 21:27:55 +00:00
if ( sp ! = null )
2009-01-14 04:18:28 +00:00
{
m_sceneGridService . RequestTeleportToLocation ( sp , regionHandle ,
position , lookAt , teleportFlags ) ;
2007-07-16 15:40:11 +00:00
}
}
2008-04-16 14:10:54 +00:00
/// <summary>
/// Tries to teleport agent to landmark.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="regionHandle"></param>
/// <param name="position"></param>
2008-09-06 07:52:41 +00:00
public void RequestTeleportLandmark ( IClientAPI remoteClient , UUID regionID , Vector3 position )
2008-04-16 14:10:54 +00:00
{
2008-08-14 00:04:37 +00:00
RegionInfo info = CommsManager . GridService . RequestNeighbourInfo ( regionID ) ;
2008-08-28 14:41:54 +00:00
2008-08-15 10:24:04 +00:00
if ( info = = null )
2008-08-14 00:04:37 +00:00
{
// can't find the region: Tell viewer and abort
remoteClient . SendTeleportFailed ( "The teleport destination could not be found." ) ;
return ;
}
2008-08-28 14:41:54 +00:00
2009-01-15 23:37:49 +00:00
ScenePresence sp = null ;
2008-05-07 22:59:30 +00:00
lock ( m_scenePresences )
2008-04-16 14:10:54 +00:00
{
2008-05-07 22:59:30 +00:00
if ( m_scenePresences . ContainsKey ( remoteClient . AgentId ) )
2009-01-15 23:37:49 +00:00
sp = m_scenePresences [ remoteClient . AgentId ] ;
}
if ( sp ! = null )
{
m_sceneGridService . RequestTeleportToLocation ( sp , info . RegionHandle ,
position , Vector3 . Zero , ( uint ) ( TPFlags . SetLastToTarget | TPFlags . ViaLandmark ) ) ;
2008-04-16 14:10:54 +00:00
}
}
2009-02-12 23:23:44 +00:00
public void CrossAgentToNewRegion ( ScenePresence agent , bool isFlying )
{
m_sceneGridService . CrossAgentToNewRegion ( this , agent , isFlying ) ;
}
2009-01-03 02:29:49 +00:00
public void SendOutChildAgentUpdates ( AgentPosition cadu , ScenePresence presence )
2008-01-22 08:52:51 +00:00
{
m_sceneGridService . SendChildAgentDataUpdate ( cadu , presence ) ;
}
2007-07-17 17:47:23 +00:00
# endregion
2007-07-19 10:44:19 +00:00
2009-02-05 18:36:53 +00:00
#region Other Methods
2008-04-10 09:36:55 +00:00
public void SetObjectCapacity ( int objects )
{
2009-01-02 17:41:12 +00:00
// Region specific config overrides global
/ /
if ( RegionInfo . ObjectCapacity ! = 0 )
objects = RegionInfo . ObjectCapacity ;
2009-01-03 03:30:03 +00:00
if ( StatsReporter ! = null )
2008-04-10 09:36:55 +00:00
{
2009-01-03 03:30:03 +00:00
StatsReporter . SetObjectCapacity ( objects ) ;
2008-04-10 09:36:55 +00:00
}
objectCapacity = objects ;
}
2009-02-05 18:36:53 +00:00
2009-05-10 12:27:05 +00:00
public List < FriendListItem > GetFriendList ( string id )
2008-04-10 18:30:34 +00:00
{
2009-05-10 12:27:05 +00:00
UUID avatarID ;
if ( ! UUID . TryParse ( id , out avatarID ) )
return new List < FriendListItem > ( ) ;
2008-04-10 18:30:34 +00:00
return CommsManager . GetUserFriendList ( avatarID ) ;
}
2008-05-16 01:22:11 +00:00
2008-11-01 22:09:48 +00:00
public Dictionary < UUID , FriendRegionInfo > GetFriendRegionInfos ( List < UUID > uuids )
{
return CommsManager . GetFriendRegionInfos ( uuids ) ;
}
2008-09-06 07:52:41 +00:00
public virtual void StoreAddFriendship ( UUID ownerID , UUID friendID , uint perms )
2008-01-01 06:12:04 +00:00
{
2008-02-16 11:55:09 +00:00
m_sceneGridService . AddNewUserFriend ( ownerID , friendID , perms ) ;
2008-01-01 06:12:04 +00:00
}
2008-09-06 07:52:41 +00:00
public virtual void StoreUpdateFriendship ( UUID ownerID , UUID friendID , uint perms )
2008-01-01 06:12:04 +00:00
{
2008-02-16 11:55:09 +00:00
m_sceneGridService . UpdateUserFriendPerms ( ownerID , friendID , perms ) ;
2008-01-01 06:12:04 +00:00
}
2008-09-06 07:52:41 +00:00
public virtual void StoreRemoveFriendship ( UUID ownerID , UUID ExfriendID )
2008-01-01 06:12:04 +00:00
{
2008-02-16 11:55:09 +00:00
m_sceneGridService . RemoveUserFriend ( ownerID , ExfriendID ) ;
2008-01-01 06:12:04 +00:00
}
2008-08-28 14:41:54 +00:00
2007-11-03 19:14:22 +00:00
# endregion
2008-09-06 07:52:41 +00:00
public void HandleObjectPermissionsUpdate ( IClientAPI controller , UUID agentID , UUID sessionID , byte field , uint localId , uint mask , byte set )
2007-12-05 06:44:32 +00:00
{
// Check for spoofing.. since this is permissions we're talking about here!
2007-12-06 04:01:56 +00:00
if ( ( controller . SessionId = = sessionID ) & & ( controller . AgentId = = agentID ) )
2007-12-05 06:44:32 +00:00
{
2008-02-10 14:27:21 +00:00
// Tell the object to do permission update
2008-03-28 14:59:52 +00:00
if ( localId ! = 0 )
{
SceneObjectGroup chObjectGroup = GetGroupByPrim ( localId ) ;
if ( chObjectGroup ! = null )
{
chObjectGroup . UpdatePermissions ( agentID , field , localId , mask , set ) ;
}
}
2007-12-05 06:44:32 +00:00
}
}
2007-12-06 04:01:56 +00:00
/// <summary>
2007-12-10 21:12:38 +00:00
/// Causes all clients to get a full object update on all of the objects in the scene.
2007-12-06 04:01:56 +00:00
/// </summary>
2007-09-17 07:31:15 +00:00
public void ForceClientUpdate ( )
2007-09-06 14:15:16 +00:00
{
2008-05-20 16:19:35 +00:00
List < EntityBase > EntityList = GetEntities ( ) ;
2007-12-17 16:41:28 +00:00
2008-05-20 16:19:35 +00:00
foreach ( EntityBase ent in EntityList )
2007-09-06 14:15:16 +00:00
{
if ( ent is SceneObjectGroup )
{
2008-05-01 18:04:42 +00:00
( ( SceneObjectGroup ) ent ) . ScheduleGroupForFullUpdate ( ) ;
2007-09-06 14:15:16 +00:00
}
}
}
2007-09-19 00:30:55 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2007-12-10 21:12:38 +00:00
/// This is currently only used for scale (to scale to MegaPrim size)
/// There is a console command that calls this in OpenSimMain
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="cmdparams"></param>
public void HandleEditCommand ( string [ ] cmdparams )
2007-09-08 11:08:38 +00:00
{
2009-02-22 20:52:55 +00:00
m_log . Debug ( "Searching for Primitive: '" + cmdparams [ 2 ] + "'" ) ;
2007-12-17 16:41:28 +00:00
2008-05-20 16:19:35 +00:00
List < EntityBase > EntityList = GetEntities ( ) ;
2007-12-17 16:41:28 +00:00
2008-05-20 16:19:35 +00:00
foreach ( EntityBase ent in EntityList )
2007-09-08 11:08:38 +00:00
{
if ( ent is SceneObjectGroup )
{
2008-05-01 18:04:42 +00:00
SceneObjectPart part = ( ( SceneObjectGroup ) ent ) . GetChildPart ( ( ( SceneObjectGroup ) ent ) . UUID ) ;
2007-09-19 00:30:55 +00:00
if ( part ! = null )
{
2009-02-07 12:25:39 +00:00
if ( part . Name = = cmdparams [ 2 ] )
2007-09-19 00:30:55 +00:00
{
part . Resize (
2009-02-07 12:25:39 +00:00
new Vector3 ( Convert . ToSingle ( cmdparams [ 3 ] ) , Convert . ToSingle ( cmdparams [ 4 ] ) ,
Convert . ToSingle ( cmdparams [ 5 ] ) ) ) ;
2007-09-19 00:30:55 +00:00
2009-02-22 20:52:55 +00:00
m_log . Debug ( "Edited scale of Primitive: " + part . Name ) ;
2007-09-19 00:30:55 +00:00
}
}
2007-09-08 11:08:38 +00:00
}
}
}
2009-02-05 18:36:53 +00:00
public override void Show ( string [ ] showParams )
2007-09-04 17:09:47 +00:00
{
2009-02-05 18:36:53 +00:00
base . Show ( showParams ) ;
2008-09-12 22:39:17 +00:00
switch ( showParams [ 0 ] )
2007-09-04 17:09:47 +00:00
{
case "users" :
2008-02-05 19:44:27 +00:00
m_log . Error ( "Current Region: " + RegionInfo . RegionName ) ;
2008-02-13 03:38:18 +00:00
m_log . ErrorFormat ( "{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}" , "Firstname" , "Lastname" ,
"Agent ID" , "Session ID" , "Circuit" , "IP" , "World" ) ;
2007-09-04 17:09:47 +00:00
2008-03-07 14:55:26 +00:00
foreach ( ScenePresence scenePresence in GetAvatars ( ) )
2007-09-04 17:09:47 +00:00
{
2008-02-13 03:38:18 +00:00
m_log . ErrorFormat ( "{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}" ,
2008-03-07 14:55:26 +00:00
scenePresence . Firstname ,
scenePresence . Lastname ,
scenePresence . UUID ,
scenePresence . ControllingClient . AgentId ,
2007-10-30 09:05:31 +00:00
"Unknown" ,
"Unknown" ,
2008-02-13 03:38:18 +00:00
RegionInfo . RegionName ) ;
2007-09-04 17:09:47 +00:00
}
2009-02-05 18:36:53 +00:00
2007-09-04 17:09:47 +00:00
break ;
2009-02-05 18:36:53 +00:00
}
2007-09-04 17:09:47 +00:00
}
2007-11-03 19:14:22 +00:00
#region Script Handling Methods
2007-12-06 04:01:56 +00:00
/// <summary>
2007-12-10 21:12:38 +00:00
/// Console command handler to send script command to script engine.
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="args"></param>
2007-11-03 19:14:22 +00:00
public void SendCommandToPlugins ( string [ ] args )
2007-09-04 17:53:21 +00:00
{
2007-11-03 19:14:22 +00:00
m_eventManager . TriggerOnPluginConsole ( args ) ;
2007-09-04 17:53:21 +00:00
}
2007-12-27 21:41:48 +00:00
Again, great thanks to Alondria for:
Adding:: llSetParcelMusicUrl(), llGetRootPosition(), llGetRootRotation(),
llGetGeometricCenter(), llSetLocalRot(), llListReplaceList(),
llGetObjectPrimCount(),llGetParcelDetails(), llGetParcelMaxPrims(),
llWater(), llGetLocalRot(), and llGetAccel()
2007-12-24 21:16:32 +00:00
public LandData GetLandData ( float x , float y )
{
2008-05-06 04:56:48 +00:00
return LandChannel . GetLandObject ( x , y ) . landData ;
Again, great thanks to Alondria for:
Adding:: llSetParcelMusicUrl(), llGetRootPosition(), llGetRootRotation(),
llGetGeometricCenter(), llSetLocalRot(), llListReplaceList(),
llGetObjectPrimCount(),llGetParcelDetails(), llGetParcelMaxPrims(),
llWater(), llGetLocalRot(), and llGetAccel()
2007-12-24 21:16:32 +00:00
}
2008-08-16 19:20:14 +00:00
public LandData GetLandData ( uint x , uint y )
{
2009-03-05 20:32:35 +00:00
m_log . DebugFormat ( "[SCENE]: returning land for {0},{1}" , x , y ) ;
2008-08-16 19:20:14 +00:00
return LandChannel . GetLandObject ( ( int ) x , ( int ) y ) . landData ;
}
2008-05-29 13:55:02 +00:00
public RegionInfo RequestClosestRegion ( string name )
{
return m_sceneGridService . RequestClosestRegion ( name ) ;
}
2007-11-03 19:14:22 +00:00
# endregion
2007-08-13 19:39:51 +00:00
#region Script Engine
2007-09-19 00:30:55 +00:00
2008-05-01 18:04:42 +00:00
private List < ScriptEngineInterface > ScriptEngines = new List < ScriptEngineInterface > ( ) ;
2009-01-21 21:14:17 +00:00
public bool DumpAssetsToFile ;
2007-09-19 00:30:55 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2008-05-16 01:22:11 +00:00
///
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="scriptEngine"></param>
2008-02-05 19:44:27 +00:00
public void AddScriptEngine ( ScriptEngineInterface scriptEngine )
2007-08-13 19:39:51 +00:00
{
2007-12-06 04:01:56 +00:00
ScriptEngines . Add ( scriptEngine ) ;
2008-02-05 19:44:27 +00:00
scriptEngine . InitializeEngine ( this ) ;
2007-08-14 13:54:46 +00:00
}
2007-09-19 00:30:55 +00:00
2008-09-25 17:26:32 +00:00
private bool ScriptDanger ( SceneObjectPart part , Vector3 pos )
2008-04-22 09:28:58 +00:00
{
2008-05-06 04:56:48 +00:00
ILandObject parcel = LandChannel . GetLandObject ( pos . X , pos . Y ) ;
2008-04-22 09:28:58 +00:00
if ( part ! = null )
{
if ( parcel ! = null )
{
2008-07-23 15:50:32 +00:00
if ( ( parcel . landData . Flags & ( uint ) Parcel . ParcelFlags . AllowOtherScripts ) ! = 0 )
2008-04-22 09:28:58 +00:00
{
return true ;
}
2008-07-23 15:50:32 +00:00
else if ( ( parcel . landData . Flags & ( uint ) Parcel . ParcelFlags . AllowGroupScripts ) ! = 0 )
2008-04-22 09:28:58 +00:00
{
2009-03-30 18:20:41 +00:00
if ( part . OwnerID = = parcel . landData . OwnerID
| | ( parcel . landData . IsGroupOwned & & part . GroupID = = parcel . landData . GroupID )
| | Permissions . IsGod ( part . OwnerID ) )
2008-04-22 09:28:58 +00:00
{
return true ;
}
else
{
return false ;
}
2008-05-16 01:22:11 +00:00
}
2008-04-22 09:28:58 +00:00
else
{
2008-07-23 15:50:32 +00:00
if ( part . OwnerID = = parcel . landData . OwnerID )
2008-04-22 09:28:58 +00:00
{
return true ;
}
else
{
return false ;
}
}
}
else
{
2008-05-01 18:04:42 +00:00
2008-04-22 09:28:58 +00:00
if ( pos . X > 0f & & pos . X < Constants . RegionSize & & pos . Y > 0f & & pos . Y < Constants . RegionSize )
{
2008-05-16 01:22:11 +00:00
// The only time parcel != null when an object is inside a region is when
2008-04-22 09:28:58 +00:00
// there is nothing behind the landchannel. IE, no land plugin loaded.
return true ;
}
else
{
// The object is outside of this region. Stop piping events to it.
return false ;
}
}
2008-04-22 10:11:29 +00:00
}
else
{
return false ;
}
}
2008-06-18 03:50:39 +00:00
2008-09-25 17:26:32 +00:00
public bool ScriptDanger ( uint localID , Vector3 pos )
2008-04-22 10:11:29 +00:00
{
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
if ( part ! = null )
{
2008-09-25 17:26:32 +00:00
return ScriptDanger ( part , pos ) ;
2008-04-22 10:11:29 +00:00
}
else
{
return false ;
}
}
2008-09-25 17:26:32 +00:00
public bool PipeEventsForScript ( uint localID )
2008-04-22 10:11:29 +00:00
{
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
if ( part ! = null )
{
2008-09-25 17:26:32 +00:00
// Changed so that child prims of attachments return ScriptDanger for their parent, so that
2008-08-13 14:19:59 +00:00
// their scripts will actually run.
// -- Leaf, Tue Aug 12 14:17:05 EDT 2008
SceneObjectPart parent = part . ParentGroup . RootPart ;
2008-08-15 10:24:04 +00:00
if ( parent ! = null & & parent . IsAttachment )
2008-09-25 17:26:32 +00:00
return ScriptDanger ( parent , parent . GetWorldPosition ( ) ) ;
2008-08-13 14:19:59 +00:00
else
2008-09-25 17:26:32 +00:00
return ScriptDanger ( part , part . GetWorldPosition ( ) ) ;
2008-04-22 09:28:58 +00:00
}
else
{
return false ;
}
}
2007-08-13 19:39:51 +00:00
# endregion
2007-08-13 20:24:37 +00:00
2008-11-12 20:16:46 +00:00
#region SceneGraph wrapper methods
2007-11-03 19:14:22 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2008-05-16 01:22:11 +00:00
///
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="localID"></param>
/// <returns></returns>
2008-09-06 07:52:41 +00:00
public UUID ConvertLocalIDToFullID ( uint localID )
2007-08-13 20:24:37 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . ConvertLocalIDToFullID ( localID ) ;
2007-08-14 17:29:15 +00:00
}
2007-12-27 21:41:48 +00:00
2007-12-12 06:58:55 +00:00
public void SwapRootAgentCount ( bool rootChildChildRootTF )
{
2008-11-12 20:16:46 +00:00
m_sceneGraph . SwapRootChildAgent ( rootChildChildRootTF ) ;
2007-12-12 06:58:55 +00:00
}
2007-12-14 00:49:40 +00:00
public void AddPhysicalPrim ( int num )
{
2008-11-12 20:16:46 +00:00
m_sceneGraph . AddPhysicalPrim ( num ) ;
2007-12-14 00:49:40 +00:00
}
public void RemovePhysicalPrim ( int num )
{
2008-11-12 20:16:46 +00:00
m_sceneGraph . RemovePhysicalPrim ( num ) ;
2007-12-14 00:49:40 +00:00
}
2007-11-03 19:14:22 +00:00
//The idea is to have a group of method that return a list of avatars meeting some requirement
2008-05-16 01:22:11 +00:00
// ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
2007-11-03 19:14:22 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2008-05-26 01:06:50 +00:00
/// Return a list of all avatars in this region.
/// This list is a new object, so it can be iterated over without locking.
2007-12-06 04:01:56 +00:00
/// </summary>
/// <returns></returns>
2007-11-03 19:14:22 +00:00
public List < ScenePresence > GetAvatars ( )
2007-09-04 13:43:56 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . GetAvatars ( ) ;
2007-11-03 19:14:22 +00:00
}
/// <summary>
2008-05-26 01:06:50 +00:00
/// Return a list of all ScenePresences in this region. This returns child agents as well as root agents.
/// This list is a new object, so it can be iterated over without locking.
2007-11-03 19:14:22 +00:00
/// </summary>
/// <returns></returns>
public List < ScenePresence > GetScenePresences ( )
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . GetScenePresences ( ) ;
2007-11-03 19:14:22 +00:00
}
/// <summary>
2008-05-26 01:06:50 +00:00
/// Request a filtered list of ScenePresences in this region.
/// This list is a new object, so it can be iterated over without locking.
2007-11-03 19:14:22 +00:00
/// </summary>
2007-12-06 04:01:56 +00:00
/// <param name="filter"></param>
2007-11-03 19:14:22 +00:00
/// <returns></returns>
public List < ScenePresence > GetScenePresences ( FilterAvatarList filter )
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . GetScenePresences ( filter ) ;
2007-11-03 19:14:22 +00:00
}
/// <summary>
2008-05-13 18:25:15 +00:00
/// Request a scene presence by UUID
2007-11-03 19:14:22 +00:00
/// </summary>
/// <param name="avatarID"></param>
/// <returns></returns>
2008-09-06 07:52:41 +00:00
public ScenePresence GetScenePresence ( UUID avatarID )
2007-11-03 19:14:22 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . GetScenePresence ( avatarID ) ;
2007-11-03 19:14:22 +00:00
}
2008-09-06 07:52:41 +00:00
public override bool PresenceChildStatus ( UUID avatarID )
2008-01-04 02:24:05 +00:00
{
ScenePresence cp = GetScenePresence ( avatarID ) ;
2009-02-04 00:01:36 +00:00
2008-12-17 19:12:56 +00:00
// FIXME: This is really crap - some logout code is relying on a NullReferenceException to halt its processing
// This needs to be fixed properly by cleaning up the logout code.
//if (cp != null)
// return cp.IsChildAgent;
2009-02-04 00:01:36 +00:00
2008-12-17 19:12:56 +00:00
//return false;
2009-02-04 00:01:36 +00:00
2008-12-17 19:12:56 +00:00
return cp . IsChildAgent ;
2008-01-04 02:24:05 +00:00
}
2007-11-03 19:14:22 +00:00
/// <summary>
2008-05-16 01:22:11 +00:00
///
2007-11-03 19:14:22 +00:00
/// </summary>
/// <param name="action"></param>
public void ForEachScenePresence ( Action < ScenePresence > action )
{
2008-05-18 23:06:50 +00:00
// We don't want to try to send messages if there are no avatars.
if ( m_scenePresences ! = null )
2007-09-04 13:43:56 +00:00
{
2007-12-27 21:41:48 +00:00
try
{
List < ScenePresence > presenceList = GetScenePresences ( ) ;
2007-12-17 16:41:28 +00:00
foreach ( ScenePresence presence in presenceList )
2007-12-11 22:20:22 +00:00
{
action ( presence ) ;
}
2007-12-27 21:41:48 +00:00
}
catch ( Exception e )
{
2009-02-15 05:00:58 +00:00
m_log . Info ( "[BUG] in " + RegionInfo . RegionName + ": " + e . ToString ( ) ) ;
2009-04-09 13:03:27 +00:00
m_log . Info ( "[BUG] Stack Trace: " + e . StackTrace ) ;
2007-11-26 05:02:18 +00:00
}
2007-09-04 13:43:56 +00:00
}
}
2008-05-16 01:22:11 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2008-05-16 01:22:11 +00:00
///
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="action"></param>
2008-02-10 14:27:21 +00:00
// public void ForEachObject(Action<SceneObjectGroup> action)
// {
// List<SceneObjectGroup> presenceList;
/ /
// lock (m_sceneObjects)
// {
// presenceList = new List<SceneObjectGroup>(m_sceneObjects.Values);
// }
/ /
// foreach (SceneObjectGroup presence in presenceList)
// {
// action(presence);
// }
// }
2008-05-01 18:04:42 +00:00
2008-10-05 14:15:39 +00:00
/// <summary>
2008-10-14 09:40:05 +00:00
/// Get a named prim contained in this scene (will return the first
2008-10-01 06:39:36 +00:00
/// found, if there are more than one prim with the same name)
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public SceneObjectPart GetSceneObjectPart ( string name )
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . GetSceneObjectPart ( name ) ;
2008-10-01 06:39:36 +00:00
}
2007-12-06 04:01:56 +00:00
/// <summary>
2008-11-10 18:10:00 +00:00
/// Get a prim via its local id
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="localID"></param>
/// <returns></returns>
2007-11-03 19:14:22 +00:00
public SceneObjectPart GetSceneObjectPart ( uint localID )
2007-09-20 07:49:11 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . GetSceneObjectPart ( localID ) ;
2007-11-03 19:14:22 +00:00
}
2007-09-20 07:49:11 +00:00
2007-12-06 04:01:56 +00:00
/// <summary>
2008-11-10 18:10:00 +00:00
/// Get a prim via its UUID
2007-12-06 04:01:56 +00:00
/// </summary>
/// <param name="fullID"></param>
/// <returns></returns>
2008-09-06 07:52:41 +00:00
public SceneObjectPart GetSceneObjectPart ( UUID fullID )
2007-11-03 19:14:22 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . GetSceneObjectPart ( fullID ) ;
2007-09-20 07:49:11 +00:00
}
2007-09-24 04:49:05 +00:00
2009-02-06 16:55:34 +00:00
public bool TryGetAvatar ( UUID avatarId , out ScenePresence avatar )
2007-09-24 04:49:05 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . TryGetAvatar ( avatarId , out avatar ) ;
2007-11-03 19:14:22 +00:00
}
2007-09-24 04:49:05 +00:00
2009-02-06 16:55:34 +00:00
public bool TryGetAvatarByName ( string avatarName , out ScenePresence avatar )
2007-11-03 19:14:22 +00:00
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . TryGetAvatarByName ( avatarName , out avatar ) ;
2007-09-24 04:49:05 +00:00
}
2007-10-29 11:54:31 +00:00
2008-12-18 13:16:41 +00:00
public void ForEachClient ( Action < IClientAPI > action )
2007-10-29 11:54:31 +00:00
{
2008-11-12 20:16:46 +00:00
m_sceneGraph . ForEachClient ( action ) ;
2007-10-29 11:54:31 +00:00
}
2007-11-03 19:14:22 +00:00
2008-05-24 21:57:00 +00:00
/// <summary>
/// Returns a list of the entities in the scene. This is a new list so operations perform on the list itself
/// will not affect the original list of objects in the scene.
/// </summary>
/// <returns></returns>
2007-12-17 16:41:28 +00:00
public List < EntityBase > GetEntities ( )
{
2008-11-12 20:16:46 +00:00
return m_sceneGraph . GetEntities ( ) ;
2007-12-17 16:41:28 +00:00
}
2007-11-03 19:14:22 +00:00
# endregion
2008-02-14 11:15:41 +00:00
2008-03-25 18:48:07 +00:00
#region Avatar Appearance Default
public static void GetDefaultAvatarAppearance ( out AvatarWearable [ ] wearables , out byte [ ] visualParams )
{
2009-03-27 20:18:55 +00:00
visualParams = AvatarAppearance . GetDefaultVisualParams ( ) ;
2008-03-25 18:48:07 +00:00
wearables = AvatarWearable . DefaultWearables ;
}
2008-06-18 03:50:39 +00:00
# endregion
2008-06-21 03:29:08 +00:00
2008-09-06 07:52:41 +00:00
public void RegionHandleRequest ( IClientAPI client , UUID regionID )
2008-08-16 19:20:14 +00:00
{
RegionInfo info ;
2008-08-17 02:31:45 +00:00
if ( regionID = = RegionInfo . RegionID )
info = RegionInfo ;
else
info = CommsManager . GridService . RequestNeighbourInfo ( regionID ) ;
if ( info ! = null )
client . SendRegionHandle ( regionID , info . RegionHandle ) ;
2008-08-16 19:20:14 +00:00
}
2008-07-21 15:13:34 +00:00
public void TerrainUnAcked ( IClientAPI client , int patchX , int patchY )
{
2009-02-22 20:52:55 +00:00
//m_log.Debug("Terrain packet unacked, resending patch: " + patchX + " , " + patchY);
2008-07-21 15:13:34 +00:00
client . SendLayerData ( patchX , patchY , Heightmap . GetFloatsSerialised ( ) ) ;
}
2008-08-19 02:12:40 +00:00
2008-09-06 07:52:41 +00:00
public void SetRootAgentScene ( UUID agentID )
2008-08-19 15:09:35 +00:00
{
2008-09-29 15:09:35 +00:00
IInventoryTransferModule inv = RequestModuleInterface < IInventoryTransferModule > ( ) ;
2008-08-19 22:41:39 +00:00
if ( inv = = null )
2008-08-19 15:09:35 +00:00
return ;
inv . SetRootAgentScene ( agentID , this ) ;
2008-11-22 22:56:00 +00:00
2008-11-22 23:38:25 +00:00
EventManager . TriggerSetRootAgentScene ( agentID , this ) ;
2008-08-19 15:09:35 +00:00
}
2008-09-06 07:52:41 +00:00
public bool NeedSceneCacheClear ( UUID agentID )
2008-08-19 15:09:35 +00:00
{
2008-09-29 15:09:35 +00:00
IInventoryTransferModule inv = RequestModuleInterface < IInventoryTransferModule > ( ) ;
2008-08-19 22:41:39 +00:00
if ( inv = = null )
2008-08-19 15:09:35 +00:00
return true ;
return inv . NeedSceneCacheClear ( agentID , this ) ;
}
2008-08-24 00:51:21 +00:00
2008-09-06 07:52:41 +00:00
public void ObjectSaleInfo ( IClientAPI client , UUID agentID , UUID sessionID , uint localID , byte saleType , int salePrice )
2008-08-24 00:51:21 +00:00
{
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
2008-08-28 14:41:54 +00:00
if ( part = = null | | part . ParentGroup = = null )
2008-08-24 00:51:21 +00:00
return ;
2008-11-17 15:40:27 +00:00
if ( part . ParentGroup . IsDeleted )
2008-08-24 00:51:21 +00:00
return ;
part = part . ParentGroup . RootPart ;
part . ObjectSaleType = saleType ;
part . SalePrice = salePrice ;
2008-08-24 05:25:26 +00:00
part . ParentGroup . HasGroupChanged = true ;
2008-08-24 00:51:21 +00:00
part . GetProperties ( client ) ;
}
2008-10-08 02:45:23 +00:00
public bool PerformObjectBuy ( IClientAPI remoteClient , UUID categoryID ,
2008-08-24 00:51:21 +00:00
uint localID , byte saleType )
{
2008-08-24 06:39:54 +00:00
SceneObjectPart part = GetSceneObjectPart ( localID ) ;
2008-08-28 14:41:54 +00:00
if ( part = = null )
2008-10-08 02:45:23 +00:00
return false ;
2008-08-24 06:39:54 +00:00
2008-08-28 14:41:54 +00:00
if ( part . ParentGroup = = null )
2008-10-08 02:45:23 +00:00
return false ;
2008-08-24 07:16:47 +00:00
SceneObjectGroup group = part . ParentGroup ;
2008-08-24 06:39:54 +00:00
switch ( saleType )
{
case 1 : // Sell as original (in-place sale)
2008-10-08 02:45:23 +00:00
uint effectivePerms = group . GetEffectivePermissions ( ) ;
if ( ( effectivePerms & ( uint ) PermissionMask . Transfer ) = = 0 )
{
2009-01-07 20:46:28 +00:00
m_dialogModule . SendAlertToUser ( remoteClient , "This item doesn't appear to be for sale" ) ;
2008-10-08 02:45:23 +00:00
return false ;
}
2008-08-24 07:16:47 +00:00
group . SetOwnerId ( remoteClient . AgentId ) ;
group . SetRootPartOwner ( part , remoteClient . AgentId ,
2008-08-24 06:39:54 +00:00
remoteClient . ActiveGroupId ) ;
List < SceneObjectPart > partList =
2008-08-24 07:16:47 +00:00
new List < SceneObjectPart > ( group . Children . Values ) ;
2008-08-24 06:39:54 +00:00
2008-11-21 22:14:57 +00:00
if ( Permissions . PropagatePermissions ( ) )
2008-08-24 06:39:54 +00:00
{
foreach ( SceneObjectPart child in partList )
{
2008-11-21 21:16:42 +00:00
child . Inventory . ChangeInventoryOwner ( remoteClient . AgentId ) ;
2008-11-27 03:17:00 +00:00
child . ApplyNextOwnerPermissions ( ) ;
2008-08-24 06:39:54 +00:00
}
}
part . ObjectSaleType = 0 ;
part . SalePrice = 10 ;
2008-08-24 07:16:47 +00:00
group . HasGroupChanged = true ;
2008-08-24 06:39:54 +00:00
part . GetProperties ( remoteClient ) ;
part . ScheduleFullUpdate ( ) ;
break ;
2008-08-24 07:16:47 +00:00
case 2 : // Sell a copy
2009-05-08 18:05:54 +00:00
string sceneObjectXml = SceneObjectSerializer . ToOriginalXmlFormat ( group ) ;
2008-08-24 07:16:47 +00:00
CachedUserInfo userInfo =
CommsManager . UserProfileCacheService . GetUserDetails ( remoteClient . AgentId ) ;
if ( userInfo ! = null )
{
2008-10-08 02:45:23 +00:00
uint perms = group . GetEffectivePermissions ( ) ;
if ( ( perms & ( uint ) PermissionMask . Transfer ) = = 0 )
{
2009-01-07 20:46:28 +00:00
m_dialogModule . SendAlertToUser ( remoteClient , "This item doesn't appear to be for sale" ) ;
2008-10-08 02:45:23 +00:00
return false ;
}
2008-08-24 07:16:47 +00:00
AssetBase asset = CreateAsset (
group . GetPartName ( localID ) ,
group . GetPartDescription ( localID ) ,
( sbyte ) AssetType . Object ,
2008-09-06 07:52:41 +00:00
Utils . StringToBytes ( sceneObjectXml ) ) ;
2009-02-16 19:15:16 +00:00
CommsManager . AssetCache . AddAsset ( asset ) ;
2008-08-24 07:16:47 +00:00
InventoryItemBase item = new InventoryItemBase ( ) ;
2009-04-08 17:50:57 +00:00
item . CreatorId = part . CreatorID . ToString ( ) ;
2008-08-24 07:16:47 +00:00
2008-09-06 07:52:41 +00:00
item . ID = UUID . Random ( ) ;
2008-08-24 07:16:47 +00:00
item . Owner = remoteClient . AgentId ;
2009-02-17 01:36:44 +00:00
item . AssetID = asset . FullID ;
item . Description = asset . Description ;
item . Name = asset . Name ;
item . AssetType = asset . Type ;
2008-08-24 07:16:47 +00:00
item . InvType = ( int ) InventoryType . Object ;
item . Folder = categoryID ;
uint nextPerms = ( perms & 7 ) < < 13 ;
if ( ( nextPerms & ( uint ) PermissionMask . Copy ) = = 0 )
perms & = ~ ( uint ) PermissionMask . Copy ;
if ( ( nextPerms & ( uint ) PermissionMask . Transfer ) = = 0 )
perms & = ~ ( uint ) PermissionMask . Transfer ;
if ( ( nextPerms & ( uint ) PermissionMask . Modify ) = = 0 )
perms & = ~ ( uint ) PermissionMask . Modify ;
item . BasePermissions = perms & part . NextOwnerMask ;
item . CurrentPermissions = perms & part . NextOwnerMask ;
item . NextPermissions = part . NextOwnerMask ;
item . EveryOnePermissions = part . EveryoneMask &
part . NextOwnerMask ;
2008-11-14 18:54:38 +00:00
item . GroupPermissions = part . GroupMask &
part . NextOwnerMask ;
2008-08-24 07:16:47 +00:00
item . CurrentPermissions | = 8 ; // Slam!
item . CreationDate = Util . UnixTimeSinceEpoch ( ) ;
userInfo . AddItem ( item ) ;
2009-02-19 03:09:56 +00:00
remoteClient . SendInventoryItemCreateUpdate ( item , 0 ) ;
2008-08-24 07:16:47 +00:00
}
2008-10-08 02:45:23 +00:00
else
{
2009-01-07 20:46:28 +00:00
m_dialogModule . SendAlertToUser ( remoteClient , "Cannot buy now. Your inventory is unavailable" ) ;
2008-10-08 02:45:23 +00:00
return false ;
}
2008-08-24 07:16:47 +00:00
break ;
2008-08-24 16:41:23 +00:00
case 3 : // Sell contents
2008-11-21 21:16:42 +00:00
List < UUID > invList = part . Inventory . GetInventoryList ( ) ;
2008-08-24 16:41:23 +00:00
2008-10-08 02:45:23 +00:00
bool okToSell = true ;
foreach ( UUID invID in invList )
{
2008-11-21 21:16:42 +00:00
TaskInventoryItem item = part . Inventory . GetInventoryItem ( invID ) ;
2008-10-08 02:45:23 +00:00
if ( ( item . CurrentPermissions &
( uint ) PermissionMask . Transfer ) = = 0 )
{
okToSell = false ;
break ;
}
}
if ( ! okToSell )
{
2009-01-07 20:46:28 +00:00
m_dialogModule . SendAlertToUser (
2009-02-04 00:01:36 +00:00
remoteClient , "This item's inventory doesn't appear to be for sale" ) ;
2008-10-08 02:45:23 +00:00
return false ;
}
2008-08-24 16:41:23 +00:00
if ( invList . Count > 0 )
MoveTaskInventoryItems ( remoteClient . AgentId , part . Name ,
part , invList ) ;
break ;
2008-08-24 06:39:54 +00:00
}
2008-10-08 02:45:23 +00:00
return true ;
2008-08-24 00:51:21 +00:00
}
2008-10-03 15:32:44 +00:00
public void CleanTempObjects ( )
{
List < EntityBase > objs = GetEntities ( ) ;
foreach ( EntityBase obj in objs )
{
if ( obj is SceneObjectGroup )
{
SceneObjectGroup grp = ( SceneObjectGroup ) obj ;
2008-11-17 15:40:27 +00:00
if ( ! grp . IsDeleted )
2008-10-03 15:32:44 +00:00
{
if ( ( grp . RootPart . Flags & PrimFlags . TemporaryOnRez ) ! = 0 )
{
if ( grp . RootPart . Expires < = DateTime . Now )
2008-11-07 05:48:44 +00:00
DeleteSceneObject ( grp , false ) ;
2008-10-03 15:32:44 +00:00
}
}
}
}
}
2008-10-03 16:18:38 +00:00
public void DeleteFromStorage ( UUID uuid )
{
m_storageManager . DataStore . RemoveObject ( uuid , m_regInfo . RegionID ) ;
}
2008-10-10 01:10:33 +00:00
public int GetHealth ( )
{
2009-04-15 20:16:18 +00:00
// Returns:
// 1 = sim is up and accepting http requests. The heartbeat has
// stopped and the sim is probably locked up, but a remote
// admin restart may succeed
/ /
// 2 = Sim is up and the heartbeat is running. The sim is likely
// usable for people within and logins _may_ work
/ /
// 3 = We have seen a new user enter within the past 4 minutes
// which can be seen as positive confirmation of sim health
/ /
2008-10-10 01:10:33 +00:00
int health = 1 ; // Start at 1, means we're up
2009-04-15 20:16:18 +00:00
if ( ( Environment . TickCount - m_lastUpdate ) < 1000 )
health + = 1 ;
else
return health ;
2008-10-10 01:10:33 +00:00
// A login in the last 4 mins? We can't be doing too badly
/ /
2009-02-12 09:53:12 +00:00
if ( ( Environment . TickCount - m_LastLogin ) < 240000 )
2008-10-10 01:10:33 +00:00
health + + ;
2009-04-15 20:16:18 +00:00
else
return health ;
2008-10-10 01:10:33 +00:00
2009-04-15 20:16:18 +00:00
return health ;
2008-10-10 01:10:33 +00:00
}
2008-12-26 12:58:02 +00:00
// This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
// update non-physical objects like the joint proxy objects that represent the position
// of the joints in the scene.
2008-12-30 01:08:07 +00:00
// This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
2008-12-26 12:58:02 +00:00
// WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
2009-02-04 00:01:36 +00:00
// from within the OdePhysicsScene.
2008-12-26 12:58:02 +00:00
protected internal void jointMoved ( PhysicsJoint joint )
{
2008-12-30 01:08:07 +00:00
// m_parentScene.PhysicsScene.DumpJointInfo(); // non-thread-locked version; we should already be in a lock (OdeLock) when this callback is invoked
2008-12-26 12:58:02 +00:00
SceneObjectPart jointProxyObject = GetSceneObjectPart ( joint . ObjectNameInScene ) ;
if ( jointProxyObject = = null )
{
jointErrorMessage ( joint , "WARNING, joint proxy not found, name " + joint . ObjectNameInScene ) ;
return ;
}
// now update the joint proxy object in the scene to have the position of the joint as returned by the physics engine
SceneObjectPart trackedBody = GetSceneObjectPart ( joint . TrackedBodyName ) ; // FIXME: causes a sequential lookup
if ( trackedBody = = null ) return ; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy.
jointProxyObject . Velocity = trackedBody . Velocity ;
jointProxyObject . RotationalVelocity = trackedBody . RotationalVelocity ;
switch ( joint . Type )
{
case PhysicsJointType . Ball :
{
PhysicsVector jointAnchor = PhysicsScene . GetJointAnchor ( joint ) ;
Vector3 proxyPos = new Vector3 ( jointAnchor . X , jointAnchor . Y , jointAnchor . Z ) ;
jointProxyObject . ParentGroup . UpdateGroupPosition ( proxyPos ) ; // schedules the entire group for a terse update
}
break ;
case PhysicsJointType . Hinge :
{
PhysicsVector jointAnchor = PhysicsScene . GetJointAnchor ( joint ) ;
// Normally, we would just ask the physics scene to return the axis for the joint.
// Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should
// never occur. Therefore we cannot rely on ODE to always return a correct joint axis.
// Therefore the following call does not always work:
//PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint);
// instead we compute the joint orientation by saving the original joint orientation
// relative to one of the jointed bodies, and applying this transformation
// to the current position of the jointed bodies (the tracked body) to compute the
// current joint orientation.
if ( joint . TrackedBodyName = = null )
{
jointErrorMessage ( joint , "joint.TrackedBodyName is null, joint " + joint . ObjectNameInScene ) ;
}
Vector3 proxyPos = new Vector3 ( jointAnchor . X , jointAnchor . Y , jointAnchor . Z ) ;
Quaternion q = trackedBody . RotationOffset * joint . LocalRotation ;
jointProxyObject . ParentGroup . UpdateGroupPosition ( proxyPos ) ; // schedules the entire group for a terse update
jointProxyObject . ParentGroup . UpdateGroupRotation ( q ) ; // schedules the entire group for a terse update
}
break ;
}
}
// This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
// update non-physical objects like the joint proxy objects that represent the position
// of the joints in the scene.
2008-12-30 01:08:07 +00:00
// This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
2008-12-26 12:58:02 +00:00
// WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
// from within the OdePhysicsScene.
protected internal void jointDeactivated ( PhysicsJoint joint )
{
//m_log.Debug("[NINJA] SceneGraph.jointDeactivated, joint:" + joint.ObjectNameInScene);
SceneObjectPart jointProxyObject = GetSceneObjectPart ( joint . ObjectNameInScene ) ;
if ( jointProxyObject = = null )
{
jointErrorMessage ( joint , "WARNING, trying to deactivate (stop interpolation of) joint proxy, but not found, name " + joint . ObjectNameInScene ) ;
return ;
}
// turn the proxy non-physical, which also stops its client-side interpolation
bool wasUsingPhysics = ( ( jointProxyObject . ObjectFlags & ( uint ) PrimFlags . Physics ) ! = 0 ) ;
if ( wasUsingPhysics )
{
jointProxyObject . UpdatePrimFlags ( false , false , true , false ) ; // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
}
}
// This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
// alert the user of errors by using the debug channel in the same way that scripts alert
// the user of compile errors.
2008-12-30 01:08:07 +00:00
// This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
2008-12-26 12:58:02 +00:00
// WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
// from within the OdePhysicsScene.
public void jointErrorMessage ( PhysicsJoint joint , string message )
{
if ( joint ! = null )
{
2009-02-04 00:01:36 +00:00
if ( joint . ErrorMessageCount > PhysicsJoint . maxErrorMessages )
2008-12-26 12:58:02 +00:00
return ;
SceneObjectPart jointProxyObject = GetSceneObjectPart ( joint . ObjectNameInScene ) ;
if ( jointProxyObject ! = null )
{
2009-02-13 20:12:11 +00:00
SimChat ( Utils . StringToBytes ( "[NINJA]: " + message ) ,
2008-12-26 12:58:02 +00:00
ChatTypeEnum . DebugChannel ,
2147483647 ,
jointProxyObject . AbsolutePosition ,
jointProxyObject . Name ,
jointProxyObject . UUID ,
false ) ;
joint . ErrorMessageCount + + ;
if ( joint . ErrorMessageCount > PhysicsJoint . maxErrorMessages )
{
2009-02-13 20:12:11 +00:00
SimChat ( Utils . StringToBytes ( "[NINJA]: Too many messages for this joint, suppressing further messages." ) ,
2008-12-26 12:58:02 +00:00
ChatTypeEnum . DebugChannel ,
2147483647 ,
jointProxyObject . AbsolutePosition ,
jointProxyObject . Name ,
jointProxyObject . UUID ,
false ) ;
}
}
else
{
// couldn't find the joint proxy object; the error message is silently suppressed
}
}
}
2009-02-07 12:25:39 +00:00
public Scene ConsoleScene ( )
{
if ( MainConsole . Instance = = null )
return null ;
if ( MainConsole . Instance . ConsoleScene is Scene )
return ( Scene ) MainConsole . Instance . ConsoleScene ;
return null ;
}
2007-07-16 15:40:11 +00:00
}
2008-08-18 00:39:10 +00:00
}