2007-03-22 10:11:15 +00:00
/ *
Copyright ( c ) OpenSim project , http : //osgrid.org/
*
* 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 < organization > 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 < copyright holder > ` ` 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 < copyright holder > 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 ;
using System.Collections ;
using System.Collections.Generic ;
using libsecondlife ;
using libsecondlife.Packets ;
2007-04-17 12:03:52 +00:00
using Nwc.XmlRpc ;
2007-03-22 10:11:15 +00:00
using System.Net ;
using System.Net.Sockets ;
using System.IO ;
using System.Threading ;
using System.Timers ;
using OpenSim.Framework.Interfaces ;
2007-04-25 13:03:48 +00:00
using OpenSim.Framework.Types ;
2007-03-22 10:11:15 +00:00
using OpenSim.Framework.Inventory ;
using OpenSim.Framework.Utilities ;
using OpenSim.world ;
using OpenSim.Assets ;
namespace OpenSim
{
2007-03-31 21:18:05 +00:00
public delegate bool PacketMethod ( SimClient simClient , Packet packet ) ;
2007-03-22 10:11:15 +00:00
/// <summary>
/// Handles new client connections
/// Constructor takes a single Packet and authenticates everything
/// </summary>
public class SimClient
{
public LLUUID AgentID ;
public LLUUID SessionID ;
public LLUUID SecureSessionID = LLUUID . Zero ;
2007-04-17 12:03:52 +00:00
public bool m_child ;
2007-03-22 10:11:15 +00:00
public uint CircuitCode ;
public world . Avatar ClientAvatar ;
private UseCircuitCodePacket cirpack ;
2007-04-17 01:38:20 +00:00
public Thread ClientThread ;
2007-04-17 12:03:52 +00:00
public EndPoint userEP ;
public LLVector3 startpos ;
2007-03-22 10:11:15 +00:00
private BlockingQueue < QueItem > PacketQueue ;
private Dictionary < uint , uint > PendingAcks = new Dictionary < uint , uint > ( ) ;
private Dictionary < uint , Packet > NeedAck = new Dictionary < uint , Packet > ( ) ;
//private Dictionary<LLUUID, AssetBase> UploadedAssets = new Dictionary<LLUUID, AssetBase>();
private System . Timers . Timer AckTimer ;
private uint Sequence = 0 ;
private object SequenceLock = new object ( ) ;
private const int MAX_APPENDED_ACKS = 10 ;
private const int RESEND_TIMEOUT = 4000 ;
private const int MAX_SEQUENCE = 0xFFFFFF ;
2007-03-25 17:34:58 +00:00
private AgentAssetUpload UploadAssets ;
2007-03-22 10:11:15 +00:00
private LLUUID newAssetFolder = LLUUID . Zero ;
2007-03-30 15:51:38 +00:00
private bool debug = false ;
2007-03-27 21:42:14 +00:00
private World m_world ;
private Dictionary < uint , SimClient > m_clientThreads ;
private AssetCache m_assetCache ;
private IGridServer m_gridServer ;
2007-03-28 18:10:52 +00:00
private IUserServer m_userServer = null ;
2007-03-28 13:08:27 +00:00
private OpenSimNetworkHandler m_application ;
2007-03-27 21:42:14 +00:00
private InventoryCache m_inventoryCache ;
2007-04-17 12:03:52 +00:00
public bool m_sandboxMode ;
2007-03-30 12:12:33 +00:00
private int cachedtextureserial = 0 ;
2007-04-17 12:03:52 +00:00
private RegionInfo m_regionData ;
2007-03-22 10:11:15 +00:00
2007-04-01 10:19:21 +00:00
protected static Dictionary < PacketType , PacketMethod > PacketHandlers = new Dictionary < PacketType , PacketMethod > ( ) ; //Global/static handlers for all clients
2007-03-28 18:10:52 +00:00
2007-04-01 10:19:21 +00:00
protected Dictionary < PacketType , PacketMethod > m_packetHandlers = new Dictionary < PacketType , PacketMethod > ( ) ; //local handlers for this instance
2007-04-10 10:45:46 +00:00
2007-03-28 18:10:52 +00:00
public IUserServer UserServer
{
set
{
this . m_userServer = value ;
}
}
2007-04-17 12:03:52 +00:00
public SimClient ( EndPoint remoteEP , UseCircuitCodePacket initialcirpack , World world , Dictionary < uint , SimClient > clientThreads , AssetCache assetCache , IGridServer gridServer , OpenSimNetworkHandler application , InventoryCache inventoryCache , bool sandboxMode , bool child , RegionInfo regionDat )
2007-04-01 10:19:21 +00:00
{
m_world = world ;
m_clientThreads = clientThreads ;
m_assetCache = assetCache ;
m_gridServer = gridServer ;
m_application = application ;
m_inventoryCache = inventoryCache ;
m_sandboxMode = sandboxMode ;
2007-04-17 12:03:52 +00:00
m_child = child ;
m_regionData = regionDat ;
2007-04-01 10:19:21 +00:00
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , "OpenSimClient.cs - Started up new client thread to handle incoming request" ) ;
2007-04-01 10:19:21 +00:00
cirpack = initialcirpack ;
userEP = remoteEP ;
2007-04-17 12:03:52 +00:00
if ( m_gridServer . GetName ( ) = = "Remote" )
{
this . startpos = ( ( RemoteGridBase ) m_gridServer ) . agentcircuits [ initialcirpack . CircuitCode . Code ] . startpos ;
}
else
{
2007-04-22 04:49:12 +00:00
this . startpos = new LLVector3 ( 128 , 128 , m_world . Terrain [ ( int ) 128 , ( int ) 128 ] + 15.0f ) ; // new LLVector3(128.0f, 128.0f, 60f);
2007-04-17 12:03:52 +00:00
}
2007-04-01 10:19:21 +00:00
PacketQueue = new BlockingQueue < QueItem > ( ) ;
this . UploadAssets = new AgentAssetUpload ( this , m_assetCache , m_inventoryCache ) ;
AckTimer = new System . Timers . Timer ( 500 ) ;
AckTimer . Elapsed + = new ElapsedEventHandler ( AckTimer_Elapsed ) ;
AckTimer . Start ( ) ;
this . RegisterLocalPacketHandlers ( ) ;
ClientThread = new Thread ( new ThreadStart ( AuthUser ) ) ;
ClientThread . IsBackground = true ;
ClientThread . Start ( ) ;
}
protected virtual void RegisterLocalPacketHandlers ( )
{
2007-04-01 12:02:44 +00:00
this . AddLocalPacketHandler ( PacketType . LogoutRequest , this . Logout ) ;
this . AddLocalPacketHandler ( PacketType . AgentCachedTexture , this . AgentTextureCached ) ;
2007-04-01 15:30:27 +00:00
this . AddLocalPacketHandler ( PacketType . MultipleObjectUpdate , this . MultipleObjUpdate ) ;
2007-04-01 10:19:21 +00:00
}
2007-04-17 12:03:52 +00:00
public void CrossSimBorder ( LLVector3 avatarpos )
{ // VERY VERY BASIC
2007-05-13 12:25:08 +00:00
2007-04-17 12:25:20 +00:00
LLVector3 newpos = avatarpos ;
uint neighbourx = this . m_regionData . RegionLocX ;
2007-04-17 12:03:52 +00:00
uint neighboury = this . m_regionData . RegionLocY ;
if ( avatarpos . X < 0 )
{
neighbourx - = 1 ;
newpos . X = 254 ;
}
if ( avatarpos . X > 255 )
{
neighbourx + = 1 ;
newpos . X = 1 ;
}
if ( avatarpos . Y < 0 )
{
neighboury - = 1 ;
newpos . Y = 254 ;
}
if ( avatarpos . Y > 255 )
{
neighbourx + = 1 ;
newpos . Y = 1 ;
}
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , "SimClient.cs:CrossSimBorder() - Crossing border to neighbouring sim at [" + neighbourx . ToString ( ) + "," + neighboury . ToString ( ) + "]" ) ;
2007-04-17 12:03:52 +00:00
Hashtable SimParams ;
ArrayList SendParams ;
XmlRpcRequest GridReq ;
XmlRpcResponse GridResp ;
foreach ( Hashtable borderingSim in ( ( RemoteGridBase ) m_gridServer ) . neighbours )
{
if ( ( ( string ) borderingSim [ "region_locx" ] ) . Equals ( neighbourx . ToString ( ) ) & & ( ( string ) borderingSim [ "region_locy" ] ) . Equals ( neighboury . ToString ( ) ) )
{
SimParams = new Hashtable ( ) ;
SimParams [ "firstname" ] = this . ClientAvatar . firstname ;
SimParams [ "lastname" ] = this . ClientAvatar . lastname ;
SimParams [ "circuit_code" ] = this . CircuitCode . ToString ( ) ;
SimParams [ "pos_x" ] = newpos . X . ToString ( ) ;
SimParams [ "pos_y" ] = newpos . Y . ToString ( ) ;
SimParams [ "pos_z" ] = newpos . Z . ToString ( ) ;
SendParams = new ArrayList ( ) ;
SendParams . Add ( SimParams ) ;
GridReq = new XmlRpcRequest ( "agent_crossing" , SendParams ) ;
GridResp = GridReq . Send ( "http://" + borderingSim [ "sim_ip" ] + ":" + borderingSim [ "sim_port" ] , 3000 ) ;
CrossedRegionPacket NewSimPack = new CrossedRegionPacket ( ) ;
NewSimPack . AgentData = new CrossedRegionPacket . AgentDataBlock ( ) ;
NewSimPack . AgentData . AgentID = this . AgentID ;
NewSimPack . AgentData . SessionID = this . SessionID ;
NewSimPack . Info = new CrossedRegionPacket . InfoBlock ( ) ;
NewSimPack . Info . Position = newpos ;
NewSimPack . Info . LookAt = new LLVector3 ( 0.99f , 0.042f , 0 ) ; // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!!
NewSimPack . RegionData = new libsecondlife . Packets . CrossedRegionPacket . RegionDataBlock ( ) ;
NewSimPack . RegionData . RegionHandle = Helpers . UIntsToLong ( ( uint ) ( Convert . ToInt32 ( borderingSim [ "region_locx" ] ) * 256 ) , ( uint ) ( Convert . ToInt32 ( borderingSim [ "region_locy" ] ) * 256 ) ) ;
System . Net . IPAddress neighbourIP = System . Net . IPAddress . Parse ( ( string ) borderingSim [ "sim_ip" ] ) ;
byte [ ] byteIP = neighbourIP . GetAddressBytes ( ) ;
NewSimPack . RegionData . SimIP = ( uint ) byteIP [ 3 ] < < 24 ;
NewSimPack . RegionData . SimIP + = ( uint ) byteIP [ 2 ] < < 16 ;
NewSimPack . RegionData . SimIP + = ( uint ) byteIP [ 1 ] < < 8 ;
NewSimPack . RegionData . SimIP + = ( uint ) byteIP [ 0 ] ;
NewSimPack . RegionData . SimPort = ( ushort ) Convert . ToInt32 ( borderingSim [ "sim_port" ] ) ;
NewSimPack . RegionData . SeedCapability = new byte [ 0 ] ;
lock ( PacketQueue )
{
ProcessOutPacket ( NewSimPack ) ;
DowngradeClient ( ) ;
}
}
}
}
public void UpgradeClient ( )
{
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , "SimClient.cs:UpgradeClient() - upgrading child to full agent" ) ;
2007-04-17 12:03:52 +00:00
this . m_child = false ;
this . m_world . RemoveViewerAgent ( this ) ;
if ( ! this . m_sandboxMode )
{
this . startpos = ( ( RemoteGridBase ) m_gridServer ) . agentcircuits [ CircuitCode ] . startpos ;
( ( RemoteGridBase ) m_gridServer ) . agentcircuits [ CircuitCode ] . child = false ;
}
this . InitNewClient ( ) ;
}
public void DowngradeClient ( )
{
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , "SimClient.cs:UpgradeClient() - changing full agent to child" ) ;
2007-04-17 12:03:52 +00:00
this . m_child = true ;
this . m_world . RemoveViewerAgent ( this ) ;
this . m_world . AddViewerAgent ( this ) ;
}
public void KillClient ( )
{
KillObjectPacket kill = new KillObjectPacket ( ) ;
kill . ObjectData = new KillObjectPacket . ObjectDataBlock [ 1 ] ;
kill . ObjectData [ 0 ] = new KillObjectPacket . ObjectDataBlock ( ) ;
kill . ObjectData [ 0 ] . ID = this . ClientAvatar . localid ;
foreach ( SimClient client in m_clientThreads . Values )
{
client . OutPacket ( kill ) ;
}
if ( this . m_userServer ! = null )
{
this . m_inventoryCache . ClientLeaving ( this . AgentID , this . m_userServer ) ;
}
else
{
this . m_inventoryCache . ClientLeaving ( this . AgentID , null ) ;
}
m_world . RemoveViewerAgent ( this ) ;
m_clientThreads . Remove ( this . CircuitCode ) ;
m_application . RemoveClientCircuit ( this . CircuitCode ) ;
this . ClientThread . Abort ( ) ;
}
2007-03-31 21:18:05 +00:00
public static bool AddPacketHandler ( PacketType packetType , PacketMethod handler )
{
bool result = false ;
lock ( PacketHandlers )
{
if ( ! PacketHandlers . ContainsKey ( packetType ) )
{
PacketHandlers . Add ( packetType , handler ) ;
result = true ;
}
}
return result ;
}
2007-04-01 10:19:21 +00:00
public bool AddLocalPacketHandler ( PacketType packetType , PacketMethod handler )
{
bool result = false ;
lock ( m_packetHandlers )
{
if ( ! m_packetHandlers . ContainsKey ( packetType ) )
{
m_packetHandlers . Add ( packetType , handler ) ;
result = true ;
}
}
return result ;
}
2007-03-31 21:18:05 +00:00
protected virtual bool ProcessPacketMethod ( Packet packet )
{
bool result = false ;
bool found = false ;
PacketMethod method ;
2007-04-01 10:19:21 +00:00
if ( m_packetHandlers . TryGetValue ( packet . Type , out method ) )
2007-03-31 21:18:05 +00:00
{
2007-04-01 10:19:21 +00:00
//there is a local handler for this packet type
result = method ( this , packet ) ;
2007-03-31 21:18:05 +00:00
}
2007-04-01 10:19:21 +00:00
else
2007-03-31 21:18:05 +00:00
{
2007-04-01 10:19:21 +00:00
//there is not a local handler so see if there is a Global handler
lock ( PacketHandlers )
{
found = PacketHandlers . TryGetValue ( packet . Type , out method ) ;
}
if ( found )
{
result = method ( this , packet ) ;
}
2007-03-31 21:18:05 +00:00
}
return result ;
}
2007-03-22 10:11:15 +00:00
private void ack_pack ( Packet Pack )
{
2007-04-03 18:47:10 +00:00
if ( Pack . Header . Reliable )
{
libsecondlife . Packets . PacketAckPacket ack_it = new PacketAckPacket ( ) ;
ack_it . Packets = new PacketAckPacket . PacketsBlock [ 1 ] ;
ack_it . Packets [ 0 ] = new PacketAckPacket . PacketsBlock ( ) ;
ack_it . Packets [ 0 ] . ID = Pack . Header . Sequence ;
ack_it . Header . Reliable = false ;
2007-03-22 10:11:15 +00:00
2007-04-03 18:47:10 +00:00
OutPacket ( ack_it ) ;
2007-03-22 10:11:15 +00:00
2007-04-03 18:47:10 +00:00
}
/ *
2007-03-22 10:11:15 +00:00
if ( Pack . Header . Reliable )
{
lock ( PendingAcks )
{
uint sequence = ( uint ) Pack . Header . Sequence ;
if ( ! PendingAcks . ContainsKey ( sequence ) ) { PendingAcks [ sequence ] = sequence ; }
}
2007-04-03 18:47:10 +00:00
} * /
2007-03-22 10:11:15 +00:00
}
protected virtual void ProcessInPacket ( Packet Pack )
{
ack_pack ( Pack ) ;
if ( debug )
{
if ( Pack . Type ! = PacketType . AgentUpdate )
{
Console . WriteLine ( Pack . Type . ToString ( ) ) ;
}
}
2007-03-31 21:18:05 +00:00
if ( this . ProcessPacketMethod ( Pack ) )
2007-03-22 10:11:15 +00:00
{
2007-04-01 10:19:21 +00:00
//there is a handler registered that handled this packet type
2007-03-31 21:18:05 +00:00
return ;
}
else
{
System . Text . Encoding _enc = System . Text . Encoding . ASCII ;
2007-04-10 10:45:46 +00:00
2007-03-31 21:18:05 +00:00
switch ( Pack . Type )
{
case PacketType . CompleteAgentMovement :
2007-04-17 12:03:52 +00:00
if ( this . m_child ) this . UpgradeClient ( ) ;
ClientAvatar . CompleteMovement ( m_world ) ;
ClientAvatar . SendInitialPosition ( ) ;
2007-05-14 21:04:14 +00:00
this . EnableNeighbours ( ) ;
2007-03-31 21:18:05 +00:00
break ;
case PacketType . RegionHandshakeReply :
m_world . SendLayerData ( this ) ;
break ;
case PacketType . AgentWearablesRequest :
ClientAvatar . SendInitialAppearance ( ) ;
foreach ( SimClient client in m_clientThreads . Values )
2007-03-22 10:11:15 +00:00
{
2007-03-31 21:18:05 +00:00
if ( client . AgentID ! = this . AgentID )
{
ObjectUpdatePacket objupdate = client . ClientAvatar . CreateUpdatePacket ( ) ;
this . OutPacket ( objupdate ) ;
client . ClientAvatar . SendAppearanceToOtherAgent ( this ) ;
}
2007-03-22 10:11:15 +00:00
}
2007-03-31 21:18:05 +00:00
m_world . GetInitialPrims ( this ) ;
break ;
case PacketType . AgentIsNowWearing :
AgentIsNowWearingPacket wear = ( AgentIsNowWearingPacket ) Pack ;
//Console.WriteLine(Pack.ToString());
break ;
case PacketType . AgentSetAppearance :
AgentSetAppearancePacket appear = ( AgentSetAppearancePacket ) Pack ;
// Console.WriteLine(appear.ToString());
this . ClientAvatar . SetAppearance ( appear ) ;
break ;
case PacketType . ObjectAdd :
m_world . AddNewPrim ( ( ObjectAddPacket ) Pack , this ) ;
break ;
case PacketType . ObjectLink :
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , Pack . ToString ( ) ) ;
2007-04-03 16:10:00 +00:00
ObjectLinkPacket link = ( ObjectLinkPacket ) Pack ;
uint parentprimid = 0 ;
OpenSim . world . Primitive parentprim = null ;
if ( link . ObjectData . Length > 1 )
{
parentprimid = link . ObjectData [ 0 ] . ObjectLocalID ;
foreach ( Entity ent in m_world . Entities . Values )
{
if ( ent . localid = = parentprimid )
{
parentprim = ( OpenSim . world . Primitive ) ent ;
2007-04-10 10:45:46 +00:00
2007-04-03 16:10:00 +00:00
}
}
for ( int i = 1 ; i < link . ObjectData . Length ; i + + )
{
foreach ( Entity ent in m_world . Entities . Values )
{
if ( ent . localid = = link . ObjectData [ i ] . ObjectLocalID )
{
( ( OpenSim . world . Primitive ) ent ) . MakeParent ( parentprim ) ;
}
}
}
}
2007-03-31 21:18:05 +00:00
break ;
case PacketType . ObjectScale :
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , Pack . ToString ( ) ) ;
2007-03-31 21:18:05 +00:00
break ;
case PacketType . ObjectShape :
ObjectShapePacket shape = ( ObjectShapePacket ) Pack ;
for ( int i = 0 ; i < shape . ObjectData . Length ; i + + )
2007-03-22 10:11:15 +00:00
{
2007-03-31 21:18:05 +00:00
foreach ( Entity ent in m_world . Entities . Values )
2007-03-22 10:11:15 +00:00
{
2007-03-31 21:18:05 +00:00
if ( ent . localid = = shape . ObjectData [ i ] . ObjectLocalID )
{
( ( OpenSim . world . Primitive ) ent ) . UpdateShape ( shape . ObjectData [ i ] ) ;
}
2007-03-22 10:11:15 +00:00
}
}
2007-03-31 21:18:05 +00:00
break ;
case PacketType . RequestImage :
RequestImagePacket imageRequest = ( RequestImagePacket ) Pack ;
for ( int i = 0 ; i < imageRequest . RequestImage . Length ; i + + )
{
m_assetCache . AddTextureRequest ( this , imageRequest . RequestImage [ i ] . Image ) ;
2007-03-22 10:11:15 +00:00
}
2007-03-31 21:18:05 +00:00
break ;
case PacketType . TransferRequest :
//Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request");
TransferRequestPacket transfer = ( TransferRequestPacket ) Pack ;
m_assetCache . AddAssetRequest ( this , transfer ) ;
break ;
case PacketType . AgentUpdate :
ClientAvatar . HandleUpdate ( ( AgentUpdatePacket ) Pack ) ;
break ;
case PacketType . ObjectImage :
ObjectImagePacket imagePack = ( ObjectImagePacket ) Pack ;
for ( int i = 0 ; i < imagePack . ObjectData . Length ; i + + )
{
2007-03-27 21:42:14 +00:00
foreach ( Entity ent in m_world . Entities . Values )
2007-03-22 10:11:15 +00:00
{
2007-03-31 21:18:05 +00:00
if ( ent . localid = = imagePack . ObjectData [ i ] . ObjectLocalID )
2007-03-22 10:11:15 +00:00
{
2007-03-31 21:18:05 +00:00
( ( OpenSim . world . Primitive ) ent ) . UpdateTexture ( imagePack . ObjectData [ i ] . TextureEntry ) ;
2007-03-22 10:11:15 +00:00
}
}
}
2007-03-31 21:18:05 +00:00
break ;
case PacketType . ObjectFlagUpdate :
ObjectFlagUpdatePacket flags = ( ObjectFlagUpdatePacket ) Pack ;
2007-03-27 21:42:14 +00:00
foreach ( Entity ent in m_world . Entities . Values )
2007-03-22 10:11:15 +00:00
{
2007-03-31 21:18:05 +00:00
if ( ent . localid = = flags . AgentData . ObjectLocalID )
2007-03-22 10:11:15 +00:00
{
2007-03-31 21:18:05 +00:00
( ( OpenSim . world . Primitive ) ent ) . UpdateObjectFlags ( flags ) ;
2007-03-22 10:11:15 +00:00
}
}
2007-03-31 21:18:05 +00:00
break ;
case PacketType . AssetUploadRequest :
AssetUploadRequestPacket request = ( AssetUploadRequestPacket ) Pack ;
2007-03-25 17:34:58 +00:00
this . UploadAssets . HandleUploadPacket ( request , request . AssetBlock . TransactionID . Combine ( this . SecureSessionID ) ) ;
2007-03-31 21:18:05 +00:00
break ;
2007-04-04 11:06:39 +00:00
case PacketType . RequestXfer :
//Console.WriteLine(Pack.ToString());
break ;
2007-03-31 21:18:05 +00:00
case PacketType . SendXferPacket :
this . UploadAssets . HandleXferPacket ( ( SendXferPacketPacket ) Pack ) ;
break ;
case PacketType . CreateInventoryFolder :
CreateInventoryFolderPacket invFolder = ( CreateInventoryFolderPacket ) Pack ;
2007-04-25 18:12:06 +00:00
m_inventoryCache . CreateNewInventoryFolder ( this , invFolder . FolderData . FolderID , ( ushort ) invFolder . FolderData . Type , Util . FieldToString ( invFolder . FolderData . Name ) , invFolder . FolderData . ParentID ) ;
2007-04-04 11:06:39 +00:00
//Console.WriteLine(Pack.ToString());
2007-03-31 21:18:05 +00:00
break ;
case PacketType . CreateInventoryItem :
2007-04-04 11:06:39 +00:00
//Console.WriteLine(Pack.ToString());
2007-03-31 21:18:05 +00:00
CreateInventoryItemPacket createItem = ( CreateInventoryItemPacket ) Pack ;
if ( createItem . InventoryBlock . TransactionID ! = LLUUID . Zero )
2007-03-25 17:34:58 +00:00
{
2007-03-31 21:18:05 +00:00
this . UploadAssets . CreateInventoryItem ( createItem ) ;
}
else
{
2007-04-10 10:45:46 +00:00
// Console.Write(Pack.ToString());
2007-03-31 21:18:05 +00:00
this . CreateInventoryItem ( createItem ) ;
}
break ;
case PacketType . FetchInventory :
//Console.WriteLine("fetch item packet");
FetchInventoryPacket FetchInventory = ( FetchInventoryPacket ) Pack ;
m_inventoryCache . FetchInventory ( this , FetchInventory ) ;
break ;
case PacketType . FetchInventoryDescendents :
FetchInventoryDescendentsPacket Fetch = ( FetchInventoryDescendentsPacket ) Pack ;
m_inventoryCache . FetchInventoryDescendents ( this , Fetch ) ;
break ;
case PacketType . UpdateInventoryItem :
UpdateInventoryItemPacket update = ( UpdateInventoryItemPacket ) Pack ;
//Console.WriteLine(Pack.ToString());
for ( int i = 0 ; i < update . InventoryData . Length ; i + + )
{
if ( update . InventoryData [ i ] . TransactionID ! = LLUUID . Zero )
2007-03-26 16:51:50 +00:00
{
2007-03-31 21:18:05 +00:00
AssetBase asset = m_assetCache . GetAsset ( update . InventoryData [ i ] . TransactionID . Combine ( this . SecureSessionID ) ) ;
2007-03-26 16:51:50 +00:00
if ( asset ! = null )
{
2007-04-10 10:45:46 +00:00
// Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache");
2007-03-29 20:55:44 +00:00
m_inventoryCache . UpdateInventoryItemAsset ( this , update . InventoryData [ i ] . ItemID , asset ) ;
2007-03-26 16:51:50 +00:00
}
2007-03-29 17:04:24 +00:00
else
{
2007-03-31 21:18:05 +00:00
asset = this . UploadAssets . AddUploadToAssetCache ( update . InventoryData [ i ] . TransactionID ) ;
if ( asset ! = null )
{
2007-04-04 11:06:39 +00:00
//Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache");
2007-03-31 21:18:05 +00:00
m_inventoryCache . UpdateInventoryItemAsset ( this , update . InventoryData [ i ] . ItemID , asset ) ;
}
else
{
2007-04-04 11:06:39 +00:00
//Console.WriteLine("trying to update inventory item, but asset is null");
2007-03-31 21:18:05 +00:00
}
2007-03-29 17:04:24 +00:00
}
2007-03-26 16:51:50 +00:00
}
2007-03-31 21:18:05 +00:00
else
{
m_inventoryCache . UpdateInventoryItemDetails ( this , update . InventoryData [ i ] . ItemID , update . InventoryData [ i ] ) ; ;
}
2007-03-25 17:34:58 +00:00
}
2007-03-31 21:18:05 +00:00
break ;
case PacketType . ViewerEffect :
ViewerEffectPacket viewer = ( ViewerEffectPacket ) Pack ;
foreach ( SimClient client in m_clientThreads . Values )
2007-03-29 20:55:44 +00:00
{
2007-03-31 21:18:05 +00:00
if ( client . AgentID ! = this . AgentID )
{
viewer . AgentData . AgentID = client . AgentID ;
viewer . AgentData . SessionID = client . SessionID ;
client . OutPacket ( viewer ) ;
}
2007-03-29 20:55:44 +00:00
}
2007-03-31 21:18:05 +00:00
break ;
case PacketType . RequestTaskInventory :
// Console.WriteLine(Pack.ToString());
RequestTaskInventoryPacket requesttask = ( RequestTaskInventoryPacket ) Pack ;
ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket ( ) ;
bool foundent = false ;
foreach ( Entity ent in m_world . Entities . Values )
{
if ( ent . localid = = requesttask . InventoryData . LocalID )
2007-03-30 16:50:19 +00:00
{
2007-03-31 21:18:05 +00:00
replytask . InventoryData . TaskID = ent . uuid ;
replytask . InventoryData . Serial = 0 ;
replytask . InventoryData . Filename = new byte [ 0 ] ;
foundent = true ;
2007-03-30 16:50:19 +00:00
}
2007-03-31 21:18:05 +00:00
}
if ( foundent )
2007-03-31 15:54:16 +00:00
{
2007-03-31 21:18:05 +00:00
this . OutPacket ( replytask ) ;
2007-03-31 15:54:16 +00:00
}
2007-03-31 21:18:05 +00:00
break ;
2007-04-03 18:15:11 +00:00
case PacketType . UpdateTaskInventory :
2007-04-10 10:45:46 +00:00
// Console.WriteLine(Pack.ToString());
2007-04-03 18:15:11 +00:00
UpdateTaskInventoryPacket updatetask = ( UpdateTaskInventoryPacket ) Pack ;
AgentInventory myinventory = this . m_inventoryCache . GetAgentsInventory ( this . AgentID ) ;
if ( myinventory ! = null )
{
2007-04-04 11:06:39 +00:00
if ( updatetask . UpdateData . Key = = 0 )
2007-04-03 18:15:11 +00:00
{
2007-04-04 11:06:39 +00:00
if ( myinventory . InventoryItems [ updatetask . InventoryData . ItemID ] ! = null )
2007-04-03 18:15:11 +00:00
{
2007-04-04 11:06:39 +00:00
if ( myinventory . InventoryItems [ updatetask . InventoryData . ItemID ] . Type = = 7 )
2007-04-03 18:15:11 +00:00
{
2007-04-04 11:06:39 +00:00
LLUUID noteaid = myinventory . InventoryItems [ updatetask . InventoryData . ItemID ] . AssetID ;
AssetBase assBase = this . m_assetCache . GetAsset ( noteaid ) ;
if ( assBase ! = null )
2007-04-03 18:15:11 +00:00
{
2007-04-04 11:06:39 +00:00
foreach ( Entity ent in m_world . Entities . Values )
2007-04-03 18:15:11 +00:00
{
2007-04-04 11:06:39 +00:00
if ( ent . localid = = updatetask . UpdateData . LocalID )
{
if ( ent is OpenSim . world . Primitive )
{
2007-04-25 18:12:06 +00:00
this . m_world . AddScript ( ent , Util . FieldToString ( assBase . Data ) ) ;
2007-04-04 11:06:39 +00:00
}
}
2007-04-03 18:15:11 +00:00
}
}
}
}
}
}
break ;
2007-03-31 21:18:05 +00:00
case PacketType . AgentAnimation :
2007-04-17 12:03:52 +00:00
if ( ! m_child )
{
AgentAnimationPacket AgentAni = ( AgentAnimationPacket ) Pack ;
for ( int i = 0 ; i < AgentAni . AnimationList . Length ; i + + )
{
if ( AgentAni . AnimationList [ i ] . StartAnim )
{
ClientAvatar . current_anim = AgentAni . AnimationList [ i ] . AnimID ;
ClientAvatar . anim_seq = 1 ;
ClientAvatar . SendAnimPack ( ) ;
}
}
}
2007-03-31 21:18:05 +00:00
break ;
case PacketType . ObjectSelect :
ObjectSelectPacket incomingselect = ( ObjectSelectPacket ) Pack ;
for ( int i = 0 ; i < incomingselect . ObjectData . Length ; i + + )
{
foreach ( Entity ent in m_world . Entities . Values )
2007-03-31 15:54:16 +00:00
{
2007-03-31 21:18:05 +00:00
if ( ent . localid = = incomingselect . ObjectData [ i ] . ObjectLocalID )
{
( ( OpenSim . world . Primitive ) ent ) . GetProperites ( this ) ;
break ;
}
2007-03-31 15:54:16 +00:00
}
}
2007-03-31 21:18:05 +00:00
break ;
2007-05-13 12:25:08 +00:00
case PacketType . MapLayerRequest :
this . RequestMapLayer ( ) ;
break ;
case PacketType . MapBlockRequest :
MapBlockRequestPacket MapRequest = ( MapBlockRequestPacket ) Pack ;
this . RequestMapBlock ( MapRequest . PositionData . MinX , MapRequest . PositionData . MinY , MapRequest . PositionData . MaxX , MapRequest . PositionData . MaxY ) ;
break ;
2007-05-11 21:03:11 +00:00
2007-03-31 21:18:05 +00:00
}
2007-03-22 10:11:15 +00:00
}
}
private void ResendUnacked ( )
{
int now = Environment . TickCount ;
lock ( NeedAck )
{
foreach ( Packet packet in NeedAck . Values )
{
if ( ( now - packet . TickCount > RESEND_TIMEOUT ) & & ( ! packet . Header . Resent ) )
{
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . VERBOSE , "Resending " + packet . Type . ToString ( ) + " packet, " +
2007-03-22 10:11:15 +00:00
( now - packet . TickCount ) + "ms have passed" ) ;
packet . Header . Resent = true ;
OutPacket ( packet ) ;
}
}
}
}
private void SendAcks ( )
{
lock ( PendingAcks )
{
if ( PendingAcks . Count > 0 )
{
if ( PendingAcks . Count > 250 )
{
// FIXME: Handle the odd case where we have too many pending ACKs queued up
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . VERBOSE , "Too many ACKs queued up!" ) ;
2007-03-22 10:11:15 +00:00
return ;
}
2007-04-04 11:06:39 +00:00
//OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Sending PacketAck");
2007-03-22 10:11:15 +00:00
int i = 0 ;
PacketAckPacket acks = new PacketAckPacket ( ) ;
acks . Packets = new PacketAckPacket . PacketsBlock [ PendingAcks . Count ] ;
foreach ( uint ack in PendingAcks . Values )
{
acks . Packets [ i ] = new PacketAckPacket . PacketsBlock ( ) ;
acks . Packets [ i ] . ID = ack ;
i + + ;
}
acks . Header . Reliable = false ;
OutPacket ( acks ) ;
PendingAcks . Clear ( ) ;
}
}
}
private void AckTimer_Elapsed ( object sender , ElapsedEventArgs ea )
{
SendAcks ( ) ;
ResendUnacked ( ) ;
}
protected virtual void ProcessOutPacket ( Packet Pack )
{
// Keep track of when this packet was sent out
Pack . TickCount = Environment . TickCount ;
if ( ! Pack . Header . Resent )
{
// Set the sequence number
lock ( SequenceLock )
{
if ( Sequence > = MAX_SEQUENCE )
Sequence = 1 ;
else
Sequence + + ;
Pack . Header . Sequence = Sequence ;
}
if ( Pack . Header . Reliable ) //DIRTY HACK
{
lock ( NeedAck )
{
if ( ! NeedAck . ContainsKey ( Pack . Header . Sequence ) )
{
2007-04-22 17:31:51 +00:00
try
{
NeedAck . Add ( Pack . Header . Sequence , Pack ) ;
}
2007-04-22 18:48:45 +00:00
catch ( Exception e ) // HACKY
2007-04-22 17:31:51 +00:00
{
2007-04-22 18:48:45 +00:00
e . ToString ( ) ;
2007-04-22 17:31:51 +00:00
// Ignore
// Seems to throw a exception here occasionally
// of 'duplicate key' despite being locked.
// !?!?!?
}
2007-03-22 10:11:15 +00:00
}
else
{
// Client.Log("Attempted to add a duplicate sequence number (" +
// packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
// packet.Type.ToString(), Helpers.LogLevel.Warning);
}
}
// Don't append ACKs to resent packets, in case that's what was causing the
// delivery to fail
if ( ! Pack . Header . Resent )
{
// Append any ACKs that need to be sent out to this packet
lock ( PendingAcks )
{
if ( PendingAcks . Count > 0 & & PendingAcks . Count < MAX_APPENDED_ACKS & &
Pack . Type ! = PacketType . PacketAck & &
Pack . Type ! = PacketType . LogoutRequest )
{
Pack . Header . AckList = new uint [ PendingAcks . Count ] ;
int i = 0 ;
foreach ( uint ack in PendingAcks . Values )
{
Pack . Header . AckList [ i ] = ack ;
i + + ;
}
PendingAcks . Clear ( ) ;
Pack . Header . AppendedAcks = true ;
}
}
}
}
}
byte [ ] ZeroOutBuffer = new byte [ 4096 ] ;
byte [ ] sendbuffer ;
sendbuffer = Pack . ToBytes ( ) ;
try
{
if ( Pack . Header . Zerocoded )
{
int packetsize = Helpers . ZeroEncode ( sendbuffer , sendbuffer . Length , ZeroOutBuffer ) ;
2007-03-27 21:42:14 +00:00
m_application . SendPacketTo ( ZeroOutBuffer , packetsize , SocketFlags . None , CircuitCode ) ; //userEP);
2007-03-22 10:11:15 +00:00
}
else
{
2007-03-27 21:42:14 +00:00
m_application . SendPacketTo ( sendbuffer , sendbuffer . Length , SocketFlags . None , CircuitCode ) ; //userEP);
2007-03-22 10:11:15 +00:00
}
}
catch ( Exception )
{
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . MEDIUM , "OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP . ToString ( ) + " - killing thread" ) ;
2007-03-22 10:11:15 +00:00
ClientThread . Abort ( ) ;
}
}
2007-03-31 21:18:05 +00:00
public virtual void InPacket ( Packet NewPack )
2007-03-22 10:11:15 +00:00
{
// Handle appended ACKs
if ( NewPack . Header . AppendedAcks )
{
lock ( NeedAck )
{
foreach ( uint ack in NewPack . Header . AckList )
{
NeedAck . Remove ( ack ) ;
}
}
}
// Handle PacketAck packets
if ( NewPack . Type = = PacketType . PacketAck )
{
PacketAckPacket ackPacket = ( PacketAckPacket ) NewPack ;
lock ( NeedAck )
{
foreach ( PacketAckPacket . PacketsBlock block in ackPacket . Packets )
{
NeedAck . Remove ( block . ID ) ;
}
}
}
else if ( ( NewPack . Type = = PacketType . StartPingCheck ) )
{
//reply to pingcheck
libsecondlife . Packets . StartPingCheckPacket startPing = ( libsecondlife . Packets . StartPingCheckPacket ) NewPack ;
libsecondlife . Packets . CompletePingCheckPacket endPing = new CompletePingCheckPacket ( ) ;
endPing . PingID . PingID = startPing . PingID . PingID ;
OutPacket ( endPing ) ;
}
else
{
QueItem item = new QueItem ( ) ;
item . Packet = NewPack ;
item . Incoming = true ;
this . PacketQueue . Enqueue ( item ) ;
}
}
public virtual void OutPacket ( Packet NewPack )
{
QueItem item = new QueItem ( ) ;
item . Packet = NewPack ;
item . Incoming = false ;
this . PacketQueue . Enqueue ( item ) ;
}
protected virtual void ClientLoop ( )
{
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , "OpenSimClient.cs:ClientLoop() - Entered loop" ) ;
2007-03-22 10:11:15 +00:00
while ( true )
{
QueItem nextPacket = PacketQueue . Dequeue ( ) ;
if ( nextPacket . Incoming )
{
//is a incoming packet
ProcessInPacket ( nextPacket . Packet ) ;
}
else
{
//is a out going packet
ProcessOutPacket ( nextPacket . Packet ) ;
}
}
}
protected virtual void InitNewClient ( )
{
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world" ) ;
2007-03-31 21:18:05 +00:00
2007-03-27 21:42:14 +00:00
m_world . AddViewerAgent ( this ) ;
world . Entity tempent = m_world . Entities [ this . AgentID ] ;
2007-03-31 21:18:05 +00:00
2007-03-22 10:11:15 +00:00
this . ClientAvatar = ( world . Avatar ) tempent ;
}
protected virtual void AuthUser ( )
{
2007-03-27 21:42:14 +00:00
AuthenticateResponse sessionInfo = m_gridServer . AuthenticateSession ( cirpack . CircuitCode . SessionID , cirpack . CircuitCode . ID , cirpack . CircuitCode . Code ) ;
2007-03-22 10:11:15 +00:00
if ( ! sessionInfo . Authorised )
{
//session/circuit not authorised
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . NORMAL , "OpenSimClient.cs:AuthUser() - New user request denied to " + userEP . ToString ( ) ) ;
2007-03-22 10:11:15 +00:00
ClientThread . Abort ( ) ;
}
else
{
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . NORMAL , "OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP . ToString ( ) ) ;
2007-03-22 10:11:15 +00:00
//session is authorised
this . AgentID = cirpack . CircuitCode . ID ;
this . SessionID = cirpack . CircuitCode . SessionID ;
this . CircuitCode = cirpack . CircuitCode . Code ;
InitNewClient ( ) ; //shouldn't be called here as we might be a child agent and not want a full avatar
this . ClientAvatar . firstname = sessionInfo . LoginInfo . First ;
this . ClientAvatar . lastname = sessionInfo . LoginInfo . Last ;
if ( sessionInfo . LoginInfo . SecureSession ! = LLUUID . Zero )
{
this . SecureSessionID = sessionInfo . LoginInfo . SecureSession ;
}
// Create Inventory, currently only works for sandbox mode
2007-03-27 21:42:14 +00:00
if ( m_sandboxMode )
2007-03-22 10:11:15 +00:00
{
2007-03-28 18:10:52 +00:00
AgentInventory inventory = null ;
2007-03-22 10:11:15 +00:00
if ( sessionInfo . LoginInfo . InventoryFolder ! = null )
{
2007-03-28 18:10:52 +00:00
inventory = this . CreateInventory ( sessionInfo . LoginInfo . InventoryFolder ) ;
2007-03-22 10:11:15 +00:00
if ( sessionInfo . LoginInfo . BaseFolder ! = null )
{
2007-03-28 18:10:52 +00:00
if ( ! inventory . HasFolder ( sessionInfo . LoginInfo . BaseFolder ) )
{
m_inventoryCache . CreateNewInventoryFolder ( this , sessionInfo . LoginInfo . BaseFolder ) ;
}
2007-03-22 10:11:15 +00:00
this . newAssetFolder = sessionInfo . LoginInfo . BaseFolder ;
2007-03-27 21:42:14 +00:00
AssetBase [ ] inventorySet = m_assetCache . CreateNewInventorySet ( this . AgentID ) ;
2007-03-22 10:11:15 +00:00
if ( inventorySet ! = null )
{
for ( int i = 0 ; i < inventorySet . Length ; i + + )
{
if ( inventorySet [ i ] ! = null )
{
2007-03-27 21:42:14 +00:00
m_inventoryCache . AddNewInventoryItem ( this , sessionInfo . LoginInfo . BaseFolder , inventorySet [ i ] ) ;
2007-03-22 10:11:15 +00:00
}
}
}
}
}
}
ClientLoop ( ) ;
}
}
2007-04-01 12:02:44 +00:00
#region Packet handlers
2007-04-17 12:03:52 +00:00
2007-04-01 12:02:44 +00:00
protected virtual bool Logout ( SimClient simClient , Packet packet )
{
2007-05-12 15:32:04 +00:00
OpenSim . Framework . Console . MainConsole . Instance . WriteLine ( OpenSim . Framework . Console . LogPriority . LOW , "OpenSimClient.cs:ProcessInPacket() - Got a logout request" ) ;
2007-04-01 12:02:44 +00:00
//send reply to let the client logout
LogoutReplyPacket logReply = new LogoutReplyPacket ( ) ;
logReply . AgentData . AgentID = this . AgentID ;
logReply . AgentData . SessionID = this . SessionID ;
logReply . InventoryData = new LogoutReplyPacket . InventoryDataBlock [ 1 ] ;
logReply . InventoryData [ 0 ] = new LogoutReplyPacket . InventoryDataBlock ( ) ;
logReply . InventoryData [ 0 ] . ItemID = LLUUID . Zero ;
OutPacket ( logReply ) ;
//tell all clients to kill our object
KillObjectPacket kill = new KillObjectPacket ( ) ;
kill . ObjectData = new KillObjectPacket . ObjectDataBlock [ 1 ] ;
kill . ObjectData [ 0 ] = new KillObjectPacket . ObjectDataBlock ( ) ;
kill . ObjectData [ 0 ] . ID = this . ClientAvatar . localid ;
foreach ( SimClient client in m_clientThreads . Values )
{
client . OutPacket ( kill ) ;
}
if ( this . m_userServer ! = null )
{
this . m_inventoryCache . ClientLeaving ( this . AgentID , this . m_userServer ) ;
}
else
{
this . m_inventoryCache . ClientLeaving ( this . AgentID , null ) ;
}
m_gridServer . LogoutSession ( this . SessionID , this . AgentID , this . CircuitCode ) ;
2007-04-04 18:26:33 +00:00
/ * lock ( m_world . Entities )
2007-04-01 12:02:44 +00:00
{
m_world . Entities . Remove ( this . AgentID ) ;
2007-04-04 18:26:33 +00:00
} * /
m_world . RemoveViewerAgent ( this ) ;
2007-04-01 12:02:44 +00:00
//need to do other cleaning up here too
2007-04-10 10:45:46 +00:00
m_clientThreads . Remove ( this . CircuitCode ) ;
2007-04-01 12:02:44 +00:00
m_application . RemoveClientCircuit ( this . CircuitCode ) ;
this . ClientThread . Abort ( ) ;
return true ;
}
protected bool AgentTextureCached ( SimClient simclient , Packet packet )
{
2007-04-10 10:45:46 +00:00
// Console.WriteLine(packet.ToString());
2007-04-01 12:02:44 +00:00
AgentCachedTexturePacket chechedtex = ( AgentCachedTexturePacket ) packet ;
AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket ( ) ;
cachedresp . AgentData . AgentID = this . AgentID ;
cachedresp . AgentData . SessionID = this . SessionID ;
cachedresp . AgentData . SerialNum = this . cachedtextureserial ;
this . cachedtextureserial + + ;
cachedresp . WearableData = new AgentCachedTextureResponsePacket . WearableDataBlock [ chechedtex . WearableData . Length ] ;
for ( int i = 0 ; i < chechedtex . WearableData . Length ; i + + )
{
cachedresp . WearableData [ i ] = new AgentCachedTextureResponsePacket . WearableDataBlock ( ) ;
cachedresp . WearableData [ i ] . TextureIndex = chechedtex . WearableData [ i ] . TextureIndex ;
cachedresp . WearableData [ i ] . TextureID = LLUUID . Zero ;
cachedresp . WearableData [ i ] . HostName = new byte [ 0 ] ;
}
this . OutPacket ( cachedresp ) ;
return true ;
}
2007-04-01 15:30:27 +00:00
protected bool MultipleObjUpdate ( SimClient simClient , Packet packet )
{
MultipleObjectUpdatePacket multipleupdate = ( MultipleObjectUpdatePacket ) packet ;
for ( int i = 0 ; i < multipleupdate . ObjectData . Length ; i + + )
{
if ( multipleupdate . ObjectData [ i ] . Type = = 9 ) //change position
{
libsecondlife . LLVector3 pos = new LLVector3 ( multipleupdate . ObjectData [ i ] . Data , 0 ) ;
foreach ( Entity ent in m_world . Entities . Values )
{
if ( ent . localid = = multipleupdate . ObjectData [ i ] . ObjectLocalID )
{
( ( OpenSim . world . Primitive ) ent ) . UpdatePosition ( pos ) ;
}
}
//should update stored position of the prim
}
else if ( multipleupdate . ObjectData [ i ] . Type = = 10 ) //rotation
{
libsecondlife . LLQuaternion rot = new LLQuaternion ( multipleupdate . ObjectData [ i ] . Data , 0 , true ) ;
foreach ( Entity ent in m_world . Entities . Values )
{
if ( ent . localid = = multipleupdate . ObjectData [ i ] . ObjectLocalID )
{
ent . rotation = new Axiom . MathLib . Quaternion ( rot . W , rot . X , rot . Y , rot . Z ) ;
( ( OpenSim . world . Primitive ) ent ) . UpdateFlag = true ;
}
}
}
else if ( multipleupdate . ObjectData [ i ] . Type = = 13 ) //scale
{
libsecondlife . LLVector3 scale = new LLVector3 ( multipleupdate . ObjectData [ i ] . Data , 12 ) ;
foreach ( Entity ent in m_world . Entities . Values )
{
if ( ent . localid = = multipleupdate . ObjectData [ i ] . ObjectLocalID )
{
( ( OpenSim . world . Primitive ) ent ) . Scale = scale ;
}
}
}
}
return true ;
}
2007-04-01 12:02:44 +00:00
# endregion
2007-03-22 10:11:15 +00:00
2007-03-28 18:10:52 +00:00
private AgentInventory CreateInventory ( LLUUID baseFolder )
2007-03-22 10:11:15 +00:00
{
2007-03-28 18:10:52 +00:00
AgentInventory inventory = null ;
if ( this . m_userServer ! = null )
{
// a user server is set so request the inventory from it
2007-03-29 17:04:24 +00:00
Console . WriteLine ( "getting inventory from user server" ) ;
2007-03-28 18:10:52 +00:00
inventory = m_inventoryCache . FetchAgentsInventory ( this . AgentID , m_userServer ) ;
}
else
{
inventory = new AgentInventory ( ) ;
inventory . AgentID = this . AgentID ;
inventory . CreateRootFolder ( this . AgentID , false ) ;
m_inventoryCache . AddNewAgentsInventory ( inventory ) ;
m_inventoryCache . CreateNewInventoryFolder ( this , baseFolder ) ;
}
return inventory ;
2007-03-22 10:11:15 +00:00
}
2007-03-30 11:09:51 +00:00
private void CreateInventoryItem ( CreateInventoryItemPacket packet )
{
2007-05-11 21:03:11 +00:00
if ( ! ( packet . InventoryBlock . Type = = 3 | | packet . InventoryBlock . Type = = 7 ) )
{
System . Console . WriteLine ( "Attempted to create " + Util . FieldToString ( packet . InventoryBlock . Name ) + " in inventory. Unsupported type" ) ;
return ;
}
//lets try this out with creating a notecard
AssetBase asset = new AssetBase ( ) ;
asset . Name = Util . FieldToString ( packet . InventoryBlock . Name ) ;
asset . Description = Util . FieldToString ( packet . InventoryBlock . Description ) ;
asset . InvType = packet . InventoryBlock . InvType ;
asset . Type = packet . InventoryBlock . Type ;
asset . FullID = LLUUID . Random ( ) ;
switch ( packet . InventoryBlock . Type )
2007-03-30 11:09:51 +00:00
{
2007-05-11 21:03:11 +00:00
case 7 : // Notecard
asset . Data = new byte [ 0 ] ;
break ;
case 3 : // Landmark
String content ;
2007-05-13 12:25:08 +00:00
content = "Landmark version 2\n" ;
2007-05-11 21:03:11 +00:00
content + = "region_id " + m_regionData . SimUUID + "\n" ;
String strPos = String . Format ( "%.2f %.2f %.2f>" ,
this . ClientAvatar . Pos . X ,
this . ClientAvatar . Pos . Y ,
this . ClientAvatar . Pos . Z ) ;
content + = "local_pos " + strPos + "\n" ;
asset . Data = ( new System . Text . ASCIIEncoding ( ) ) . GetBytes ( content ) ;
break ;
default :
break ;
2007-03-30 11:09:51 +00:00
}
2007-05-11 21:03:11 +00:00
m_assetCache . AddAsset ( asset ) ;
m_inventoryCache . AddNewInventoryItem ( this , packet . InventoryBlock . FolderID , asset ) ;
2007-03-30 11:09:51 +00:00
}
2007-05-13 12:25:08 +00:00
public void RequestMapLayer ( ) //should be getting the map layer from the grid server
{
//send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area)
MapLayerReplyPacket mapReply = new MapLayerReplyPacket ( ) ;
mapReply . AgentData . AgentID = this . AgentID ;
mapReply . AgentData . Flags = 0 ;
mapReply . LayerData = new MapLayerReplyPacket . LayerDataBlock [ 1 ] ;
mapReply . LayerData [ 0 ] = new MapLayerReplyPacket . LayerDataBlock ( ) ;
mapReply . LayerData [ 0 ] . Bottom = 800 ;
mapReply . LayerData [ 0 ] . Left = 800 ;
mapReply . LayerData [ 0 ] . Top = 1200 ;
mapReply . LayerData [ 0 ] . Right = 1200 ;
2007-05-13 12:48:42 +00:00
mapReply . LayerData [ 0 ] . ImageID = new LLUUID ( "00000000-0000-0000-9999-000000000006" ) ;
2007-05-13 12:25:08 +00:00
this . OutPacket ( mapReply ) ;
}
public void RequestMapBlock ( int minX , int minY , int maxX , int maxY )
{
//check if our own map was requested
this . m_world . RequestMapBlock ( this , minX , minY , maxX , maxY ) ;
//now should get other regions maps from gridserver
}
2007-05-14 21:04:14 +00:00
public void EnableNeighbours ( )
{
if ( ( this . m_gridServer . GetName ( ) = = "Remote" ) & & ( ! this . m_child ) )
{
Hashtable SimParams ;
ArrayList SendParams ;
XmlRpcRequest GridReq ;
XmlRpcResponse GridResp ;
foreach ( Hashtable neighbour in ( ( RemoteGridBase ) this . m_gridServer ) . neighbours )
{
Console . WriteLine ( "http://" + neighbour [ "sim_ip" ] + ":" + neighbour [ "sim_port" ] ) ;
SimParams = new Hashtable ( ) ;
SimParams [ "session_id" ] = ( ( RemoteGridBase ) this . m_gridServer ) . agentcircuits [ CircuitCode ] . SessionID . ToString ( ) ;
SimParams [ "secure_session_id" ] = ( ( RemoteGridBase ) this . m_gridServer ) . agentcircuits [ CircuitCode ] . SecureSessionID . ToString ( ) ;
SimParams [ "firstname" ] = ( ( RemoteGridBase ) this . m_gridServer ) . agentcircuits [ CircuitCode ] . firstname ;
SimParams [ "lastname" ] = ( ( RemoteGridBase ) this . m_gridServer ) . agentcircuits [ CircuitCode ] . lastname ;
SimParams [ "agent_id" ] = ( ( RemoteGridBase ) this . m_gridServer ) . agentcircuits [ CircuitCode ] . AgentID . ToString ( ) ;
SimParams [ "circuit_code" ] = ( Int32 ) this . CircuitCode ;
SimParams [ "child_agent" ] = "1" ;
SendParams = new ArrayList ( ) ;
SendParams . Add ( SimParams ) ;
GridReq = new XmlRpcRequest ( "expect_user" , SendParams ) ;
GridResp = GridReq . Send ( "http://" + neighbour [ "sim_ip" ] + ":" + neighbour [ "sim_port" ] , 3000 ) ;
EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket ( ) ;
enablesimpacket . SimulatorInfo = new EnableSimulatorPacket . SimulatorInfoBlock ( ) ;
enablesimpacket . SimulatorInfo . Handle = Helpers . UIntsToLong ( ( uint ) ( Convert . ToInt32 ( neighbour [ "region_locx" ] ) * 256 ) , ( uint ) ( Convert . ToInt32 ( neighbour [ "region_locy" ] ) * 256 ) ) ;
System . Net . IPAddress neighbourIP = System . Net . IPAddress . Parse ( ( string ) neighbour [ "sim_ip" ] ) ;
byte [ ] byteIP = neighbourIP . GetAddressBytes ( ) ;
enablesimpacket . SimulatorInfo . IP = ( uint ) byteIP [ 3 ] < < 24 ;
enablesimpacket . SimulatorInfo . IP + = ( uint ) byteIP [ 2 ] < < 16 ;
enablesimpacket . SimulatorInfo . IP + = ( uint ) byteIP [ 1 ] < < 8 ;
enablesimpacket . SimulatorInfo . IP + = ( uint ) byteIP [ 0 ] ;
enablesimpacket . SimulatorInfo . Port = ( ushort ) Convert . ToInt32 ( neighbour [ "sim_port" ] ) ;
Thread . Sleep ( 3000 ) ;
this . OutPacket ( enablesimpacket ) ;
}
}
}
2007-03-22 10:11:15 +00:00
}
}