2007-12-27 21:41:48 +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 .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
2009-06-01 06:37:14 +00:00
* * Neither the name of the OpenSimulator Project nor the
2008-03-18 05:16:43 +00:00
* 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-12-11 01:26:06 +00:00
using System ;
2007-11-04 14:34:45 +00:00
using System.Collections.Generic ;
using System.Net ;
2008-04-21 07:09:17 +00:00
using System.Reflection ;
2008-05-01 14:45:56 +00:00
using System.Threading ;
2008-09-06 07:52:41 +00:00
using OpenMetaverse ;
2008-09-27 23:06:28 +00:00
using OpenMetaverse.StructuredData ;
2008-04-21 07:09:17 +00:00
using log4net ;
2007-11-04 14:34:45 +00:00
using OpenSim.Framework ;
2009-05-23 05:44:18 +00:00
using OpenSim.Framework.Client ;
2007-11-04 14:34:45 +00:00
using OpenSim.Framework.Communications ;
2009-06-18 14:33:35 +00:00
using OpenSim.Framework.Capabilities ;
2009-02-06 16:55:34 +00:00
using OpenSim.Region.Framework.Interfaces ;
2009-06-14 15:35:09 +00:00
using OpenSim.Services.Interfaces ;
2008-11-19 06:25:34 +00:00
using OSD = OpenMetaverse . StructuredData . OSD ;
2009-09-26 14:48:21 +00:00
using GridRegion = OpenSim . Services . Interfaces . GridRegion ;
2007-11-04 14:34:45 +00:00
2009-02-06 16:55:34 +00:00
namespace OpenSim.Region.Framework.Scenes
2007-11-04 14:34:45 +00:00
{
2008-09-06 07:52:41 +00:00
public delegate void RemoveKnownRegionsFromAvatarList ( UUID avatarID , List < ulong > regionlst ) ;
2008-02-20 01:17:21 +00:00
2009-08-15 01:19:04 +00:00
/// <summary>
/// Class that Region communications runs through
/// </summary>
2007-11-04 14:34:45 +00:00
public class SceneCommunicationService //one instance per region
{
2008-04-21 07:09:17 +00:00
private static readonly ILog m_log = LogManager . GetLogger ( MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2008-02-05 19:44:27 +00:00
2007-11-04 14:34:45 +00:00
protected RegionInfo m_regionInfo ;
2009-09-26 14:48:21 +00:00
protected Scene m_scene ;
2008-05-01 18:04:42 +00:00
2009-09-26 14:48:21 +00:00
public void SetScene ( Scene s )
{
m_scene = s ;
m_regionInfo = s . RegionInfo ;
}
2009-06-14 15:35:09 +00:00
public delegate void InformNeighbourThatRegionUpDelegate ( INeighbourService nService , RegionInfo region , ulong regionhandle ) ;
2008-05-01 18:04:42 +00:00
2007-11-29 02:07:19 +00:00
private void InformNeighborsThatRegionisUpCompleted ( IAsyncResult iar )
{
2007-12-27 21:41:48 +00:00
InformNeighbourThatRegionUpDelegate icon = ( InformNeighbourThatRegionUpDelegate ) iar . AsyncState ;
2007-11-29 02:07:19 +00:00
icon . EndInvoke ( iar ) ;
}
2008-03-22 22:17:35 +00:00
/// <summary>
/// Asynchronous call to information neighbouring regions that this region is up
/// </summary>
/// <param name="region"></param>
/// <param name="regionhandle"></param>
2009-06-14 15:35:09 +00:00
private void InformNeighboursThatRegionIsUpAsync ( INeighbourService neighbourService , RegionInfo region , ulong regionhandle )
2007-11-29 02:07:19 +00:00
{
2009-09-27 17:14:10 +00:00
uint x = 0 , y = 0 ;
Utils . LongToUInts ( regionhandle , out x , out y ) ;
2008-03-30 08:01:47 +00:00
2009-09-27 17:14:10 +00:00
GridRegion neighbour = null ;
2009-06-14 15:35:09 +00:00
if ( neighbourService ! = null )
2009-09-27 17:14:10 +00:00
neighbour = neighbourService . HelloNeighbour ( regionhandle , region ) ;
2009-06-14 15:35:09 +00:00
else
2012-06-07 23:18:25 +00:00
m_log . DebugFormat ( "[SCENE COMMUNICATION SERVICE]: No neighbour service provided for informing neigbhours of this region" ) ;
2007-11-29 02:07:19 +00:00
2009-09-27 17:14:10 +00:00
if ( neighbour ! = null )
2007-11-29 02:07:19 +00:00
{
2012-06-07 23:18:25 +00:00
m_log . DebugFormat ( "[SCENE COMMUNICATION SERVICE]: Successfully informed neighbour {0}-{1} that I'm here" , x / Constants . RegionSize , y / Constants . RegionSize ) ;
2009-09-27 17:14:10 +00:00
m_scene . EventManager . TriggerOnRegionUp ( neighbour ) ;
2007-11-29 02:07:19 +00:00
}
else
{
2012-06-07 23:18:25 +00:00
m_log . InfoFormat ( "[SCENE COMMUNICATION SERVICE]: Failed to inform neighbour {0}-{1} that I'm here." , x / Constants . RegionSize , y / Constants . RegionSize ) ;
2007-11-29 02:07:19 +00:00
}
}
2007-12-27 21:41:48 +00:00
2009-06-14 15:35:09 +00:00
public void InformNeighborsThatRegionisUp ( INeighbourService neighbourService , RegionInfo region )
2007-11-29 02:07:19 +00:00
{
2008-02-05 19:44:27 +00:00
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
2007-11-29 06:06:42 +00:00
2010-06-14 02:06:22 +00:00
List < GridRegion > neighbours = m_scene . GridService . GetNeighbours ( m_scene . RegionInfo . ScopeID , m_scene . RegionInfo . RegionID ) ;
2012-06-07 23:18:25 +00:00
m_log . DebugFormat ( "[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that this region is up" , neighbours . Count ) ;
2010-06-14 02:06:22 +00:00
foreach ( GridRegion n in neighbours )
2009-12-12 05:14:01 +00:00
{
2010-06-14 02:06:22 +00:00
InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync ;
d . BeginInvoke ( neighbourService , region , n . RegionHandle ,
InformNeighborsThatRegionisUpCompleted ,
d ) ;
2009-12-12 05:14:01 +00:00
}
2007-11-29 02:07:19 +00:00
}
2007-12-27 21:41:48 +00:00
2011-02-03 20:43:46 +00:00
public delegate void SendChildAgentDataUpdateDelegate ( AgentPosition cAgentData , UUID scopeID , GridRegion dest ) ;
2008-05-01 18:04:42 +00:00
2007-12-10 21:12:38 +00:00
/// <summary>
/// This informs all neighboring regions about the settings of it's child agent.
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
2008-05-16 01:22:11 +00:00
///
2007-12-10 21:12:38 +00:00
/// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc.
2008-05-16 01:22:11 +00:00
///
2007-12-10 21:12:38 +00:00
/// </summary>
2011-02-03 20:43:46 +00:00
private void SendChildAgentDataUpdateAsync ( AgentPosition cAgentData , UUID scopeID , GridRegion dest )
2007-12-10 00:46:56 +00:00
{
2009-01-01 19:42:24 +00:00
//m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName);
2008-01-26 17:00:35 +00:00
try
2007-12-10 00:46:56 +00:00
{
2011-02-03 20:43:46 +00:00
m_scene . SimulationService . UpdateAgent ( dest , cAgentData ) ;
2007-12-10 00:46:56 +00:00
}
2008-12-22 07:06:01 +00:00
catch
2008-01-26 17:00:35 +00:00
{
2008-12-22 07:06:01 +00:00
// Ignore; we did our best
2008-01-26 17:00:35 +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
private void SendChildAgentDataUpdateCompleted ( IAsyncResult iar )
{
2007-12-27 21:41:48 +00:00
SendChildAgentDataUpdateDelegate icon = ( SendChildAgentDataUpdateDelegate ) iar . AsyncState ;
2007-12-10 00:46:56 +00:00
icon . EndInvoke ( iar ) ;
}
2007-12-27 21:41:48 +00:00
2009-01-03 02:29:49 +00:00
public void SendChildAgentDataUpdate ( AgentPosition cAgentData , ScenePresence presence )
2007-12-10 00:46:56 +00:00
{
// This assumes that we know what our neighbors are.
2008-12-22 07:06:01 +00:00
try
{
2011-02-03 20:43:46 +00:00
uint x = 0 , y = 0 ;
List < string > simulatorList = new List < string > ( ) ;
2011-10-07 05:47:33 +00:00
foreach ( ulong regionHandle in presence . KnownRegionHandles )
2008-12-22 07:06:01 +00:00
{
2008-12-29 22:22:05 +00:00
if ( regionHandle ! = m_regionInfo . RegionHandle )
{
2011-02-03 20:43:46 +00:00
// we only want to send one update to each simulator; the simulator will
// hand it off to the regions where a child agent exists, this does assume
// that the region position is cached or performance will degrade
Utils . LongToUInts ( regionHandle , out x , out y ) ;
GridRegion dest = m_scene . GridService . GetRegionByPosition ( UUID . Zero , ( int ) x , ( int ) y ) ;
2012-04-09 00:54:59 +00:00
if ( dest = = null )
continue ;
2012-02-24 05:25:18 +00:00
if ( ! simulatorList . Contains ( dest . ServerURI ) )
2011-02-03 20:43:46 +00:00
{
// we havent seen this simulator before, add it to the list
// and send it an update
simulatorList . Add ( dest . ServerURI ) ;
2012-02-19 20:28:07 +00:00
// Let move this to sync. Mono definitely does not like async networking.
2012-02-20 18:58:07 +00:00
m_scene . SimulationService . UpdateAgent ( dest , cAgentData ) ;
2012-02-19 20:28:07 +00:00
// Leaving this here as a reminder that we tried, and it sucks.
//SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
//d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
// SendChildAgentDataUpdateCompleted,
// d);
2011-02-03 20:43:46 +00:00
}
2008-12-29 22:22:05 +00:00
}
2008-12-22 07:06:01 +00:00
}
}
catch ( InvalidOperationException )
{
// We're ignoring a collection was modified error because this data gets old and outdated fast.
}
2007-12-10 00:46:56 +00:00
}
2007-12-27 21:41:48 +00:00
2008-01-21 23:04:42 +00:00
/// <summary>
2011-01-07 18:25:49 +00:00
/// Closes a child agent on a given region
2008-01-21 23:04:42 +00:00
/// </summary>
2011-01-07 18:25:49 +00:00
protected void SendCloseChildAgent ( UUID agentID , ulong regionHandle )
2008-01-21 23:04:42 +00:00
{
2008-12-22 07:06:01 +00:00
// let's do our best, but there's not much we can do if the neighbour doesn't accept.
2008-05-16 01:22:11 +00:00
2009-01-01 19:42:24 +00:00
//m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
2010-01-07 23:53:55 +00:00
uint x = 0 , y = 0 ;
Utils . LongToUInts ( regionHandle , out x , out y ) ;
2011-11-19 01:16:07 +00:00
2011-01-03 19:42:26 +00:00
GridRegion destination = m_scene . GridService . GetRegionByPosition ( m_regionInfo . ScopeID , ( int ) x , ( int ) y ) ;
2011-11-19 01:16:07 +00:00
m_log . DebugFormat (
2012-06-07 23:18:25 +00:00
"[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}" , agentID , destination . RegionName ) ;
2011-11-19 01:16:07 +00:00
2010-01-07 23:53:55 +00:00
m_scene . SimulationService . CloseAgent ( destination , agentID ) ;
2008-01-21 23:04:42 +00:00
}
2011-01-07 18:25:49 +00:00
/// <summary>
/// Closes a child agents in a collection of regions. Does so asynchronously
/// so that the caller doesn't wait.
/// </summary>
/// <param name="agentID"></param>
/// <param name="regionslst"></param>
2008-09-06 07:52:41 +00:00
public void SendCloseChildAgentConnections ( UUID agentID , List < ulong > regionslst )
2008-01-21 23:04:42 +00:00
{
2011-12-17 01:24:50 +00:00
foreach ( ulong handle in regionslst )
2008-12-22 07:06:01 +00:00
{
2011-12-17 01:24:50 +00:00
SendCloseChildAgent ( agentID , handle ) ;
}
2008-01-21 23:04:42 +00:00
}
2010-01-11 03:42:36 +00:00
2009-09-26 14:48:21 +00:00
public List < GridRegion > RequestNamedRegions ( string name , int maxNumber )
2008-10-03 23:00:42 +00:00
{
2009-09-26 14:48:21 +00:00
return m_scene . GridService . GetRegionsByName ( UUID . Zero , name , maxNumber ) ;
2008-10-03 23:00:42 +00:00
}
2007-11-04 14:34:45 +00:00
}
2011-11-15 18:16:43 +00:00
}