2010-03-10 04:15:36 +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 .
* * Neither the name of the OpenSimulator 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 .
* /
using System ;
2010-01-18 18:37:11 +00:00
using System.Collections ;
using System.Collections.Generic ;
2010-01-24 22:30:48 +00:00
using System.Drawing ;
2010-12-13 20:19:33 +00:00
using System.IO ;
2010-01-18 18:37:11 +00:00
using System.Net ;
2010-01-24 22:30:48 +00:00
using System.Reflection ;
using OpenSim.Framework ;
2010-01-18 18:37:11 +00:00
using OpenSim.Services.Interfaces ;
using GridRegion = OpenSim . Services . Interfaces . GridRegion ;
using OpenMetaverse ;
2010-01-24 22:30:48 +00:00
using OpenMetaverse.Imaging ;
2010-08-20 01:55:30 +00:00
using OpenMetaverse.StructuredData ;
2010-01-18 18:37:11 +00:00
using Nwc.XmlRpc ;
2010-01-24 22:30:48 +00:00
using log4net ;
2010-01-18 18:37:11 +00:00
using OpenSim.Services.Connectors.Simulation ;
namespace OpenSim.Services.Connectors.Hypergrid
{
public class GatekeeperServiceConnector : SimulationServiceConnector
{
2010-01-24 22:30:48 +00:00
private static readonly ILog m_log = LogManager . GetLogger ( MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
2010-12-13 20:19:33 +00:00
private static UUID m_HGMapImage = new UUID ( "00000000-0000-1111-9999-000000000013" ) ;
2010-01-24 22:30:48 +00:00
private IAssetService m_AssetService ;
2013-06-22 03:52:46 +00:00
public GatekeeperServiceConnector ( )
: base ( )
2010-01-24 22:30:48 +00:00
{
}
public GatekeeperServiceConnector ( IAssetService assService )
{
m_AssetService = assService ;
}
2010-01-18 18:37:11 +00:00
protected override string AgentPath ( )
{
2010-10-03 22:03:53 +00:00
return "foreignagent/" ;
2010-01-18 18:37:11 +00:00
}
protected override string ObjectPath ( )
{
2010-10-03 22:03:53 +00:00
return "foreignobject/" ;
2010-01-18 18:37:11 +00:00
}
2010-01-27 16:00:29 +00:00
public bool LinkRegion ( GridRegion info , out UUID regionID , out ulong realHandle , out string externalName , out string imageURL , out string reason )
2010-01-24 22:30:48 +00:00
{
regionID = UUID . Zero ;
imageURL = string . Empty ;
realHandle = 0 ;
2010-01-27 16:00:29 +00:00
externalName = string . Empty ;
2010-01-24 22:30:48 +00:00
reason = string . Empty ;
Hashtable hash = new Hashtable ( ) ;
hash [ "region_name" ] = info . RegionName ;
IList paramList = new ArrayList ( ) ;
paramList . Add ( hash ) ;
XmlRpcRequest request = new XmlRpcRequest ( "link_region" , paramList ) ;
2010-10-03 22:03:53 +00:00
m_log . Debug ( "[GATEKEEPER SERVICE CONNECTOR]: Linking to " + info . ServerURI ) ;
2010-01-24 22:30:48 +00:00
XmlRpcResponse response = null ;
try
{
2010-10-03 22:03:53 +00:00
response = request . Send ( info . ServerURI , 10000 ) ;
2010-01-24 22:30:48 +00:00
}
catch ( Exception e )
{
m_log . Debug ( "[GATEKEEPER SERVICE CONNECTOR]: Exception " + e . Message ) ;
reason = "Error contacting remote server" ;
return false ;
}
if ( response . IsFault )
{
reason = response . FaultString ;
m_log . ErrorFormat ( "[GATEKEEPER SERVICE CONNECTOR]: remote call returned an error: {0}" , response . FaultString ) ;
return false ;
}
hash = ( Hashtable ) response . Value ;
2010-12-06 03:43:24 +00:00
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
2010-01-24 22:30:48 +00:00
try
{
bool success = false ;
Boolean . TryParse ( ( string ) hash [ "result" ] , out success ) ;
if ( success )
{
UUID . TryParse ( ( string ) hash [ "uuid" ] , out regionID ) ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, uuid: " + regionID);
2010-01-24 22:30:48 +00:00
if ( ( string ) hash [ "handle" ] ! = null )
{
realHandle = Convert . ToUInt64 ( ( string ) hash [ "handle" ] ) ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, realHandle: " + realHandle);
2010-01-24 22:30:48 +00:00
}
2013-06-22 03:52:46 +00:00
if ( hash [ "region_image" ] ! = null )
{
2010-01-24 22:30:48 +00:00
imageURL = ( string ) hash [ "region_image" ] ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, imageURL: " + imageURL);
2010-10-02 23:17:02 +00:00
}
2013-06-22 03:52:46 +00:00
if ( hash [ "external_name" ] ! = null )
{
2010-01-27 16:00:29 +00:00
externalName = ( string ) hash [ "external_name" ] ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, externalName: " + externalName);
2010-10-02 23:17:02 +00:00
}
2010-01-24 22:30:48 +00:00
}
}
catch ( Exception e )
{
reason = "Error parsing return arguments" ;
m_log . Error ( "[GATEKEEPER SERVICE CONNECTOR]: Got exception while parsing hyperlink response " + e . StackTrace ) ;
return false ;
}
return true ;
}
2010-12-13 20:19:33 +00:00
public UUID GetMapImage ( UUID regionID , string imageURL , string storagePath )
2010-01-24 22:30:48 +00:00
{
if ( m_AssetService = = null )
2010-12-14 19:24:23 +00:00
{
m_log . DebugFormat ( "[GATEKEEPER SERVICE CONNECTOR]: No AssetService defined. Map tile not retrieved." ) ;
2010-12-13 20:19:33 +00:00
return m_HGMapImage ;
2010-12-14 19:24:23 +00:00
}
2010-01-24 22:30:48 +00:00
2010-12-13 20:19:33 +00:00
UUID mapTile = m_HGMapImage ;
string filename = string . Empty ;
2012-04-20 02:32:38 +00:00
2010-01-24 22:30:48 +00:00
try
{
WebClient c = new WebClient ( ) ;
2010-12-13 20:19:33 +00:00
string name = regionID . ToString ( ) ;
filename = Path . Combine ( storagePath , name + ".jpg" ) ;
2011-01-06 20:48:28 +00:00
m_log . DebugFormat ( "[GATEKEEPER SERVICE CONNECTOR]: Map image at {0}, cached at {1}" , imageURL , filename ) ;
if ( ! File . Exists ( filename ) )
{
m_log . DebugFormat ( "[GATEKEEPER SERVICE CONNECTOR]: downloading..." ) ;
c . DownloadFile ( imageURL , filename ) ;
}
else
2012-04-20 02:32:38 +00:00
{
2011-01-06 20:48:28 +00:00
m_log . DebugFormat ( "[GATEKEEPER SERVICE CONNECTOR]: using cached image" ) ;
2012-04-20 02:32:38 +00:00
}
2011-01-06 20:48:28 +00:00
2012-04-20 02:32:38 +00:00
byte [ ] imageData = null ;
using ( Bitmap bitmap = new Bitmap ( filename ) )
{
//m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width);
imageData = OpenJPEG . EncodeFromImage ( bitmap , true ) ;
}
2013-06-22 03:52:46 +00:00
2010-12-13 20:19:33 +00:00
AssetBase ass = new AssetBase ( UUID . Random ( ) , "region " + name , ( sbyte ) AssetType . Texture , regionID . ToString ( ) ) ;
2010-01-24 22:30:48 +00:00
// !!! for now
//info.RegionSettings.TerrainImageID = ass.FullID;
ass . Data = imageData ;
2011-01-06 20:48:28 +00:00
mapTile = ass . FullID ;
2010-01-24 22:30:48 +00:00
// finally
2011-01-06 20:48:28 +00:00
m_AssetService . Store ( ass ) ;
2010-01-24 22:30:48 +00:00
}
catch // LEGIT: Catching problems caused by OpenJPEG p/invoke
{
2010-12-13 21:00:34 +00:00
m_log . Info ( "[GATEKEEPER SERVICE CONNECTOR]: Failed getting/storing map image, because it is probably already in the cache" ) ;
2010-01-24 22:30:48 +00:00
}
2010-12-13 20:19:33 +00:00
return mapTile ;
2010-01-24 22:30:48 +00:00
}
2014-04-06 13:18:40 +00:00
public GridRegion GetHyperlinkRegion ( GridRegion gatekeeper , UUID regionID , UUID agentID , string agentHomeURI , out string message )
2010-01-24 22:30:48 +00:00
{
Hashtable hash = new Hashtable ( ) ;
hash [ "region_uuid" ] = regionID . ToString ( ) ;
2014-04-06 13:18:40 +00:00
if ( agentID ! = UUID . Zero )
{
hash [ "agent_id" ] = agentID . ToString ( ) ;
if ( agentHomeURI ! = null )
hash [ "agent_home_uri" ] = agentHomeURI ;
}
2010-01-24 22:30:48 +00:00
IList paramList = new ArrayList ( ) ;
paramList . Add ( hash ) ;
XmlRpcRequest request = new XmlRpcRequest ( "get_region" , paramList ) ;
2010-10-22 03:22:15 +00:00
m_log . Debug ( "[GATEKEEPER SERVICE CONNECTOR]: contacting " + gatekeeper . ServerURI ) ;
2010-01-24 22:30:48 +00:00
XmlRpcResponse response = null ;
try
{
2010-10-03 22:03:53 +00:00
response = request . Send ( gatekeeper . ServerURI , 10000 ) ;
2010-01-24 22:30:48 +00:00
}
catch ( Exception e )
{
2014-04-03 09:47:20 +00:00
message = "Error contacting grid." ;
2010-10-22 03:22:15 +00:00
m_log . Debug ( "[GATEKEEPER SERVICE CONNECTOR]: Exception " + e . Message ) ;
2010-01-24 22:30:48 +00:00
return null ;
}
if ( response . IsFault )
{
2014-04-03 09:47:20 +00:00
message = "Error contacting grid." ;
2010-01-24 22:30:48 +00:00
m_log . ErrorFormat ( "[GATEKEEPER SERVICE CONNECTOR]: remote call returned an error: {0}" , response . FaultString ) ;
return null ;
}
hash = ( Hashtable ) response . Value ;
2010-10-20 06:36:59 +00:00
//foreach (Object o in hash)
// m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
2010-01-24 22:30:48 +00:00
try
{
bool success = false ;
Boolean . TryParse ( ( string ) hash [ "result" ] , out success ) ;
2014-04-03 09:47:20 +00:00
if ( hash [ "message" ] ! = null )
message = ( string ) hash [ "message" ] ;
else if ( success )
message = null ;
else
message = "The teleport destination could not be found." ; // probably the dest grid is old and doesn't send 'message', but the most common problem is that the region is unavailable
2010-01-24 22:30:48 +00:00
if ( success )
{
GridRegion region = new GridRegion ( ) ;
UUID . TryParse ( ( string ) hash [ "uuid" ] , out region . RegionID ) ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, uuid: " + region.RegionID);
2010-01-24 22:30:48 +00:00
int n = 0 ;
if ( hash [ "x" ] ! = null )
{
Int32 . TryParse ( ( string ) hash [ "x" ] , out n ) ;
region . RegionLocX = n ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, x: " + region.RegionLocX);
2010-01-24 22:30:48 +00:00
}
if ( hash [ "y" ] ! = null )
{
Int32 . TryParse ( ( string ) hash [ "y" ] , out n ) ;
region . RegionLocY = n ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, y: " + region.RegionLocY);
2010-01-24 22:30:48 +00:00
}
2014-01-24 00:20:18 +00:00
if ( hash [ "size_x" ] ! = null )
{
Int32 . TryParse ( ( string ) hash [ "size_x" ] , out n ) ;
region . RegionSizeX = n ;
//m_log.Debug(">> HERE, x: " + region.RegionLocX);
}
if ( hash [ "size_y" ] ! = null )
{
Int32 . TryParse ( ( string ) hash [ "size_y" ] , out n ) ;
region . RegionSizeY = n ;
//m_log.Debug(">> HERE, y: " + region.RegionLocY);
}
2010-01-24 22:30:48 +00:00
if ( hash [ "region_name" ] ! = null )
{
region . RegionName = ( string ) hash [ "region_name" ] ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, region_name: " + region.RegionName);
2010-01-24 22:30:48 +00:00
}
2013-06-22 03:52:46 +00:00
if ( hash [ "hostname" ] ! = null )
{
2010-01-24 22:30:48 +00:00
region . ExternalHostName = ( string ) hash [ "hostname" ] ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, hostname: " + region.ExternalHostName);
2010-10-22 03:22:15 +00:00
}
2010-01-24 22:30:48 +00:00
if ( hash [ "http_port" ] ! = null )
{
uint p = 0 ;
UInt32 . TryParse ( ( string ) hash [ "http_port" ] , out p ) ;
region . HttpPort = p ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, http_port: " + region.HttpPort);
2010-01-24 22:30:48 +00:00
}
if ( hash [ "internal_port" ] ! = null )
{
int p = 0 ;
Int32 . TryParse ( ( string ) hash [ "internal_port" ] , out p ) ;
region . InternalEndPoint = new IPEndPoint ( IPAddress . Parse ( "0.0.0.0" ) , p ) ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, internal_port: " + region.InternalEndPoint);
2010-10-22 03:22:15 +00:00
}
2013-06-22 03:52:46 +00:00
2010-10-22 03:22:15 +00:00
if ( hash [ "server_uri" ] ! = null )
{
2013-06-22 03:52:46 +00:00
region . ServerURI = ( string ) hash [ "server_uri" ] ;
2010-12-06 03:43:24 +00:00
//m_log.Debug(">> HERE, server_uri: " + region.ServerURI);
2010-01-24 22:30:48 +00:00
}
// Successful return
return region ;
}
}
catch ( Exception e )
{
2014-04-03 09:47:20 +00:00
message = "Error parsing response from grid." ;
2010-01-24 22:30:48 +00:00
m_log . Error ( "[GATEKEEPER SERVICE CONNECTOR]: Got exception while parsing hyperlink response " + e . StackTrace ) ;
return null ;
}
return null ;
}
2010-01-18 18:37:11 +00:00
}
}