diff --git a/OpenSim/Framework/General/ClientManager.cs b/OpenSim/Framework/General/ClientManager.cs index 274a2d379d..b0328496f6 100644 --- a/OpenSim/Framework/General/ClientManager.cs +++ b/OpenSim/Framework/General/ClientManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using libsecondlife.Packets; using OpenSim.Framework.Interfaces; +using libsecondlife; namespace OpenSim.Framework { @@ -24,7 +25,7 @@ namespace OpenSim.Framework m_clients = new Dictionary(); } - public void Remove(uint id) + private void Remove(uint id) { m_clients.Remove(id); } @@ -44,19 +45,46 @@ namespace OpenSim.Framework } } - public void ConnectionClosed(uint circuitCode) + public void CloseAllAgents(uint circuitCode) { IClientAPI client; if (m_clients.TryGetValue(circuitCode, out client)) { - m_clients.Remove(circuitCode); - client.Close(); - - // TODO: Now remove all local childagents too + CloseAllCircuits(client.AgentId); } } + public void CloseAllCircuits( LLUUID agentId ) + { + uint[] circuits = GetAllCircuits(agentId); + foreach (uint circuit in circuits ) + { + IClientAPI client; + if (m_clients.TryGetValue(circuit, out client)) + { + Remove(circuit); + client.Close(); + } + } + } + + private uint[] GetAllCircuits(LLUUID agentId) + { + List circuits = new List(); + + foreach (KeyValuePair pair in m_clients) + { + if( pair.Value.AgentId == agentId ) + { + circuits.Add( pair.Key ); + } + } + + return circuits.ToArray(); + } + + public void ViewerEffectHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock) { ViewerEffectPacket packet = new ViewerEffectPacket(); diff --git a/OpenSim/Framework/General/Interfaces/IClientAPI.cs b/OpenSim/Framework/General/Interfaces/IClientAPI.cs index 9c0771fe7f..5fd5adf701 100644 --- a/OpenSim/Framework/General/Interfaces/IClientAPI.cs +++ b/OpenSim/Framework/General/Interfaces/IClientAPI.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ +using System; using System.Collections.Generic; using System.Net; using libsecondlife; @@ -192,6 +193,12 @@ namespace OpenSim.Framework.Interfaces get; } + uint CircuitCode + { + get; + set; + } + void OutPacket(Packet newPack); void SendWearables(AvatarWearable[] wearables); void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry); @@ -245,5 +252,7 @@ namespace OpenSim.Framework.Interfaces void InPacket(Packet NewPack); void Close(); event ViewerEffectEventHandler OnViewerEffect; + event Action OnLogout; + event Action OnConnectionClosed; } } diff --git a/OpenSim/Framework/General/NullClientAPI.cs b/OpenSim/Framework/General/NullClientAPI.cs deleted file mode 100644 index 2fe46d6e9f..0000000000 --- a/OpenSim/Framework/General/NullClientAPI.cs +++ /dev/null @@ -1,183 +0,0 @@ -using System.Collections.Generic; -using System.Net; -using OpenSim.Framework.Interfaces; -using OpenSim.Framework.Types; -using OpenSim.Framework.Data; -using libsecondlife; -using libsecondlife.Packets; - - -namespace OpenSim.Framework -{ - public class NullClientAPI : IClientAPI - { -#pragma warning disable 67 - public event ImprovedInstantMessage OnInstantMessage; - public event ChatFromViewer OnChatFromViewer; - public event RezObject OnRezObject; - public event ModifyTerrain OnModifyTerrain; - public event SetAppearance OnSetAppearance; - public event StartAnim OnStartAnim; - public event LinkObjects OnLinkObjects; - public event RequestMapBlocks OnRequestMapBlocks; - public event TeleportLocationRequest OnTeleportLocationRequest; - public event DisconnectUser OnDisconnectUser; - public event RequestAvatarProperties OnRequestAvatarProperties; - - public event GenericCall4 OnDeRezObject; - public event GenericCall OnRegionHandShakeReply; - public event GenericCall OnRequestWearables; - public event GenericCall2 OnCompleteMovementToRegion; - public event UpdateAgent OnAgentUpdate; - public event GenericCall OnRequestAvatarsData; - public event AddNewPrim OnAddPrim; - public event ObjectDuplicate OnObjectDuplicate; - public event UpdateVector OnGrabObject; - public event ObjectSelect OnDeGrabObject; - public event MoveObject OnGrabUpdate; - - public event UpdateShape OnUpdatePrimShape; - public event ObjectExtraParams OnUpdateExtraParams; - public event ObjectSelect OnObjectSelect; - public event GenericCall7 OnObjectDescription; - public event GenericCall7 OnObjectName; - public event UpdatePrimFlags OnUpdatePrimFlags; - public event UpdatePrimTexture OnUpdatePrimTexture; - public event UpdateVector OnUpdatePrimGroupPosition; - public event UpdateVector OnUpdatePrimSinglePosition; - public event UpdatePrimRotation OnUpdatePrimGroupRotation; - public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; - public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; - public event UpdateVector OnUpdatePrimScale; - public event StatusChange OnChildAgentStatus; - public event GenericCall2 OnStopMovement; - public event GenericCall6 OnRemoveAvatar; - public event ViewerEffectEventHandler OnViewerEffect; - - public event CreateNewInventoryItem OnCreateNewInventoryItem; - public event CreateInventoryFolder OnCreateNewInventoryFolder; - public event FetchInventoryDescendents OnFetchInventoryDescendents; - public event FetchInventory OnFetchInventory; - public event RequestTaskInventory OnRequestTaskInventory; - public event UpdateInventoryItemTransaction OnUpdateInventoryItem; - public event UDPAssetUploadRequest OnAssetUploadRequest; - public event XferReceive OnXferReceive; - public event RequestXfer OnRequestXfer; - public event ConfirmXfer OnConfirmXfer; - public event RezScript OnRezScript; - public event UpdateTaskInventory OnUpdateTaskInventory; - public event RemoveTaskInventory OnRemoveTaskItem; - - public event UUIDNameRequest OnNameFromUUIDRequest; - - public event ParcelPropertiesRequest OnParcelPropertiesRequest; - public event ParcelDivideRequest OnParcelDivideRequest; - public event ParcelJoinRequest OnParcelJoinRequest; - public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; - public event ParcelSelectObjects OnParcelSelectObjects; - public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest; - public event ObjectDeselect OnObjectDeselect; - - - public event EstateOwnerMessageRequest OnEstateOwnerMessage; -#pragma warning restore 67 - - private LLUUID m_uuid = LLUUID.Random(); - public virtual LLVector3 StartPos - { - get { return new LLVector3(); } - set { } - } - - public virtual LLUUID AgentId - { - get { return m_uuid; } - } - - public LLUUID SessionId - { - get { return LLUUID.Zero; } - } - - public virtual string FirstName - { - get { return ""; } - } - - public virtual string LastName - { - get { return ""; } - } - - public NullClientAPI() - { - } - - public virtual void OutPacket(Packet newPack){} - public virtual void SendWearables(AvatarWearable[] wearables){} - public virtual void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry) { } - public virtual void SendStartPingCheck(byte seq){} - public virtual void SendKillObject(ulong regionHandle, uint localID){} - public virtual void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId){} - public virtual void SendRegionHandshake(RegionInfo regionInfo){} - public virtual void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) { } - public virtual void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID){} - public virtual void SendInstantMessage(LLUUID fromAgent, LLUUID fromAgentSession, string message, LLUUID toAgent, LLUUID imSessionID, string fromName, byte dialog, uint timeStamp){} - public virtual void SendLayerData(float[] map){} - public virtual void SendLayerData(int px, int py, float[] map){} - public virtual void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look){} - public virtual void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint){} - public virtual AgentCircuitData RequestClientInfo() { return new AgentCircuitData(); } - public virtual void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint newRegionExternalEndPoint, string capsURL){} - public virtual void SendMapBlock(List mapBlocks){} - public virtual void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags){} - public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, uint flags, string capsURL){} - public virtual void SendTeleportCancel(){} - public virtual void SendTeleportLocationStart(){} - public virtual void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance){} - - public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos, byte[] textureEntry){} - public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity, LLQuaternion rotation){} - public virtual void SendCoarseLocationUpdate(List CoarseLocations) { } - - public virtual void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint){} - public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation){} - public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation){} - - public virtual void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List items){} - public virtual void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item){} - public virtual void SendInventoryItemUpdate(InventoryItemBase Item) { } - public virtual void SendRemoveInventoryItem(LLUUID itemID) { } - public virtual void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName) { } - public virtual void SendXferPacket(ulong xferID, uint packet, byte[] data) { } - - public virtual void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID) { } - public virtual void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags) { } - - public virtual void SendNameReply(LLUUID profileId, string firstname, string lastname){} - public void SendAlertMessage(string message) { } - public void SendAgentAlertMessage(string message, bool modal) { } - public void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message, string url) { } - - - public bool AddMoney(int debit) - { - return false; - } - - public void SendViewerTime(int phase) { } - public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, uint flags, LLUUID flImageID, LLUUID imageID, string profileURL, LLUUID partnerID) { } - public void SetDebug(int newDebug) { } - - public void InPacket(Packet NewPack) - { - } - - public void Close() - { - } - - - } -} - diff --git a/OpenSim/Region/ClientStack/ClientView.API.cs b/OpenSim/Region/ClientStack/ClientView.API.cs index a15a964268..253807c2f5 100644 --- a/OpenSim/Region/ClientStack/ClientView.API.cs +++ b/OpenSim/Region/ClientStack/ClientView.API.cs @@ -42,6 +42,8 @@ namespace OpenSim.Region.ClientStack { partial class ClientView { + public event Action OnLogout; + public event Action OnConnectionClosed; public event ViewerEffectEventHandler OnViewerEffect; public event ImprovedInstantMessage OnInstantMessage; public event ChatFromViewer OnChatFromViewer; @@ -373,7 +375,7 @@ namespace OpenSim.Region.ClientStack agentData.AgentID = this.AgentId; agentData.SessionID = this.m_sessionId; agentData.SecureSessionID = this.SecureSessionID; - agentData.circuitcode = this.CircuitCode; + agentData.circuitcode = this.m_circuitCode; agentData.child = false; agentData.firstname = this.firstName; agentData.lastname = this.lastName; diff --git a/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs index 65ad431d23..643b158df1 100644 --- a/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs +++ b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs @@ -56,19 +56,12 @@ namespace OpenSim.Region.ClientStack protected virtual bool Logout(IClientAPI client, Packet packet) { - // TODO: Refactor out this into an OnLogout so the ClientManager can close all clients. - MainLog.Instance.Verbose("OpenSimClient.cs:ProcessInPacket() - Got a logout request"); - //send reply to let the client logout - LogoutReplyPacket logReply = new LogoutReplyPacket(); - logReply.AgentData.AgentID = this.AgentId; - logReply.AgentData.SessionID = this.m_sessionId; - logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; - logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); - logReply.InventoryData[0].ItemID = LLUUID.Zero; - OutPacket(logReply); - // - this.Close(); + + if( OnLogout != null ) + { + OnLogout(client); + } return true; } diff --git a/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs b/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs index 05c2869f3a..bfcb19f26f 100644 --- a/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs +++ b/OpenSim/Region/ClientStack/ClientView.PacketQueue.cs @@ -51,11 +51,17 @@ namespace OpenSim.Region.ClientStack protected const int RESEND_TIMEOUT = 4000; protected const int MAX_SEQUENCE = 0xFFFFFF; - public uint CircuitCode; + private uint m_circuitCode; public EndPoint userEP; protected PacketServer m_networkServer; + public uint CircuitCode + { + get { return m_circuitCode; } + set { m_circuitCode = value; } + } + protected virtual void ProcessOutPacket(Packet Pack) { // Keep track of when this packet was sent out @@ -142,11 +148,11 @@ namespace OpenSim.Region.ClientStack if (Pack.Header.Zerocoded) { int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); - m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP); + m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode);//userEP); } else { - m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP); + m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode); //userEP); } } catch (Exception) diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index f8ac1d8ea8..2341b7b48e 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -133,8 +133,6 @@ namespace OpenSim.Region.ClientStack m_scene.RemoveClient(this.AgentId); - m_clientManager.Remove(this.CircuitCode); // TODO: Move out and delete ref to clientmanager. - m_networkServer.RemoveClientCircuit(this.CircuitCode); this.ClientThread.Abort(); } @@ -215,7 +213,7 @@ namespace OpenSim.Region.ClientStack } else { info = packet.Type.ToString(); } - Console.WriteLine(CircuitCode + ":" + direction + ": " + info); + Console.WriteLine(m_circuitCode + ":" + direction + ": " + info); } } @@ -252,8 +250,10 @@ namespace OpenSim.Region.ClientStack probesWithNoIngressPackets++; if (probesWithNoIngressPackets > 30) { - // Refactor out this into an OnConnectionClosed so the ClientManager can clean up - this.Close(); + if( OnConnectionClosed != null ) + { + OnConnectionClosed(this); + } } else { @@ -283,7 +283,7 @@ namespace OpenSim.Region.ClientStack protected virtual void AuthUser() { - // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.m_sessionId, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); + // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.m_circuitCode.m_sessionId, cirpack.m_circuitCode.ID, cirpack.m_circuitCode.Code); AuthenticateResponse sessionInfo = this.m_authenticateSessionsHandler.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); if (!sessionInfo.Authorised) { @@ -297,7 +297,7 @@ namespace OpenSim.Region.ClientStack //session is authorised m_agentId = cirpack.CircuitCode.ID; this.m_sessionId = cirpack.CircuitCode.SessionID; - this.CircuitCode = cirpack.CircuitCode.Code; + this.m_circuitCode = cirpack.CircuitCode.Code; this.firstName = sessionInfo.LoginInfo.First; this.lastName = sessionInfo.LoginInfo.Last; diff --git a/OpenSim/Region/ClientStack/PacketServer.cs b/OpenSim/Region/ClientStack/PacketServer.cs index bceeeb3869..28f25bde8d 100644 --- a/OpenSim/Region/ClientStack/PacketServer.cs +++ b/OpenSim/Region/ClientStack/PacketServer.cs @@ -33,14 +33,15 @@ using OpenSim.Framework; using OpenSim.Framework.Types; using OpenSim.Framework.Interfaces; using OpenSim.Framework.Communications.Caches; +using libsecondlife; namespace OpenSim.Region.ClientStack { public class PacketServer { - private ClientStackNetworkHandler _networkHandler; + private ClientStackNetworkHandler m_networkHandler; private IScene _localScene; - private ClientManager m_clientManager = new ClientManager(); + private readonly ClientManager m_clientManager = new ClientManager(); public ClientManager ClientManager { get { return m_clientManager; } @@ -48,8 +49,8 @@ namespace OpenSim.Region.ClientStack public PacketServer(ClientStackNetworkHandler networkHandler) { - _networkHandler = networkHandler; - _networkHandler.RegisterPacketServer(this); + m_networkHandler = networkHandler; + m_networkHandler.RegisterPacketServer(this); } public IScene LocalScene @@ -70,11 +71,6 @@ namespace OpenSim.Region.ClientStack m_clientManager.InPacket(circuitCode, packet); } - public virtual void ConnectionClosed(uint circuitCode) - { - m_clientManager.ConnectionClosed(circuitCode); - } - /// /// /// @@ -145,10 +141,24 @@ namespace OpenSim.Region.ClientStack this.m_clientManager.Add(useCircuit.CircuitCode.Code, newuser); newuser.OnViewerEffect += m_clientManager.ViewerEffectHandler; + newuser.OnLogout += LogoutHandler; + newuser.OnConnectionClosed += CloseClient; return true; } + public void LogoutHandler(IClientAPI client) + { + LogoutReplyPacket logReply = new LogoutReplyPacket(); + logReply.AgentData.AgentID = client.AgentId; + logReply.AgentData.SessionID = client.SessionId; + logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; + logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); + logReply.InventoryData[0].ItemID = LLUUID.Zero; + client.OutPacket(logReply); + + CloseClient( client ); + } /// @@ -160,17 +170,22 @@ namespace OpenSim.Region.ClientStack /// public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode) { - this._networkHandler.SendPacketTo(buffer, size, flags, circuitcode); + this.m_networkHandler.SendPacketTo(buffer, size, flags, circuitcode); } /// /// /// /// - public virtual void RemoveClientCircuit(uint circuitcode) + public virtual void CloseCircuit(uint circuitcode) { - this._networkHandler.RemoveClientCircuit(circuitcode); - this.m_clientManager.Remove(circuitcode); + m_networkHandler.RemoveClientCircuit( circuitcode ); + m_clientManager.CloseAllAgents( circuitcode ); + } + + public virtual void CloseClient( IClientAPI client ) + { + CloseCircuit( client.CircuitCode ); } } } diff --git a/OpenSim/Region/ClientStack/UDPServer.cs b/OpenSim/Region/ClientStack/UDPServer.cs index efc9c87ade..b0b529c13c 100644 --- a/OpenSim/Region/ClientStack/UDPServer.cs +++ b/OpenSim/Region/ClientStack/UDPServer.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.ClientStack protected IPEndPoint ipeSender; protected EndPoint epSender; protected AsyncCallback ReceivedData; - protected PacketServer _packetServer; + protected PacketServer m_packetServer; protected int listenPort; protected IScene m_localScene; @@ -61,11 +61,11 @@ namespace OpenSim.Region.ClientStack { get { - return _packetServer; + return m_packetServer; } set { - _packetServer = value; + m_packetServer = value; } } @@ -74,7 +74,7 @@ namespace OpenSim.Region.ClientStack set { this.m_localScene = value; - this._packetServer.LocalScene = this.m_localScene; + this.m_packetServer.LocalScene = this.m_localScene; } } @@ -111,7 +111,9 @@ namespace OpenSim.Region.ClientStack catch (System.Net.Sockets.SocketException) { Console.WriteLine("Remote host Closed connection"); - this._packetServer.ConnectionClosed(this.clientCircuits[epSender]); + + this.m_packetServer.CloseCircuit(this.clientCircuits[epSender]); + ipeSender = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); epSender = (EndPoint)ipeSender; Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); @@ -126,7 +128,7 @@ namespace OpenSim.Region.ClientStack if (this.clientCircuits.ContainsKey(epSender)) { //if so then send packet to the packetserver - this._packetServer.InPacket(this.clientCircuits[epSender], packet); + this.m_packetServer.InPacket(this.clientCircuits[epSender], packet); } else if (packet.Type == PacketType.UseCircuitCode) { @@ -170,7 +172,7 @@ namespace OpenSim.Region.ClientStack public virtual void RegisterPacketServer(PacketServer server) { - this._packetServer = server; + this.m_packetServer = server; } public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)//EndPoint packetSender) diff --git a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs index a0553398f7..9839b0ce0e 100644 --- a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs @@ -232,5 +232,22 @@ namespace SimpleApp public void Close() { } + + private uint m_circuitCode; + public uint CircuitCode + { + get + { + return m_circuitCode; + } + set + { + m_circuitCode = value; + } + } + + public event System.Action OnLogout; + + public event System.Action OnConnectionClosed; } }