From 429a84f390212d0f414a08420707fc90aca2a331 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Mon, 5 Oct 2009 17:38:14 -0700 Subject: [PATCH 01/36] Beginning work on the new LLUDP implementation --- OpenSim/Framework/ThrottleOutPacketType.cs | 8 +- OpenSim/Region/Application/OpenSimBase.cs | 2 +- .../ClientStack/IClientNetworkServer.cs | 2 +- .../LindenUDP/ILLClientStackNetworkHandler.cs | 38 - .../ClientStack/LindenUDP/ILLPacketHandler.cs | 83 - .../Region/ClientStack/LindenUDP/J2KImage.cs | 6 +- .../ClientStack/LindenUDP/LLClientView.cs | 2993 +++++++---------- .../ClientStack/LindenUDP/LLImageManager.cs | 2 +- .../ClientStack/LindenUDP/LLPacketHandler.cs | 7 +- .../ClientStack/LindenUDP/LLPacketServer.cs | 4 +- .../ClientStack/LindenUDP/LLUDPServer.cs | 1143 ++++--- .../Region/ClientStack/LindenUDP/LLUtil.cs | 5 + .../LindenUDP/Tests/PacketHandlerTests.cs | 2 +- .../LindenUDP/Tests/TestLLPacketServer.cs | 2 +- 14 files changed, 1889 insertions(+), 2408 deletions(-) delete mode 100644 OpenSim/Region/ClientStack/LindenUDP/ILLClientStackNetworkHandler.cs delete mode 100644 OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs diff --git a/OpenSim/Framework/ThrottleOutPacketType.cs b/OpenSim/Framework/ThrottleOutPacketType.cs index 08437577a8..fd490a5c6a 100644 --- a/OpenSim/Framework/ThrottleOutPacketType.cs +++ b/OpenSim/Framework/ThrottleOutPacketType.cs @@ -29,9 +29,9 @@ using System; namespace OpenSim.Framework { - [Flags] public enum ThrottleOutPacketType : int { + Unknown = -1, // Also doubles as 'do not throttle' Resend = 0, Land = 1, Wind = 2, @@ -39,11 +39,5 @@ namespace OpenSim.Framework Task = 4, Texture = 5, Asset = 6, - Unknown = 7, // Also doubles as 'do not throttle' - Back = 8, - - TypeMask = 15, // The mask to mask off the flags - - LowPriority = 128 // Additional flags } } diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 6e7a2a0a5e..4592c318b5 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -675,7 +675,7 @@ namespace OpenSim if (foundClientServer) { - m_clientServers[clientServerElement].Server.Close(); + m_clientServers[clientServerElement].NetworkStop(); m_clientServers.RemoveAt(clientServerElement); } IScene scene; diff --git a/OpenSim/Region/ClientStack/IClientNetworkServer.cs b/OpenSim/Region/ClientStack/IClientNetworkServer.cs index a71ad4d46e..54a441bbe6 100644 --- a/OpenSim/Region/ClientStack/IClientNetworkServer.cs +++ b/OpenSim/Region/ClientStack/IClientNetworkServer.cs @@ -38,7 +38,7 @@ namespace OpenSim.Region.ClientStack IPAddress _listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager authenticateClass); - Socket Server { get; } + void NetworkStop(); bool HandlesRegion(Location x); void AddScene(IScene x); diff --git a/OpenSim/Region/ClientStack/LindenUDP/ILLClientStackNetworkHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/ILLClientStackNetworkHandler.cs deleted file mode 100644 index ee151718ba..0000000000 --- a/OpenSim/Region/ClientStack/LindenUDP/ILLClientStackNetworkHandler.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.Net.Sockets; - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - public interface ILLClientStackNetworkHandler - { - void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode); // EndPoint packetSender); - void RemoveClientCircuit(uint circuitcode); - void RegisterPacketServer(LLPacketServer server); - } -} diff --git a/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs deleted file mode 100644 index 31f9580a88..0000000000 --- a/OpenSim/Region/ClientStack/LindenUDP/ILLPacketHandler.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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; -using OpenMetaverse; -using OpenMetaverse.Packets; -using OpenSim.Framework; - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); - public delegate void PacketDrop(Packet pack, Object id); - public delegate void QueueEmpty(ThrottleOutPacketType queue); - public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, UUID agentID, ThrottleOutPacketType throttlePacketType); - - /// - /// Interface to a class that handles all the activity involved with maintaining the client circuit (handling acks, - /// resends, pings, etc.) - /// - public interface ILLPacketHandler : IDisposable - { - event PacketStats OnPacketStats; - event PacketDrop OnPacketDrop; - event QueueEmpty OnQueueEmpty; - SynchronizeClientHandler SynchronizeClient { set; } - - int PacketsReceived { get; } - int PacketsReceivedReported { get; } - uint ResendTimeout { get; set; } - bool ReliableIsImportant { get; set; } - int MaxReliableResends { get; set; } - - /// - /// Initial handling of a received packet. It will be processed later in ProcessInPacket() - /// - /// - void InPacket(Packet packet); - - /// - /// Take action depending on the type and contents of an received packet. - /// - /// - void ProcessInPacket(LLQueItem item); - - void ProcessOutPacket(LLQueItem item); - void OutPacket(Packet NewPack, - ThrottleOutPacketType throttlePacketType); - void OutPacket(Packet NewPack, - ThrottleOutPacketType throttlePacketType, Object id); - LLPacketQueue PacketQueue { get; } - void Flush(); - void Clear(); - ClientInfo GetClientInfo(); - void SetClientInfo(ClientInfo info); - void AddImportantPacket(PacketType type); - void RemoveImportantPacket(PacketType type); - int GetQueueCount(ThrottleOutPacketType queue); - } -} diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 19ad0b497f..000f455c3f 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs @@ -197,12 +197,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_currentPacket = StartPacket; } - if ((m_imageManager != null) && (m_imageManager.Client != null) && (m_imageManager.Client.PacketHandler != null)) - if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) + if (m_imageManager != null && m_imageManager.Client != null) + { + if (m_imageManager.Client.IsThrottleEmpty(ThrottleOutPacketType.Texture)) { //m_log.Debug("No textures queued, sending one packet to kickstart it"); SendPacket(m_imageManager.Client); } + } } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 00527290ad..31cd53ff06 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -58,442 +58,120 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + // LLClientView Only + public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args); - /* static variables */ - public static SynchronizeClientHandler SynchronizeClient; - /* private variables */ + /// Used to adjust Sun Orbit values so Linden based viewers properly position sun + private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + protected static Dictionary PacketHandlers = new Dictionary(); //Global/static handlers for all clients + + private readonly LLUDPServer m_udpServer; + private readonly LLUDPClient m_udpClient; private readonly UUID m_sessionId; private readonly UUID m_secureSessionId = UUID.Zero; + private readonly UUID m_agentId; + private readonly uint m_circuitCode; + private readonly byte[] m_channelVersion = Utils.StringToBytes("OpenSimulator Server"); // Dummy value needed by libSL + private readonly Dictionary m_defaultAnimations = new Dictionary(); + private readonly IGroupsModule m_GroupsModule; private int m_debugPacketLevel; - - //private readonly IAssetCache m_assetCache; private int m_cachedTextureSerial; private Timer m_clientPingTimer; - private Timer m_avatarTerseUpdateTimer; private List m_avatarTerseUpdates = new List(); - private Timer m_primTerseUpdateTimer; private List m_primTerseUpdates = new List(); private Timer m_primFullUpdateTimer; - private List m_primFullUpdates = - new List(); - + private List m_primFullUpdates = new List(); private bool m_clientBlocked; - private int m_probesWithNoIngressPackets; - - private readonly UUID m_agentId; - private readonly uint m_circuitCode; private int m_moneyBalance; - private readonly ILLPacketHandler m_PacketHandler; - private int m_animationSequenceNumber = 1; - - private readonly byte[] m_channelVersion = Utils.StringToBytes("OpenSimulator Server"); // Dummy value needed by libSL - - private readonly Dictionary m_defaultAnimations = new Dictionary(); - private bool m_SendLogoutPacketWhenClosing = true; - private int m_inPacketsChecked; - - // Used to adjust Sun Orbit values so Linden based viewers properly position sun - private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; - - - /* protected variables */ - - protected static Dictionary PacketHandlers = - new Dictionary(); //Global/static handlers for all clients + private AgentUpdateArgs lastarg; + private bool m_IsActive = true; protected Dictionary m_packetHandlers = new Dictionary(); protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers - protected IScene m_scene; - - protected LLPacketServer m_networkServer; - protected LLImageManager m_imageManager; - - /* public variables */ protected string m_firstName; protected string m_lastName; protected Thread m_clientThread; protected Vector3 m_startpos; protected EndPoint m_userEndPoint; - protected EndPoint m_proxyEndPoint; protected UUID m_activeGroupID = UUID.Zero; protected string m_activeGroupName = String.Empty; protected ulong m_activeGroupPowers; protected Dictionary m_groupPowers = new Dictionary(); - protected int m_avatarTerseUpdateRate = 50; - protected int m_avatarTerseUpdatesPerPacket = 5; + protected int m_terrainCheckerCount; - // LL uses these limits, apparently. Compressed terse would be - // 23, but we don't have that yet - // + // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet protected int m_primTerseUpdatesPerPacket = 10; protected int m_primFullUpdatesPerPacket = 14; - protected int m_primTerseUpdateRate = 10; protected int m_primFullUpdateRate = 14; - protected int m_textureSendLimit = 20; protected int m_textureDataLimit = 10; - + protected int m_avatarTerseUpdateRate = 50; + protected int m_avatarTerseUpdatesPerPacket = 5; protected int m_packetMTU = 1400; - protected IAssetService m_assetService; - // LLClientView Only - public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args); - - /* Instantiated Designated Event Delegates */ - //- used so we don't create new objects for each incoming packet and then toss it out later */ - - private GenericMessage handlerGenericMessage; - private RequestAvatarProperties handlerRequestAvatarProperties; //OnRequestAvatarProperties; - private UpdateAvatarProperties handlerUpdateAvatarProperties; // OnUpdateAvatarProperties; - private ChatMessage handlerChatFromClient; //OnChatFromClient; - private ChatMessage handlerChatFromClient2; //OnChatFromClient; - private ImprovedInstantMessage handlerInstantMessage; //OnInstantMessage; - private FriendActionDelegate handlerApproveFriendRequest; //OnApproveFriendRequest; - private FriendshipTermination handlerTerminateFriendship; //OnTerminateFriendship; - private RezObject handlerRezObject; //OnRezObject; - private DeRezObject handlerDeRezObject; //OnDeRezObject; - private ModifyTerrain handlerModifyTerrain; - private BakeTerrain handlerBakeTerrain; - private EstateChangeInfo handlerEstateChangeInfo; - private Action handlerRegionHandShakeReply; //OnRegionHandShakeReply; - private GenericCall2 handlerRequestWearables; //OnRequestWearables; - private Action handlerRequestAvatarsData; //OnRequestAvatarsData; - private SetAppearance handlerSetAppearance; //OnSetAppearance; - private AvatarNowWearing handlerAvatarNowWearing; //OnAvatarNowWearing; - private RezSingleAttachmentFromInv handlerRezSingleAttachment; //OnRezSingleAttachmentFromInv; - private RezMultipleAttachmentsFromInv handlerRezMultipleAttachments; //OnRezMultipleAttachmentsFromInv; - private UUIDNameRequest handlerDetachAttachmentIntoInv; // Detach attachment! - private ObjectAttach handlerObjectAttach; //OnObjectAttach; - private SetAlwaysRun handlerSetAlwaysRun; //OnSetAlwaysRun; - private GenericCall2 handlerCompleteMovementToRegion; //OnCompleteMovementToRegion; - private UpdateAgent handlerAgentUpdate; //OnAgentUpdate; - private StartAnim handlerStartAnim; - private StopAnim handlerStopAnim; - private AgentRequestSit handlerAgentRequestSit; //OnAgentRequestSit; - private AgentSit handlerAgentSit; //OnAgentSit; - private AvatarPickerRequest handlerAvatarPickerRequest; //OnAvatarPickerRequest; - private FetchInventory handlerAgentDataUpdateRequest; //OnAgentDataUpdateRequest; - private TeleportLocationRequest handlerSetStartLocationRequest; //OnSetStartLocationRequest; - private TeleportLandmarkRequest handlerTeleportLandmarkRequest; //OnTeleportLandmarkRequest; - private LinkObjects handlerLinkObjects; //OnLinkObjects; - private DelinkObjects handlerDelinkObjects; //OnDelinkObjects; - private AddNewPrim handlerAddPrim; //OnAddPrim; - private UpdateShape handlerUpdatePrimShape; //null; - private ObjectExtraParams handlerUpdateExtraParams; //OnUpdateExtraParams; - private ObjectDuplicate handlerObjectDuplicate; - private ObjectDuplicateOnRay handlerObjectDuplicateOnRay; - private ObjectRequest handlerObjectRequest; - private ObjectSelect handlerObjectSelect; - private ObjectDeselect handlerObjectDeselect; - private ObjectIncludeInSearch handlerObjectIncludeInSearch; - private UpdatePrimFlags handlerUpdatePrimFlags; //OnUpdatePrimFlags; - private UpdatePrimTexture handlerUpdatePrimTexture; - private GrabObject handlerGrabObject; //OnGrabObject; - private MoveObject handlerGrabUpdate; //OnGrabUpdate; - private DeGrabObject handlerDeGrabObject; //OnDeGrabObject; - private SpinStart handlerSpinStart; //OnSpinStart; - private SpinObject handlerSpinUpdate; //OnSpinUpdate; - private SpinStop handlerSpinStop; //OnSpinStop; - private GenericCall7 handlerObjectDescription; - private GenericCall7 handlerObjectName; - private GenericCall7 handlerObjectClickAction; - private GenericCall7 handlerObjectMaterial; - private ObjectPermissions handlerObjectPermissions; - private RequestObjectPropertiesFamily handlerRequestObjectPropertiesFamily; //OnRequestObjectPropertiesFamily; - //private TextureRequest handlerTextureRequest; - private UDPAssetUploadRequest handlerAssetUploadRequest; //OnAssetUploadRequest; - private RequestXfer handlerRequestXfer; //OnRequestXfer; - private XferReceive handlerXferReceive; //OnXferReceive; - private ConfirmXfer handlerConfirmXfer; //OnConfirmXfer; - private AbortXfer handlerAbortXfer; - private CreateInventoryFolder handlerCreateInventoryFolder; //OnCreateNewInventoryFolder; - private UpdateInventoryFolder handlerUpdateInventoryFolder; - private MoveInventoryFolder handlerMoveInventoryFolder; - private CreateNewInventoryItem handlerCreateNewInventoryItem; //OnCreateNewInventoryItem; - private FetchInventory handlerFetchInventory; - private FetchInventoryDescendents handlerFetchInventoryDescendents; //OnFetchInventoryDescendents; - private PurgeInventoryDescendents handlerPurgeInventoryDescendents; //OnPurgeInventoryDescendents; - private UpdateInventoryItem handlerUpdateInventoryItem; - private CopyInventoryItem handlerCopyInventoryItem; - private MoveInventoryItem handlerMoveInventoryItem; - private RemoveInventoryItem handlerRemoveInventoryItem; - private RemoveInventoryFolder handlerRemoveInventoryFolder; - private RequestTaskInventory handlerRequestTaskInventory; //OnRequestTaskInventory; - private UpdateTaskInventory handlerUpdateTaskInventory; //OnUpdateTaskInventory; - private MoveTaskInventory handlerMoveTaskItem; - private RemoveTaskInventory handlerRemoveTaskItem; //OnRemoveTaskItem; - private RezScript handlerRezScript; //OnRezScript; - private RequestMapBlocks handlerRequestMapBlocks; //OnRequestMapBlocks; - private RequestMapName handlerMapNameRequest; //OnMapNameRequest; - private TeleportLocationRequest handlerTeleportLocationRequest; //OnTeleportLocationRequest; - private MoneyBalanceRequest handlerMoneyBalanceRequest; //OnMoneyBalanceRequest; - private UUIDNameRequest handlerNameRequest; - private ParcelAccessListRequest handlerParcelAccessListRequest; //OnParcelAccessListRequest; - private ParcelAccessListUpdateRequest handlerParcelAccessListUpdateRequest; //OnParcelAccessListUpdateRequest; - private ParcelPropertiesRequest handlerParcelPropertiesRequest; //OnParcelPropertiesRequest; - private ParcelDivideRequest handlerParcelDivideRequest; //OnParcelDivideRequest; - private ParcelJoinRequest handlerParcelJoinRequest; //OnParcelJoinRequest; - private ParcelPropertiesUpdateRequest handlerParcelPropertiesUpdateRequest; //OnParcelPropertiesUpdateRequest; - private ParcelSelectObjects handlerParcelSelectObjects; //OnParcelSelectObjects; - private ParcelObjectOwnerRequest handlerParcelObjectOwnerRequest; //OnParcelObjectOwnerRequest; - private ParcelAbandonRequest handlerParcelAbandonRequest; - private ParcelGodForceOwner handlerParcelGodForceOwner; - private ParcelReclaim handlerParcelReclaim; - private RequestTerrain handlerRequestTerrain; - private RequestTerrain handlerUploadTerrain; - private ParcelReturnObjectsRequest handlerParcelReturnObjectsRequest; - private RegionInfoRequest handlerRegionInfoRequest; //OnRegionInfoRequest; - private EstateCovenantRequest handlerEstateCovenantRequest; //OnEstateCovenantRequest; - private RequestGodlikePowers handlerReqGodlikePowers; //OnRequestGodlikePowers; - private GodKickUser handlerGodKickUser; //OnGodKickUser; - private ViewerEffectEventHandler handlerViewerEffect; //OnViewerEffect; - private Action handlerLogout; //OnLogout; - private MoneyTransferRequest handlerMoneyTransferRequest; //OnMoneyTransferRequest; - private ParcelBuy handlerParcelBuy; - private EconomyDataRequest handlerEconomoyDataRequest; - - private UpdateVector handlerUpdatePrimSinglePosition; //OnUpdatePrimSinglePosition; - private UpdatePrimSingleRotation handlerUpdatePrimSingleRotation; //OnUpdatePrimSingleRotation; - private UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition; //OnUpdatePrimSingleRotation; - private UpdateVector handlerUpdatePrimScale; //OnUpdatePrimScale; - private UpdateVector handlerUpdatePrimGroupScale; //OnUpdateGroupScale; - private UpdateVector handlerUpdateVector; //OnUpdatePrimGroupPosition; - private UpdatePrimRotation handlerUpdatePrimRotation; //OnUpdatePrimGroupRotation; - // private UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; //OnUpdatePrimGroupMouseRotation; - // private RequestAsset handlerRequestAsset; // OnRequestAsset; - private UUIDNameRequest handlerTeleportHomeRequest; - - private RegionHandleRequest handlerRegionHandleRequest; // OnRegionHandleRequest - private ParcelInfoRequest handlerParcelInfoRequest; // OnParcelInfoRequest - - private ScriptAnswer handlerScriptAnswer; - private RequestPayPrice handlerRequestPayPrice; - private ObjectSaleInfo handlerObjectSaleInfo; - private ObjectBuy handlerObjectBuy; - //private BuyObjectInventory handlerBuyObjectInventory; - private ObjectDeselect handlerObjectDetach; - private ObjectDrop handlerObjectDrop; - private AgentSit handlerOnUndo; - - private ForceReleaseControls handlerForceReleaseControls; - - private GodLandStatRequest handlerLandStatRequest; - - private UUIDNameRequest handlerUUIDGroupNameRequest; - - private ParcelDeedToGroup handlerParcelDeedToGroup; - - private RequestObjectPropertiesFamily handlerObjectGroupRequest; - private ScriptReset handlerScriptReset; - private GetScriptRunning handlerGetScriptRunning; - private SetScriptRunning handlerSetScriptRunning; - private UpdateVector handlerAutoPilotGo; - //Gesture - private ActivateGesture handlerActivateGesture; - private DeactivateGesture handlerDeactivateGesture; - //Sound - private SoundTrigger handlerSoundTrigger; - private ObjectOwner handlerObjectOwner; - - private DirPlacesQuery handlerDirPlacesQuery; - private DirFindQuery handlerDirFindQuery; - private DirLandQuery handlerDirLandQuery; - private DirPopularQuery handlerDirPopularQuery; - private DirClassifiedQuery handlerDirClassifiedQuery; - private ParcelSetOtherCleanTime handlerParcelSetOtherCleanTime; - - private MapItemRequest handlerMapItemRequest; - - private StartLure handlerStartLure; - private TeleportLureRequest handlerTeleportLureRequest; - - private NetworkStats handlerNetworkStatsUpdate; - - private ClassifiedInfoRequest handlerClassifiedInfoRequest; - private ClassifiedInfoUpdate handlerClassifiedInfoUpdate; - private ClassifiedDelete handlerClassifiedDelete; - private ClassifiedDelete handlerClassifiedGodDelete; - - private EventNotificationAddRequest handlerEventNotificationAddRequest; - private EventNotificationRemoveRequest handlerEventNotificationRemoveRequest; - private EventGodDelete handlerEventGodDelete; - - private ParcelDwellRequest handlerParcelDwellRequest; - - private UserInfoRequest handlerUserInfoRequest; - private UpdateUserInfo handlerUpdateUserInfo; - - private RetrieveInstantMessages handlerRetrieveInstantMessages; - - private PickDelete handlerPickDelete; - private PickGodDelete handlerPickGodDelete; - private PickInfoUpdate handlerPickInfoUpdate; - private AvatarNotesUpdate handlerAvatarNotesUpdate; - - private MuteListRequest handlerMuteListRequest; - - //private AvatarInterestUpdate handlerAvatarInterestUpdate; - - private PlacesQuery handlerPlacesQuery; - - private readonly IGroupsModule m_GroupsModule; - - private AgentUpdateArgs lastarg = null; - - //private TerrainUnacked handlerUnackedTerrain = null; - - //** - - /* Properties */ - - public UUID SecureSessionId - { - get { return m_secureSessionId; } - } - - public IScene Scene - { - get { return m_scene; } - } - - public UUID SessionId - { - get { return m_sessionId; } - } + #region Properties + public UUID SecureSessionId { get { return m_secureSessionId; } } + public IScene Scene { get { return m_scene; } } + public UUID SessionId { get { return m_sessionId; } } public Vector3 StartPos { get { return m_startpos; } set { m_startpos = value; } } - - public UUID AgentId - { - get { return m_agentId; } - } - - public UUID ActiveGroupId - { - get { return m_activeGroupID; } - } - - public string ActiveGroupName - { - get { return m_activeGroupName; } - } - - public ulong ActiveGroupPowers - { - get { return m_activeGroupPowers; } - } - - public bool IsGroupMember(UUID groupID) - { - return m_groupPowers.ContainsKey(groupID); - } - - public ulong GetGroupPowers(UUID groupID) - { - if (groupID == m_activeGroupID) - return m_activeGroupPowers; - - if (m_groupPowers.ContainsKey(groupID)) - return m_groupPowers[groupID]; - - return 0; - } - - /// - /// This is a utility method used by single states to not duplicate kicks and blue card of death messages. - /// - public bool ChildAgentStatus() - { - return m_scene.PresenceChildStatus(AgentId); - } - + public UUID AgentId { get { return m_agentId; } } + public UUID ActiveGroupId { get { return m_activeGroupID; } } + public string ActiveGroupName { get { return m_activeGroupName; } } + public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } + public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } /// /// First name of the agent/avatar represented by the client /// - public string FirstName - { - get { return m_firstName; } - } - + public string FirstName { get { return m_firstName; } } /// /// Last name of the agent/avatar represented by the client /// - public string LastName - { - get { return m_lastName; } - } - + public string LastName { get { return m_lastName; } } /// /// Full name of the client (first name and last name) /// - public string Name - { - get { return FirstName + " " + LastName; } - } - - public uint CircuitCode - { - get { return m_circuitCode; } - } - - public int MoneyBalance - { - get { return m_moneyBalance; } - } - - public int NextAnimationSequenceNumber - { - get { return m_animationSequenceNumber++; } - } - - public ILLPacketHandler PacketHandler - { - get { return m_PacketHandler; } - } - - bool m_IsActive = true; - + public string Name { get { return FirstName + " " + LastName; } } + public uint CircuitCode { get { return m_circuitCode; } } + public int MoneyBalance { get { return m_moneyBalance; } } + public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } public bool IsActive { get { return m_IsActive; } set { m_IsActive = value; } } + public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } - public bool SendLogoutPacketWhenClosing - { - set { m_SendLogoutPacketWhenClosing = value; } - } - - /* METHODS */ + #endregion Properties /// /// Constructor /// - public LLClientView( - EndPoint remoteEP, IScene scene, LLPacketServer packServer, - AuthenticateResponse sessionInfo, UUID agentId, UUID sessionId, uint circuitCode, EndPoint proxyEP, - ClientStackUserSettings userSettings) + public LLClientView(EndPoint remoteEP, IScene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, + UUID agentId, UUID sessionId, uint circuitCode) { - // Should be called first? - RegisterInterfaces(); - + RegisterInterface(this); + RegisterInterface(this); + RegisterInterface(this); m_GroupsModule = scene.RequestModuleInterface(); + m_moneyBalance = 1000; m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); @@ -505,14 +183,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_assetService = m_scene.RequestModuleInterface(); - m_networkServer = packServer; + m_udpServer = udpServer; + m_udpClient = udpClient; m_agentId = agentId; m_sessionId = sessionId; m_circuitCode = circuitCode; m_userEndPoint = remoteEP; - m_proxyEndPoint = proxyEP; m_firstName = sessionInfo.LoginInfo.First; m_lastName = sessionInfo.LoginInfo.Last; @@ -528,40 +206,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // in it to process. It's an on-purpose threadlock though because // without it, the clientloop will suck up all sim resources. - m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); - m_PacketHandler.SynchronizeClient = SynchronizeClient; - m_PacketHandler.OnPacketStats += PopulateStats; - m_PacketHandler.OnQueueEmpty += HandleQueueEmpty; - - if (scene.Config != null) - { - IConfig clientConfig = scene.Config.Configs["LLClient"]; - if (clientConfig != null) - { - m_PacketHandler.ReliableIsImportant = - clientConfig.GetBoolean("ReliableIsImportant", - false); - m_PacketHandler.MaxReliableResends = clientConfig.GetInt("MaxReliableResends", - m_PacketHandler.MaxReliableResends); - m_primTerseUpdatesPerPacket = clientConfig.GetInt("TerseUpdatesPerPacket", - m_primTerseUpdatesPerPacket); - m_primFullUpdatesPerPacket = clientConfig.GetInt("FullUpdatesPerPacket", - m_primFullUpdatesPerPacket); - - m_primTerseUpdateRate = clientConfig.GetInt("TerseUpdateRate", - m_primTerseUpdateRate); - m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", - m_primFullUpdateRate); - - m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", - m_textureSendLimit); - - m_textureDataLimit = clientConfig.GetInt("TextureDataLimit", - m_textureDataLimit); - - m_packetMTU = clientConfig.GetInt("PacketMTU", 1400); - } - } + //m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); + //m_PacketHandler.SynchronizeClient = SynchronizeClient; + //m_PacketHandler.OnPacketStats += PopulateStats; + //m_PacketHandler.OnQueueEmpty += HandleQueueEmpty; RegisterLocalPacketHandlers(); m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface()); @@ -572,12 +220,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_debugPacketLevel = newDebugPacketLevel; } - # region Client Methods + #region Client Methods private void CloseCleanup(bool shutdownCircuit) { - - m_scene.RemoveClient(AgentId); //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); @@ -645,8 +291,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_imageManager != null) m_imageManager.Close(); - if (m_PacketHandler != null) - m_PacketHandler.Flush(); + if (m_udpServer != null) + m_udpServer.Flush(); // raise an event on the packet server to Shutdown the circuit // Now, if we raise the event then the packet server will call this method itself, so don't try cleanup @@ -700,28 +346,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdateTimer.Stop(); } - public void Restart() - { - // re-construct - m_PacketHandler.Clear(); - - m_clientPingTimer = new Timer(5000); - m_clientPingTimer.Elapsed += CheckClientConnectivity; - m_clientPingTimer.Enabled = true; - - m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); - m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); - m_avatarTerseUpdateTimer.AutoReset = false; - - m_primTerseUpdateTimer = new Timer(m_primTerseUpdateRate); - m_primTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimTerseUpdates); - m_primTerseUpdateTimer.AutoReset = false; - - m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); - m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); - m_primFullUpdateTimer.AutoReset = false; - } - private void Terminate() { IsActive = false; @@ -730,9 +354,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_avatarTerseUpdateTimer.Close(); m_primTerseUpdateTimer.Close(); m_primFullUpdateTimer.Close(); - - m_PacketHandler.OnPacketStats -= PopulateStats; - m_PacketHandler.Dispose(); + + //m_udpServer.OnPacketStats -= PopulateStats; + m_udpClient.Shutdown(); // wait for thread stoped // m_clientThread.Join(); @@ -741,13 +365,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP //m_networkServer.CloseClient(this); } - #endregion + #endregion Client Methods - # region Packet Handling + #region Packet Handling public void PopulateStats(int inPackets, int outPackets, int unAckedBytes) { - handlerNetworkStatsUpdate = OnNetworkStatsUpdate; + NetworkStats handlerNetworkStatsUpdate = OnNetworkStatsUpdate; if (handlerNetworkStatsUpdate != null) { handlerNetworkStatsUpdate(inPackets, outPackets, unAckedBytes); @@ -856,86 +480,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Console.WriteLine(m_circuitCode + ":" + direction + ": " + info); } - /// - /// Main packet processing loop for the UDP component of the client session. Both incoming and outgoing - /// packets are processed here. - /// - protected virtual void ClientLoop() - { - m_log.DebugFormat( - "[CLIENT]: Entered main packet processing loop for {0} in {1}", Name, Scene.RegionInfo.RegionName); - - while (IsActive) - { - LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue(); - - if (nextPacket == null) { - m_log.DebugFormat("[CLIENT]: PacketQueue return null LLQueItem"); - continue; - } - - if (nextPacket.Incoming) - { - if (m_debugPacketLevel > 0) - DebugPacket("IN", nextPacket.Packet); - m_PacketHandler.ProcessInPacket(nextPacket); - } - else - { - if (m_debugPacketLevel > 0) - DebugPacket("OUT", nextPacket.Packet); - m_PacketHandler.ProcessOutPacket(nextPacket); - } - } - } - - # endregion - - protected int m_terrainCheckerCount; - - /// - /// Event handler for check client timer - /// Checks to ensure that the client is still connected. If the client has failed to respond to many pings - /// in succession then close down the connection. - /// - /// - /// - protected void CheckClientConnectivity(object sender, ElapsedEventArgs e) - { - if (m_PacketHandler.PacketsReceived == m_inPacketsChecked) - { - // no packet came in since the last time we checked... - - m_probesWithNoIngressPackets++; - if ((m_probesWithNoIngressPackets > 30 && !m_clientBlocked) // agent active - || (m_probesWithNoIngressPackets > 90 && m_clientBlocked)) // agent paused - { - m_clientPingTimer.Enabled = false; - - m_log.WarnFormat( - "[CLIENT]: Client for agent {0} {1} has stopped responding to pings. Closing connection", - Name, AgentId); - - if (OnConnectionClosed != null) - { - OnConnectionClosed(this); - } - } - else - { - // this will normally trigger at least one packet (ping response) - SendStartPingCheck(0); - } - } - else - { - // Something received in the meantime - we can reset the counters - m_probesWithNoIngressPackets = 0; - // ... and store the current number of packets received to find out if another one got in on the next cycle - m_inPacketsChecked = m_PacketHandler.PacketsReceived; - } - - } + #endregion Packet Handling # region Setup @@ -947,11 +492,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { //this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache); - // Ping the client regularly to check that it's still there - m_clientPingTimer = new Timer(5000); - m_clientPingTimer.Elapsed += CheckClientConnectivity; - m_clientPingTimer.Enabled = true; - m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); m_avatarTerseUpdateTimer.AutoReset = false; @@ -981,7 +521,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Run a user session. This method lies at the base of the entire client thread. /// - protected virtual void RunUserSession() + protected void RunUserSession() { //tell this thread we are using the culture set up for the sim (currently hardcoded to en_US) //otherwise it will override this and use the system default @@ -991,7 +531,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // This sets up all the timers InitNewClient(); - ClientLoop(); } catch (Exception e) { @@ -1015,11 +554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP + "Any further actions taken will not be processed.\n" + "Please relog", true); - LLQueItem item = new LLQueItem(); - item.Packet = packet; - item.Sequence = packet.Header.Sequence; - - m_PacketHandler.ProcessOutPacket(item); + m_udpServer.SendPacket(m_agentId, packet, ThrottleOutPacketType.Unknown, false); // There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to // listeners yet, though. @@ -1037,7 +572,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP # endregion - // Previously ClientView.API partial class + #region Events + public event GenericMessage OnGenericMessage; public event BinaryGenericMessage OnBinaryGenericMessage; public event Action OnLogout; @@ -1197,13 +733,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; public event UpdateVector OnAutoPilotGo; - public event TerrainUnacked OnUnackedTerrain; - public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; public event ObjectOwner OnObjectOwner; - public event DirPlacesQuery OnDirPlacesQuery; public event DirFindQuery OnDirFindQuery; public event DirLandQuery OnDirLandQuery; @@ -1211,45 +744,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event DirClassifiedQuery OnDirClassifiedQuery; public event EventInfoRequest OnEventInfoRequest; public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime; - public event MapItemRequest OnMapItemRequest; - public event OfferCallingCard OnOfferCallingCard; public event AcceptCallingCard OnAcceptCallingCard; public event DeclineCallingCard OnDeclineCallingCard; public event SoundTrigger OnSoundTrigger; - public event StartLure OnStartLure; public event TeleportLureRequest OnTeleportLureRequest; public event NetworkStats OnNetworkStatsUpdate; - public event ClassifiedInfoRequest OnClassifiedInfoRequest; public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; public event ClassifiedDelete OnClassifiedDelete; public event ClassifiedDelete OnClassifiedGodDelete; - public event EventNotificationAddRequest OnEventNotificationAddRequest; public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; public event EventGodDelete OnEventGodDelete; - public event ParcelDwellRequest OnParcelDwellRequest; - public event UserInfoRequest OnUserInfoRequest; public event UpdateUserInfo OnUpdateUserInfo; - public event RetrieveInstantMessages OnRetrieveInstantMessages; - public event PickDelete OnPickDelete; public event PickGodDelete OnPickGodDelete; public event PickInfoUpdate OnPickInfoUpdate; public event AvatarNotesUpdate OnAvatarNotesUpdate; - public event MuteListRequest OnMuteListRequest; - - //public event AvatarInterestUpdate OnAvatarInterestUpdate; - + public event AvatarInterestUpdate OnAvatarInterestUpdate; public event PlacesQuery OnPlacesQuery; + #endregion Events + public void ActivateGesture(UUID assetId, UUID gestureId) { } @@ -2768,7 +2291,953 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(avatarReply, ThrottleOutPacketType.Task); } - #endregion + /// + /// Send the client an Estate message blue box pop-down with a single OK button + /// + /// + /// + /// + /// + public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message) + { + if (!ChildAgentStatus()) + SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3())); + + //SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch()); + } + + public void SendLogoutPacket() + { + // I know this is a bit of a hack, however there are times when you don't + // want to send this, but still need to do the rest of the shutdown process + // this method gets called from the packet server.. which makes it practically + // impossible to do any other way. + + if (m_SendLogoutPacketWhenClosing) + { + LogoutReplyPacket logReply = (LogoutReplyPacket)PacketPool.Instance.GetPacket(PacketType.LogoutReply); + // TODO: don't create new blocks if recycling an old packet + logReply.AgentData.AgentID = AgentId; + logReply.AgentData.SessionID = SessionId; + logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; + logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); + logReply.InventoryData[0].ItemID = UUID.Zero; + + OutPacket(logReply, ThrottleOutPacketType.Task); + } + } + + public void SendHealth(float health) + { + HealthMessagePacket healthpacket = (HealthMessagePacket)PacketPool.Instance.GetPacket(PacketType.HealthMessage); + healthpacket.HealthData.Health = health; + OutPacket(healthpacket, ThrottleOutPacketType.Task); + } + + public void SendAgentOnline(UUID[] agentIDs) + { + OnlineNotificationPacket onp = new OnlineNotificationPacket(); + OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length]; + for (int i = 0; i < agentIDs.Length; i++) + { + OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); + onpbl.AgentID = agentIDs[i]; + onpb[i] = onpbl; + } + onp.AgentBlock = onpb; + onp.Header.Reliable = true; + OutPacket(onp, ThrottleOutPacketType.Task); + } + + public void SendAgentOffline(UUID[] agentIDs) + { + OfflineNotificationPacket offp = new OfflineNotificationPacket(); + OfflineNotificationPacket.AgentBlockBlock[] offpb = new OfflineNotificationPacket.AgentBlockBlock[agentIDs.Length]; + for (int i = 0; i < agentIDs.Length; i++) + { + OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); + onpbl.AgentID = agentIDs[i]; + offpb[i] = onpbl; + } + offp.AgentBlock = offpb; + offp.Header.Reliable = true; + OutPacket(offp, ThrottleOutPacketType.Task); + } + + public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, + Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) + { + AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); + avatarSitResponse.SitObject.ID = TargetID; + if (CameraAtOffset != Vector3.Zero) + { + avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset; + avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset; + } + avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook; + avatarSitResponse.SitTransform.AutoPilot = autopilot; + avatarSitResponse.SitTransform.SitPosition = OffsetPos; + avatarSitResponse.SitTransform.SitRotation = SitOrientation; + + OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); + } + + public void SendAdminResponse(UUID Token, uint AdminLevel) + { + GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket(); + GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock(); + GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock(); + + adb.AgentID = AgentId; + adb.SessionID = SessionId; // More security + gdb.GodLevel = (byte)AdminLevel; + gdb.Token = Token; + //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock; + respondPacket.GrantData = gdb; + respondPacket.AgentData = adb; + OutPacket(respondPacket, ThrottleOutPacketType.Task); + } + + public void SendGroupMembership(GroupMembershipData[] GroupMembership) + { + m_groupPowers.Clear(); + + AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket(); + AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[GroupMembership.Length]; + for (int i = 0; i < GroupMembership.Length; i++) + { + m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; + + AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock(); + Group.AcceptNotices = GroupMembership[i].AcceptNotices; + Group.Contribution = GroupMembership[i].Contribution; + Group.GroupID = GroupMembership[i].GroupID; + Group.GroupInsigniaID = GroupMembership[i].GroupPicture; + Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); + Group.GroupPowers = GroupMembership[i].GroupPowers; + Groups[i] = Group; + + + } + Groupupdate.GroupData = Groups; + Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock(); + Groupupdate.AgentData.AgentID = AgentId; + OutPacket(Groupupdate, ThrottleOutPacketType.Task); + + try + { + IEventQueue eq = Scene.RequestModuleInterface(); + if (eq != null) + { + eq.GroupMembership(Groupupdate, this.AgentId); + } + } + catch (Exception ex) + { + m_log.Error("Unable to send group membership data via eventqueue - exception: " + ex.ToString()); + m_log.Warn("sending group membership data via UDP"); + OutPacket(Groupupdate, ThrottleOutPacketType.Task); + } + } + + + public void SendGroupNameReply(UUID groupLLUID, string GroupName) + { + UUIDGroupNameReplyPacket pack = new UUIDGroupNameReplyPacket(); + UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; + UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); + uidnamebloc.ID = groupLLUID; + uidnamebloc.GroupName = Utils.StringToBytes(GroupName); + uidnameblock[0] = uidnamebloc; + pack.UUIDNameBlock = uidnameblock; + OutPacket(pack, ThrottleOutPacketType.Task); + } + + public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia) + { + LandStatReplyPacket lsrp = new LandStatReplyPacket(); + // LandStatReplyPacket.RequestDataBlock lsreqdpb = new LandStatReplyPacket.RequestDataBlock(); + LandStatReplyPacket.ReportDataBlock[] lsrepdba = new LandStatReplyPacket.ReportDataBlock[lsrpia.Length]; + //LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); + // lsrepdb. + lsrp.RequestData.ReportType = reportType; + lsrp.RequestData.RequestFlags = requestFlags; + lsrp.RequestData.TotalObjectCount = resultCount; + for (int i = 0; i < lsrpia.Length; i++) + { + LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); + lsrepdb.LocationX = lsrpia[i].LocationX; + lsrepdb.LocationY = lsrpia[i].LocationY; + lsrepdb.LocationZ = lsrpia[i].LocationZ; + lsrepdb.Score = lsrpia[i].Score; + lsrepdb.TaskID = lsrpia[i].TaskID; + lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; + lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); + lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); + lsrepdba[i] = lsrepdb; + } + lsrp.ReportData = lsrepdba; + OutPacket(lsrp, ThrottleOutPacketType.Task); + } + + public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running) + { + ScriptRunningReplyPacket scriptRunningReply = new ScriptRunningReplyPacket(); + scriptRunningReply.Script.ObjectID = objectID; + scriptRunningReply.Script.ItemID = itemID; + scriptRunningReply.Script.Running = running; + + OutPacket(scriptRunningReply, ThrottleOutPacketType.Task); + } + + public void SendAsset(AssetRequestToClient req) + { + //m_log.Debug("sending asset " + req.RequestAssetID); + TransferInfoPacket Transfer = new TransferInfoPacket(); + Transfer.TransferInfo.ChannelType = 2; + Transfer.TransferInfo.Status = 0; + Transfer.TransferInfo.TargetType = 0; + if (req.AssetRequestSource == 2) + { + Transfer.TransferInfo.Params = new byte[20]; + Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + int assType = req.AssetInf.Type; + Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); + } + else if (req.AssetRequestSource == 3) + { + Transfer.TransferInfo.Params = req.Params; + // Transfer.TransferInfo.Params = new byte[100]; + //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); + } + Transfer.TransferInfo.Size = req.AssetInf.Data.Length; + Transfer.TransferInfo.TransferID = req.TransferRequestID; + Transfer.Header.Zerocoded = true; + OutPacket(Transfer, ThrottleOutPacketType.Asset); + + if (req.NumPackets == 1) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = 0; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + TransferPacket.TransferData.Data = req.AssetInf.Data; + TransferPacket.TransferData.Status = 1; + TransferPacket.Header.Zerocoded = true; + OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + } + else + { + int processedLength = 0; + int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; + int packetNumber = 0; + + while (processedLength < req.AssetInf.Data.Length) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = packetNumber; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + + int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); + byte[] chunk = new byte[chunkSize]; + Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); + + TransferPacket.TransferData.Data = chunk; + + // 0 indicates more packets to come, 1 indicates last packet + if (req.AssetInf.Data.Length - processedLength > maxChunkSize) + { + TransferPacket.TransferData.Status = 0; + } + else + { + TransferPacket.TransferData.Status = 1; + } + TransferPacket.Header.Zerocoded = true; + OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + + processedLength += chunkSize; + packetNumber++; + } + } + } + + public void SendTexture(AssetBase TextureAsset) + { + + } + + public void SendRegionHandle(UUID regionID, ulong handle) + { + RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply); + reply.ReplyBlock.RegionID = regionID; + reply.ReplyBlock.RegionHandle = handle; + OutPacket(reply, ThrottleOutPacketType.Land); + } + + public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) + { + ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); + reply.AgentData.AgentID = m_agentId; + reply.Data.ParcelID = parcelID; + reply.Data.OwnerID = land.OwnerID; + reply.Data.Name = Utils.StringToBytes(land.Name); + reply.Data.Desc = Utils.StringToBytes(land.Description); + reply.Data.ActualArea = land.Area; + reply.Data.BillableArea = land.Area; // TODO: what is this? + + // Bit 0: Mature, bit 7: on sale, other bits: no idea + reply.Data.Flags = (byte)( + ((land.Flags & (uint)ParcelFlags.MaturePublish) != 0 ? (1 << 0) : 0) + + ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0)); + + Vector3 pos = land.UserLocation; + if (pos.Equals(Vector3.Zero)) + { + pos = (land.AABBMax + land.AABBMin) * 0.5f; + } + reply.Data.GlobalX = info.RegionLocX * Constants.RegionSize + x; + reply.Data.GlobalY = info.RegionLocY * Constants.RegionSize + y; + reply.Data.GlobalZ = pos.Z; + reply.Data.SimName = Utils.StringToBytes(info.RegionName); + reply.Data.SnapshotID = land.SnapshotID; + reply.Data.Dwell = land.Dwell; + reply.Data.SalePrice = land.SalePrice; + reply.Data.AuctionID = (int)land.AuctionID; + + OutPacket(reply, ThrottleOutPacketType.Land); + } + + public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt) + { + ScriptTeleportRequestPacket packet = (ScriptTeleportRequestPacket)PacketPool.Instance.GetPacket(PacketType.ScriptTeleportRequest); + + packet.Data.ObjectName = Utils.StringToBytes(objName); + packet.Data.SimName = Utils.StringToBytes(simName); + packet.Data.SimPosition = pos; + packet.Data.LookAt = lookAt; + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data) + { + DirPlacesReplyPacket packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply); + + packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock(); + + packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; + packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); + + packet.QueryReplies = + new DirPlacesReplyPacket.QueryRepliesBlock[data.Length]; + + packet.StatusData = new DirPlacesReplyPacket.StatusDataBlock[ + data.Length]; + + packet.AgentData.AgentID = AgentId; + + packet.QueryData[0].QueryID = queryID; + + int i = 0; + foreach (DirPlacesReplyData d in data) + { + packet.QueryReplies[i] = + new DirPlacesReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirPlacesReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = Utils.StringToBytes(d.name); + packet.QueryReplies[i].ForSale = d.forSale; + packet.QueryReplies[i].Auction = d.auction; + packet.QueryReplies[i].Dwell = d.dwell; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data) + { + DirPeopleReplyPacket packet = (DirPeopleReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPeopleReply); + + packet.AgentData = new DirPeopleReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirPeopleReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirPeopleReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirPeopleReplyData d in data) + { + packet.QueryReplies[i] = new DirPeopleReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].AgentID = d.agentID; + packet.QueryReplies[i].FirstName = + Utils.StringToBytes(d.firstName); + packet.QueryReplies[i].LastName = + Utils.StringToBytes(d.lastName); + packet.QueryReplies[i].Group = + Utils.StringToBytes(d.group); + packet.QueryReplies[i].Online = d.online; + packet.QueryReplies[i].Reputation = d.reputation; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data) + { + DirEventsReplyPacket packet = (DirEventsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirEventsReply); + + packet.AgentData = new DirEventsReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirEventsReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirEventsReplyPacket.QueryRepliesBlock[ + data.Length]; + + packet.StatusData = new DirEventsReplyPacket.StatusDataBlock[ + data.Length]; + + int i = 0; + foreach (DirEventsReplyData d in data) + { + packet.QueryReplies[i] = new DirEventsReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirEventsReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].OwnerID = d.ownerID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].EventID = d.eventID; + packet.QueryReplies[i].Date = + Utils.StringToBytes(d.date); + packet.QueryReplies[i].UnixTime = d.unixTime; + packet.QueryReplies[i].EventFlags = d.eventFlags; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data) + { + DirGroupsReplyPacket packet = (DirGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirGroupsReply); + + packet.AgentData = new DirGroupsReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirGroupsReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirGroupsReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirGroupsReplyData d in data) + { + packet.QueryReplies[i] = new DirGroupsReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].GroupID = d.groupID; + packet.QueryReplies[i].GroupName = + Utils.StringToBytes(d.groupName); + packet.QueryReplies[i].Members = d.members; + packet.QueryReplies[i].SearchOrder = d.searchOrder; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data) + { + DirClassifiedReplyPacket packet = (DirClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirClassifiedReply); + + packet.AgentData = new DirClassifiedReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirClassifiedReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirClassifiedReplyPacket.QueryRepliesBlock[ + data.Length]; + packet.StatusData = new DirClassifiedReplyPacket.StatusDataBlock[ + data.Length]; + + int i = 0; + foreach (DirClassifiedReplyData d in data) + { + packet.QueryReplies[i] = new DirClassifiedReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirClassifiedReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].ClassifiedID = d.classifiedID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].ClassifiedFlags = d.classifiedFlags; + packet.QueryReplies[i].CreationDate = d.creationDate; + packet.QueryReplies[i].ExpirationDate = d.expirationDate; + packet.QueryReplies[i].PriceForListing = d.price; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirLandReply(UUID queryID, DirLandReplyData[] data) + { + DirLandReplyPacket packet = (DirLandReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirLandReply); + + packet.AgentData = new DirLandReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirLandReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirLandReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirLandReplyData d in data) + { + packet.QueryReplies[i] = new DirLandReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].Auction = d.auction; + packet.QueryReplies[i].ForSale = d.forSale; + packet.QueryReplies[i].SalePrice = d.salePrice; + packet.QueryReplies[i].ActualArea = d.actualArea; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data) + { + DirPopularReplyPacket packet = (DirPopularReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPopularReply); + + packet.AgentData = new DirPopularReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirPopularReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirPopularReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirPopularReplyData d in data) + { + packet.QueryReplies[i] = new DirPopularReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].Dwell = d.dwell; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendEventInfoReply(EventData data) + { + EventInfoReplyPacket packet = (EventInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.EventInfoReply); + + packet.AgentData = new EventInfoReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.EventData = new EventInfoReplyPacket.EventDataBlock(); + packet.EventData.EventID = data.eventID; + packet.EventData.Creator = Utils.StringToBytes(data.creator); + packet.EventData.Name = Utils.StringToBytes(data.name); + packet.EventData.Category = Utils.StringToBytes(data.category); + packet.EventData.Desc = Utils.StringToBytes(data.description); + packet.EventData.Date = Utils.StringToBytes(data.date); + packet.EventData.DateUTC = data.dateUTC; + packet.EventData.Duration = data.duration; + packet.EventData.Cover = data.cover; + packet.EventData.Amount = data.amount; + packet.EventData.SimName = Utils.StringToBytes(data.simName); + packet.EventData.GlobalPos = new Vector3d(data.globalPos); + packet.EventData.EventFlags = data.eventFlags; + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags) + { + MapItemReplyPacket mirplk = new MapItemReplyPacket(); + mirplk.AgentData.AgentID = AgentId; + mirplk.RequestData.ItemType = mapitemtype; + mirplk.Data = new MapItemReplyPacket.DataBlock[replies.Length]; + for (int i = 0; i < replies.Length; i++) + { + MapItemReplyPacket.DataBlock mrdata = new MapItemReplyPacket.DataBlock(); + mrdata.X = replies[i].x; + mrdata.Y = replies[i].y; + mrdata.ID = replies[i].id; + mrdata.Extra = replies[i].Extra; + mrdata.Extra2 = replies[i].Extra2; + mrdata.Name = Utils.StringToBytes(replies[i].name); + mirplk.Data[i] = mrdata; + } + //m_log.Debug(mirplk.ToString()); + OutPacket(mirplk, ThrottleOutPacketType.Task); + + } + + public void SendOfferCallingCard(UUID srcID, UUID transactionID) + { + // a bit special, as this uses AgentID to store the source instead + // of the destination. The destination (the receiver) goes into destID + OfferCallingCardPacket p = (OfferCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.OfferCallingCard); + p.AgentData.AgentID = srcID; + p.AgentData.SessionID = UUID.Zero; + p.AgentBlock.DestID = AgentId; + p.AgentBlock.TransactionID = transactionID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAcceptCallingCard(UUID transactionID) + { + AcceptCallingCardPacket p = (AcceptCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.AcceptCallingCard); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = UUID.Zero; + p.FolderData = new AcceptCallingCardPacket.FolderDataBlock[1]; + p.FolderData[0] = new AcceptCallingCardPacket.FolderDataBlock(); + p.FolderData[0].FolderID = UUID.Zero; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendDeclineCallingCard(UUID transactionID) + { + DeclineCallingCardPacket p = (DeclineCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.DeclineCallingCard); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = UUID.Zero; + p.TransactionBlock.TransactionID = transactionID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendTerminateFriend(UUID exFriendID) + { + TerminateFriendshipPacket p = (TerminateFriendshipPacket)PacketPool.Instance.GetPacket(PacketType.TerminateFriendship); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = SessionId; + p.ExBlock.OtherID = exFriendID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) + { + AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); + + p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + p.AgentData.AvatarID = avatarID; + + p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; + int i = 0; + foreach (GroupMembershipData m in data) + { + p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); + p.GroupData[i].GroupPowers = m.GroupPowers; + p.GroupData[i].AcceptNotices = m.AcceptNotices; + p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); + p.GroupData[i].GroupID = m.GroupID; + p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); + p.GroupData[i].GroupInsigniaID = m.GroupPicture; + i++; + } + + p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); + p.NewGroupData.ListInProfile = true; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendJoinGroupReply(UUID groupID, bool success) + { + JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply); + + p.AgentData = new JoinGroupReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + + p.GroupData = new JoinGroupReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + p.GroupData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success) + { + EjectGroupMemberReplyPacket p = (EjectGroupMemberReplyPacket)PacketPool.Instance.GetPacket(PacketType.EjectGroupMemberReply); + + p.AgentData = new EjectGroupMemberReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = agentID; + + p.GroupData = new EjectGroupMemberReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + + p.EjectData = new EjectGroupMemberReplyPacket.EjectDataBlock(); + p.EjectData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendLeaveGroupReply(UUID groupID, bool success) + { + LeaveGroupReplyPacket p = (LeaveGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.LeaveGroupReply); + + p.AgentData = new LeaveGroupReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + + p.GroupData = new LeaveGroupReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + p.GroupData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name) + { + if (classifiedID.Length != name.Length) + return; + + AvatarClassifiedReplyPacket ac = + (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarClassifiedReply); + + ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); + ac.AgentData.AgentID = AgentId; + ac.AgentData.TargetID = targetID; + + ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifiedID.Length]; + int i; + for (i = 0; i < classifiedID.Length; i++) + { + ac.Data[i].ClassifiedID = classifiedID[i]; + ac.Data[i].Name = Utils.StringToBytes(name[i]); + } + + OutPacket(ac, ThrottleOutPacketType.Task); + } + + public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price) + { + ClassifiedInfoReplyPacket cr = + (ClassifiedInfoReplyPacket)PacketPool.Instance.GetPacket( + PacketType.ClassifiedInfoReply); + + cr.AgentData = new ClassifiedInfoReplyPacket.AgentDataBlock(); + cr.AgentData.AgentID = AgentId; + + cr.Data = new ClassifiedInfoReplyPacket.DataBlock(); + cr.Data.ClassifiedID = classifiedID; + cr.Data.CreatorID = creatorID; + cr.Data.CreationDate = creationDate; + cr.Data.ExpirationDate = expirationDate; + cr.Data.Category = category; + cr.Data.Name = Utils.StringToBytes(name); + cr.Data.Desc = Utils.StringToBytes(description); + cr.Data.ParcelID = parcelID; + cr.Data.ParentEstate = parentEstate; + cr.Data.SnapshotID = snapshotID; + cr.Data.SimName = Utils.StringToBytes(simName); + cr.Data.PosGlobal = new Vector3d(globalPos); + cr.Data.ParcelName = Utils.StringToBytes(parcelName); + cr.Data.ClassifiedFlags = classifiedFlags; + cr.Data.PriceForListing = price; + + OutPacket(cr, ThrottleOutPacketType.Task); + } + + public void SendAgentDropGroup(UUID groupID) + { + AgentDropGroupPacket dg = + (AgentDropGroupPacket)PacketPool.Instance.GetPacket( + PacketType.AgentDropGroup); + + dg.AgentData = new AgentDropGroupPacket.AgentDataBlock(); + dg.AgentData.AgentID = AgentId; + dg.AgentData.GroupID = groupID; + + OutPacket(dg, ThrottleOutPacketType.Task); + } + + public void SendAvatarNotesReply(UUID targetID, string text) + { + AvatarNotesReplyPacket an = + (AvatarNotesReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarNotesReply); + + an.AgentData = new AvatarNotesReplyPacket.AgentDataBlock(); + an.AgentData.AgentID = AgentId; + + an.Data = new AvatarNotesReplyPacket.DataBlock(); + an.Data.TargetID = targetID; + an.Data.Notes = Utils.StringToBytes(text); + + OutPacket(an, ThrottleOutPacketType.Task); + } + + public void SendAvatarPicksReply(UUID targetID, Dictionary picks) + { + AvatarPicksReplyPacket ap = + (AvatarPicksReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarPicksReply); + + ap.AgentData = new AvatarPicksReplyPacket.AgentDataBlock(); + ap.AgentData.AgentID = AgentId; + ap.AgentData.TargetID = targetID; + + ap.Data = new AvatarPicksReplyPacket.DataBlock[picks.Count]; + + int i = 0; + foreach (KeyValuePair pick in picks) + { + ap.Data[i] = new AvatarPicksReplyPacket.DataBlock(); + ap.Data[i].PickID = pick.Key; + ap.Data[i].PickName = Utils.StringToBytes(pick.Value); + i++; + } + + OutPacket(ap, ThrottleOutPacketType.Task); + } + + public void SendAvatarClassifiedReply(UUID targetID, Dictionary classifieds) + { + AvatarClassifiedReplyPacket ac = + (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarClassifiedReply); + + ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); + ac.AgentData.AgentID = AgentId; + ac.AgentData.TargetID = targetID; + + ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifieds.Count]; + + int i = 0; + foreach (KeyValuePair classified in classifieds) + { + ac.Data[i] = new AvatarClassifiedReplyPacket.DataBlock(); + ac.Data[i].ClassifiedID = classified.Key; + ac.Data[i].Name = Utils.StringToBytes(classified.Value); + i++; + } + + OutPacket(ac, ThrottleOutPacketType.Task); + } + + public void SendParcelDwellReply(int localID, UUID parcelID, float dwell) + { + ParcelDwellReplyPacket pd = + (ParcelDwellReplyPacket)PacketPool.Instance.GetPacket( + PacketType.ParcelDwellReply); + + pd.AgentData = new ParcelDwellReplyPacket.AgentDataBlock(); + pd.AgentData.AgentID = AgentId; + + pd.Data = new ParcelDwellReplyPacket.DataBlock(); + pd.Data.LocalID = localID; + pd.Data.ParcelID = parcelID; + pd.Data.Dwell = dwell; + + OutPacket(pd, ThrottleOutPacketType.Land); + } + + public void SendUserInfoReply(bool imViaEmail, bool visible, string email) + { + UserInfoReplyPacket ur = + (UserInfoReplyPacket)PacketPool.Instance.GetPacket( + PacketType.UserInfoReply); + + string Visible = "hidden"; + if (visible) + Visible = "default"; + + ur.AgentData = new UserInfoReplyPacket.AgentDataBlock(); + ur.AgentData.AgentID = AgentId; + + ur.UserData = new UserInfoReplyPacket.UserDataBlock(); + ur.UserData.IMViaEMail = imViaEmail; + ur.UserData.DirectoryVisibility = Utils.StringToBytes(Visible); + ur.UserData.EMail = Utils.StringToBytes(email); + + OutPacket(ur, ThrottleOutPacketType.Task); + } + + public void SendCreateGroupReply(UUID groupID, bool success, string message) + { + CreateGroupReplyPacket createGroupReply = (CreateGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.CreateGroupReply); + + createGroupReply.AgentData = + new CreateGroupReplyPacket.AgentDataBlock(); + createGroupReply.ReplyData = + new CreateGroupReplyPacket.ReplyDataBlock(); + + createGroupReply.AgentData.AgentID = AgentId; + createGroupReply.ReplyData.GroupID = groupID; + + createGroupReply.ReplyData.Success = success; + createGroupReply.ReplyData.Message = Utils.StringToBytes(message); + OutPacket(createGroupReply, ThrottleOutPacketType.Task); + } + + public void SendUseCachedMuteList() + { + UseCachedMuteListPacket useCachedMuteList = (UseCachedMuteListPacket)PacketPool.Instance.GetPacket(PacketType.UseCachedMuteList); + + useCachedMuteList.AgentData = new UseCachedMuteListPacket.AgentDataBlock(); + useCachedMuteList.AgentData.AgentID = AgentId; + + OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); + } + + public void SendMuteListUpdate(string filename) + { + MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); + + muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock(); + muteListUpdate.MuteData.AgentID = AgentId; + muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename); + + OutPacket(muteListUpdate, ThrottleOutPacketType.Task); + } + + public void SendPickInfoReply(UUID pickID, UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) + { + PickInfoReplyPacket pickInfoReply = (PickInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.PickInfoReply); + + pickInfoReply.AgentData = new PickInfoReplyPacket.AgentDataBlock(); + pickInfoReply.AgentData.AgentID = AgentId; + + pickInfoReply.Data = new PickInfoReplyPacket.DataBlock(); + pickInfoReply.Data.PickID = pickID; + pickInfoReply.Data.CreatorID = creatorID; + pickInfoReply.Data.TopPick = topPick; + pickInfoReply.Data.ParcelID = parcelID; + pickInfoReply.Data.Name = Utils.StringToBytes(name); + pickInfoReply.Data.Desc = Utils.StringToBytes(desc); + pickInfoReply.Data.SnapshotID = snapshotID; + pickInfoReply.Data.User = Utils.StringToBytes(user); + pickInfoReply.Data.OriginalName = Utils.StringToBytes(originalName); + pickInfoReply.Data.SimName = Utils.StringToBytes(simName); + pickInfoReply.Data.PosGlobal = new Vector3d(posGlobal); + pickInfoReply.Data.SortOrder = sortOrder; + pickInfoReply.Data.Enabled = enabled; + + OutPacket(pickInfoReply, ThrottleOutPacketType.Task); + } + + #endregion Scene/Avatar to Client // Gesture @@ -3201,7 +3670,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } outPacket.Header.Zerocoded = true; - OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); + OutPacket(outPacket, ThrottleOutPacketType.Task); if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) lock (m_primFullUpdateTimer) @@ -3291,7 +3760,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP outPacket.Header.Reliable = false; outPacket.Header.Zerocoded = true; - OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); + OutPacket(outPacket, ThrottleOutPacketType.Task); if (m_primTerseUpdates.Count == 0) lock (m_primTerseUpdateTimer) @@ -4242,6 +4711,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task); } + public ulong GetGroupPowers(UUID groupID) + { + if (groupID == m_activeGroupID) + return m_activeGroupPowers; + + if (m_groupPowers.ContainsKey(groupID)) + return m_groupPowers[groupID]; + + return 0; + } + + /// + /// This is a utility method used by single states to not duplicate kicks and blue card of death messages. + /// + public bool ChildAgentStatus() + { + return m_scene.PresenceChildStatus(AgentId); + } + #endregion /// @@ -4260,6 +4748,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); } + #region Packet Handlers + private bool HandleMoneyTransferRequest(IClientAPI sender, Packet Pack) { MoneyTransferRequestPacket money = (MoneyTransferRequestPacket) Pack; @@ -4267,7 +4757,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (money.MoneyData.SourceID == sender.AgentId && money.AgentData.AgentID == sender.AgentId && money.AgentData.SessionID == sender.SessionId) { - handlerMoneyTransferRequest = OnMoneyTransferRequest; + MoneyTransferRequest handlerMoneyTransferRequest = OnMoneyTransferRequest; if (handlerMoneyTransferRequest != null) { handlerMoneyTransferRequest(money.MoneyData.SourceID, money.MoneyData.DestID, @@ -4286,7 +4776,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelBuyPacket parcel = (ParcelBuyPacket) Pack; if (parcel.AgentData.AgentID == AgentId && parcel.AgentData.SessionID == SessionId) { - handlerParcelBuy = OnParcelBuy; + ParcelBuy handlerParcelBuy = OnParcelBuy; if (handlerParcelBuy != null) { handlerParcelBuy(parcel.AgentData.AgentID, parcel.Data.GroupID, parcel.Data.Final, @@ -4307,7 +4797,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < upack.UUIDNameBlock.Length; i++) { - handlerUUIDGroupNameRequest = OnUUIDGroupNameRequest; + UUIDNameRequest handlerUUIDGroupNameRequest = OnUUIDGroupNameRequest; if (handlerUUIDGroupNameRequest != null) { handlerUUIDGroupNameRequest(upack.UUIDNameBlock[i].ID, this); @@ -4323,7 +4813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_genericPacketHandlers.Count == 0) return false; if (gmpack.AgentData.SessionID != SessionId) return false; - handlerGenericMessage = null; + GenericMessage handlerGenericMessage = null; string method = Util.FieldToString(gmpack.MethodData.Method).ToLower().Trim(); @@ -4364,7 +4854,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectGroupPacket ogpack = (ObjectGroupPacket)Pack; if (ogpack.AgentData.SessionID != SessionId) return false; - handlerObjectGroupRequest = OnObjectGroupRequest; + RequestObjectPropertiesFamily handlerObjectGroupRequest = OnObjectGroupRequest; if (handlerObjectGroupRequest != null) { for (int i = 0; i < ogpack.ObjectData.Length; i++) @@ -4379,7 +4869,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { ViewerEffectPacket viewer = (ViewerEffectPacket)Pack; if (viewer.AgentData.SessionID != SessionId) return false; - handlerViewerEffect = OnViewerEffect; + ViewerEffectEventHandler handlerViewerEffect = OnViewerEffect; if (handlerViewerEffect != null) { int length = viewer.Effect.Length; @@ -4403,6 +4893,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } + #endregion Packet Handlers + public void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question) { ScriptQuestionPacket scriptQuestion = (ScriptQuestionPacket)PacketPool.Instance.GetPacket(PacketType.ScriptQuestion); @@ -4468,7 +4960,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.InfoFormat("[CLIENT]: Got a logout request for {0} in {1}", Name, Scene.RegionInfo.RegionName); - handlerLogout = OnLogout; + Action handlerLogout = OnLogout; if (handlerLogout != null) { @@ -4550,7 +5042,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 1: Vector3 pos1 = new Vector3(block.Data, 0); - handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; + UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; if (handlerUpdatePrimSinglePosition != null) { // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); @@ -4560,7 +5052,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 2: Quaternion rot1 = new Quaternion(block.Data, 0, true); - handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; + UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; if (handlerUpdatePrimSingleRotation != null) { // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W); @@ -4571,7 +5063,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Vector3 rotPos = new Vector3(block.Data, 0); Quaternion rot2 = new Quaternion(block.Data, 12, true); - handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; + UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; if (handlerUpdatePrimSingleRotationPosition != null) { // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z); @@ -4583,7 +5075,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 20: Vector3 scale4 = new Vector3(block.Data, 0); - handlerUpdatePrimScale = OnUpdatePrimScale; + UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; if (handlerUpdatePrimScale != null) { // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z); @@ -4611,7 +5103,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 9: Vector3 pos2 = new Vector3(block.Data, 0); - handlerUpdateVector = OnUpdatePrimGroupPosition; + UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; if (handlerUpdateVector != null) { @@ -4622,7 +5114,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 10: Quaternion rot3 = new Quaternion(block.Data, 0, true); - handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; + UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; if (handlerUpdatePrimRotation != null) { // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W); @@ -4645,7 +5137,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 28: Vector3 scale7 = new Vector3(block.Data, 0); - handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; + UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; if (handlerUpdatePrimGroupScale != null) { // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z); @@ -4765,45 +5257,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP } /// - /// returns a byte array of the client set throttles Gets multiplied by the multiplier - /// - /// - /// non 1 multiplier for subdividing the throttles between individual regions - /// - public byte[] GetThrottlesPacked(float multiplier) - { - return m_PacketHandler.PacketQueue.GetThrottlesPacked(multiplier); - } - /// - /// sets the throttles from values supplied by the client + /// Sets the throttles from values supplied by the client /// /// public void SetChildAgentThrottle(byte[] throttles) { - m_PacketHandler.PacketQueue.SetThrottleFromClient(throttles); + m_udpClient.SetThrottles(throttles); + } + + public byte[] GetThrottlesPacked(float multiplier) + { + return m_udpClient.GetThrottlesPacked(); + } + + public bool IsThrottleEmpty(ThrottleOutPacketType category) + { + return m_udpClient.IsThrottleEmpty(category); } /// - /// Method gets called when a new packet has arrived from the UDP - /// server. This happens after it's been decoded into a libsl object. + /// Unused /// - /// object containing the packet. public virtual void InPacket(object NewPack) { - // Cast NewPack to Packet. - m_PacketHandler.InPacket((Packet) NewPack); + throw new NotImplementedException(); } /// - /// This is the starting point for sending a simulator packet out to the client. - /// - /// Please do not call this from outside the LindenUDP client stack. + /// This is the starting point for sending a simulator packet out to the client /// - /// - /// Corresponds to the type of data that is going out. Enum - public void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType) + /// Packet to send + /// Throttling category for the packet + private void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) { - m_PacketHandler.OutPacket(NewPack, throttlePacketType); + m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); } public bool AddMoney(int debit) @@ -4847,7 +5334,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; } - handlerAutoPilotGo = OnAutoPilotGo; + UpdateVector handlerAutoPilotGo = OnAutoPilotGo; if (handlerAutoPilotGo != null) { handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this); @@ -4899,7 +5386,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRequestAvatarProperties = OnRequestAvatarProperties; + RequestAvatarProperties handlerRequestAvatarProperties = OnRequestAvatarProperties; if (handlerRequestAvatarProperties != null) { handlerRequestAvatarProperties(this, avatarProperties.AgentData.AvatarID); @@ -4940,7 +5427,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP args.Sender = this; args.SenderUUID = this.AgentId; - handlerChatFromClient = OnChatFromClient; + ChatMessage handlerChatFromClient = OnChatFromClient; if (handlerChatFromClient != null) handlerChatFromClient(this, args); } @@ -4958,7 +5445,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdateAvatarProperties = OnUpdateAvatarProperties; + UpdateAvatarProperties handlerUpdateAvatarProperties = OnUpdateAvatarProperties; if (handlerUpdateAvatarProperties != null) { AvatarPropertiesUpdatePacket.PropertiesDataBlock Properties = avatarProps.PropertiesData; @@ -4998,7 +5485,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP args.Position = new Vector3(); args.Scene = Scene; args.Sender = this; - handlerChatFromClient2 = OnChatFromClient; + ChatMessage handlerChatFromClient2 = OnChatFromClient; if (handlerChatFromClient2 != null) handlerChatFromClient2(this, args); } @@ -5019,7 +5506,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName); string IMmessage = Utils.BytesToString(msgpack.MessageBlock.Message); - handlerInstantMessage = OnInstantMessage; + ImprovedInstantMessage handlerInstantMessage = OnInstantMessage; if (handlerInstantMessage != null) { @@ -5062,7 +5549,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP callingCardFolders.Add(afriendpack.FolderData[fi].FolderID); } - handlerApproveFriendRequest = OnApproveFriendRequest; + FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest; if (handlerApproveFriendRequest != null) { handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders); @@ -5105,7 +5592,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID listOwnerAgentID = tfriendpack.AgentData.AgentID; UUID exFriendID = tfriendpack.ExBlock.OtherID; - handlerTerminateFriendship = OnTerminateFriendship; + FriendshipTermination handlerTerminateFriendship = OnTerminateFriendship; if (handlerTerminateFriendship != null) { handlerTerminateFriendship(this, listOwnerAgentID, exFriendID); @@ -5124,7 +5611,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRezObject = OnRezObject; + RezObject handlerRezObject = OnRezObject; if (handlerRezObject != null) { handlerRezObject(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd, @@ -5147,7 +5634,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDeRezObject = OnDeRezObject; + DeRezObject handlerDeRezObject = OnDeRezObject; if (handlerDeRezObject != null) { List deRezIDs = new List(); @@ -5186,7 +5673,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { for (int i = 0; i < modify.ParcelData.Length; i++) { - handlerModifyTerrain = OnModifyTerrain; + ModifyTerrain handlerModifyTerrain = OnModifyTerrain; if (handlerModifyTerrain != null) { handlerModifyTerrain(AgentId, modify.ModifyBlock.Height, modify.ModifyBlock.Seconds, @@ -5203,7 +5690,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RegionHandshakeReply: - handlerRegionHandShakeReply = OnRegionHandShakeReply; + Action handlerRegionHandShakeReply = OnRegionHandShakeReply; if (handlerRegionHandShakeReply != null) { handlerRegionHandShakeReply(this); @@ -5212,14 +5699,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.AgentWearablesRequest: - handlerRequestWearables = OnRequestWearables; + GenericCall2 handlerRequestWearables = OnRequestWearables; if (handlerRequestWearables != null) { handlerRequestWearables(); } - handlerRequestAvatarsData = OnRequestAvatarsData; + Action handlerRequestAvatarsData = OnRequestAvatarsData; if (handlerRequestAvatarsData != null) { @@ -5240,7 +5727,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSetAppearance = OnSetAppearance; + SetAppearance handlerSetAppearance = OnSetAppearance; if (handlerSetAppearance != null) { // Temporarily protect ourselves from the mantis #951 failure. @@ -5291,7 +5778,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP wearingArgs.NowWearing.Add(wearable); } - handlerAvatarNowWearing = OnAvatarNowWearing; + AvatarNowWearing handlerAvatarNowWearing = OnAvatarNowWearing; if (handlerAvatarNowWearing != null) { handlerAvatarNowWearing(this, wearingArgs); @@ -5300,7 +5787,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.RezSingleAttachmentFromInv: - handlerRezSingleAttachment = OnRezSingleAttachmentFromInv; + RezSingleAttachmentFromInv handlerRezSingleAttachment = OnRezSingleAttachmentFromInv; if (handlerRezSingleAttachment != null) { RezSingleAttachmentFromInvPacket rez = (RezSingleAttachmentFromInvPacket)Pack; @@ -5321,7 +5808,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.RezMultipleAttachmentsFromInv: - handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv; + RezMultipleAttachmentsFromInv handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv; if (handlerRezMultipleAttachments != null) { RezMultipleAttachmentsFromInvPacket rez = (RezMultipleAttachmentsFromInvPacket)Pack; @@ -5332,7 +5819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.DetachAttachmentIntoInv: - handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv; + UUIDNameRequest handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv; if (handlerDetachAttachmentIntoInv != null) { DetachAttachmentIntoInvPacket detachtoInv = (DetachAttachmentIntoInvPacket)Pack; @@ -5362,7 +5849,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectAttach = OnObjectAttach; + ObjectAttach handlerObjectAttach = OnObjectAttach; if (handlerObjectAttach != null) { @@ -5389,7 +5876,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int j = 0; j < dett.ObjectData.Length; j++) { uint obj = dett.ObjectData[j].ObjectLocalID; - handlerObjectDetach = OnObjectDetach; + ObjectDeselect handlerObjectDetach = OnObjectDetach; if (handlerObjectDetach != null) { handlerObjectDetach(obj, this); @@ -5413,7 +5900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int j = 0; j < dropp.ObjectData.Length; j++) { uint obj = dropp.ObjectData[j].ObjectLocalID; - handlerObjectDrop = OnObjectDrop; + ObjectDrop handlerObjectDrop = OnObjectDrop; if (handlerObjectDrop != null) { handlerObjectDrop(obj, this); @@ -5433,14 +5920,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSetAlwaysRun = OnSetAlwaysRun; + SetAlwaysRun handlerSetAlwaysRun = OnSetAlwaysRun; if (handlerSetAlwaysRun != null) handlerSetAlwaysRun(this, run.AgentData.AlwaysRun); break; case PacketType.CompleteAgentMovement: - handlerCompleteMovementToRegion = OnCompleteMovementToRegion; + GenericCall2 handlerCompleteMovementToRegion = OnCompleteMovementToRegion; if (handlerCompleteMovementToRegion != null) { handlerCompleteMovementToRegion(); @@ -5509,7 +5996,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP arg.HeadRotation = x.HeadRotation; arg.SessionID = x.SessionID; arg.State = x.State; - handlerAgentUpdate = OnAgentUpdate; + UpdateAgent handlerAgentUpdate = OnAgentUpdate; lastarg = arg; // save this set of arguments for nexttime if (handlerAgentUpdate != null) OnAgentUpdate(this, arg); @@ -5532,8 +6019,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerStartAnim = null; - handlerStopAnim = null; + StartAnim handlerStartAnim = null; + StopAnim handlerStopAnim = null; for (int i = 0; i < AgentAni.AnimationList.Length; i++) { @@ -5570,7 +6057,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerAgentRequestSit = OnAgentRequestSit; + AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; if (handlerAgentRequestSit != null) handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); @@ -5591,7 +6078,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerAgentSit = OnAgentSit; + AgentSit handlerAgentSit = OnAgentSit; if (handlerAgentSit != null) { OnAgentSit(this, agentSit.AgentData.AgentID); @@ -5609,7 +6096,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSoundTrigger = OnSoundTrigger; + SoundTrigger handlerSoundTrigger = OnSoundTrigger; if (handlerSoundTrigger != null) { handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, soundTriggerPacket.SoundData.OwnerID, @@ -5636,7 +6123,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AvatarPickerRequestPacket.DataBlock querydata = avRequestQuery.Data; //m_log.Debug("Agent Sends:" + Utils.BytesToString(querydata.Name)); - handlerAvatarPickerRequest = OnAvatarPickerRequest; + AvatarPickerRequest handlerAvatarPickerRequest = OnAvatarPickerRequest; if (handlerAvatarPickerRequest != null) { handlerAvatarPickerRequest(this, Requestdata.AgentID, Requestdata.QueryID, @@ -5656,7 +6143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerAgentDataUpdateRequest = OnAgentDataUpdateRequest; + FetchInventory handlerAgentDataUpdateRequest = OnAgentDataUpdateRequest; if (handlerAgentDataUpdateRequest != null) { @@ -5666,7 +6153,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.UserInfoRequest: - handlerUserInfoRequest = OnUserInfoRequest; + UserInfoRequest handlerUserInfoRequest = OnUserInfoRequest; if (handlerUserInfoRequest != null) { handlerUserInfoRequest(this); @@ -5689,7 +6176,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdateUserInfo = OnUpdateUserInfo; + UpdateUserInfo handlerUpdateUserInfo = OnUpdateUserInfo; if (handlerUpdateUserInfo != null) { bool visible = true; @@ -5718,7 +6205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (avSetStartLocationRequestPacket.AgentData.AgentID == AgentId && avSetStartLocationRequestPacket.AgentData.SessionID == SessionId) { - handlerSetStartLocationRequest = OnSetStartLocationRequest; + TeleportLocationRequest handlerSetStartLocationRequest = OnSetStartLocationRequest; if (handlerSetStartLocationRequest != null) { handlerSetStartLocationRequest(this, 0, avSetStartLocationRequestPacket.StartLocationData.LocationPos, @@ -5740,7 +6227,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - m_PacketHandler.PacketQueue.SetThrottleFromClient(atpack.Throttle.Throttles); + m_udpClient.SetThrottles(atpack.Throttle.Throttles); break; case PacketType.AgentPause: @@ -5756,7 +6243,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.ForceScriptControlRelease: - handlerForceReleaseControls = OnForceReleaseControls; + ForceReleaseControls handlerForceReleaseControls = OnForceReleaseControls; if (handlerForceReleaseControls != null) { handlerForceReleaseControls(this, AgentId); @@ -5790,7 +6277,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP childrenprims.Add(link.ObjectData[i].ObjectLocalID); } } - handlerLinkObjects = OnLinkObjects; + LinkObjects handlerLinkObjects = OnLinkObjects; if (handlerLinkObjects != null) { handlerLinkObjects(this, parentprimid, childrenprims); @@ -5818,7 +6305,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { prims.Add(delink.ObjectData[i].ObjectLocalID); } - handlerDelinkObjects = OnDelinkObjects; + DelinkObjects handlerDelinkObjects = OnDelinkObjects; if (handlerDelinkObjects != null) { handlerDelinkObjects(prims); @@ -5850,7 +6337,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //Check to see if adding the prim is allowed; useful for any module wanting to restrict the //object from rezing initially - handlerAddPrim = OnAddPrim; + AddNewPrim handlerAddPrim = OnAddPrim; if (handlerAddPrim != null) handlerAddPrim(AgentId, ActiveGroupId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape, addPacket.ObjectData.BypassRaycast, addPacket.ObjectData.RayStart, addPacket.ObjectData.RayTargetID, addPacket.ObjectData.RayEndIsIntersection); } @@ -5868,7 +6355,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdatePrimShape = null; + UpdateShape handlerUpdatePrimShape = null; for (int i = 0; i < shapePacket.ObjectData.Length; i++) { handlerUpdatePrimShape = OnUpdatePrimShape; @@ -5913,7 +6400,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdateExtraParams = OnUpdateExtraParams; + ObjectExtraParams handlerUpdateExtraParams = OnUpdateExtraParams; if (handlerUpdateExtraParams != null) { for (int i = 0 ; i < extraPar.ObjectData.Length ; i++) @@ -5938,7 +6425,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectDuplicatePacket.AgentDataBlock AgentandGroupData = dupe.AgentData; - handlerObjectDuplicate = null; + ObjectDuplicate handlerObjectDuplicate = null; for (int i = 0; i < dupe.ObjectData.Length; i++) { @@ -5965,7 +6452,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectRequest = null; + ObjectRequest handlerObjectRequest = null; for (int i = 0; i < incomingRequest.ObjectData.Length; i++) { @@ -5988,7 +6475,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectSelect = null; + ObjectSelect handlerObjectSelect = null; for (int i = 0; i < incomingselect.ObjectData.Length; i++) { @@ -6011,7 +6498,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectDeselect = null; + ObjectDeselect handlerObjectDeselect = null; for (int i = 0; i < incomingdeselect.ObjectData.Length; i++) { @@ -6038,7 +6525,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < position.ObjectData.Length; i++) { - handlerUpdateVector = OnUpdatePrimGroupPosition; + UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; if (handlerUpdateVector != null) handlerUpdateVector(position.ObjectData[i].ObjectLocalID, position.ObjectData[i].Position, this); } @@ -6059,7 +6546,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < scale.ObjectData.Length; i++) { - handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; + UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; if (handlerUpdatePrimGroupScale != null) handlerUpdatePrimGroupScale(scale.ObjectData[i].ObjectLocalID, scale.ObjectData[i].Scale, this); } @@ -6080,7 +6567,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < rotation.ObjectData.Length; i++) { - handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; + UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; if (handlerUpdatePrimRotation != null) handlerUpdatePrimRotation(rotation.ObjectData[i].ObjectLocalID, rotation.ObjectData[i].Rotation, this); } @@ -6098,7 +6585,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdatePrimFlags = OnUpdatePrimFlags; + UpdatePrimFlags handlerUpdatePrimFlags = OnUpdatePrimFlags; if (handlerUpdatePrimFlags != null) { @@ -6115,7 +6602,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ObjectImage: ObjectImagePacket imagePack = (ObjectImagePacket)Pack; - handlerUpdatePrimTexture = null; + UpdatePrimTexture handlerUpdatePrimTexture = null; for (int i = 0; i < imagePack.ObjectData.Length; i++) { handlerUpdatePrimTexture = OnUpdatePrimTexture; @@ -6138,7 +6625,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerGrabObject = OnGrabObject; + GrabObject handlerGrabObject = OnGrabObject; if (handlerGrabObject != null) { @@ -6172,7 +6659,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerGrabUpdate = OnGrabUpdate; + MoveObject handlerGrabUpdate = OnGrabUpdate; if (handlerGrabUpdate != null) { @@ -6207,7 +6694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDeGrabObject = OnDeGrabObject; + DeGrabObject handlerDeGrabObject = OnDeGrabObject; if (handlerDeGrabObject != null) { List touchArgs = new List(); @@ -6241,7 +6728,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSpinStart = OnSpinStart; + SpinStart handlerSpinStart = OnSpinStart; if (handlerSpinStart != null) { handlerSpinStart(spinStart.ObjectData.ObjectID, this); @@ -6265,7 +6752,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP spinUpdate.ObjectData.Rotation.GetAxisAngle(out axis, out angle); //m_log.Warn("[CLIENT]: ObjectSpinUpdate packet rot axis:" + axis + " angle:" + angle); - handlerSpinUpdate = OnSpinUpdate; + SpinObject handlerSpinUpdate = OnSpinUpdate; if (handlerSpinUpdate != null) { handlerSpinUpdate(spinUpdate.ObjectData.ObjectID, spinUpdate.ObjectData.Rotation, this); @@ -6284,7 +6771,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSpinStop = OnSpinStop; + SpinStop handlerSpinStop = OnSpinStop; if (handlerSpinStop != null) { handlerSpinStop(spinStop.ObjectData.ObjectID, this); @@ -6303,7 +6790,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectDescription = null; + GenericCall7 handlerObjectDescription = null; for (int i = 0; i < objDes.ObjectData.Length; i++) { @@ -6327,7 +6814,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectName = null; + GenericCall7 handlerObjectName = null; for (int i = 0; i < objName.ObjectData.Length; i++) { handlerObjectName = OnObjectName; @@ -6355,7 +6842,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID AgentID = newobjPerms.AgentData.AgentID; UUID SessionID = newobjPerms.AgentData.SessionID; - handlerObjectPermissions = null; + ObjectPermissions handlerObjectPermissions = null; for (int i = 0; i < newobjPerms.ObjectData.Length; i++) { @@ -6404,7 +6891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < undoitem.ObjectData.Length; i++) { UUID objiD = undoitem.ObjectData[i].ObjectID; - handlerOnUndo = OnUndo; + AgentSit handlerOnUndo = OnUndo; if (handlerOnUndo != null) { handlerOnUndo(this, objiD); @@ -6425,8 +6912,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectDuplicateOnRay = null; - + ObjectDuplicateOnRay handlerObjectDuplicateOnRay = null; for (int i = 0; i < dupeOnRay.ObjectData.Length; i++) { @@ -6456,7 +6942,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP RequestObjectPropertiesFamilyPacket.ObjectDataBlock packObjBlock = packToolTip.ObjectData; - handlerRequestObjectPropertiesFamily = OnRequestObjectPropertiesFamily; + RequestObjectPropertiesFamily handlerRequestObjectPropertiesFamily = OnRequestObjectPropertiesFamily; if (handlerRequestObjectPropertiesFamily != null) { @@ -6468,7 +6954,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ObjectIncludeInSearch: //This lets us set objects to appear in search (stuff like DataSnapshot, etc) ObjectIncludeInSearchPacket packInSearch = (ObjectIncludeInSearchPacket)Pack; - handlerObjectIncludeInSearch = null; + ObjectIncludeInSearch handlerObjectIncludeInSearch = null; #region Packet Session and User Check if (m_checkPackets) @@ -6505,7 +6991,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerScriptAnswer = OnScriptAnswer; + ScriptAnswer handlerScriptAnswer = OnScriptAnswer; if (handlerScriptAnswer != null) { handlerScriptAnswer(this, scriptAnswer.Data.TaskID, scriptAnswer.Data.ItemID, scriptAnswer.Data.Questions); @@ -6524,7 +7010,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectClickAction = OnObjectClickAction; + GenericCall7 handlerObjectClickAction = OnObjectClickAction; if (handlerObjectClickAction != null) { foreach (ObjectClickActionPacket.ObjectDataBlock odata in ocpacket.ObjectData) @@ -6548,7 +7034,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectMaterial = OnObjectMaterial; + GenericCall7 handlerObjectMaterial = OnObjectMaterial; if (handlerObjectMaterial != null) { foreach (ObjectMaterialPacket.ObjectDataBlock odata in ompacket.ObjectData) @@ -6702,7 +7188,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // m_log.Debug("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionId).ToString()); UUID temp = UUID.Combine(request.AssetBlock.TransactionID, SecureSessionId); - handlerAssetUploadRequest = OnAssetUploadRequest; + UDPAssetUploadRequest handlerAssetUploadRequest = OnAssetUploadRequest; if (handlerAssetUploadRequest != null) { @@ -6715,7 +7201,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RequestXfer: RequestXferPacket xferReq = (RequestXferPacket)Pack; - handlerRequestXfer = OnRequestXfer; + RequestXfer handlerRequestXfer = OnRequestXfer; if (handlerRequestXfer != null) { @@ -6725,7 +7211,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.SendXferPacket: SendXferPacketPacket xferRec = (SendXferPacketPacket)Pack; - handlerXferReceive = OnXferReceive; + XferReceive handlerXferReceive = OnXferReceive; if (handlerXferReceive != null) { handlerXferReceive(this, xferRec.XferID.ID, xferRec.XferID.Packet, xferRec.DataPacket.Data); @@ -6734,7 +7220,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ConfirmXferPacket: ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket)Pack; - handlerConfirmXfer = OnConfirmXfer; + ConfirmXfer handlerConfirmXfer = OnConfirmXfer; if (handlerConfirmXfer != null) { handlerConfirmXfer(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet); @@ -6742,7 +7228,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.AbortXfer: AbortXferPacket abortXfer = (AbortXferPacket)Pack; - handlerAbortXfer = OnAbortXfer; + AbortXfer handlerAbortXfer = OnAbortXfer; if (handlerAbortXfer != null) { handlerAbortXfer(this, abortXfer.XferID.ID); @@ -6761,7 +7247,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerCreateInventoryFolder = OnCreateNewInventoryFolder; + CreateInventoryFolder handlerCreateInventoryFolder = OnCreateNewInventoryFolder; if (handlerCreateInventoryFolder != null) { handlerCreateInventoryFolder(this, invFolder.FolderData.FolderID, @@ -6784,7 +7270,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdateInventoryFolder = null; + UpdateInventoryFolder handlerUpdateInventoryFolder = null; for (int i = 0; i < invFolderx.FolderData.Length; i++) { @@ -6813,7 +7299,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerMoveInventoryFolder = null; + MoveInventoryFolder handlerMoveInventoryFolder = null; for (int i = 0; i < invFoldery.InventoryData.Length; i++) { @@ -6838,7 +7324,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerCreateNewInventoryItem = OnCreateNewInventoryItem; + CreateNewInventoryItem handlerCreateNewInventoryItem = OnCreateNewInventoryItem; if (handlerCreateNewInventoryItem != null) { handlerCreateNewInventoryItem(this, createItem.InventoryBlock.TransactionID, @@ -6867,7 +7353,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerFetchInventory = null; + FetchInventory handlerFetchInventory = null; for (int i = 0; i < FetchInventoryx.InventoryData.Length; i++) { @@ -6893,7 +7379,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerFetchInventoryDescendents = OnFetchInventoryDescendents; + FetchInventoryDescendents handlerFetchInventoryDescendents = OnFetchInventoryDescendents; if (handlerFetchInventoryDescendents != null) { handlerFetchInventoryDescendents(this, Fetch.InventoryData.FolderID, Fetch.InventoryData.OwnerID, @@ -6913,7 +7399,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerPurgeInventoryDescendents = OnPurgeInventoryDescendents; + PurgeInventoryDescendents handlerPurgeInventoryDescendents = OnPurgeInventoryDescendents; if (handlerPurgeInventoryDescendents != null) { handlerPurgeInventoryDescendents(this, Purge.InventoryData.FolderID); @@ -6933,7 +7419,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnUpdateInventoryItem != null) { - handlerUpdateInventoryItem = null; + UpdateInventoryItem handlerUpdateInventoryItem = null; for (int i = 0; i < inventoryItemUpdate.InventoryData.Length; i++) { handlerUpdateInventoryItem = OnUpdateInventoryItem; @@ -6955,49 +7441,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP itemUpd.SalePrice = inventoryItemUpdate.InventoryData[i].SalePrice; itemUpd.SaleType = inventoryItemUpdate.InventoryData[i].SaleType; itemUpd.Flags = inventoryItemUpdate.InventoryData[i].Flags; - /* - OnUpdateInventoryItem(this, inventoryItemUpdate.InventoryData[i].TransactionID, - inventoryItemUpdate.InventoryData[i].ItemID, - Util.FieldToString(inventoryItemUpdate.InventoryData[i].Name), - Util.FieldToString(inventoryItemUpdate.InventoryData[i].Description), - inventoryItemUpdate.InventoryData[i].NextOwnerMask); - */ + OnUpdateInventoryItem(this, inventoryItemUpdate.InventoryData[i].TransactionID, inventoryItemUpdate.InventoryData[i].ItemID, itemUpd); } } } - //m_log.Debug(Pack.ToString()); - /*for (int i = 0; i < inventoryItemUpdate.InventoryData.Length; i++) - { - if (inventoryItemUpdate.InventoryData[i].TransactionID != UUID.Zero) - { - AssetBase asset = m_assetCache.GetAsset(inventoryItemUpdate.InventoryData[i].TransactionID.Combine(this.SecureSessionId)); - if (asset != null) - { - // m_log.Debug("updating inventory item, found asset" + asset.FullID.ToString() + " already in cache"); - m_inventoryCache.UpdateInventoryItemAsset(this, inventoryItemUpdate.InventoryData[i].ItemID, asset); - } - else - { - asset = this.UploadAssets.AddUploadToAssetCache(inventoryItemUpdate.InventoryData[i].TransactionID); - if (asset != null) - { - //m_log.Debug("updating inventory item, adding asset" + asset.FullID.ToString() + " to cache"); - m_inventoryCache.UpdateInventoryItemAsset(this, inventoryItemUpdate.InventoryData[i].ItemID, asset); - } - else - { - //m_log.Debug("trying to update inventory item, but asset is null"); - } - } - } - else - { - m_inventoryCache.UpdateInventoryItemDetails(this, inventoryItemUpdate.InventoryData[i].ItemID, inventoryItemUpdate.InventoryData[i]); ; - } - }*/ break; case PacketType.CopyInventoryItem: CopyInventoryItemPacket copyitem = (CopyInventoryItemPacket)Pack; @@ -7011,7 +7461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerCopyInventoryItem = null; + CopyInventoryItem handlerCopyInventoryItem = null; if (OnCopyInventoryItem != null) { foreach (CopyInventoryItemPacket.InventoryDataBlock datablock in copyitem.InventoryData) @@ -7040,7 +7490,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnMoveInventoryItem != null) { - handlerMoveInventoryItem = null; + MoveInventoryItem handlerMoveInventoryItem = null; InventoryItemBase itm = null; List items = new List(); foreach (MoveInventoryItemPacket.InventoryDataBlock datablock in moveitem.InventoryData) @@ -7073,7 +7523,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryItem != null) { - handlerRemoveInventoryItem = null; + RemoveInventoryItem handlerRemoveInventoryItem = null; List uuids = new List(); foreach (RemoveInventoryItemPacket.InventoryDataBlock datablock in removeItem.InventoryData) { @@ -7101,7 +7551,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryFolder != null) { - handlerRemoveInventoryFolder = null; + RemoveInventoryFolder handlerRemoveInventoryFolder = null; List uuids = new List(); foreach (RemoveInventoryFolderPacket.FolderDataBlock datablock in removeFolder.FolderData) { @@ -7126,7 +7576,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion if (OnRemoveInventoryFolder != null) { - handlerRemoveInventoryFolder = null; + RemoveInventoryFolder handlerRemoveInventoryFolder = null; List uuids = new List(); foreach (RemoveInventoryObjectsPacket.FolderDataBlock datablock in removeObject.FolderData) { @@ -7141,7 +7591,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryItem != null) { - handlerRemoveInventoryItem = null; + RemoveInventoryItem handlerRemoveInventoryItem = null; List uuids = new List(); foreach (RemoveInventoryObjectsPacket.ItemDataBlock datablock in removeObject.ItemData) { @@ -7166,7 +7616,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRequestTaskInventory = OnRequestTaskInventory; + RequestTaskInventory handlerRequestTaskInventory = OnRequestTaskInventory; if (handlerRequestTaskInventory != null) { handlerRequestTaskInventory(this, requesttask.InventoryData.LocalID); @@ -7188,7 +7638,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (updatetask.UpdateData.Key == 0) { - handlerUpdateTaskInventory = OnUpdateTaskInventory; + UpdateTaskInventory handlerUpdateTaskInventory = OnUpdateTaskInventory; if (handlerUpdateTaskInventory != null) { TaskInventoryItem newTaskItem = new TaskInventoryItem(); @@ -7232,7 +7682,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRemoveTaskItem = OnRemoveTaskItem; + RemoveTaskInventory handlerRemoveTaskItem = OnRemoveTaskItem; if (handlerRemoveTaskItem != null) { @@ -7254,7 +7704,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerMoveTaskItem = OnMoveTaskItem; + MoveTaskInventory handlerMoveTaskItem = OnMoveTaskItem; if (handlerMoveTaskItem != null) { @@ -7279,7 +7729,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRezScript = OnRezScript; + RezScript handlerRezScript = OnRezScript; InventoryItemBase item = new InventoryItemBase(); item.ID = rezScriptx.InventoryBlock.ItemID; item.Folder = rezScriptx.InventoryBlock.FolderID; @@ -7322,7 +7772,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRequestMapBlocks = OnRequestMapBlocks; + RequestMapBlocks handlerRequestMapBlocks = OnRequestMapBlocks; if (handlerRequestMapBlocks != null) { handlerRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, @@ -7343,7 +7793,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP string mapName = Util.UTF8.GetString(map.NameData.Name, 0, map.NameData.Name.Length - 1); - handlerMapNameRequest = OnMapNameRequest; + RequestMapName handlerMapNameRequest = OnMapNameRequest; if (handlerMapNameRequest != null) { handlerMapNameRequest(this, mapName); @@ -7394,7 +7844,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { // Teleport home request - handlerTeleportHomeRequest = OnTeleportHomeRequest; + UUIDNameRequest handlerTeleportHomeRequest = OnTeleportHomeRequest; if (handlerTeleportHomeRequest != null) { handlerTeleportHomeRequest(AgentId, this); @@ -7402,7 +7852,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; } - handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; + TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; if (handlerTeleportLandmarkRequest != null) { handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position); @@ -7433,7 +7883,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerTeleportLocationRequest = OnTeleportLocationRequest; + TeleportLocationRequest handlerTeleportLocationRequest = OnTeleportLocationRequest; if (handlerTeleportLocationRequest != null) { handlerTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position, @@ -7456,7 +7906,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock) { - handlerNameRequest = OnNameFromUUIDRequest; + UUIDNameRequest handlerNameRequest = OnNameFromUUIDRequest; if (handlerNameRequest != null) { handlerNameRequest(UUIDBlock.ID, this); @@ -7469,7 +7919,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RegionHandleRequest: RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; - handlerRegionHandleRequest = OnRegionHandleRequest; + RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; if (handlerRegionHandleRequest != null) { handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); @@ -7488,7 +7938,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelInfoRequest = OnParcelInfoRequest; + ParcelInfoRequest handlerParcelInfoRequest = OnParcelInfoRequest; if (handlerParcelInfoRequest != null) { handlerParcelInfoRequest(this, pirPack.Data.ParcelID); @@ -7507,7 +7957,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelAccessListRequest = OnParcelAccessListRequest; + ParcelAccessListRequest handlerParcelAccessListRequest = OnParcelAccessListRequest; if (handlerParcelAccessListRequest != null) { @@ -7539,7 +7989,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP entries.Add(entry); } - handlerParcelAccessListUpdateRequest = OnParcelAccessListUpdateRequest; + ParcelAccessListUpdateRequest handlerParcelAccessListUpdateRequest = OnParcelAccessListUpdateRequest; if (handlerParcelAccessListUpdateRequest != null) { handlerParcelAccessListUpdateRequest(updatePacket.AgentData.AgentID, @@ -7560,7 +8010,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelPropertiesRequest = OnParcelPropertiesRequest; + ParcelPropertiesRequest handlerParcelPropertiesRequest = OnParcelPropertiesRequest; if (handlerParcelPropertiesRequest != null) { handlerParcelPropertiesRequest((int)Math.Round(propertiesRequest.ParcelData.West), @@ -7583,7 +8033,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelDivideRequest = OnParcelDivideRequest; + ParcelDivideRequest handlerParcelDivideRequest = OnParcelDivideRequest; if (handlerParcelDivideRequest != null) { handlerParcelDivideRequest((int)Math.Round(landDivide.ParcelData.West), @@ -7604,7 +8054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelJoinRequest = OnParcelJoinRequest; + ParcelJoinRequest handlerParcelJoinRequest = OnParcelJoinRequest; if (handlerParcelJoinRequest != null) { @@ -7626,7 +8076,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelPropertiesUpdateRequest = OnParcelPropertiesUpdateRequest; + ParcelPropertiesUpdateRequest handlerParcelPropertiesUpdateRequest = OnParcelPropertiesUpdateRequest; if (handlerParcelPropertiesUpdateRequest != null) { @@ -7672,7 +8122,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP returnIDs.Add(rb.ReturnID); } - handlerParcelSelectObjects = OnParcelSelectObjects; + ParcelSelectObjects handlerParcelSelectObjects = OnParcelSelectObjects; if (handlerParcelSelectObjects != null) { @@ -7693,7 +8143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelObjectOwnerRequest = OnParcelObjectOwnerRequest; + ParcelObjectOwnerRequest handlerParcelObjectOwnerRequest = OnParcelObjectOwnerRequest; if (handlerParcelObjectOwnerRequest != null) { @@ -7712,7 +8162,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelGodForceOwner = OnParcelGodForceOwner; + ParcelGodForceOwner handlerParcelGodForceOwner = OnParcelGodForceOwner; if (handlerParcelGodForceOwner != null) { handlerParcelGodForceOwner(godForceOwnerPacket.Data.LocalID, godForceOwnerPacket.Data.OwnerID, this); @@ -7730,7 +8180,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelAbandonRequest = OnParcelAbandonRequest; + ParcelAbandonRequest handlerParcelAbandonRequest = OnParcelAbandonRequest; if (handlerParcelAbandonRequest != null) { handlerParcelAbandonRequest(releasePacket.Data.LocalID, this); @@ -7748,7 +8198,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelReclaim = OnParcelReclaim; + ParcelReclaim handlerParcelReclaim = OnParcelReclaim; if (handlerParcelReclaim != null) { handlerParcelReclaim(reclaimPacket.Data.LocalID, this); @@ -7777,7 +8227,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int parceliterator = 0; parceliterator < parcelReturnObjects.TaskIDs.Length; parceliterator++) puserselectedTaskIDs[parceliterator] = parcelReturnObjects.TaskIDs[parceliterator].TaskID; - handlerParcelReturnObjectsRequest = OnParcelReturnObjectsRequest; + ParcelReturnObjectsRequest handlerParcelReturnObjectsRequest = OnParcelReturnObjectsRequest; if (handlerParcelReturnObjectsRequest != null) { handlerParcelReturnObjectsRequest(parcelReturnObjects.ParcelData.LocalID, parcelReturnObjects.ParcelData.ReturnType, puserselectedOwnerIDs, puserselectedTaskIDs, this); @@ -7797,7 +8247,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelSetOtherCleanTime = OnParcelSetOtherCleanTime; + ParcelSetOtherCleanTime handlerParcelSetOtherCleanTime = OnParcelSetOtherCleanTime; if (handlerParcelSetOtherCleanTime != null) { handlerParcelSetOtherCleanTime(this, @@ -7818,7 +8268,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerLandStatRequest = OnLandStatRequest; + GodLandStatRequest handlerLandStatRequest = OnLandStatRequest; if (handlerLandStatRequest != null) { handlerLandStatRequest(lsrp.RequestData.ParcelLocalID, lsrp.RequestData.ReportType, lsrp.RequestData.RequestFlags, Utils.BytesToString(lsrp.RequestData.Filter), this); @@ -7838,7 +8288,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelDwellRequest = OnParcelDwellRequest; + ParcelDwellRequest handlerParcelDwellRequest = OnParcelDwellRequest; if (handlerParcelDwellRequest != null) { handlerParcelDwellRequest(dwellrq.Data.LocalID, this); @@ -8082,7 +8532,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (Utils.BytesToString(messagePacket.ParamList[0].Parameter) == "bake") { - handlerBakeTerrain = OnBakeTerrain; + BakeTerrain handlerBakeTerrain = OnBakeTerrain; if (handlerBakeTerrain != null) { handlerBakeTerrain(this); @@ -8092,7 +8542,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (messagePacket.ParamList.Length > 1) { - handlerRequestTerrain = OnRequestTerrain; + RequestTerrain handlerRequestTerrain = OnRequestTerrain; if (handlerRequestTerrain != null) { handlerRequestTerrain(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter)); @@ -8103,7 +8553,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (messagePacket.ParamList.Length > 1) { - handlerUploadTerrain = OnUploadTerrain; + RequestTerrain handlerUploadTerrain = OnUploadTerrain; if (handlerUploadTerrain != null) { handlerUploadTerrain(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter)); @@ -8125,7 +8575,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UInt32 param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter)); UInt32 param2 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[2].Parameter)); - handlerEstateChangeInfo = OnEstateChangeInfo; + EstateChangeInfo handlerEstateChangeInfo = OnEstateChangeInfo; if (handlerEstateChangeInfo != null) { handlerEstateChangeInfo(this, invoice, SenderID, param1, param2); @@ -8159,7 +8609,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRegionInfoRequest = OnRegionInfoRequest; + RegionInfoRequest handlerRegionInfoRequest = OnRegionInfoRequest; if (handlerRegionInfoRequest != null) { handlerRegionInfoRequest(this); @@ -8170,7 +8620,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //EstateCovenantRequestPacket.AgentDataBlock epack = // ((EstateCovenantRequestPacket)Pack).AgentData; - handlerEstateCovenantRequest = OnEstateCovenantRequest; + EstateCovenantRequest handlerEstateCovenantRequest = OnEstateCovenantRequest; if (handlerEstateCovenantRequest != null) { handlerEstateCovenantRequest(this); @@ -8188,7 +8638,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP RequestGodlikePowersPacket.AgentDataBlock ablock = rglpPack.AgentData; - handlerReqGodlikePowers = OnRequestGodlikePowers; + RequestGodlikePowers handlerReqGodlikePowers = OnRequestGodlikePowers; if (handlerReqGodlikePowers != null) { @@ -8201,7 +8651,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (gkupack.UserInfo.GodSessionID == SessionId && AgentId == gkupack.UserInfo.GodID) { - handlerGodKickUser = OnGodKickUser; + GodKickUser handlerGodKickUser = OnGodKickUser; if (handlerGodKickUser != null) { handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID, @@ -8241,7 +8691,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerMoneyBalanceRequest = OnMoneyBalanceRequest; + MoneyBalanceRequest handlerMoneyBalanceRequest = OnMoneyBalanceRequest; if (handlerMoneyBalanceRequest != null) { @@ -8252,7 +8702,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.EconomyDataRequest: - handlerEconomoyDataRequest = OnEconomyDataRequest; + EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; if (handlerEconomoyDataRequest != null) { handlerEconomoyDataRequest(AgentId); @@ -8261,7 +8711,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RequestPayPrice: RequestPayPricePacket requestPayPricePacket = (RequestPayPricePacket)Pack; - handlerRequestPayPrice = OnRequestPayPrice; + RequestPayPrice handlerRequestPayPrice = OnRequestPayPrice; if (handlerRequestPayPrice != null) { handlerRequestPayPrice(this, requestPayPricePacket.ObjectData.ObjectID); @@ -8280,7 +8730,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectSaleInfo = OnObjectSaleInfo; + ObjectSaleInfo handlerObjectSaleInfo = OnObjectSaleInfo; if (handlerObjectSaleInfo != null) { foreach (ObjectSaleInfoPacket.ObjectDataBlock d @@ -8308,7 +8758,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectBuy = OnObjectBuy; + ObjectBuy handlerObjectBuy = OnObjectBuy; if (handlerObjectBuy != null) { @@ -8334,7 +8784,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.GetScriptRunning: GetScriptRunningPacket scriptRunning = (GetScriptRunningPacket)Pack; - handlerGetScriptRunning = OnGetScriptRunning; + GetScriptRunning handlerGetScriptRunning = OnGetScriptRunning; if (handlerGetScriptRunning != null) { handlerGetScriptRunning(this, scriptRunning.Script.ObjectID, scriptRunning.Script.ItemID); @@ -8353,7 +8803,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSetScriptRunning = OnSetScriptRunning; + SetScriptRunning handlerSetScriptRunning = OnSetScriptRunning; if (handlerSetScriptRunning != null) { handlerSetScriptRunning(this, setScriptRunning.Script.ObjectID, setScriptRunning.Script.ItemID, setScriptRunning.Script.Running); @@ -8372,7 +8822,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerScriptReset = OnScriptReset; + ScriptReset handlerScriptReset = OnScriptReset; if (handlerScriptReset != null) { handlerScriptReset(this, scriptResetPacket.Script.ObjectID, scriptResetPacket.Script.ItemID); @@ -8395,7 +8845,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerActivateGesture = OnActivateGesture; + ActivateGesture handlerActivateGesture = OnActivateGesture; if (handlerActivateGesture != null) { handlerActivateGesture(this, @@ -8418,7 +8868,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDeactivateGesture = OnDeactivateGesture; + DeactivateGesture handlerDeactivateGesture = OnDeactivateGesture; if (handlerDeactivateGesture != null) { handlerDeactivateGesture(this, deactivateGesturePacket.Data[0].ItemID); @@ -8441,7 +8891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP foreach (ObjectOwnerPacket.ObjectDataBlock d in objectOwnerPacket.ObjectData) localIDs.Add(d.ObjectLocalID); - handlerObjectOwner = OnObjectOwner; + ObjectOwner handlerObjectOwner = OnObjectOwner; if (handlerObjectOwner != null) { handlerObjectOwner(this, objectOwnerPacket.HeaderData.OwnerID, objectOwnerPacket.HeaderData.GroupID, localIDs); @@ -8482,7 +8932,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion //m_log.Debug(mirpk.ToString()); - handlerMapItemRequest = OnMapItemRequest; + MapItemRequest handlerMapItemRequest = OnMapItemRequest; if (handlerMapItemRequest != null) { handlerMapItemRequest(this,mirpk.AgentData.Flags, mirpk.AgentData.EstateID, @@ -8509,7 +8959,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerMuteListRequest = OnMuteListRequest; + MuteListRequest handlerMuteListRequest = OnMuteListRequest; if (handlerMuteListRequest != null) { handlerMuteListRequest(this, muteListRequest.MuteData.MuteCRC); @@ -8546,7 +8996,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirPlacesQuery = OnDirPlacesQuery; + DirPlacesQuery handlerDirPlacesQuery = OnDirPlacesQuery; if (handlerDirPlacesQuery != null) { handlerDirPlacesQuery(this, @@ -8572,7 +9022,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirFindQuery = OnDirFindQuery; + DirFindQuery handlerDirFindQuery = OnDirFindQuery; if (handlerDirFindQuery != null) { handlerDirFindQuery(this, @@ -8595,7 +9045,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirLandQuery = OnDirLandQuery; + DirLandQuery handlerDirLandQuery = OnDirLandQuery; if (handlerDirLandQuery != null) { handlerDirLandQuery(this, @@ -8619,7 +9069,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirPopularQuery = OnDirPopularQuery; + DirPopularQuery handlerDirPopularQuery = OnDirPopularQuery; if (handlerDirPopularQuery != null) { handlerDirPopularQuery(this, @@ -8639,7 +9089,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirClassifiedQuery = OnDirClassifiedQuery; + DirClassifiedQuery handlerDirClassifiedQuery = OnDirClassifiedQuery; if (handlerDirClassifiedQuery != null) { handlerDirClassifiedQuery(this, @@ -9155,7 +9605,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelDeedToGroupPacket parcelDeedToGroup = (ParcelDeedToGroupPacket)Pack; if (m_GroupsModule != null) { - handlerParcelDeedToGroup = OnParcelDeedToGroup; + ParcelDeedToGroup handlerParcelDeedToGroup = OnParcelDeedToGroup; if (handlerParcelDeedToGroup != null) { handlerParcelDeedToGroup(parcelDeedToGroup.Data.LocalID, parcelDeedToGroup.Data.GroupID,this); @@ -9399,7 +9849,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerStartLure = OnStartLure; + StartLure handlerStartLure = OnStartLure; if (handlerStartLure != null) handlerStartLure(startLureRequest.Info.LureType, Utils.BytesToString( @@ -9421,7 +9871,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerTeleportLureRequest = OnTeleportLureRequest; + TeleportLureRequest handlerTeleportLureRequest = OnTeleportLureRequest; if (handlerTeleportLureRequest != null) handlerTeleportLureRequest( teleportLureRequest.Info.LureID, @@ -9442,7 +9892,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerClassifiedInfoRequest = OnClassifiedInfoRequest; + ClassifiedInfoRequest handlerClassifiedInfoRequest = OnClassifiedInfoRequest; if (handlerClassifiedInfoRequest != null) handlerClassifiedInfoRequest( classifiedInfoRequest.Data.ClassifiedID, @@ -9462,7 +9912,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerClassifiedInfoUpdate = OnClassifiedInfoUpdate; + ClassifiedInfoUpdate handlerClassifiedInfoUpdate = OnClassifiedInfoUpdate; if (handlerClassifiedInfoUpdate != null) handlerClassifiedInfoUpdate( classifiedInfoUpdate.Data.ClassifiedID, @@ -9494,7 +9944,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerClassifiedDelete = OnClassifiedDelete; + ClassifiedDelete handlerClassifiedDelete = OnClassifiedDelete; if (handlerClassifiedDelete != null) handlerClassifiedDelete( classifiedDelete.Data.ClassifiedID, @@ -9514,7 +9964,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerClassifiedGodDelete = OnClassifiedGodDelete; + ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; if (handlerClassifiedGodDelete != null) handlerClassifiedGodDelete( classifiedGodDelete.Data.ClassifiedID, @@ -9534,7 +9984,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerEventGodDelete = OnEventGodDelete; + EventGodDelete handlerEventGodDelete = OnEventGodDelete; if (handlerEventGodDelete != null) handlerEventGodDelete( eventGodDelete.EventData.EventID, @@ -9559,7 +10009,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerEventNotificationAddRequest = OnEventNotificationAddRequest; + EventNotificationAddRequest handlerEventNotificationAddRequest = OnEventNotificationAddRequest; if (handlerEventNotificationAddRequest != null) handlerEventNotificationAddRequest( eventNotificationAdd.EventData.EventID, this); @@ -9578,7 +10028,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerEventNotificationRemoveRequest = OnEventNotificationRemoveRequest; + EventNotificationRemoveRequest handlerEventNotificationRemoveRequest = OnEventNotificationRemoveRequest; if (handlerEventNotificationRemoveRequest != null) handlerEventNotificationRemoveRequest( eventNotificationRemove.EventData.EventID, this); @@ -9596,7 +10046,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRetrieveInstantMessages = OnRetrieveInstantMessages; + RetrieveInstantMessages handlerRetrieveInstantMessages = OnRetrieveInstantMessages; if (handlerRetrieveInstantMessages != null) handlerRetrieveInstantMessages(this); break; @@ -9614,7 +10064,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerPickDelete = OnPickDelete; + PickDelete handlerPickDelete = OnPickDelete; if (handlerPickDelete != null) handlerPickDelete(this, pickDelete.Data.PickID); break; @@ -9631,7 +10081,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerPickGodDelete = OnPickGodDelete; + PickGodDelete handlerPickGodDelete = OnPickGodDelete; if (handlerPickGodDelete != null) handlerPickGodDelete(this, pickGodDelete.AgentData.AgentID, @@ -9651,7 +10101,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerPickInfoUpdate = OnPickInfoUpdate; + PickInfoUpdate handlerPickInfoUpdate = OnPickInfoUpdate; if (handlerPickInfoUpdate != null) handlerPickInfoUpdate(this, pickInfoUpdate.Data.PickID, @@ -9676,7 +10126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerAvatarNotesUpdate = OnAvatarNotesUpdate; + AvatarNotesUpdate handlerAvatarNotesUpdate = OnAvatarNotesUpdate; if (handlerAvatarNotesUpdate != null) handlerAvatarNotesUpdate(this, avatarNotesUpdate.Data.TargetID, @@ -9693,7 +10143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP PlacesQueryPacket placesQueryPacket = (PlacesQueryPacket)Pack; - handlerPlacesQuery = OnPlacesQuery; + PlacesQuery handlerPlacesQuery = OnPlacesQuery; if (handlerPlacesQuery != null) handlerPlacesQuery(placesQueryPacket.AgentData.QueryID, @@ -9747,291 +10197,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP //shape.Textures = ntex; return shape; } - - /// - /// Send the client an Estate message blue box pop-down with a single OK button - /// - /// - /// - /// - /// - public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message) - { - if (!ChildAgentStatus()) - SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3())); - - //SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch()); - } - - public void SendLogoutPacket() - { - // I know this is a bit of a hack, however there are times when you don't - // want to send this, but still need to do the rest of the shutdown process - // this method gets called from the packet server.. which makes it practically - // impossible to do any other way. - - if (m_SendLogoutPacketWhenClosing) - { - LogoutReplyPacket logReply = (LogoutReplyPacket)PacketPool.Instance.GetPacket(PacketType.LogoutReply); - // TODO: don't create new blocks if recycling an old packet - logReply.AgentData.AgentID = AgentId; - logReply.AgentData.SessionID = SessionId; - logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; - logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); - logReply.InventoryData[0].ItemID = UUID.Zero; - - OutPacket(logReply, ThrottleOutPacketType.Task); - } - } - - public void SendHealth(float health) - { - HealthMessagePacket healthpacket = (HealthMessagePacket)PacketPool.Instance.GetPacket(PacketType.HealthMessage); - healthpacket.HealthData.Health = health; - OutPacket(healthpacket, ThrottleOutPacketType.Task); - } - - public void SendAgentOnline(UUID[] agentIDs) - { - OnlineNotificationPacket onp = new OnlineNotificationPacket(); - OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length]; - for (int i = 0; i < agentIDs.Length; i++) - { - OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); - onpbl.AgentID = agentIDs[i]; - onpb[i] = onpbl; - } - onp.AgentBlock = onpb; - onp.Header.Reliable = true; - OutPacket(onp, ThrottleOutPacketType.Task); - } - - public void SendAgentOffline(UUID[] agentIDs) - { - OfflineNotificationPacket offp = new OfflineNotificationPacket(); - OfflineNotificationPacket.AgentBlockBlock[] offpb = new OfflineNotificationPacket.AgentBlockBlock[agentIDs.Length]; - for (int i = 0; i < agentIDs.Length; i++) - { - OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); - onpbl.AgentID = agentIDs[i]; - offpb[i] = onpbl; - } - offp.AgentBlock = offpb; - offp.Header.Reliable = true; - OutPacket(offp, ThrottleOutPacketType.Task); - } - - public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, - Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) - { - AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); - avatarSitResponse.SitObject.ID = TargetID; - if (CameraAtOffset != Vector3.Zero) - { - avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset; - avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset; - } - avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook; - avatarSitResponse.SitTransform.AutoPilot = autopilot; - avatarSitResponse.SitTransform.SitPosition = OffsetPos; - avatarSitResponse.SitTransform.SitRotation = SitOrientation; - - OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); - } - - public void SendAdminResponse(UUID Token, uint AdminLevel) - { - GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket(); - GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock(); - GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock(); - - adb.AgentID = AgentId; - adb.SessionID = SessionId; // More security - gdb.GodLevel = (byte)AdminLevel; - gdb.Token = Token; - //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock; - respondPacket.GrantData = gdb; - respondPacket.AgentData = adb; - OutPacket(respondPacket, ThrottleOutPacketType.Task); - } - - public void SendGroupMembership(GroupMembershipData[] GroupMembership) - { - m_groupPowers.Clear(); - - AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket(); - AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[GroupMembership.Length]; - for (int i = 0; i < GroupMembership.Length; i++) - { - m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; - - AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock(); - Group.AcceptNotices = GroupMembership[i].AcceptNotices; - Group.Contribution = GroupMembership[i].Contribution; - Group.GroupID = GroupMembership[i].GroupID; - Group.GroupInsigniaID = GroupMembership[i].GroupPicture; - Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); - Group.GroupPowers = GroupMembership[i].GroupPowers; - Groups[i] = Group; - - - } - Groupupdate.GroupData = Groups; - Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock(); - Groupupdate.AgentData.AgentID = AgentId; - OutPacket(Groupupdate, ThrottleOutPacketType.Task); - - try - { - IEventQueue eq = Scene.RequestModuleInterface(); - if (eq != null) - { - eq.GroupMembership(Groupupdate, this.AgentId); - } - } - catch (Exception ex) - { - m_log.Error("Unable to send group membership data via eventqueue - exception: " + ex.ToString()); - m_log.Warn("sending group membership data via UDP"); - OutPacket(Groupupdate, ThrottleOutPacketType.Task); - } - } - - - public void SendGroupNameReply(UUID groupLLUID, string GroupName) - { - UUIDGroupNameReplyPacket pack = new UUIDGroupNameReplyPacket(); - UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; - UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); - uidnamebloc.ID = groupLLUID; - uidnamebloc.GroupName = Utils.StringToBytes(GroupName); - uidnameblock[0] = uidnamebloc; - pack.UUIDNameBlock = uidnameblock; - OutPacket(pack, ThrottleOutPacketType.Task); - } - - public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia) - { - LandStatReplyPacket lsrp = new LandStatReplyPacket(); - // LandStatReplyPacket.RequestDataBlock lsreqdpb = new LandStatReplyPacket.RequestDataBlock(); - LandStatReplyPacket.ReportDataBlock[] lsrepdba = new LandStatReplyPacket.ReportDataBlock[lsrpia.Length]; - //LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); - // lsrepdb. - lsrp.RequestData.ReportType = reportType; - lsrp.RequestData.RequestFlags = requestFlags; - lsrp.RequestData.TotalObjectCount = resultCount; - for (int i = 0; i < lsrpia.Length; i++) - { - LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); - lsrepdb.LocationX = lsrpia[i].LocationX; - lsrepdb.LocationY = lsrpia[i].LocationY; - lsrepdb.LocationZ = lsrpia[i].LocationZ; - lsrepdb.Score = lsrpia[i].Score; - lsrepdb.TaskID = lsrpia[i].TaskID; - lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; - lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); - lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); - lsrepdba[i] = lsrepdb; - } - lsrp.ReportData = lsrepdba; - OutPacket(lsrp, ThrottleOutPacketType.Task); - } - - public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running) - { - ScriptRunningReplyPacket scriptRunningReply = new ScriptRunningReplyPacket(); - scriptRunningReply.Script.ObjectID = objectID; - scriptRunningReply.Script.ItemID = itemID; - scriptRunningReply.Script.Running = running; - - OutPacket(scriptRunningReply, ThrottleOutPacketType.Task); - } - - public void SendAsset(AssetRequestToClient req) - { - //m_log.Debug("sending asset " + req.RequestAssetID); - TransferInfoPacket Transfer = new TransferInfoPacket(); - Transfer.TransferInfo.ChannelType = 2; - Transfer.TransferInfo.Status = 0; - Transfer.TransferInfo.TargetType = 0; - if (req.AssetRequestSource == 2) - { - Transfer.TransferInfo.Params = new byte[20]; - Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - int assType = req.AssetInf.Type; - Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); - } - else if (req.AssetRequestSource == 3) - { - Transfer.TransferInfo.Params = req.Params; - // Transfer.TransferInfo.Params = new byte[100]; - //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); - } - Transfer.TransferInfo.Size = req.AssetInf.Data.Length; - Transfer.TransferInfo.TransferID = req.TransferRequestID; - Transfer.Header.Zerocoded = true; - OutPacket(Transfer, ThrottleOutPacketType.Asset); - - if (req.NumPackets == 1) - { - TransferPacketPacket TransferPacket = new TransferPacketPacket(); - TransferPacket.TransferData.Packet = 0; - TransferPacket.TransferData.ChannelType = 2; - TransferPacket.TransferData.TransferID = req.TransferRequestID; - TransferPacket.TransferData.Data = req.AssetInf.Data; - TransferPacket.TransferData.Status = 1; - TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, ThrottleOutPacketType.Asset); - } - else - { - int processedLength = 0; - int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; - int packetNumber = 0; - - while (processedLength < req.AssetInf.Data.Length) - { - TransferPacketPacket TransferPacket = new TransferPacketPacket(); - TransferPacket.TransferData.Packet = packetNumber; - TransferPacket.TransferData.ChannelType = 2; - TransferPacket.TransferData.TransferID = req.TransferRequestID; - - int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); - byte[] chunk = new byte[chunkSize]; - Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); - - TransferPacket.TransferData.Data = chunk; - - // 0 indicates more packets to come, 1 indicates last packet - if (req.AssetInf.Data.Length - processedLength > maxChunkSize) - { - TransferPacket.TransferData.Status = 0; - } - else - { - TransferPacket.TransferData.Status = 1; - } - TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, ThrottleOutPacketType.Asset); - - processedLength += chunkSize; - packetNumber++; - } - } - } - - public void SendTexture(AssetBase TextureAsset) - { - - } - + public ClientInfo GetClientInfo() { - ClientInfo info = m_PacketHandler.GetClientInfo(); + ClientInfo info = m_udpClient.GetClientInfo(); info.userEP = m_userEndPoint; - info.proxyEP = m_proxyEndPoint; + info.proxyEP = null; info.agentcircuit = new sAgentCircuitData(RequestClientInfo()); return info; @@ -10044,7 +10216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SetClientInfo(ClientInfo info) { - m_PacketHandler.SetClientInfo(info); + m_udpClient.SetClientInfo(info); } #region Media Parcel Members @@ -10079,7 +10251,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion - #region Camera public void SendSetFollowCamProperties (UUID objectID, SortedDictionary parameters) @@ -10109,70 +10280,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion - public void SendRegionHandle(UUID regionID, ulong handle) { - RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply); - reply.ReplyBlock.RegionID = regionID; - reply.ReplyBlock.RegionHandle = handle; - OutPacket(reply, ThrottleOutPacketType.Land); - } - - public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) - { - ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); - reply.AgentData.AgentID = m_agentId; - reply.Data.ParcelID = parcelID; - reply.Data.OwnerID = land.OwnerID; - reply.Data.Name = Utils.StringToBytes(land.Name); - reply.Data.Desc = Utils.StringToBytes(land.Description); - reply.Data.ActualArea = land.Area; - reply.Data.BillableArea = land.Area; // TODO: what is this? - - // Bit 0: Mature, bit 7: on sale, other bits: no idea - reply.Data.Flags = (byte)( - ((land.Flags & (uint)ParcelFlags.MaturePublish) != 0 ? (1 << 0) : 0) + - ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0)); - - Vector3 pos = land.UserLocation; - if (pos.Equals(Vector3.Zero)) - { - pos = (land.AABBMax + land.AABBMin) * 0.5f; - } - reply.Data.GlobalX = info.RegionLocX * Constants.RegionSize + x; - reply.Data.GlobalY = info.RegionLocY * Constants.RegionSize + y; - reply.Data.GlobalZ = pos.Z; - reply.Data.SimName = Utils.StringToBytes(info.RegionName); - reply.Data.SnapshotID = land.SnapshotID; - reply.Data.Dwell = land.Dwell; - reply.Data.SalePrice = land.SalePrice; - reply.Data.AuctionID = (int)land.AuctionID; - - OutPacket(reply, ThrottleOutPacketType.Land); - } - - public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt) - { - ScriptTeleportRequestPacket packet = (ScriptTeleportRequestPacket)PacketPool.Instance.GetPacket(PacketType.ScriptTeleportRequest); - - packet.Data.ObjectName = Utils.StringToBytes(objName); - packet.Data.SimName = Utils.StringToBytes(simName); - packet.Data.SimPosition = pos; - packet.Data.LookAt = lookAt; - - OutPacket(packet, ThrottleOutPacketType.Task); - } - public void SetClientOption(string option, string value) { switch (option) { - case "ReliableIsImportant": - bool val; - - if (bool.TryParse(value, out val)) - m_PacketHandler.ReliableIsImportant = val; - break; - default: - break; + default: + break; } } @@ -10180,571 +10293,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP { switch (option) { - case "ReliableIsImportant": - return m_PacketHandler.ReliableIsImportant.ToString(); - default: break; } return string.Empty; } - public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data) - { - DirPlacesReplyPacket packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply); - - packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock(); - - packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; - packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); - - packet.QueryReplies = - new DirPlacesReplyPacket.QueryRepliesBlock[data.Length]; - - packet.StatusData = new DirPlacesReplyPacket.StatusDataBlock[ - data.Length]; - - packet.AgentData.AgentID = AgentId; - - packet.QueryData[0].QueryID = queryID; - - int i = 0; - foreach (DirPlacesReplyData d in data) - { - packet.QueryReplies[i] = - new DirPlacesReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirPlacesReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = Utils.StringToBytes(d.name); - packet.QueryReplies[i].ForSale = d.forSale; - packet.QueryReplies[i].Auction = d.auction; - packet.QueryReplies[i].Dwell = d.dwell; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data) - { - DirPeopleReplyPacket packet = (DirPeopleReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPeopleReply); - - packet.AgentData = new DirPeopleReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirPeopleReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirPeopleReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirPeopleReplyData d in data) - { - packet.QueryReplies[i] = new DirPeopleReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].AgentID = d.agentID; - packet.QueryReplies[i].FirstName = - Utils.StringToBytes(d.firstName); - packet.QueryReplies[i].LastName = - Utils.StringToBytes(d.lastName); - packet.QueryReplies[i].Group = - Utils.StringToBytes(d.group); - packet.QueryReplies[i].Online = d.online; - packet.QueryReplies[i].Reputation = d.reputation; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data) - { - DirEventsReplyPacket packet = (DirEventsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirEventsReply); - - packet.AgentData = new DirEventsReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirEventsReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirEventsReplyPacket.QueryRepliesBlock[ - data.Length]; - - packet.StatusData = new DirEventsReplyPacket.StatusDataBlock[ - data.Length]; - - int i = 0; - foreach (DirEventsReplyData d in data) - { - packet.QueryReplies[i] = new DirEventsReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirEventsReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].OwnerID = d.ownerID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].EventID = d.eventID; - packet.QueryReplies[i].Date = - Utils.StringToBytes(d.date); - packet.QueryReplies[i].UnixTime = d.unixTime; - packet.QueryReplies[i].EventFlags = d.eventFlags; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data) - { - DirGroupsReplyPacket packet = (DirGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirGroupsReply); - - packet.AgentData = new DirGroupsReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirGroupsReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirGroupsReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirGroupsReplyData d in data) - { - packet.QueryReplies[i] = new DirGroupsReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].GroupID = d.groupID; - packet.QueryReplies[i].GroupName = - Utils.StringToBytes(d.groupName); - packet.QueryReplies[i].Members = d.members; - packet.QueryReplies[i].SearchOrder = d.searchOrder; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data) - { - DirClassifiedReplyPacket packet = (DirClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirClassifiedReply); - - packet.AgentData = new DirClassifiedReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirClassifiedReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirClassifiedReplyPacket.QueryRepliesBlock[ - data.Length]; - packet.StatusData = new DirClassifiedReplyPacket.StatusDataBlock[ - data.Length]; - - int i = 0; - foreach (DirClassifiedReplyData d in data) - { - packet.QueryReplies[i] = new DirClassifiedReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirClassifiedReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].ClassifiedID = d.classifiedID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].ClassifiedFlags = d.classifiedFlags; - packet.QueryReplies[i].CreationDate = d.creationDate; - packet.QueryReplies[i].ExpirationDate = d.expirationDate; - packet.QueryReplies[i].PriceForListing = d.price; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirLandReply(UUID queryID, DirLandReplyData[] data) - { - DirLandReplyPacket packet = (DirLandReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirLandReply); - - packet.AgentData = new DirLandReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirLandReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirLandReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirLandReplyData d in data) - { - packet.QueryReplies[i] = new DirLandReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].Auction = d.auction; - packet.QueryReplies[i].ForSale = d.forSale; - packet.QueryReplies[i].SalePrice = d.salePrice; - packet.QueryReplies[i].ActualArea = d.actualArea; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data) - { - DirPopularReplyPacket packet = (DirPopularReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPopularReply); - - packet.AgentData = new DirPopularReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirPopularReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirPopularReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirPopularReplyData d in data) - { - packet.QueryReplies[i] = new DirPopularReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].Dwell = d.dwell; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendEventInfoReply(EventData data) - { - EventInfoReplyPacket packet = (EventInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.EventInfoReply); - - packet.AgentData = new EventInfoReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.EventData = new EventInfoReplyPacket.EventDataBlock(); - packet.EventData.EventID = data.eventID; - packet.EventData.Creator = Utils.StringToBytes(data.creator); - packet.EventData.Name = Utils.StringToBytes(data.name); - packet.EventData.Category = Utils.StringToBytes(data.category); - packet.EventData.Desc = Utils.StringToBytes(data.description); - packet.EventData.Date = Utils.StringToBytes(data.date); - packet.EventData.DateUTC = data.dateUTC; - packet.EventData.Duration = data.duration; - packet.EventData.Cover = data.cover; - packet.EventData.Amount = data.amount; - packet.EventData.SimName = Utils.StringToBytes(data.simName); - packet.EventData.GlobalPos = new Vector3d(data.globalPos); - packet.EventData.EventFlags = data.eventFlags; - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags) - { - MapItemReplyPacket mirplk = new MapItemReplyPacket(); - mirplk.AgentData.AgentID = AgentId; - mirplk.RequestData.ItemType = mapitemtype; - mirplk.Data = new MapItemReplyPacket.DataBlock[replies.Length]; - for (int i = 0; i < replies.Length; i++) - { - MapItemReplyPacket.DataBlock mrdata = new MapItemReplyPacket.DataBlock(); - mrdata.X = replies[i].x; - mrdata.Y = replies[i].y; - mrdata.ID = replies[i].id; - mrdata.Extra = replies[i].Extra; - mrdata.Extra2 = replies[i].Extra2; - mrdata.Name = Utils.StringToBytes(replies[i].name); - mirplk.Data[i] = mrdata; - } - //m_log.Debug(mirplk.ToString()); - OutPacket(mirplk, ThrottleOutPacketType.Task); - - } - - public void SendOfferCallingCard(UUID srcID, UUID transactionID) - { - // a bit special, as this uses AgentID to store the source instead - // of the destination. The destination (the receiver) goes into destID - OfferCallingCardPacket p = (OfferCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.OfferCallingCard); - p.AgentData.AgentID = srcID; - p.AgentData.SessionID = UUID.Zero; - p.AgentBlock.DestID = AgentId; - p.AgentBlock.TransactionID = transactionID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAcceptCallingCard(UUID transactionID) - { - AcceptCallingCardPacket p = (AcceptCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.AcceptCallingCard); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = UUID.Zero; - p.FolderData = new AcceptCallingCardPacket.FolderDataBlock[1]; - p.FolderData[0] = new AcceptCallingCardPacket.FolderDataBlock(); - p.FolderData[0].FolderID = UUID.Zero; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendDeclineCallingCard(UUID transactionID) - { - DeclineCallingCardPacket p = (DeclineCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.DeclineCallingCard); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = UUID.Zero; - p.TransactionBlock.TransactionID = transactionID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendTerminateFriend(UUID exFriendID) - { - TerminateFriendshipPacket p = (TerminateFriendshipPacket)PacketPool.Instance.GetPacket(PacketType.TerminateFriendship); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = SessionId; - p.ExBlock.OtherID = exFriendID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) - { - AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); - - p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - p.AgentData.AvatarID = avatarID; - - p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; - int i = 0; - foreach (GroupMembershipData m in data) - { - p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); - p.GroupData[i].GroupPowers = m.GroupPowers; - p.GroupData[i].AcceptNotices = m.AcceptNotices; - p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); - p.GroupData[i].GroupID = m.GroupID; - p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); - p.GroupData[i].GroupInsigniaID = m.GroupPicture; - i++; - } - - p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); - p.NewGroupData.ListInProfile = true; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendJoinGroupReply(UUID groupID, bool success) - { - JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply); - - p.AgentData = new JoinGroupReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - - p.GroupData = new JoinGroupReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - p.GroupData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success) - { - EjectGroupMemberReplyPacket p = (EjectGroupMemberReplyPacket)PacketPool.Instance.GetPacket(PacketType.EjectGroupMemberReply); - - p.AgentData = new EjectGroupMemberReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = agentID; - - p.GroupData = new EjectGroupMemberReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - - p.EjectData = new EjectGroupMemberReplyPacket.EjectDataBlock(); - p.EjectData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendLeaveGroupReply(UUID groupID, bool success) - { - LeaveGroupReplyPacket p = (LeaveGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.LeaveGroupReply); - - p.AgentData = new LeaveGroupReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - - p.GroupData = new LeaveGroupReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - p.GroupData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name) - { - if (classifiedID.Length != name.Length) - return; - - AvatarClassifiedReplyPacket ac = - (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarClassifiedReply); - - ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); - ac.AgentData.AgentID = AgentId; - ac.AgentData.TargetID = targetID; - - ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifiedID.Length]; - int i; - for (i = 0 ; i < classifiedID.Length ; i++) - { - ac.Data[i].ClassifiedID = classifiedID[i]; - ac.Data[i].Name = Utils.StringToBytes(name[i]); - } - - OutPacket(ac, ThrottleOutPacketType.Task); - } - - public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price) - { - ClassifiedInfoReplyPacket cr = - (ClassifiedInfoReplyPacket)PacketPool.Instance.GetPacket( - PacketType.ClassifiedInfoReply); - - cr.AgentData = new ClassifiedInfoReplyPacket.AgentDataBlock(); - cr.AgentData.AgentID = AgentId; - - cr.Data = new ClassifiedInfoReplyPacket.DataBlock(); - cr.Data.ClassifiedID = classifiedID; - cr.Data.CreatorID = creatorID; - cr.Data.CreationDate = creationDate; - cr.Data.ExpirationDate = expirationDate; - cr.Data.Category = category; - cr.Data.Name = Utils.StringToBytes(name); - cr.Data.Desc = Utils.StringToBytes(description); - cr.Data.ParcelID = parcelID; - cr.Data.ParentEstate = parentEstate; - cr.Data.SnapshotID = snapshotID; - cr.Data.SimName = Utils.StringToBytes(simName); - cr.Data.PosGlobal = new Vector3d(globalPos); - cr.Data.ParcelName = Utils.StringToBytes(parcelName); - cr.Data.ClassifiedFlags = classifiedFlags; - cr.Data.PriceForListing = price; - - OutPacket(cr, ThrottleOutPacketType.Task); - } - - public void SendAgentDropGroup(UUID groupID) - { - AgentDropGroupPacket dg = - (AgentDropGroupPacket)PacketPool.Instance.GetPacket( - PacketType.AgentDropGroup); - - dg.AgentData = new AgentDropGroupPacket.AgentDataBlock(); - dg.AgentData.AgentID = AgentId; - dg.AgentData.GroupID = groupID; - - OutPacket(dg, ThrottleOutPacketType.Task); - } - - public void SendAvatarNotesReply(UUID targetID, string text) - { - AvatarNotesReplyPacket an = - (AvatarNotesReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarNotesReply); - - an.AgentData = new AvatarNotesReplyPacket.AgentDataBlock(); - an.AgentData.AgentID = AgentId; - - an.Data = new AvatarNotesReplyPacket.DataBlock(); - an.Data.TargetID = targetID; - an.Data.Notes = Utils.StringToBytes(text); - - OutPacket(an, ThrottleOutPacketType.Task); - } - - public void SendAvatarPicksReply(UUID targetID, Dictionary picks) - { - AvatarPicksReplyPacket ap = - (AvatarPicksReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarPicksReply); - - ap.AgentData = new AvatarPicksReplyPacket.AgentDataBlock(); - ap.AgentData.AgentID = AgentId; - ap.AgentData.TargetID = targetID; - - ap.Data = new AvatarPicksReplyPacket.DataBlock[picks.Count]; - - int i = 0; - foreach (KeyValuePair pick in picks) - { - ap.Data[i] = new AvatarPicksReplyPacket.DataBlock(); - ap.Data[i].PickID = pick.Key; - ap.Data[i].PickName = Utils.StringToBytes(pick.Value); - i++; - } - - OutPacket(ap, ThrottleOutPacketType.Task); - } - - public void SendAvatarClassifiedReply(UUID targetID, Dictionary classifieds) - { - AvatarClassifiedReplyPacket ac = - (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarClassifiedReply); - - ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); - ac.AgentData.AgentID = AgentId; - ac.AgentData.TargetID = targetID; - - ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifieds.Count]; - - int i = 0; - foreach (KeyValuePair classified in classifieds) - { - ac.Data[i] = new AvatarClassifiedReplyPacket.DataBlock(); - ac.Data[i].ClassifiedID = classified.Key; - ac.Data[i].Name = Utils.StringToBytes(classified.Value); - i++; - } - - OutPacket(ac, ThrottleOutPacketType.Task); - } - - public void SendParcelDwellReply(int localID, UUID parcelID, float dwell) - { - ParcelDwellReplyPacket pd = - (ParcelDwellReplyPacket)PacketPool.Instance.GetPacket( - PacketType.ParcelDwellReply); - - pd.AgentData = new ParcelDwellReplyPacket.AgentDataBlock(); - pd.AgentData.AgentID = AgentId; - - pd.Data = new ParcelDwellReplyPacket.DataBlock(); - pd.Data.LocalID = localID; - pd.Data.ParcelID = parcelID; - pd.Data.Dwell = dwell; - - OutPacket(pd, ThrottleOutPacketType.Land); - } - - public void SendUserInfoReply(bool imViaEmail, bool visible, string email) - { - UserInfoReplyPacket ur = - (UserInfoReplyPacket)PacketPool.Instance.GetPacket( - PacketType.UserInfoReply); - - string Visible = "hidden"; - if (visible) - Visible = "default"; - - ur.AgentData = new UserInfoReplyPacket.AgentDataBlock(); - ur.AgentData.AgentID = AgentId; - - ur.UserData = new UserInfoReplyPacket.UserDataBlock(); - ur.UserData.IMViaEMail = imViaEmail; - ur.UserData.DirectoryVisibility = Utils.StringToBytes(Visible); - ur.UserData.EMail = Utils.StringToBytes(email); - - OutPacket(ur, ThrottleOutPacketType.Task); - } - public void KillEndDone() { - KillPacket kp = new KillPacket(); - OutPacket(kp, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); + m_udpClient.Shutdown(); } #region IClientCore @@ -10767,13 +10324,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - protected virtual void RegisterInterfaces() - { - RegisterInterface(this); - RegisterInterface(this); - RegisterInterface(this); - } - public bool TryGet(out T iface) { if (m_clientInterfaces.ContainsKey(typeof(T))) @@ -10821,78 +10371,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public void SendCreateGroupReply(UUID groupID, bool success, string message) - { - CreateGroupReplyPacket createGroupReply = (CreateGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.CreateGroupReply); - - createGroupReply.AgentData = - new CreateGroupReplyPacket.AgentDataBlock(); - createGroupReply.ReplyData = - new CreateGroupReplyPacket.ReplyDataBlock(); - - createGroupReply.AgentData.AgentID = AgentId; - createGroupReply.ReplyData.GroupID = groupID; - - createGroupReply.ReplyData.Success = success; - createGroupReply.ReplyData.Message = Utils.StringToBytes(message); - OutPacket(createGroupReply, ThrottleOutPacketType.Task); - } - - public void SendUseCachedMuteList() - { - UseCachedMuteListPacket useCachedMuteList = (UseCachedMuteListPacket)PacketPool.Instance.GetPacket(PacketType.UseCachedMuteList); - - useCachedMuteList.AgentData = new UseCachedMuteListPacket.AgentDataBlock(); - useCachedMuteList.AgentData.AgentID = AgentId; - - OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); - } - - public void SendMuteListUpdate(string filename) - { - MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); - - muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock(); - muteListUpdate.MuteData.AgentID = AgentId; - muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename); - - OutPacket(muteListUpdate, ThrottleOutPacketType.Task); - } - - public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) - { - PickInfoReplyPacket pickInfoReply = (PickInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.PickInfoReply); - - pickInfoReply.AgentData = new PickInfoReplyPacket.AgentDataBlock(); - pickInfoReply.AgentData.AgentID = AgentId; - - pickInfoReply.Data = new PickInfoReplyPacket.DataBlock(); - pickInfoReply.Data.PickID = pickID; - pickInfoReply.Data.CreatorID = creatorID; - pickInfoReply.Data.TopPick = topPick; - pickInfoReply.Data.ParcelID = parcelID; - pickInfoReply.Data.Name = Utils.StringToBytes(name); - pickInfoReply.Data.Desc = Utils.StringToBytes(desc); - pickInfoReply.Data.SnapshotID = snapshotID; - pickInfoReply.Data.User = Utils.StringToBytes(user); - pickInfoReply.Data.OriginalName = Utils.StringToBytes(originalName); - pickInfoReply.Data.SimName = Utils.StringToBytes(simName); - pickInfoReply.Data.PosGlobal = new Vector3d(posGlobal); - pickInfoReply.Data.SortOrder = sortOrder; - pickInfoReply.Data.Enabled = enabled; - - OutPacket(pickInfoReply, ThrottleOutPacketType.Task); - } - public string Report() { - LLPacketHandler handler = (LLPacketHandler) m_PacketHandler; - return handler.PacketQueue.GetStats(); + return m_udpClient.GetStats(); } public string XReport(string uptime, string version) { - return ""; + return String.Empty; } public void MakeAssetRequest(TransferRequestPacket transferRequest) @@ -10981,7 +10467,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return numPackets; } - #region IClientIPEndpoint Members public IPAddress EndPoint diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index facfb9d2ed..5219df708d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs @@ -172,7 +172,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_lastloopprocessed = DateTime.Now.Ticks; // This can happen during Close() - if (m_client == null || m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null) + if (m_client == null) return false; while ((imagereq = GetHighestPriorityImage()) != null) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs index e98a360211..f30df4d7fa 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs @@ -39,7 +39,12 @@ using Timer=System.Timers.Timer; namespace OpenSim.Region.ClientStack.LindenUDP { - public class LLPacketHandler : ILLPacketHandler + public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); + public delegate void PacketDrop(Packet pack, Object id); + public delegate void QueueEmpty(ThrottleOutPacketType queue); + public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, UUID agentID, ThrottleOutPacketType throttlePacketType); + + public class LLPacketHandler { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketServer.cs index 70d94e7777..f08b7be002 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketServer.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // private static readonly log4net.ILog m_log // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - protected readonly ILLClientStackNetworkHandler m_networkHandler; + protected readonly LLUDPServer m_networkHandler; protected IScene m_scene; /// @@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// private ClientStackUserSettings m_userSettings; - public LLPacketServer(ILLClientStackNetworkHandler networkHandler, ClientStackUserSettings userSettings) + public LLPacketServer(LLUDPServer networkHandler, ClientStackUserSettings userSettings) { m_userSettings = userSettings; m_networkHandler = networkHandler; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index c779b08fa7..7964c505b3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -26,616 +26,727 @@ */ using System; -using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Reflection; +using System.Threading; using log4net; using Nini.Config; using OpenMetaverse.Packets; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; +using OpenMetaverse; namespace OpenSim.Region.ClientStack.LindenUDP { - /// - /// This class handles the initial UDP circuit setup with a client and passes on subsequent packets to the LLPacketServer - /// - public class LLUDPServer : ILLClientStackNetworkHandler, IClientNetworkServer + public class LLUDPServerShim : IClientNetworkServer { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + LLUDPServer m_udpServer; - /// - /// The client circuits established with this UDP server. If a client exists here we can also assume that - /// it is populated in clientCircuits_reverse and proxyCircuits (if relevant) - /// - protected Dictionary clientCircuits = new Dictionary(); - public Hashtable clientCircuits_reverse = Hashtable.Synchronized(new Hashtable()); - protected Dictionary proxyCircuits = new Dictionary(); - - private Socket m_socket; - protected IPEndPoint ServerIncoming; - protected byte[] RecvBuffer = new byte[4096]; - protected byte[] ZeroBuffer = new byte[8192]; - - /// - /// This is an endpoint that is reused where we don't need to protect the information from potentially - /// being stomped on by other threads. - /// - protected EndPoint reusedEpSender = new IPEndPoint(IPAddress.Any, 0); - - protected int proxyPortOffset; - - protected AsyncCallback ReceivedData; - protected LLPacketServer m_packetServer; - protected Location m_location; - - protected uint listenPort; - protected bool Allow_Alternate_Port; - protected IPAddress listenIP = IPAddress.Parse("0.0.0.0"); - protected IScene m_localScene; - protected int m_clientSocketReceiveBuffer = 0; - - /// - /// Manages authentication for agent circuits - /// - protected AgentCircuitManager m_circuitManager; - - public IScene LocalScene + public LLUDPServerShim() { - set - { - m_localScene = value; - m_packetServer.LocalScene = m_localScene; - - m_location = new Location(m_localScene.RegionInfo.RegionHandle); - } } - public ulong RegionHandle + public void Initialise(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) { - get { return m_location.RegionHandle; } + m_udpServer = new LLUDPServer(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager); } - Socket IClientNetworkServer.Server + public void NetworkStop() { - get { return m_socket; } + m_udpServer.Stop(); + } + + public void AddScene(IScene scene) + { + m_udpServer.AddScene(scene); } public bool HandlesRegion(Location x) { - //return x.RegionHandle == m_location.RegionHandle; - return x == m_location; - } - - public void AddScene(IScene x) - { - LocalScene = x; + return m_udpServer.HandlesRegion(x); } public void Start() { - ServerListener(); + m_udpServer.Start(); } public void Stop() { - m_socket.Close(); + m_udpServer.Stop(); } + } - public LLUDPServer() + public class LLUDPServer : UDPBase + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + /// Handlers for incoming packets + //PacketEventDictionary packetEvents = new PacketEventDictionary(); + /// Incoming packets that are awaiting handling + private OpenMetaverse.BlockingQueue packetInbox = new OpenMetaverse.BlockingQueue(); + /// + private UDPClientCollection clients = new UDPClientCollection(); + /// Bandwidth throttle for this UDP server + private TokenBucket m_throttle; + /// Bandwidth throttle rates for this UDP server + private ThrottleRates m_throttleRates; + /// Manages authentication for agent circuits + private AgentCircuitManager m_circuitManager; + /// Reference to the scene this UDP server is attached to + private IScene m_scene; + /// The X/Y coordinates of the scene this UDP server is attached to + private Location m_location; + /// The measured resolution of Environment.TickCount + private float m_tickCountResolution; + + /// The measured resolution of Environment.TickCount + public float TickCountResolution { get { return m_tickCountResolution; } } + public Socket Server { get { return null; } } + + public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) + : base((int)port) { - } + #region Environment.TickCount Measurement - public LLUDPServer( - IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, IConfigSource configSource, - AgentCircuitManager authenticateClass) - { - Initialise(_listenIP, ref port, proxyPortOffset, allow_alternate_port, configSource, authenticateClass); - } - - /// - /// Initialize the server - /// - /// - /// - /// - /// - /// - /// - /// - public void Initialise( - IPAddress _listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, - AgentCircuitManager circuitManager) - { - ClientStackUserSettings userSettings = new ClientStackUserSettings(); - - IConfig config = configSource.Configs["ClientStack.LindenUDP"]; - - if (config != null) + // Measure the resolution of Environment.TickCount + m_tickCountResolution = 0f; + for (int i = 0; i < 5; i++) { - if (config.Contains("client_throttle_max_bps")) - { - int maxBPS = config.GetInt("client_throttle_max_bps", 1500000); - userSettings.TotalThrottleSettings = new ThrottleSettings(0, maxBPS, - maxBPS > 28000 ? maxBPS : 28000); - } - - if (config.Contains("client_throttle_multiplier")) - userSettings.ClientThrottleMultipler = config.GetFloat("client_throttle_multiplier"); - if (config.Contains("client_socket_rcvbuf_size")) - m_clientSocketReceiveBuffer = config.GetInt("client_socket_rcvbuf_size"); + int start = Environment.TickCount; + int now = start; + while (now == start) + now = Environment.TickCount; + m_tickCountResolution += (float)(now - start) * 0.2f; } - - m_log.DebugFormat("[CLIENT]: client_throttle_multiplier = {0}", userSettings.ClientThrottleMultipler); - m_log.DebugFormat("[CLIENT]: client_socket_rcvbuf_size = {0}", (m_clientSocketReceiveBuffer != 0 ? - m_clientSocketReceiveBuffer.ToString() : "OS default")); - - proxyPortOffset = proxyPortOffsetParm; - listenPort = (uint) (port + proxyPortOffsetParm); - listenIP = _listenIP; - Allow_Alternate_Port = allow_alternate_port; + m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms"); + + #endregion Environment.TickCount Measurement + m_circuitManager = circuitManager; - CreatePacketServer(userSettings); - // Return new port - // This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered. - // So the option allow_alternate_ports="true" was added to default.xml - port = (uint)(listenPort - proxyPortOffsetParm); + // TODO: Config support for throttling the entire connection + m_throttle = new TokenBucket(null, 0, 0); + m_throttleRates = new ThrottleRates(configSource); } - protected virtual void CreatePacketServer(ClientStackUserSettings userSettings) + public new void Start() { - new LLPacketServer(this, userSettings); + if (m_scene == null) + throw new InvalidOperationException("Cannot LLUDPServer.Start() without an IScene reference"); + + base.Start(); + + // Start the incoming packet processing thread + Thread incomingThread = new Thread(IncomingPacketHandler); + incomingThread.Name = "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")"; + incomingThread.Start(); + + Thread outgoingThread = new Thread(OutgoingPacketHandler); + outgoingThread.Name = "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")"; + outgoingThread.Start(); } - /// - /// This method is called every time that we receive new UDP data. - /// - /// - protected virtual void OnReceivedData(IAsyncResult result) + public new void Stop() { + base.Stop(); + } + + public void AddScene(IScene scene) + { + if (m_scene == null) + { + m_scene = scene; + m_location = new Location(m_scene.RegionInfo.RegionHandle); + } + else + { + m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene"); + } + } + + public bool HandlesRegion(Location x) + { + return x == m_location; + } + + public void RemoveClient(IClientAPI client) + { + m_scene.ClientManager.Remove(client.CircuitCode); + client.Close(false); + + LLUDPClient udpClient; + if (clients.TryGetValue(client.AgentId, out udpClient)) + { + m_log.Debug("[LLUDPSERVER]: Removing LLUDPClient for " + client.Name); + udpClient.Shutdown(); + clients.Remove(client.AgentId, udpClient.RemoteEndPoint); + } + else + { + m_log.Warn("[LLUDPSERVER]: Failed to remove LLUDPClient for " + client.Name); + } + } + + public void RemoveClient(LLUDPClient udpClient) + { + IClientAPI client; + + if (m_scene.ClientManager.TryGetClient(udpClient.CircuitCode, out client)) + RemoveClient(client); + else + m_log.Warn("[LLUDPSERVER]: Failed to lookup IClientAPI for LLUDPClient " + udpClient.AgentID); + } + + public void SetClientPaused(UUID agentID, bool paused) + { + LLUDPClient client; + if (clients.TryGetValue(agentID, out client)) + { + client.IsPaused = paused; + } + else + { + m_log.Warn("[LLUDPSERVER]: Attempted to pause/unpause unknown agent " + agentID); + } + } + + public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) + { + if (allowSplitting && packet.HasVariableBlocks) + { + byte[][] datas = packet.ToBytesMultiple(); + int packetCount = datas.Length; + + if (packetCount > 1) + m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); + + for (int i = 0; i < packetCount; i++) + { + byte[] data = datas[i]; + clients.ForEach( + delegate(LLUDPClient client) + { SendPacketData(client, data, data.Length, packet.Type, packet.Header.Zerocoded, category); }); + } + } + else + { + byte[] data = packet.ToBytes(); + clients.ForEach( + delegate(LLUDPClient client) + { SendPacketData(client, data, data.Length, packet.Type, packet.Header.Zerocoded, category); }); + } + } + + public void SendPacket(UUID agentID, Packet packet, ThrottleOutPacketType category, bool allowSplitting) + { + LLUDPClient client; + if (clients.TryGetValue(agentID, out client)) + SendPacket(client, packet, category, allowSplitting); + else + m_log.Warn("[LLUDPSERVER]: Attempted to send a packet to unknown agentID " + agentID); + } + + public void SendPacket(LLUDPClient client, Packet packet, ThrottleOutPacketType category, bool allowSplitting) + { + if (allowSplitting && packet.HasVariableBlocks) + { + byte[][] datas = packet.ToBytesMultiple(); + int packetCount = datas.Length; + + if (packetCount > 1) + m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); + + for (int i = 0; i < packetCount; i++) + { + byte[] data = datas[i]; + SendPacketData(client, data, data.Length, packet.Type, packet.Header.Zerocoded, category); + } + } + else + { + byte[] data = packet.ToBytes(); + SendPacketData(client, data, data.Length, packet.Type, packet.Header.Zerocoded, category); + } + } + + public void SendPacketData(LLUDPClient client, byte[] data, int dataLength, PacketType type, bool doZerocode, ThrottleOutPacketType category) + { + // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum. + // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting + // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here + // to accomodate for both common scenarios and provide ample room for ACK appending in both + int bufferSize = (dataLength > 180) ? Packet.MTU : 200; + + UDPPacketBuffer buffer = new UDPPacketBuffer(client.RemoteEndPoint, bufferSize); + + // Zerocode if needed + if (doZerocode) + { + try { dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data); } + catch (IndexOutOfRangeException) + { + // The packet grew larger than the bufferSize while zerocoding. + // Remove the MSG_ZEROCODED flag and send the unencoded data + // instead + m_log.Info("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding. Removing MSG_ZEROCODED flag"); + data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); + Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); + } + } + else + { + Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); + } + buffer.DataLength = dataLength; + + #region Queue or Send + + // Look up the UDPClient this is going to + OutgoingPacket outgoingPacket = new OutgoingPacket(client, buffer, category); + + if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) + SendPacketFinal(outgoingPacket); + + #endregion Queue or Send + } + + public void SendAcks(LLUDPClient client) + { + uint ack; + + if (client.PendingAcks.Dequeue(out ack)) + { + List blocks = new List(); + PacketAckPacket.PacketsBlock block = new PacketAckPacket.PacketsBlock(); + block.ID = ack; + blocks.Add(block); + + while (client.PendingAcks.Dequeue(out ack)) + { + block = new PacketAckPacket.PacketsBlock(); + block.ID = ack; + blocks.Add(block); + } + + PacketAckPacket packet = new PacketAckPacket(); + packet.Header.Reliable = false; + packet.Packets = blocks.ToArray(); + + SendPacket(client, packet, ThrottleOutPacketType.Unknown, true); + } + } + + public void ResendUnacked(LLUDPClient client) + { + if (client.NeedAcks.Count > 0) + { + List expiredPackets = client.NeedAcks.GetExpiredPackets(client.RTO); + + if (expiredPackets != null) + { + // Resend packets + for (int i = 0; i < expiredPackets.Count; i++) + { + OutgoingPacket outgoingPacket = expiredPackets[i]; + + // FIXME: Make this an .ini setting + if (outgoingPacket.ResendCount < 3) + { + //Logger.Debug(String.Format("Resending packet #{0} (attempt {1}), {2}ms have passed", + // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount)); + + // Set the resent flag + outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT); + outgoingPacket.Category = ThrottleOutPacketType.Resend; + + // The TickCount will be set to the current time when the packet + // is actually sent out again + outgoingPacket.TickCount = 0; + + Interlocked.Increment(ref outgoingPacket.ResendCount); + //Interlocked.Increment(ref Stats.ResentPackets); + + // Queue or (re)send the packet + if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) + SendPacketFinal(outgoingPacket); + } + else + { + m_log.DebugFormat("[LLUDPSERVER]: Dropping packet #{0} for agent {1} after {2} failed attempts", + outgoingPacket.SequenceNumber, outgoingPacket.Client.RemoteEndPoint, outgoingPacket.ResendCount); + + lock (client.NeedAcks.SyncRoot) + client.NeedAcks.RemoveUnsafe(outgoingPacket.SequenceNumber); + + //Interlocked.Increment(ref Stats.DroppedPackets); + + // Disconnect an agent if no packets are received for some time + //FIXME: Make 60 an .ini setting + if (Environment.TickCount - client.TickLastPacketReceived > 1000 * 60) + { + m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + client.RemoteEndPoint); + + RemoveClient(client); + return; + } + } + } + } + } + } + + public void Flush() + { + } + + protected override void PacketReceived(UDPPacketBuffer buffer) + { + // Debugging/Profiling + //try { Thread.CurrentThread.Name = "PacketReceived (" + scene.RegionName + ")"; } + //catch (Exception) { } + + LLUDPClient client = null; Packet packet = null; - int numBytes = 1; - EndPoint epSender = new IPEndPoint(IPAddress.Any, 0); - EndPoint epProxy = null; + int packetEnd = buffer.DataLength - 1; + IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint; + + #region Decoding try { - if (EndReceive(out numBytes, result, ref epSender)) - { - // Make sure we are getting zeroes when running off the - // end of grab / degrab packets from old clients - Array.Clear(RecvBuffer, numBytes, RecvBuffer.Length - numBytes); - - int packetEnd = numBytes - 1; - if (proxyPortOffset != 0) packetEnd -= 6; - - try - { - packet = PacketPool.Instance.GetPacket(RecvBuffer, ref packetEnd, ZeroBuffer); - } - catch (MalformedDataException e) - { - m_log.DebugFormat("[CLIENT]: Dropped Malformed Packet due to MalformedDataException: {0}", e.StackTrace); - } - catch (IndexOutOfRangeException e) - { - m_log.DebugFormat("[CLIENT]: Dropped Malformed Packet due to IndexOutOfRangeException: {0}", e.StackTrace); - } - catch (Exception e) - { - m_log.Debug("[CLIENT]: " + e); - } - } - - - if (proxyPortOffset != 0) - { - // If we've received a use circuit packet, then we need to decode an endpoint proxy, if one exists, - // before allowing the RecvBuffer to be overwritten by the next packet. - if (packet != null && packet.Type == PacketType.UseCircuitCode) - { - epProxy = epSender; - } - - // Now decode the message from the proxy server - epSender = ProxyCodec.DecodeProxyMessage(RecvBuffer, ref numBytes); - } + packet = Packet.BuildPacket(buffer.Data, ref packetEnd, + // Only allocate a buffer for zerodecoding if the packet is zerocoded + ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); } - catch (Exception ex) + catch (MalformedDataException) { - m_log.ErrorFormat("[CLIENT]: Exception thrown during EndReceive(): {0}", ex); + m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse packet:\n{0}", + Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); } - BeginRobustReceive(); - - if (packet != null) + // Fail-safe check + if (packet == null) { - if (packet.Type == PacketType.UseCircuitCode) - AddNewClient((UseCircuitCodePacket)packet, epSender, epProxy); + m_log.Warn("[LLUDPSERVER]: Couldn't build a message from the incoming data"); + return; + } + + //Stats.RecvBytes += (ulong)buffer.DataLength; + //++Stats.RecvPackets; + + #endregion Decoding + + #region UseCircuitCode Handling + + if (packet.Type == PacketType.UseCircuitCode) + { + UseCircuitCodePacket useCircuitCode = (UseCircuitCodePacket)packet; + IClientAPI newuser; + uint circuitCode = useCircuitCode.CircuitCode.Code; + + // Check if the client is already established + if (!m_scene.ClientManager.TryGetClient(circuitCode, out newuser)) + { + AddNewClient(useCircuitCode, (IPEndPoint)buffer.RemoteEndPoint); + } + } + + // Determine which agent this packet came from + if (!clients.TryGetValue(address, out client)) + { + m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address); + return; + } + + #endregion UseCircuitCode Handling + + //if (packet.Header.Resent) + // Interlocked.Increment(ref Stats.ReceivedResends); + + #region ACK Receiving + + int now = Environment.TickCount; + client.TickLastPacketReceived = now; + + // Handle appended ACKs + if (packet.Header.AppendedAcks && packet.Header.AckList != null) + { + lock (client.NeedAcks.SyncRoot) + { + for (int i = 0; i < packet.Header.AckList.Length; i++) + AcknowledgePacket(client, packet.Header.AckList[i], now, packet.Header.Resent); + } + } + + // Handle PacketAck packets + if (packet.Type == PacketType.PacketAck) + { + PacketAckPacket ackPacket = (PacketAckPacket)packet; + + lock (client.NeedAcks.SyncRoot) + { + for (int i = 0; i < ackPacket.Packets.Length; i++) + AcknowledgePacket(client, ackPacket.Packets[i].ID, now, packet.Header.Resent); + } + } + + #endregion ACK Receiving + + #region ACK Sending + + if (packet.Header.Reliable) + client.PendingAcks.Enqueue((uint)packet.Header.Sequence); + + // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, + // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove + // 2*MTU bytes from the value and send ACKs, and finally add the local value back to + // client.BytesSinceLastACK. Lockless thread safety + int bytesSinceLastACK = Interlocked.Exchange(ref client.BytesSinceLastACK, 0); + bytesSinceLastACK += buffer.DataLength; + if (bytesSinceLastACK > Packet.MTU * 2) + { + bytesSinceLastACK -= Packet.MTU * 2; + SendAcks(client); + } + Interlocked.Add(ref client.BytesSinceLastACK, bytesSinceLastACK); + + #endregion ACK Sending + + #region Incoming Packet Accounting + + // Check the archive of received reliable packet IDs to see whether we already received this packet + if (packet.Header.Reliable && !client.PacketArchive.TryEnqueue(packet.Header.Sequence)) + { + if (packet.Header.Resent) + m_log.Debug("[LLUDPSERVER]: Received a resend of already processed packet #" + packet.Header.Sequence + ", type: " + packet.Type); else - ProcessInPacket(packet, epSender); + m_log.Warn("[LLUDPSERVER]: Received a duplicate (not marked as resend) of packet #" + packet.Header.Sequence + ", type: " + packet.Type); + + // Avoid firing a callback twice for the same packet + return; + } + + #endregion Incoming Packet Accounting + + // Don't bother clogging up the queue with PacketAck packets that are already handled here + if (packet.Type != PacketType.PacketAck) + { + // Inbox insertion + IncomingPacket incomingPacket; + incomingPacket.Client = client; + incomingPacket.Packet = packet; + + packetInbox.Enqueue(incomingPacket); } } - - /// - /// Process a successfully received packet. - /// - /// - /// - protected virtual void ProcessInPacket(Packet packet, EndPoint epSender) + + protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent) { - try - { - // do we already have a circuit for this endpoint - uint circuit; - bool ret; - - lock (clientCircuits) - { - ret = clientCircuits.TryGetValue(epSender, out circuit); - } - - if (ret) - { - //if so then send packet to the packetserver - //m_log.DebugFormat( - // "[UDPSERVER]: For circuit {0} {1} got packet {2}", circuit, epSender, packet.Type); - - m_packetServer.InPacket(circuit, packet); - } - } - catch (Exception e) - { - m_log.Error("[CLIENT]: Exception in processing packet - ignoring: ", e); - } } - - /// - /// Begin an asynchronous receive of the next bit of raw data - /// - protected virtual void BeginReceive() + + private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) { - m_socket.BeginReceiveFrom( - RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref reusedEpSender, ReceivedData, null); + UUID agentID = useCircuitCode.CircuitCode.ID; + UUID sessionID = useCircuitCode.CircuitCode.SessionID; + uint circuitCode = useCircuitCode.CircuitCode.Code; + + sessionInfo = m_circuitManager.AuthenticateSession(sessionID, agentID, circuitCode); + return sessionInfo.Authorised; } - /// - /// Begin a robust asynchronous receive of the next bit of raw data. Robust means that SocketExceptions are - /// automatically dealt with until the next set of valid UDP data is received. - /// - private void BeginRobustReceive() - { - bool done = false; - - while (!done) - { - try - { - BeginReceive(); - done = true; - } - catch (SocketException e) - { - // ENDLESS LOOP ON PURPOSE! - // Reset connection and get next UDP packet off the buffer - // If the UDP packet is part of the same stream, this will happen several hundreds of times before - // the next set of UDP data is for a valid client. - - try - { - CloseCircuit(e); - } - catch (Exception e2) - { - m_log.ErrorFormat( - "[CLIENT]: Exception thrown when trying to close the circuit for {0} - {1}", reusedEpSender, - e2); - } - } - catch (ObjectDisposedException) - { - m_log.Info( - "[UDPSERVER]: UDP Object disposed. No need to worry about this if you're restarting the simulator."); - - done = true; - } - catch (Exception ex) - { - m_log.ErrorFormat("[CLIENT]: Exception thrown during BeginReceive(): {0}", ex); - } - } - } - - /// - /// Close a client circuit. This is done in response to an exception on receive, and should not be called - /// normally. - /// - /// The exception that caused the close. Can be null if there was no exception - private void CloseCircuit(Exception e) - { - uint circuit; - lock (clientCircuits) - { - if (clientCircuits.TryGetValue(reusedEpSender, out circuit)) - { - m_packetServer.CloseCircuit(circuit); - - if (e != null) - m_log.ErrorFormat( - "[CLIENT]: Closed circuit {0} {1} due to exception {2}", circuit, reusedEpSender, e); - } - } - } - - /// - /// Finish the process of asynchronously receiving the next bit of raw data - /// - /// The number of bytes received. Will return 0 if no bytes were recieved - /// - /// The sender of the data - /// - protected virtual bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender) - { - bool hasReceivedOkay = false; - numBytes = 0; - - try - { - numBytes = m_socket.EndReceiveFrom(result, ref epSender); - hasReceivedOkay = true; - } - catch (SocketException e) - { - // TODO : Actually only handle those states that we have control over, re-throw everything else, - // TODO: implement cases as we encounter them. - //m_log.Error("[CLIENT]: Connection Error! - " + e.ToString()); - switch (e.SocketErrorCode) - { - case SocketError.AlreadyInProgress: - return hasReceivedOkay; - - case SocketError.NetworkReset: - case SocketError.ConnectionReset: - case SocketError.OperationAborted: - break; - - default: - throw; - } - } - catch (ObjectDisposedException e) - { - m_log.DebugFormat("[CLIENT]: ObjectDisposedException: Object {0} disposed.", e.ObjectName); - // Uhh, what object, and why? this needs better handling. - } - - return hasReceivedOkay; - } - - /// - /// Add a new client circuit. - /// - /// - /// - /// - protected virtual void AddNewClient(UseCircuitCodePacket useCircuit, EndPoint epSender, EndPoint epProxy) + private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint) { //Slave regions don't accept new clients - if (m_localScene.RegionStatus != RegionStatus.SlaveScene) + if (m_scene.RegionStatus != RegionStatus.SlaveScene) { AuthenticateResponse sessionInfo; - bool isNewCircuit = false; - - if (!m_packetServer.IsClientAuthorized(useCircuit, m_circuitManager, out sessionInfo)) + bool isNewCircuit = !clients.ContainsKey(remoteEndPoint); + + if (!IsClientAuthorized(useCircuitCode, out sessionInfo)) { m_log.WarnFormat( "[CONNECTION FAILURE]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}", - useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code, epSender); - + useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint); return; } - - lock (clientCircuits) - { - if (!clientCircuits.ContainsKey(epSender)) - { - clientCircuits.Add(epSender, useCircuit.CircuitCode.Code); - isNewCircuit = true; - } - } if (isNewCircuit) { - // This doesn't need locking as it's synchronized data - clientCircuits_reverse[useCircuit.CircuitCode.Code] = epSender; + UUID agentID = useCircuitCode.CircuitCode.ID; + UUID sessionID = useCircuitCode.CircuitCode.SessionID; + uint circuitCode = useCircuitCode.CircuitCode.Code; - lock (proxyCircuits) - { - proxyCircuits[useCircuit.CircuitCode.Code] = epProxy; - } - - m_packetServer.AddNewClient(epSender, useCircuit, sessionInfo, epProxy); - - //m_log.DebugFormat( - // "[CONNECTION SUCCESS]: Incoming client {0} (circuit code {1}) received and authenticated for {2}", - // useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code, m_localScene.RegionInfo.RegionName); - } - } - - // Ack the UseCircuitCode packet - PacketAckPacket ack_it = (PacketAckPacket)PacketPool.Instance.GetPacket(PacketType.PacketAck); - // TODO: don't create new blocks if recycling an old packet - ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; - ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); - ack_it.Packets[0].ID = useCircuit.Header.Sequence; - // ((useCircuit.Header.Sequence < uint.MaxValue) ? useCircuit.Header.Sequence : 0) is just a failsafe to ensure that we don't overflow. - ack_it.Header.Sequence = ((useCircuit.Header.Sequence < uint.MaxValue) ? useCircuit.Header.Sequence : 0) + 1; - ack_it.Header.Reliable = false; - - byte[] ackmsg = ack_it.ToBytes(); - - // Need some extra space in case we need to add proxy - // information to the message later - byte[] msg = new byte[4096]; - Buffer.BlockCopy(ackmsg, 0, msg, 0, ackmsg.Length); - - SendPacketTo(msg, ackmsg.Length, SocketFlags.None, useCircuit.CircuitCode.Code); - - PacketPool.Instance.ReturnPacket(useCircuit); - } - - public void ServerListener() - { - uint newPort = listenPort; - m_log.Info("[UDPSERVER]: Opening UDP socket on " + listenIP + " " + newPort + "."); - - ServerIncoming = new IPEndPoint(listenIP, (int)newPort); - m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - if (0 != m_clientSocketReceiveBuffer) - m_socket.ReceiveBufferSize = m_clientSocketReceiveBuffer; - m_socket.Bind(ServerIncoming); - // Add flags to the UDP socket to prevent "Socket forcibly closed by host" - // uint IOC_IN = 0x80000000; - // uint IOC_VENDOR = 0x18000000; - // uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; - // TODO: this apparently works in .NET but not in Mono, need to sort out the right flags here. - // m_socket.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); - - listenPort = newPort; - - m_log.Info("[UDPSERVER]: UDP socket bound, getting ready to listen"); - - ReceivedData = OnReceivedData; - BeginReceive(); - - m_log.Info("[UDPSERVER]: Listening on port " + newPort); - } - - public virtual void RegisterPacketServer(LLPacketServer server) - { - m_packetServer = server; - } - - public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode) - //EndPoint packetSender) - { - // find the endpoint for this circuit - EndPoint sendto; - try - { - sendto = (EndPoint)clientCircuits_reverse[circuitcode]; - } - catch - { - // Exceptions here mean there is no circuit - m_log.Warn("[CLIENT]: Circuit not found, not sending packet"); - return; - } - - if (sendto != null) - { - //we found the endpoint so send the packet to it - if (proxyPortOffset != 0) - { - //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo proxy " + proxyCircuits[circuitcode].ToString() + ": client " + sendto.ToString()); - ProxyCodec.EncodeProxyMessage(buffer, ref size, sendto); - m_socket.SendTo(buffer, size, flags, proxyCircuits[circuitcode]); - } - else - { - //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo : client " + sendto.ToString()); - try - { - m_socket.SendTo(buffer, size, flags, sendto); - } - catch (SocketException SockE) - { - m_log.ErrorFormat("[UDPSERVER]: Caught Socket Error in the send buffer!. {0}",SockE.ToString()); - } + AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo); } } } - public virtual void RemoveClientCircuit(uint circuitcode) + private void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) { - EndPoint sendto; - if (clientCircuits_reverse.Contains(circuitcode)) + // Create the LLUDPClient + LLUDPClient client = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); + clients.Add(agentID, client.RemoteEndPoint, client); + + // Create the IClientAPI + IClientAPI clientApi = new LLClientView(remoteEndPoint, m_scene, this, client, sessionInfo, agentID, sessionID, circuitCode); + clientApi.OnViewerEffect += m_scene.ClientManager.ViewerEffectHandler; + clientApi.OnLogout += LogoutHandler; + clientApi.OnConnectionClosed += RemoveClient; + + // Give LLUDPClient a reference to IClientAPI + client.ClientAPI = clientApi; + + // Start the IClientAPI + m_scene.ClientManager.Add(circuitCode, clientApi); + clientApi.Start(); + } + + private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend) + { + OutgoingPacket ackedPacket; + if (client.NeedAcks.RemoveUnsafe(ack, out ackedPacket) && !fromResend) { - sendto = (EndPoint)clientCircuits_reverse[circuitcode]; - - clientCircuits_reverse.Remove(circuitcode); - - lock (clientCircuits) - { - if (sendto != null) - { - clientCircuits.Remove(sendto); - } - else - { - m_log.DebugFormat( - "[CLIENT]: endpoint for circuit code {0} in RemoveClientCircuit() was unexpectedly null!", circuitcode); - } - } - lock (proxyCircuits) - { - proxyCircuits.Remove(circuitcode); - } + // Calculate the round-trip time for this packet and its ACK + int rtt = currentTime - ackedPacket.TickCount; + if (rtt > 0) + client.UpdateRoundTrip(rtt); } } - public void RestoreClient(AgentCircuitData circuit, EndPoint userEP, EndPoint proxyEP) + private void IncomingPacketHandler() { - //MainLog.Instance.Verbose("UDPSERVER", "RestoreClient"); + IncomingPacket incomingPacket = new IncomingPacket(); + Packet packet = null; + LLUDPClient client = null; - UseCircuitCodePacket useCircuit = new UseCircuitCodePacket(); - useCircuit.CircuitCode.Code = circuit.circuitcode; - useCircuit.CircuitCode.ID = circuit.AgentID; - useCircuit.CircuitCode.SessionID = circuit.SessionID; - - AuthenticateResponse sessionInfo; - - if (!m_packetServer.IsClientAuthorized(useCircuit, m_circuitManager, out sessionInfo)) + while (base.IsRunning) { - m_log.WarnFormat( - "[CLIENT]: Restore request denied to avatar {0} connecting with unauthorized circuit code {1}", - useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code); - - return; - } + // Reset packet to null for the check below + packet = null; - lock (clientCircuits) - { - if (!clientCircuits.ContainsKey(userEP)) - clientCircuits.Add(userEP, useCircuit.CircuitCode.Code); - else - m_log.Error("[CLIENT]: clientCircuits already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding."); - } - - // This data structure is synchronized, so we don't need the lock - if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code)) - clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP); - else - m_log.Error("[CLIENT]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code + ". NOT adding."); - - lock (proxyCircuits) - { - if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code)) + if (packetInbox.Dequeue(100, ref incomingPacket)) { - proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP); - } - else - { - // re-set proxy endpoint - proxyCircuits.Remove(useCircuit.CircuitCode.Code); - proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP); + packet = incomingPacket.Packet; + client = incomingPacket.Client; + + if (packet != null && client != null) + client.ClientAPI.ProcessInPacket(packet); } } - m_packetServer.AddNewClient(userEP, useCircuit, sessionInfo, proxyEP); + if (packetInbox.Count > 0) + m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count + " packets"); + packetInbox.Clear(); + } + + private void OutgoingPacketHandler() + { + int now = Environment.TickCount; + int elapsedMS = 0; + int elapsed100MS = 0; + + while (base.IsRunning) + { + bool resendUnacked = false; + bool sendAcks = false; + bool packetSent = false; + + elapsedMS += Environment.TickCount - now; + + // Check for packets that need to be resent every 100ms + if (elapsedMS >= 100) + { + resendUnacked = true; + elapsedMS -= 100; + ++elapsed100MS; + } + // Check for ACKs that need to be sent out every 500ms + if (elapsed100MS >= 5) + { + sendAcks = true; + elapsed100MS = 0; + } + + clients.ForEach( + delegate(LLUDPClient client) + { + if (client.DequeueOutgoing()) + packetSent = true; + if (resendUnacked) + ResendUnacked(client); + if (sendAcks) + SendAcks(client); + } + ); + + if (!packetSent) + Thread.Sleep(20); + } + } + + private void LogoutHandler(IClientAPI client) + { + client.SendLogoutPacket(); + RemoveClient(client); + } + + internal void SendPacketFinal(OutgoingPacket outgoingPacket) + { + UDPPacketBuffer buffer = outgoingPacket.Buffer; + byte flags = buffer.Data[0]; + bool isResend = (flags & Helpers.MSG_RESENT) != 0; + bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; + LLUDPClient client = outgoingPacket.Client; + + // Keep track of when this packet was sent out (right now) + outgoingPacket.TickCount = Environment.TickCount; + + #region ACK Appending + + int dataLength = buffer.DataLength; + + // Keep appending ACKs until there is no room left in the packet or there are + // no more ACKs to append + uint ackCount = 0; + uint ack; + while (dataLength + 5 < buffer.Data.Length && client.PendingAcks.Dequeue(out ack)) + { + Utils.UIntToBytesBig(ack, buffer.Data, dataLength); + dataLength += 4; + ++ackCount; + } + + if (ackCount > 0) + { + // Set the last byte of the packet equal to the number of appended ACKs + buffer.Data[dataLength++] = (byte)ackCount; + // Set the appended ACKs flag on this packet + buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS); + } + + buffer.DataLength = dataLength; + + #endregion ACK Appending + + if (!isResend) + { + // Not a resend, assign a new sequence number + uint sequenceNumber = (uint)Interlocked.Increment(ref client.CurrentSequence); + Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1); + outgoingPacket.SequenceNumber = sequenceNumber; + + if (isReliable) + { + // Add this packet to the list of ACK responses we are waiting on from the server + client.NeedAcks.Add(outgoingPacket); + } + } + + // Put the UDP payload on the wire + AsyncBeginSend(buffer); } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUtil.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUtil.cs index c45d11fb11..066b19d031 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUtil.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUtil.cs @@ -25,8 +25,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; +using System.Collections.Generic; +using System.Net; using OpenMetaverse; +using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim; + namespace OpenSim.Region.ClientStack.LindenUDP { public class LLUtil diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs index cde155b2e1..7d0757f3d1 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests TestClient testClient = new TestClient(agent, scene); - ILLPacketHandler packetHandler + LLPacketHandler packetHandler = new LLPacketHandler(testClient, testLLPacketServer, new ClientStackUserSettings()); packetHandler.InPacket(new AgentAnimationPacket()); diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs b/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs index 1fba8472ef..e995d65edb 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs @@ -37,7 +37,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests /// protected Dictionary m_packetsReceived = new Dictionary(); - public TestLLPacketServer(ILLClientStackNetworkHandler networkHandler, ClientStackUserSettings userSettings) + public TestLLPacketServer(LLUDPServer networkHandler, ClientStackUserSettings userSettings) : base(networkHandler, userSettings) {} From e7c877407f2a72a9519eb53debca5aeef20cded9 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 02:38:00 -0700 Subject: [PATCH 02/36] * Continued work on the new LLUDP implementation. Appears to be functioning, although not everything is reimplemented yet * Replaced logic in ThreadTracker with a call to System.Diagnostics that does the same thing * Added Util.StringToBytes256() and Util.StringToBytes1024() to clamp output at byte[256] and byte[1024], respectively * Fixed formatting for a MySQLAssetData error logging line --- OpenSim/Data/MySQL/MySQLAssetData.cs | 6 +- OpenSim/Framework/Parallel.cs | 207 +++++ OpenSim/Framework/ThreadTracker.cs | 127 +-- OpenSim/Framework/Util.cs | 36 + .../{LLQueItem.cs => IncomingPacket.cs} | 21 +- ....cs => IncomingPacketHistoryCollection.cs} | 62 +- .../Region/ClientStack/LindenUDP/J2KImage.cs | 33 +- .../ClientStack/LindenUDP/LLClientView.cs | 286 +++--- .../ClientStack/LindenUDP/LLPacketHandler.cs | 875 ------------------ .../ClientStack/LindenUDP/LLPacketQueue.cs | 742 --------------- .../ClientStack/LindenUDP/LLPacketServer.cs | 206 ----- .../ClientStack/LindenUDP/LLUDPClient.cs | 370 ++++++++ .../LindenUDP/LLUDPClientCollection.cs | 185 ++++ .../ClientStack/LindenUDP/LLUDPServer.cs | 138 ++- .../{LLUtil.cs => OutgoingPacket.cs} | 40 +- .../ClientStack/LindenUDP/ThrottleRates.cs | 76 ++ .../LindenUDP/UnackedPacketCollection.cs | 114 +++ 17 files changed, 1280 insertions(+), 2244 deletions(-) create mode 100644 OpenSim/Framework/Parallel.cs rename OpenSim/Region/ClientStack/LindenUDP/{LLQueItem.cs => IncomingPacket.cs} (85%) rename OpenSim/Region/ClientStack/LindenUDP/{KillPacket.cs => IncomingPacketHistoryCollection.cs} (61%) delete mode 100644 OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs delete mode 100644 OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs delete mode 100644 OpenSim/Region/ClientStack/LindenUDP/LLPacketServer.cs create mode 100644 OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs create mode 100644 OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs rename OpenSim/Region/ClientStack/LindenUDP/{LLUtil.cs => OutgoingPacket.cs} (65%) create mode 100644 OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs create mode 100644 OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index 8f974400fa..259e186629 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -239,10 +239,8 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.ErrorFormat( - "[ASSETS DB]: " + - "MySql failure creating asset {0} with name {1}" + Environment.NewLine + e.ToString() - + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name); + m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Attempting reconnect. Error: {2}", + asset.FullID, asset.Name, e.Message); _dbConnection.Reconnect(); } } diff --git a/OpenSim/Framework/Parallel.cs b/OpenSim/Framework/Parallel.cs new file mode 100644 index 0000000000..74537ba460 --- /dev/null +++ b/OpenSim/Framework/Parallel.cs @@ -0,0 +1,207 @@ +/* + * 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; +using System.Collections.Generic; +using System.Threading; + +namespace OpenSim.Framework +{ + /// + /// Provides helper methods for parallelizing loops + /// + public static class Parallel + { + private static readonly int processorCount = System.Environment.ProcessorCount; + + /// + /// Executes a for loop in which iterations may run in parallel + /// + /// The loop will be started at this index + /// The loop will be terminated before this index is reached + /// Method body to run for each iteration of the loop + public static void For(int fromInclusive, int toExclusive, Action body) + { + For(processorCount, fromInclusive, toExclusive, body); + } + + /// + /// Executes a for loop in which iterations may run in parallel + /// + /// The number of concurrent execution threads to run + /// The loop will be started at this index + /// The loop will be terminated before this index is reached + /// Method body to run for each iteration of the loop + public static void For(int threadCount, int fromInclusive, int toExclusive, Action body) + { + int counter = threadCount; + AutoResetEvent threadFinishEvent = new AutoResetEvent(false); + Exception exception = null; + + --fromInclusive; + + for (int i = 0; i < threadCount; i++) + { + ThreadPool.QueueUserWorkItem( + delegate(object o) + { + int threadIndex = (int)o; + + while (exception == null) + { + int currentIndex = Interlocked.Increment(ref fromInclusive); + + if (currentIndex >= toExclusive) + break; + + try { body(currentIndex); } + catch (Exception ex) { exception = ex; break; } + } + + if (Interlocked.Decrement(ref counter) == 0) + threadFinishEvent.Set(); + }, i + ); + } + + threadFinishEvent.WaitOne(); + + if (exception != null) + throw new Exception(exception.Message, exception); + } + + /// + /// Executes a foreach loop in which iterations may run in parallel + /// + /// Object type that the collection wraps + /// An enumerable collection to iterate over + /// Method body to run for each object in the collection + public static void ForEach(IEnumerable enumerable, Action body) + { + ForEach(processorCount, enumerable, body); + } + + /// + /// Executes a foreach loop in which iterations may run in parallel + /// + /// Object type that the collection wraps + /// The number of concurrent execution threads to run + /// An enumerable collection to iterate over + /// Method body to run for each object in the collection + public static void ForEach(int threadCount, IEnumerable enumerable, Action body) + { + int counter = threadCount; + AutoResetEvent threadFinishEvent = new AutoResetEvent(false); + IEnumerator enumerator = enumerable.GetEnumerator(); + Exception exception = null; + + for (int i = 0; i < threadCount; i++) + { + ThreadPool.QueueUserWorkItem( + delegate(object o) + { + int threadIndex = (int)o; + + while (exception == null) + { + T entry; + + lock (enumerator) + { + if (!enumerator.MoveNext()) + break; + entry = (T)enumerator.Current; // Explicit typecast for Mono's sake + } + + try { body(entry); } + catch (Exception ex) { exception = ex; break; } + } + + if (Interlocked.Decrement(ref counter) == 0) + threadFinishEvent.Set(); + }, i + ); + } + + threadFinishEvent.WaitOne(); + + if (exception != null) + throw new Exception(exception.Message, exception); + } + + /// + /// Executes a series of tasks in parallel + /// + /// A series of method bodies to execute + public static void Invoke(params Action[] actions) + { + Invoke(processorCount, actions); + } + + /// + /// Executes a series of tasks in parallel + /// + /// The number of concurrent execution threads to run + /// A series of method bodies to execute + public static void Invoke(int threadCount, params Action[] actions) + { + int counter = threadCount; + AutoResetEvent threadFinishEvent = new AutoResetEvent(false); + int index = -1; + Exception exception = null; + + for (int i = 0; i < threadCount; i++) + { + ThreadPool.QueueUserWorkItem( + delegate(object o) + { + int threadIndex = (int)o; + + while (exception == null) + { + int currentIndex = Interlocked.Increment(ref index); + + if (currentIndex >= actions.Length) + break; + + try { actions[currentIndex](); } + catch (Exception ex) { exception = ex; break; } + } + + if (Interlocked.Decrement(ref counter) == 0) + threadFinishEvent.Set(); + }, i + ); + } + + threadFinishEvent.WaitOne(); + + if (exception != null) + throw new Exception(exception.Message, exception); + } + } +} diff --git a/OpenSim/Framework/ThreadTracker.cs b/OpenSim/Framework/ThreadTracker.cs index d3a239de22..b68d9b3278 100644 --- a/OpenSim/Framework/ThreadTracker.cs +++ b/OpenSim/Framework/ThreadTracker.cs @@ -26,138 +26,21 @@ */ using System; -using System.Collections; using System.Collections.Generic; using System.Reflection; -using System.Threading; +using System.Diagnostics; using log4net; namespace OpenSim.Framework { public static class ThreadTracker { - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private static readonly long ThreadTimeout = 30 * 10000000; - public static List m_Threads; - public static Thread ThreadTrackerThread; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - static ThreadTracker() + public static ProcessThreadCollection GetThreads() { -#if DEBUG - m_Threads = new List(); - ThreadTrackerThread = new Thread(ThreadTrackerThreadLoop); - ThreadTrackerThread.Name = "ThreadTrackerThread"; - ThreadTrackerThread.IsBackground = true; - ThreadTrackerThread.Priority = ThreadPriority.BelowNormal; - ThreadTrackerThread.Start(); - Add(ThreadTrackerThread); -#endif + Process thisProc = Process.GetCurrentProcess(); + return thisProc.Threads; } - - private static void ThreadTrackerThreadLoop() - { - try - { - while (true) - { - Thread.Sleep(5000); - CleanUp(); - } - } - catch (Exception e) - { - m_log.ErrorFormat( - "[THREAD TRACKER]: Thread tracker cleanup thread terminating with exception. Please report this error. Exception is {0}", - e); - } - } - - public static void Add(Thread thread) - { -#if DEBUG - if (thread != null) - { - lock (m_Threads) - { - ThreadTrackerItem tti = new ThreadTrackerItem(); - tti.Thread = thread; - tti.LastSeenActive = DateTime.Now.Ticks; - m_Threads.Add(tti); - } - } -#endif - } - - public static void Remove(Thread thread) - { -#if DEBUG - lock (m_Threads) - { - foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) - { - if (tti.Thread == thread) - m_Threads.Remove(tti); - } - } -#endif - } - - public static void CleanUp() - { - lock (m_Threads) - { - foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) - { - try - { - - - if (tti.Thread.IsAlive) - { - // Its active - tti.LastSeenActive = DateTime.Now.Ticks; - } - else - { - // Its not active -- if its expired then remove it - if (tti.LastSeenActive + ThreadTimeout < DateTime.Now.Ticks) - m_Threads.Remove(tti); - } - } - catch (NullReferenceException) - { - m_Threads.Remove(tti); - } - } - } - } - - public static List GetThreads() - { - if (m_Threads == null) - return null; - - List threads = new List(); - lock (m_Threads) - { - foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) - { - threads.Add(tti.Thread); - } - } - return threads; - } - - #region Nested type: ThreadTrackerItem - - public class ThreadTrackerItem - { - public long LastSeenActive; - public Thread Thread; - } - - #endregion } } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 0851d26b69..189fa3853e 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1231,6 +1231,42 @@ namespace OpenSim.Framework return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri; } + public static byte[] StringToBytes256(string str) + { + if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } + if (str.Length > 254) str = str.Remove(254); + if (!str.EndsWith("\0")) { str += "\0"; } + + // Because this is UTF-8 encoding and not ASCII, it's possible we + // might have gotten an oversized array even after the string trim + byte[] data = UTF8.GetBytes(str); + if (data.Length > 256) + { + Array.Resize(ref data, 256); + data[255] = 0; + } + + return data; + } + + public static byte[] StringToBytes1024(string str) + { + if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } + if (str.Length > 1023) str = str.Remove(1023); + if (!str.EndsWith("\0")) { str += "\0"; } + + // Because this is UTF-8 encoding and not ASCII, it's possible we + // might have gotten an oversized array even after the string trim + byte[] data = UTF8.GetBytes(str); + if (data.Length > 1024) + { + Array.Resize(ref data, 1024); + data[1023] = 0; + } + + return data; + } + #region FireAndForget Threading Pattern public static void FireAndForget(System.Threading.WaitCallback callback) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs b/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs similarity index 85% rename from OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs rename to OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs index 0ed2bc13ea..dc0d62aaf2 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLQueItem.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -26,24 +26,17 @@ */ using System; -using OpenMetaverse.Packets; using OpenSim.Framework; +using OpenMetaverse; +using OpenMetaverse.Packets; namespace OpenSim.Region.ClientStack.LindenUDP { - public class LLQueItem + public struct IncomingPacket { - public LLQueItem() - { - } - + /// Client this packet came from + public LLUDPClient Client; + /// Packet data that has been received public Packet Packet; - public bool Incoming; - public ThrottleOutPacketType throttleType; - public int TickCount; - public Object Identifier; - public int Resends; - public int Length; - public uint Sequence; } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/KillPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs similarity index 61% rename from OpenSim/Region/ClientStack/LindenUDP/KillPacket.cs rename to OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs index a80c1f026c..1f73a1d7fd 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/KillPacket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -25,47 +25,49 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using OpenMetaverse.Packets; +using System; +using System.Collections.Generic; namespace OpenSim.Region.ClientStack.LindenUDP { /// - /// When packetqueue dequeues this packet in the outgoing stream, it thread aborts - /// Ensures that the thread abort happens from within the client thread - /// regardless of where the close method is called + /// A circular buffer and hashset for tracking incoming packet sequence + /// numbers /// - class KillPacket : Packet + public sealed class IncomingPacketHistoryCollection { - public override int Length + private readonly uint[] m_items; + private HashSet m_hashSet; + private int m_first; + private int m_next; + private int m_capacity; + + public IncomingPacketHistoryCollection(int capacity) { - get { return 0; } + this.m_capacity = capacity; + m_items = new uint[capacity]; + m_hashSet = new HashSet(); } - public override void FromBytes(Header header, byte[] bytes, ref int i, ref int packetEnd) + public bool TryEnqueue(uint ack) { - } + lock (m_hashSet) + { + if (m_hashSet.Add(ack)) + { + m_items[m_next] = ack; + m_next = (m_next + 1) % m_capacity; + if (m_next == m_first) + { + m_hashSet.Remove(m_items[m_first]); + m_first = (m_first + 1) % m_capacity; + } - public override void FromBytes(byte[] bytes, ref int i, ref int packetEnd, byte[] zeroBuffer) - { - } + return true; + } + } - public override byte[] ToBytes() - { - return new byte[0]; - } - - public override byte[][] ToBytesMultiple() - { - return new byte[][] { new byte[0] }; - } - - public KillPacket() - { - Type = PacketType.UseCircuitCode; - Header = new Header(); - Header.Frequency = OpenMetaverse.PacketFrequency.Low; - Header.ID = 65531; - Header.Reliable = true; + return false; } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 000f455c3f..2f1face8cf 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs @@ -76,27 +76,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (m_currentPacket <= m_stopPacket) { - bool SendMore = true; + int count = 0; + bool sendMore = true; + if (!m_sentInfo || (m_currentPacket == 0)) { - if (SendFirstPacket(client)) - { - SendMore = false; - } + sendMore = !SendFirstPacket(client); + m_sentInfo = true; - m_currentPacket++; + ++m_currentPacket; + ++count; } if (m_currentPacket < 2) { m_currentPacket = 2; } - - int count = 0; - while (SendMore && count < maxpack && m_currentPacket <= m_stopPacket) + + while (sendMore && count < maxpack && m_currentPacket <= m_stopPacket) { - count++; - SendMore = SendPacket(client); - m_currentPacket++; + sendMore = SendPacket(client); + ++m_currentPacket; + ++count; } if (m_currentPacket > m_stopPacket) @@ -196,15 +196,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_currentPacket = StartPacket; } - - if (m_imageManager != null && m_imageManager.Client != null) - { - if (m_imageManager.Client.IsThrottleEmpty(ThrottleOutPacketType.Texture)) - { - //m_log.Debug("No textures queued, sending one packet to kickstart it"); - SendPacket(m_imageManager.Client); - } - } } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 31cd53ff06..767020f27c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -70,28 +70,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP private readonly LLUDPServer m_udpServer; private readonly LLUDPClient m_udpClient; private readonly UUID m_sessionId; - private readonly UUID m_secureSessionId = UUID.Zero; + private readonly UUID m_secureSessionId; private readonly UUID m_agentId; private readonly uint m_circuitCode; - private readonly byte[] m_channelVersion = Utils.StringToBytes("OpenSimulator Server"); // Dummy value needed by libSL + private readonly byte[] m_channelVersion = Utils.EmptyBytes; private readonly Dictionary m_defaultAnimations = new Dictionary(); private readonly IGroupsModule m_GroupsModule; - private int m_debugPacketLevel; private int m_cachedTextureSerial; - private Timer m_clientPingTimer; private Timer m_avatarTerseUpdateTimer; private List m_avatarTerseUpdates = new List(); private Timer m_primTerseUpdateTimer; private List m_primTerseUpdates = new List(); private Timer m_primFullUpdateTimer; private List m_primFullUpdates = new List(); - private bool m_clientBlocked; - private int m_probesWithNoIngressPackets; private int m_moneyBalance; private int m_animationSequenceNumber = 1; private bool m_SendLogoutPacketWhenClosing = true; - private int m_inPacketsChecked; private AgentUpdateArgs lastarg; private bool m_IsActive = true; @@ -170,58 +165,72 @@ namespace OpenSim.Region.ClientStack.LindenUDP RegisterInterface(this); RegisterInterface(this); RegisterInterface(this); - m_GroupsModule = scene.RequestModuleInterface(); - - m_moneyBalance = 1000; - - m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); - + InitDefaultAnimations(); m_scene = scene; - //m_assetCache = assetCache; - m_assetService = m_scene.RequestModuleInterface(); - - m_udpServer = udpServer; - m_udpClient = udpClient; - + m_GroupsModule = scene.RequestModuleInterface(); + m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface()); + m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); m_agentId = agentId; m_sessionId = sessionId; + m_secureSessionId = sessionInfo.LoginInfo.SecureSession; m_circuitCode = circuitCode; - m_userEndPoint = remoteEP; - m_firstName = sessionInfo.LoginInfo.First; m_lastName = sessionInfo.LoginInfo.Last; m_startpos = sessionInfo.LoginInfo.StartPos; + m_moneyBalance = 1000; - if (sessionInfo.LoginInfo.SecureSession != UUID.Zero) - { - m_secureSessionId = sessionInfo.LoginInfo.SecureSession; - } - - // While working on this, the BlockingQueue had me fooled for a bit. - // The Blocking queue causes the thread to stop until there's something - // in it to process. It's an on-purpose threadlock though because - // without it, the clientloop will suck up all sim resources. - - //m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); - //m_PacketHandler.SynchronizeClient = SynchronizeClient; - //m_PacketHandler.OnPacketStats += PopulateStats; - //m_PacketHandler.OnQueueEmpty += HandleQueueEmpty; + m_udpServer = udpServer; + m_udpClient = udpClient; + m_udpClient.OnQueueEmpty += HandleQueueEmpty; + // FIXME: Implement this + //m_udpClient.OnPacketStats += PopulateStats; RegisterLocalPacketHandlers(); - m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface()); } - public void SetDebugPacketLevel(int newDebugPacketLevel) + public void SetDebugPacketLevel(int newDebug) { - m_debugPacketLevel = newDebugPacketLevel; } #region Client Methods + /// + /// Close down the client view. This *must* be the last method called, since the last # + /// statement of CloseCleanup() aborts the thread. + /// + /// + public void Close(bool shutdownCircuit) + { + m_log.DebugFormat( + "[CLIENT]: Close has been called with shutdownCircuit = {0} for {1} attached to scene {2}", + shutdownCircuit, Name, m_scene.RegionInfo.RegionName); + + if (m_imageManager != null) + m_imageManager.Close(); + + if (m_udpServer != null) + m_udpServer.Flush(); + + // raise an event on the packet server to Shutdown the circuit + // Now, if we raise the event then the packet server will call this method itself, so don't try cleanup + // here otherwise we'll end up calling it twice. + // FIXME: In truth, I might be wrong but this whole business of calling this method twice (with different args) looks + // horribly tangly. Hopefully it should be possible to greatly simplify it. + if (shutdownCircuit) + { + if (OnConnectionClosed != null) + OnConnectionClosed(this); + } + else + { + CloseCleanup(shutdownCircuit); + } + } + private void CloseCleanup(bool shutdownCircuit) { m_scene.RemoveClient(AgentId); @@ -236,9 +245,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP Thread.Sleep(2000); // Shut down timers. Thread Context of this method is murky. Lock all timers - if (m_clientPingTimer.Enabled) - lock (m_clientPingTimer) - m_clientPingTimer.Stop(); if (m_avatarTerseUpdateTimer.Enabled) lock (m_avatarTerseUpdateTimer) m_avatarTerseUpdateTimer.Stop(); @@ -271,43 +277,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP // of the client thread regardless of where Close() is called. KillEndDone(); } - - Terminate(); - } - /// - /// Close down the client view. This *must* be the last method called, since the last # - /// statement of CloseCleanup() aborts the thread. - /// - /// - public void Close(bool shutdownCircuit) - { - m_clientPingTimer.Enabled = false; + IsActive = false; - m_log.DebugFormat( - "[CLIENT]: Close has been called with shutdownCircuit = {0} for {1} attached to scene {2}", - shutdownCircuit, Name, m_scene.RegionInfo.RegionName); + m_avatarTerseUpdateTimer.Close(); + m_primTerseUpdateTimer.Close(); + m_primFullUpdateTimer.Close(); - if (m_imageManager != null) - m_imageManager.Close(); + //m_udpServer.OnPacketStats -= PopulateStats; + m_udpClient.Shutdown(); - if (m_udpServer != null) - m_udpServer.Flush(); + // wait for thread stoped + // m_clientThread.Join(); - // raise an event on the packet server to Shutdown the circuit - // Now, if we raise the event then the packet server will call this method itself, so don't try cleanup - // here otherwise we'll end up calling it twice. - // FIXME: In truth, I might be wrong but this whole business of calling this method twice (with different args) looks - // horribly tangly. Hopefully it should be possible to greatly simplify it. - if (shutdownCircuit) - { - if (OnConnectionClosed != null) - OnConnectionClosed(this); - } - else - { - CloseCleanup(shutdownCircuit); - } + // delete circuit code + //m_networkServer.CloseClient(this); } public void Kick(string message) @@ -329,10 +313,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void Stop() { // Shut down timers. Thread Context is Murky, lock all timers! - if (m_clientPingTimer.Enabled) - lock (m_clientPingTimer) - m_clientPingTimer.Stop(); - if (m_avatarTerseUpdateTimer.Enabled) lock (m_avatarTerseUpdateTimer) m_avatarTerseUpdateTimer.Stop(); @@ -346,25 +326,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdateTimer.Stop(); } - private void Terminate() - { - IsActive = false; - - m_clientPingTimer.Close(); - m_avatarTerseUpdateTimer.Close(); - m_primTerseUpdateTimer.Close(); - m_primFullUpdateTimer.Close(); - - //m_udpServer.OnPacketStats -= PopulateStats; - m_udpClient.Shutdown(); - - // wait for thread stoped - // m_clientThread.Join(); - - // delete circuit code - //m_networkServer.CloseClient(this); - } - #endregion Client Methods #region Packet Handling @@ -452,7 +413,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return result; } - protected void DebugPacket(string direction, Packet packet) + /*protected void DebugPacket(string direction, Packet packet) { string info; @@ -478,7 +439,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } Console.WriteLine(m_circuitCode + ":" + direction + ": " + info); - } + }*/ #endregion Packet Handling @@ -490,8 +451,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// protected virtual void InitNewClient() { - //this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache); - m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); m_avatarTerseUpdateTimer.AutoReset = false; @@ -511,11 +470,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void Start() { - m_clientThread = new Thread(RunUserSession); - m_clientThread.Name = "ClientThread"; - m_clientThread.IsBackground = true; - m_clientThread.Start(); - ThreadTracker.Add(m_clientThread); + // This sets up all the timers + InitNewClient(); } /// @@ -523,14 +479,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// protected void RunUserSession() { - //tell this thread we are using the culture set up for the sim (currently hardcoded to en_US) - //otherwise it will override this and use the system default - Culture.SetCurrentCulture(); - try { - // This sets up all the timers - InitNewClient(); + } catch (Exception e) { @@ -1373,8 +1324,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendStartPingCheck(byte seq) { StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); - pc.PingID.PingID = seq; pc.Header.Reliable = false; + + OutgoingPacket oldestPacket = m_udpClient.NeedAcks.GetOldest(); + + pc.PingID.PingID = seq; + pc.PingID.OldestUnacked = (oldestPacket != null) ? oldestPacket.SequenceNumber : 0; + OutPacket(pc, ThrottleOutPacketType.Unknown); } @@ -1450,12 +1406,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP descend.ItemData[i].AssetID = item.AssetID; descend.ItemData[i].CreatorID = item.CreatorIdAsUuid; descend.ItemData[i].BaseMask = item.BasePermissions; - descend.ItemData[i].Description = LLUtil.StringToPacketBytes(item.Description); + descend.ItemData[i].Description = Util.StringToBytes256(item.Description); descend.ItemData[i].EveryoneMask = item.EveryOnePermissions; descend.ItemData[i].OwnerMask = item.CurrentPermissions; descend.ItemData[i].FolderID = item.Folder; descend.ItemData[i].InvType = (sbyte)item.InvType; - descend.ItemData[i].Name = LLUtil.StringToPacketBytes(item.Name); + descend.ItemData[i].Name = Util.StringToBytes256(item.Name); descend.ItemData[i].NextOwnerMask = item.NextPermissions; descend.ItemData[i].OwnerID = item.Owner; descend.ItemData[i].Type = (sbyte)item.AssetType; @@ -1536,7 +1492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { descend.FolderData[i] = new InventoryDescendentsPacket.FolderDataBlock(); descend.FolderData[i].FolderID = folder.ID; - descend.FolderData[i].Name = LLUtil.StringToPacketBytes(folder.Name); + descend.FolderData[i].Name = Util.StringToBytes256(folder.Name); descend.FolderData[i].ParentID = folder.ParentID; descend.FolderData[i].Type = (sbyte)folder.Type; @@ -1651,11 +1607,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP inventoryReply.InventoryData[0].BaseMask = item.BasePermissions; inventoryReply.InventoryData[0].CreationDate = item.CreationDate; - inventoryReply.InventoryData[0].Description = LLUtil.StringToPacketBytes(item.Description); + inventoryReply.InventoryData[0].Description = Util.StringToBytes256(item.Description); inventoryReply.InventoryData[0].EveryoneMask = item.EveryOnePermissions; inventoryReply.InventoryData[0].FolderID = item.Folder; inventoryReply.InventoryData[0].InvType = (sbyte)item.InvType; - inventoryReply.InventoryData[0].Name = LLUtil.StringToPacketBytes(item.Name); + inventoryReply.InventoryData[0].Name = Util.StringToBytes256(item.Name); inventoryReply.InventoryData[0].NextOwnerMask = item.NextPermissions; inventoryReply.InventoryData[0].OwnerID = item.Owner; inventoryReply.InventoryData[0].OwnerMask = item.CurrentPermissions; @@ -1780,7 +1736,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP folderBlock.FolderID = folder.ID; folderBlock.ParentID = folder.ParentID; folderBlock.Type = -1; - folderBlock.Name = LLUtil.StringToPacketBytes(folder.Name); + folderBlock.Name = Util.StringToBytes256(folder.Name); return folderBlock; } @@ -1798,11 +1754,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP itemBlock.AssetID = item.AssetID; itemBlock.CreatorID = item.CreatorIdAsUuid; itemBlock.BaseMask = item.BasePermissions; - itemBlock.Description = LLUtil.StringToPacketBytes(item.Description); + itemBlock.Description = Util.StringToBytes256(item.Description); itemBlock.EveryoneMask = item.EveryOnePermissions; itemBlock.FolderID = item.Folder; itemBlock.InvType = (sbyte)item.InvType; - itemBlock.Name = LLUtil.StringToPacketBytes(item.Name); + itemBlock.Name = Util.StringToBytes256(item.Name); itemBlock.NextOwnerMask = item.NextPermissions; itemBlock.OwnerID = item.Owner; itemBlock.OwnerMask = item.CurrentPermissions; @@ -1862,11 +1818,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP bulkUpdate.ItemData[0].CreatorID = item.CreatorIdAsUuid; bulkUpdate.ItemData[0].BaseMask = item.BasePermissions; bulkUpdate.ItemData[0].CreationDate = item.CreationDate; - bulkUpdate.ItemData[0].Description = LLUtil.StringToPacketBytes(item.Description); + bulkUpdate.ItemData[0].Description = Util.StringToBytes256(item.Description); bulkUpdate.ItemData[0].EveryoneMask = item.EveryOnePermissions; bulkUpdate.ItemData[0].FolderID = item.Folder; bulkUpdate.ItemData[0].InvType = (sbyte)item.InvType; - bulkUpdate.ItemData[0].Name = LLUtil.StringToPacketBytes(item.Name); + bulkUpdate.ItemData[0].Name = Util.StringToBytes256(item.Name); bulkUpdate.ItemData[0].NextOwnerMask = item.NextPermissions; bulkUpdate.ItemData[0].OwnerID = item.Owner; bulkUpdate.ItemData[0].OwnerMask = item.CurrentPermissions; @@ -1909,11 +1865,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP InventoryReply.InventoryData[0].AssetID = Item.AssetID; InventoryReply.InventoryData[0].CreatorID = Item.CreatorIdAsUuid; InventoryReply.InventoryData[0].BaseMask = Item.BasePermissions; - InventoryReply.InventoryData[0].Description = LLUtil.StringToPacketBytes(Item.Description); + InventoryReply.InventoryData[0].Description = Util.StringToBytes256(Item.Description); InventoryReply.InventoryData[0].EveryoneMask = Item.EveryOnePermissions; InventoryReply.InventoryData[0].FolderID = Item.Folder; InventoryReply.InventoryData[0].InvType = (sbyte)Item.InvType; - InventoryReply.InventoryData[0].Name = LLUtil.StringToPacketBytes(Item.Name); + InventoryReply.InventoryData[0].Name = Util.StringToBytes256(Item.Name); InventoryReply.InventoryData[0].NextOwnerMask = Item.NextPermissions; InventoryReply.InventoryData[0].OwnerID = Item.Owner; InventoryReply.InventoryData[0].OwnerMask = Item.CurrentPermissions; @@ -2080,7 +2036,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// /// - protected AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) + public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) { AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); alertPack.AgentData.AgentID = AgentId; @@ -3533,7 +3489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP objectData.FullID = objectID; objectData.OwnerID = ownerID; - objectData.Text = LLUtil.StringToPacketBytes(text); + objectData.Text = Util.StringToBytes256(text); objectData.TextColor[0] = color[0]; objectData.TextColor[1] = color[1]; objectData.TextColor[2] = color[2]; @@ -3911,8 +3867,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP objPropDB.SalePrice = SalePrice; objPropDB.Category = Category; objPropDB.LastOwnerID = LastOwnerID; - objPropDB.Name = LLUtil.StringToPacketBytes(ObjectName); - objPropDB.Description = LLUtil.StringToPacketBytes(Description); + objPropDB.Name = Util.StringToBytes256(ObjectName); + objPropDB.Description = Util.StringToBytes256(Description); objPropFamilyPack.ObjectData = objPropDB; objPropFamilyPack.Header.Zerocoded = true; OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task); @@ -3946,11 +3902,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP proper.ObjectData[0].OwnerID = UUID.Zero; else proper.ObjectData[0].OwnerID = OwnerUUID; - proper.ObjectData[0].TouchName = LLUtil.StringToPacketBytes(TouchTitle); + proper.ObjectData[0].TouchName = Util.StringToBytes256(TouchTitle); proper.ObjectData[0].TextureID = TextureID; - proper.ObjectData[0].SitName = LLUtil.StringToPacketBytes(SitTitle); - proper.ObjectData[0].Name = LLUtil.StringToPacketBytes(ItemName); - proper.ObjectData[0].Description = LLUtil.StringToPacketBytes(ItemDescription); + proper.ObjectData[0].SitName = Util.StringToBytes256(SitTitle); + proper.ObjectData[0].Name = Util.StringToBytes256(ItemName); + proper.ObjectData[0].Description = Util.StringToBytes256(ItemDescription); proper.ObjectData[0].OwnerMask = OwnerMask; proper.ObjectData[0].NextOwnerMask = NextOwnerMask; proper.ObjectData[0].GroupMask = GroupMask; @@ -4191,11 +4147,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP updatePacket.ParcelData.MediaAutoScale = landData.MediaAutoScale; updatePacket.ParcelData.MediaID = landData.MediaID; - updatePacket.ParcelData.MediaURL = LLUtil.StringToPacketBytes(landData.MediaURL); - updatePacket.ParcelData.MusicURL = LLUtil.StringToPacketBytes(landData.MusicURL); - updatePacket.ParcelData.Name = Utils.StringToBytes(landData.Name); + updatePacket.ParcelData.MediaURL = Util.StringToBytes256(landData.MediaURL); + updatePacket.ParcelData.MusicURL = Util.StringToBytes256(landData.MusicURL); + updatePacket.ParcelData.Name = Util.StringToBytes256(landData.Name); updatePacket.ParcelData.OtherCleanTime = landData.OtherCleanTime; - updatePacket.ParcelData.OtherCount = 0; //unemplemented + updatePacket.ParcelData.OtherCount = 0; //TODO: Unimplemented updatePacket.ParcelData.OtherPrims = landData.OtherPrims; updatePacket.ParcelData.OwnerID = landData.OwnerID; updatePacket.ParcelData.OwnerPrims = landData.OwnerPrims; @@ -4203,22 +4159,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP updatePacket.ParcelData.ParcelPrimBonus = simObjectBonusFactor; updatePacket.ParcelData.PassHours = landData.PassHours; updatePacket.ParcelData.PassPrice = landData.PassPrice; - updatePacket.ParcelData.PublicCount = 0; //unemplemented + updatePacket.ParcelData.PublicCount = 0; //TODO: Unimplemented - updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint)RegionFlags.DenyAnonymous) > - 0); - updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint)RegionFlags.DenyIdentified) > - 0); - updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint)RegionFlags.DenyTransacted) > - 0); - updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint)RegionFlags.RestrictPushObject) > - 0); + updatePacket.ParcelData.RegionDenyAnonymous = (regionFlags & (uint)RegionFlags.DenyAnonymous) > 0; + updatePacket.ParcelData.RegionDenyIdentified = (regionFlags & (uint)RegionFlags.DenyIdentified) > 0; + updatePacket.ParcelData.RegionDenyTransacted = (regionFlags & (uint)RegionFlags.DenyTransacted) > 0; + updatePacket.ParcelData.RegionPushOverride = (regionFlags & (uint)RegionFlags.RestrictPushObject) > 0; updatePacket.ParcelData.RentPrice = 0; updatePacket.ParcelData.RequestResult = request_result; updatePacket.ParcelData.SalePrice = landData.SalePrice; updatePacket.ParcelData.SelectedPrims = landData.SelectedPrims; - updatePacket.ParcelData.SelfCount = 0; //unemplemented + updatePacket.ParcelData.SelfCount = 0; //TODO: Unimplemented updatePacket.ParcelData.SequenceID = sequence_id; if (landData.SimwideArea > 0) { @@ -5265,18 +5217,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpClient.SetThrottles(throttles); } + /// + /// Get the current throttles for this client as a packed byte array + /// + /// Unused + /// public byte[] GetThrottlesPacked(float multiplier) { return m_udpClient.GetThrottlesPacked(); } - public bool IsThrottleEmpty(ThrottleOutPacketType category) - { - return m_udpClient.IsThrottleEmpty(category); - } - /// - /// Unused + /// Cruft? /// public virtual void InPacket(object NewPack) { @@ -6231,14 +6183,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.AgentPause: - m_probesWithNoIngressPackets = 0; - m_clientBlocked = true; + m_udpClient.IsPaused = true; break; case PacketType.AgentResume: - m_probesWithNoIngressPackets = 0; - m_clientBlocked = false; - SendStartPingCheck(0); + m_udpClient.IsPaused = false; + SendStartPingCheck(m_udpClient.CurrentPingSequence++); break; @@ -8904,14 +8854,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region unimplemented handlers case PacketType.StartPingCheck: - // Send the client the ping response back - // Pass the same PingID in the matching packet - // Handled In the packet processing - //m_log.Debug("[CLIENT]: possibly unhandled StartPingCheck packet"); + StartPingCheckPacket pingStart = (StartPingCheckPacket)Pack; + CompletePingCheckPacket pingComplete = new CompletePingCheckPacket(); + pingComplete.PingID.PingID = pingStart.PingID.PingID; + m_udpServer.SendPacket(m_udpClient, pingComplete, ThrottleOutPacketType.Unknown, false); break; + case PacketType.CompletePingCheck: - // TODO: Perhaps this should be processed on the Sim to determine whether or not to drop a dead client - //m_log.Warn("[CLIENT]: unhandled CompletePingCheck packet"); + // TODO: Do stats tracking or something with these? break; case PacketType.ViewerStats: @@ -10209,16 +10159,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP return info; } - public EndPoint GetClientEP() - { - return m_userEndPoint; - } - public void SetClientInfo(ClientInfo info) { m_udpClient.SetClientInfo(info); } + public EndPoint GetClientEP() + { + return m_userEndPoint; + } + #region Media Parcel Members public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs deleted file mode 100644 index f30df4d7fa..0000000000 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs +++ /dev/null @@ -1,875 +0,0 @@ -/* - * 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; -using System.Reflection; -using System.Collections.Generic; -using System.Net.Sockets; -using System.Threading; -using System.Timers; -using OpenMetaverse; -using OpenMetaverse.Packets; -using log4net; -using OpenSim.Framework; -using Timer=System.Timers.Timer; - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); - public delegate void PacketDrop(Packet pack, Object id); - public delegate void QueueEmpty(ThrottleOutPacketType queue); - public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, UUID agentID, ThrottleOutPacketType throttlePacketType); - - public class LLPacketHandler - { - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - //private int m_resentCount; - - // Packet queues - // - LLPacketQueue m_PacketQueue; - - public LLPacketQueue PacketQueue - { - get { return m_PacketQueue; } - } - - // Timer to run stats and acks on - // - private Timer m_AckTimer = new Timer(250); - - // A list of the packets we haven't acked yet - // - private List m_PendingAcks = new List(); - private Dictionary m_PendingAcksMap = new Dictionary(); - - private Dictionary m_NeedAck = - new Dictionary(); - - /// - /// The number of milliseconds that can pass before a packet that needs an ack is resent. - /// - private uint m_ResendTimeout = 4000; - - public uint ResendTimeout - { - get { return m_ResendTimeout; } - set { m_ResendTimeout = value; } - } - - private int m_MaxReliableResends = 3; - - public int MaxReliableResends - { - get { return m_MaxReliableResends; } - set { m_MaxReliableResends = value; } - } - - // Track duplicated packets. This uses a Dictionary. Both insertion - // and lookup are common operations and need to take advantage of - // the hashing. Expiration is less common and can be allowed the - // time for a linear scan. - // - private List m_alreadySeenList = new List(); - private Dictionarym_alreadySeenTracker = new Dictionary(); - private int m_alreadySeenWindow = 30000; - private int m_lastAlreadySeenCheck = Environment.TickCount & Int32.MaxValue; - - // private Dictionary m_DupeTracker = - // new Dictionary(); - // private uint m_DupeTrackerWindow = 30; - // private int m_DupeTrackerLastCheck = Environment.TickCount; - - // Values for the SimStatsReporter - // - private int m_PacketsReceived = 0; - private int m_PacketsReceivedReported = 0; - private int m_PacketsSent = 0; - private int m_PacketsSentReported = 0; - private int m_UnackedBytes = 0; - - private int m_LastResend = 0; - - public int PacketsReceived - { - get { return m_PacketsReceived; } - } - - public int PacketsReceivedReported - { - get { return m_PacketsReceivedReported; } - } - - // The client we are working for - // - private IClientAPI m_Client; - - // Some events - // - public event PacketStats OnPacketStats; - public event PacketDrop OnPacketDrop; - public event QueueEmpty OnQueueEmpty; - - - //private SynchronizeClientHandler m_SynchronizeClient = null; - - public SynchronizeClientHandler SynchronizeClient - { - set { /* m_SynchronizeClient = value; */ } - } - - // Packet sequencing - // - private uint m_Sequence = 0; - private object m_SequenceLock = new object(); - private const int MAX_SEQUENCE = 0xFFFFFF; - - // Packet dropping - // - List m_ImportantPackets = new List(); - private bool m_ReliableIsImportant = false; - - public bool ReliableIsImportant - { - get { return m_ReliableIsImportant; } - set { m_ReliableIsImportant = value; } - } - - private int m_DropSafeTimeout; - - LLPacketServer m_PacketServer; - private byte[] m_ZeroOutBuffer = new byte[4096]; - - //////////////////////////////////////////////////////////////////// - - // Constructors - // - public LLPacketHandler(IClientAPI client, LLPacketServer server, ClientStackUserSettings userSettings) - { - m_Client = client; - m_PacketServer = server; - m_DropSafeTimeout = Environment.TickCount + 15000; - - m_PacketQueue = new LLPacketQueue(client.AgentId, userSettings); - - m_PacketQueue.OnQueueEmpty += TriggerOnQueueEmpty; - - m_AckTimer.Elapsed += AckTimerElapsed; - m_AckTimer.Start(); - } - - public void Dispose() - { - m_AckTimer.Stop(); - m_AckTimer.Close(); - - m_PacketQueue.Enqueue(null); - m_PacketQueue.Close(); - m_Client = null; - } - - // Send one packet. This actually doesn't send anything, it queues - // it. Designed to be fire-and-forget, but there is an optional - // notifier. - // - public void OutPacket( - Packet packet, ThrottleOutPacketType throttlePacketType) - { - OutPacket(packet, throttlePacketType, null); - } - - public void OutPacket( - Packet packet, ThrottleOutPacketType throttlePacketType, - Object id) - { - // Call the load balancer's hook. If this is not active here - // we defer to the sim server this client is actually connected - // to. Packet drop notifies will not be triggered in this - // configuration! - // - - packet.Header.Sequence = 0; - - lock (m_NeedAck) - { - DropResend(id); - - AddAcks(ref packet); - QueuePacket(packet, throttlePacketType, id); - } - } - - private void AddAcks(ref Packet packet) - { - // These packet types have shown to have issues with - // acks being appended to the payload, just don't send - // any with them until libsl is fixed. - // - if (packet is ViewerEffectPacket) - return; - if (packet is SimStatsPacket) - return; - - // Add acks to outgoing packets - // - if (m_PendingAcks.Count > 0) - { - int count = m_PendingAcks.Count; - if (count > 10) - count = 10; - packet.Header.AckList = new uint[count]; - packet.Header.AppendedAcks = true; - - for (int i = 0; i < count; i++) - { - packet.Header.AckList[i] = m_PendingAcks[i]; - m_PendingAcksMap.Remove(m_PendingAcks[i]); - } - m_PendingAcks.RemoveRange(0, count); - } - } - - private void QueuePacket( - Packet packet, ThrottleOutPacketType throttlePacketType, - Object id) - { - LLQueItem item = new LLQueItem(); - item.Packet = packet; - item.Incoming = false; - item.throttleType = throttlePacketType; - item.TickCount = Environment.TickCount; - item.Identifier = id; - item.Resends = 0; - item.Length = packet.Length; - item.Sequence = packet.Header.Sequence; - - m_PacketQueue.Enqueue(item); - m_PacketsSent++; - } - - private void ResendUnacked() - { - int now = Environment.TickCount; - - int intervalMs = 250; - - if (m_LastResend != 0) - intervalMs = now - m_LastResend; - - lock (m_NeedAck) - { - if (m_DropSafeTimeout > now || - intervalMs > 500) // We were frozen! - { - foreach (LLQueItem data in m_NeedAck.Values) - { - if (m_DropSafeTimeout > now) - { - m_NeedAck[data.Packet.Header.Sequence].TickCount = now; - } - else - { - m_NeedAck[data.Packet.Header.Sequence].TickCount += intervalMs; - } - } - } - - m_LastResend = now; - - // Unless we have received at least one ack, don't bother resending - // anything. There may not be a client there, don't clog up the - // pipes. - - - // Nothing to do - // - if (m_NeedAck.Count == 0) - return; - - int resent = 0; - long dueDate = now - m_ResendTimeout; - - List dropped = new List(); - foreach (LLQueItem data in m_NeedAck.Values) - { - Packet packet = data.Packet; - - // Packets this old get resent - // - if (data.TickCount < dueDate && data.Sequence != 0 && !m_PacketQueue.Contains(data.Sequence)) - { - if (resent < 20) // Was 20 (= Max 117kbit/sec resends) - { - m_NeedAck[packet.Header.Sequence].Resends++; - - // The client needs to be told that a packet is being resent, otherwise it appears to believe - // that it should reset its sequence to that packet number. - packet.Header.Resent = true; - - if ((m_NeedAck[packet.Header.Sequence].Resends >= m_MaxReliableResends) && - (!m_ReliableIsImportant)) - { - dropped.Add(data); - continue; - } - - m_NeedAck[packet.Header.Sequence].TickCount = Environment.TickCount; - QueuePacket(packet, ThrottleOutPacketType.Resend, data.Identifier); - resent++; - } - else - { - m_NeedAck[packet.Header.Sequence].TickCount += intervalMs; - } - } - } - - foreach (LLQueItem data in dropped) - { - m_NeedAck.Remove(data.Packet.Header.Sequence); - TriggerOnPacketDrop(data.Packet, data.Identifier); - m_PacketQueue.Cancel(data.Packet.Header.Sequence); - PacketPool.Instance.ReturnPacket(data.Packet); - } - } - } - - // Send the pending packet acks to the client - // Will send blocks of acks for up to 250 packets - // - private void SendAcks() - { - lock (m_NeedAck) - { - if (m_PendingAcks.Count == 0) - return; - - PacketAckPacket acks = (PacketAckPacket)PacketPool.Instance.GetPacket(PacketType.PacketAck); - - // The case of equality is more common than one might think, - // because this function will be called unconditionally when - // the counter reaches 250. So there is a good chance another - // packet with 250 blocks exists. - // - if (acks.Packets == null || - acks.Packets.Length != m_PendingAcks.Count) - acks.Packets = new PacketAckPacket.PacketsBlock[m_PendingAcks.Count]; - - for (int i = 0; i < m_PendingAcks.Count; i++) - { - acks.Packets[i] = new PacketAckPacket.PacketsBlock(); - acks.Packets[i].ID = m_PendingAcks[i]; - - } - m_PendingAcks.Clear(); - m_PendingAcksMap.Clear(); - - acks.Header.Reliable = false; - OutPacket(acks, ThrottleOutPacketType.Unknown); - } - } - - // Queue a packet ack. It will be sent either after 250 acks are - // queued, or when the timer fires. - // - private void AckPacket(Packet packet) - { - lock (m_NeedAck) - { - if (m_PendingAcks.Count < 250) - { - if (!m_PendingAcksMap.ContainsKey(packet.Header.Sequence)) - { - m_PendingAcks.Add(packet.Header.Sequence); - m_PendingAcksMap.Add(packet.Header.Sequence, - packet.Header.Sequence); - } - return; - } - } - - SendAcks(); - - lock (m_NeedAck) - { - // If this is still full we have a truly exceptional - // condition (means, can't happen) - // - if (m_PendingAcks.Count < 250) - { - if (!m_PendingAcksMap.ContainsKey(packet.Header.Sequence)) - { - m_PendingAcks.Add(packet.Header.Sequence); - m_PendingAcksMap.Add(packet.Header.Sequence, - packet.Header.Sequence); - } - return; - } - } - } - - // When the timer elapses, send the pending acks, trigger resends - // and report all the stats. - // - private void AckTimerElapsed(object sender, ElapsedEventArgs ea) - { - SendAcks(); - ResendUnacked(); - SendPacketStats(); - } - - // Push out pachet counts for the sim status reporter - // - private void SendPacketStats() - { - PacketStats handlerPacketStats = OnPacketStats; - if (handlerPacketStats != null) - { - handlerPacketStats( - m_PacketsReceived - m_PacketsReceivedReported, - m_PacketsSent - m_PacketsSentReported, - m_UnackedBytes); - - m_PacketsReceivedReported = m_PacketsReceived; - m_PacketsSentReported = m_PacketsSent; - } - } - - // We can't keep an unlimited record of dupes. This will prune the - // dictionary by age. - // - // NOTE: this needs to be called from within lock - // (m_alreadySeenTracker) context! - private void ExpireSeenPackets() - { - if (m_alreadySeenList.Count < 1024) - return; - - int ticks = 0; - int tc = Environment.TickCount & Int32.MaxValue; - if (tc >= m_lastAlreadySeenCheck) - ticks = tc - m_lastAlreadySeenCheck; - else - ticks = Int32.MaxValue - m_lastAlreadySeenCheck + tc; - - if (ticks < 2000) return; - m_lastAlreadySeenCheck = tc; - - // we calculate the drop dead tick count here instead of - // in the loop: any packet with a timestamp before - // dropDeadTC can be expired - int dropDeadTC = tc - m_alreadySeenWindow; - int i = 0; - while (i < m_alreadySeenList.Count && m_alreadySeenTracker[m_alreadySeenList[i]] < dropDeadTC) - { - m_alreadySeenTracker.Remove(m_alreadySeenList[i]); - i++; - } - // if we dropped packet from m_alreadySeenTracker we need - // to drop them from m_alreadySeenList as well, let's do - // that in one go: the list is ordered after all. - if (i > 0) - { - m_alreadySeenList.RemoveRange(0, i); - // m_log.DebugFormat("[CLIENT]: expired {0} packets, {1}:{2} left", i, m_alreadySeenList.Count, m_alreadySeenTracker.Count); - } - } - - public void InPacket(Packet packet) - { - if (packet == null) - return; - - // When too many acks are needed to be sent, the client sends - // a packet consisting of acks only - // - if (packet.Type == PacketType.PacketAck) - { - PacketAckPacket ackPacket = (PacketAckPacket)packet; - - foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) - { - ProcessAck(block.ID); - } - - PacketPool.Instance.ReturnPacket(packet); - return; - } - - // Any packet can have some packet acks in the header. - // Process them here - // - if (packet.Header.AppendedAcks) - { - foreach (uint id in packet.Header.AckList) - { - ProcessAck(id); - } - } - - // If this client is on another partial instance, no need - // to handle packets - // - if (!m_Client.IsActive && packet.Type != PacketType.LogoutRequest) - { - PacketPool.Instance.ReturnPacket(packet); - return; - } - - if (packet.Type == PacketType.StartPingCheck) - { - StartPingCheckPacket startPing = (StartPingCheckPacket)packet; - CompletePingCheckPacket endPing - = (CompletePingCheckPacket)PacketPool.Instance.GetPacket(PacketType.CompletePingCheck); - - endPing.PingID.PingID = startPing.PingID.PingID; - OutPacket(endPing, ThrottleOutPacketType.Task); - } - else - { - LLQueItem item = new LLQueItem(); - item.Packet = packet; - item.Incoming = true; - m_PacketQueue.Enqueue(item); - } - } - - public void ProcessInPacket(LLQueItem item) - { - Packet packet = item.Packet; - - // Always ack the packet! - // - if (packet.Header.Reliable) - AckPacket(packet); - - if (packet.Type != PacketType.AgentUpdate) - m_PacketsReceived++; - - // Check for duplicate packets.. packets that the client is - // resending because it didn't receive our ack - // - lock (m_alreadySeenTracker) - { - ExpireSeenPackets(); - - if (m_alreadySeenTracker.ContainsKey(packet.Header.Sequence)) - return; - - m_alreadySeenTracker.Add(packet.Header.Sequence, Environment.TickCount & Int32.MaxValue); - m_alreadySeenList.Add(packet.Header.Sequence); - } - - m_Client.ProcessInPacket(packet); - } - - public void Flush() - { - m_PacketQueue.Flush(); - m_UnackedBytes = (-1 * m_UnackedBytes); - SendPacketStats(); - } - - public void Clear() - { - m_UnackedBytes = (-1 * m_UnackedBytes); - SendPacketStats(); - lock (m_NeedAck) - { - m_NeedAck.Clear(); - m_PendingAcks.Clear(); - m_PendingAcksMap.Clear(); - } - m_Sequence += 1000000; - } - - private void ProcessAck(uint id) - { - LLQueItem data; - - lock (m_NeedAck) - { - //m_log.DebugFormat("[CLIENT]: In {0} received ack for packet {1}", m_Client.Scene.RegionInfo.ExternalEndPoint.Port, id); - - if (!m_NeedAck.TryGetValue(id, out data)) - return; - - m_NeedAck.Remove(id); - m_PacketQueue.Cancel(data.Sequence); - PacketPool.Instance.ReturnPacket(data.Packet); - m_UnackedBytes -= data.Length; - } - } - - // Allocate packet sequence numbers in a threadsave manner - // - protected uint NextPacketSequenceNumber() - { - // Set the sequence number - uint seq = 1; - lock (m_SequenceLock) - { - if (m_Sequence >= MAX_SEQUENCE) - { - m_Sequence = 1; - } - else - { - m_Sequence++; - } - seq = m_Sequence; - } - return seq; - } - - public ClientInfo GetClientInfo() - { - ClientInfo info = new ClientInfo(); - - info.pendingAcks = m_PendingAcksMap; - info.needAck = new Dictionary(); - - lock (m_NeedAck) - { - foreach (uint key in m_NeedAck.Keys) - info.needAck.Add(key, m_NeedAck[key].Packet.ToBytes()); - } - - LLQueItem[] queitems = m_PacketQueue.GetQueueArray(); - - for (int i = 0; i < queitems.Length; i++) - { - if (queitems[i].Incoming == false) - info.out_packets.Add(queitems[i].Packet.ToBytes()); - } - - info.sequence = m_Sequence; - - float multiplier = m_PacketQueue.ThrottleMultiplier; - info.resendThrottle = (int) (m_PacketQueue.ResendThrottle.Throttle / multiplier); - info.landThrottle = (int) (m_PacketQueue.LandThrottle.Throttle / multiplier); - info.windThrottle = (int) (m_PacketQueue.WindThrottle.Throttle / multiplier); - info.cloudThrottle = (int) (m_PacketQueue.CloudThrottle.Throttle / multiplier); - info.taskThrottle = (int) (m_PacketQueue.TaskThrottle.Throttle / multiplier); - info.assetThrottle = (int) (m_PacketQueue.AssetThrottle.Throttle / multiplier); - info.textureThrottle = (int) (m_PacketQueue.TextureThrottle.Throttle / multiplier); - info.totalThrottle = (int) (m_PacketQueue.TotalThrottle.Throttle / multiplier); - - return info; - } - - public void SetClientInfo(ClientInfo info) - { - m_PendingAcksMap = info.pendingAcks; - m_PendingAcks = new List(m_PendingAcksMap.Keys); - m_NeedAck = new Dictionary(); - - Packet packet = null; - int packetEnd = 0; - byte[] zero = new byte[3000]; - - foreach (uint key in info.needAck.Keys) - { - byte[] buff = info.needAck[key]; - packetEnd = buff.Length - 1; - - try - { - packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero); - } - catch (Exception) - { - } - - LLQueItem item = new LLQueItem(); - item.Packet = packet; - item.Incoming = false; - item.throttleType = 0; - item.TickCount = Environment.TickCount; - item.Identifier = 0; - item.Resends = 0; - item.Length = packet.Length; - item.Sequence = packet.Header.Sequence; - m_NeedAck.Add(key, item); - } - - m_Sequence = info.sequence; - - m_PacketQueue.ResendThrottle.Throttle = info.resendThrottle; - m_PacketQueue.LandThrottle.Throttle = info.landThrottle; - m_PacketQueue.WindThrottle.Throttle = info.windThrottle; - m_PacketQueue.CloudThrottle.Throttle = info.cloudThrottle; - m_PacketQueue.TaskThrottle.Throttle = info.taskThrottle; - m_PacketQueue.AssetThrottle.Throttle = info.assetThrottle; - m_PacketQueue.TextureThrottle.Throttle = info.textureThrottle; - m_PacketQueue.TotalThrottle.Throttle = info.totalThrottle; - } - - public void AddImportantPacket(PacketType type) - { - if (m_ImportantPackets.Contains(type)) - return; - - m_ImportantPackets.Add(type); - } - - public void RemoveImportantPacket(PacketType type) - { - if (!m_ImportantPackets.Contains(type)) - return; - - m_ImportantPackets.Remove(type); - } - - private void DropResend(Object id) - { - LLQueItem d = null; - - foreach (LLQueItem data in m_NeedAck.Values) - { - if (data.Identifier != null && data.Identifier == id) - { - d = data; - break; - } - } - - if (null == d) return; - - m_NeedAck.Remove(d.Packet.Header.Sequence); - m_PacketQueue.Cancel(d.Sequence); - PacketPool.Instance.ReturnPacket(d.Packet); - } - - private void TriggerOnPacketDrop(Packet packet, Object id) - { - PacketDrop handlerPacketDrop = OnPacketDrop; - - if (handlerPacketDrop == null) - return; - - handlerPacketDrop(packet, id); - } - - private void TriggerOnQueueEmpty(ThrottleOutPacketType queue) - { - QueueEmpty handlerQueueEmpty = OnQueueEmpty; - - if (handlerQueueEmpty != null) - handlerQueueEmpty(queue); - } - - // Convert the packet to bytes and stuff it onto the send queue - // - public void ProcessOutPacket(LLQueItem item) - { - Packet packet = item.Packet; - - // Assign sequence number here to prevent out of order packets - if (packet.Header.Sequence == 0) - { - lock (m_NeedAck) - { - packet.Header.Sequence = NextPacketSequenceNumber(); - item.Sequence = packet.Header.Sequence; - item.TickCount = Environment.TickCount; - - // We want to see that packet arrive if it's reliable - if (packet.Header.Reliable) - { - m_UnackedBytes += item.Length; - - // Keep track of when this packet was sent out - item.TickCount = Environment.TickCount; - - m_NeedAck[packet.Header.Sequence] = item; - } - } - } - - // If we sent a killpacket - if (packet is KillPacket) - Abort(); - - try - { - // If this packet has been reused/returned, the ToBytes - // will blow up in our face. - // Fail gracefully. - // - - // Actually make the byte array and send it - byte[] sendbuffer = item.Packet.ToBytes(); - - if (packet.Header.Zerocoded) - { - int packetsize = Helpers.ZeroEncode(sendbuffer, - sendbuffer.Length, m_ZeroOutBuffer); - m_PacketServer.SendPacketTo(m_ZeroOutBuffer, packetsize, - SocketFlags.None, m_Client.CircuitCode); - } - else - { - // Need some extra space in case we need to add proxy - // information to the message later - Buffer.BlockCopy(sendbuffer, 0, m_ZeroOutBuffer, 0, - sendbuffer.Length); - m_PacketServer.SendPacketTo(m_ZeroOutBuffer, - sendbuffer.Length, SocketFlags.None, m_Client.CircuitCode); - } - } - catch (NullReferenceException) - { - m_log.Error("[PACKET]: Detected reuse of a returned packet"); - m_PacketQueue.Cancel(item.Sequence); - return; - } - - // If this is a reliable packet, we are still holding a ref - // Dont't return in that case - // - if (!packet.Header.Reliable) - { - m_PacketQueue.Cancel(item.Sequence); - PacketPool.Instance.ReturnPacket(packet); - } - } - - private void Abort() - { - m_PacketQueue.Close(); - Thread.CurrentThread.Abort(); - } - - public int GetQueueCount(ThrottleOutPacketType queue) - { - return m_PacketQueue.GetQueueCount(queue); - } - } -} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs deleted file mode 100644 index 3eed2e0fc1..0000000000 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs +++ /dev/null @@ -1,742 +0,0 @@ -/* - * 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; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using System.Timers; -using log4net; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Statistics; -using OpenSim.Framework.Statistics.Interfaces; -using Timer=System.Timers.Timer; - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - public class LLPacketQueue : IPullStatsProvider, IDisposable - { - private static readonly ILog m_log - = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// Is queueing enabled at all? - /// - private bool m_enabled = true; - - private OpenSim.Framework.BlockingQueue SendQueue; - - private Queue IncomingPacketQueue; - private Queue OutgoingPacketQueue; - private Queue ResendOutgoingPacketQueue; - private Queue LandOutgoingPacketQueue; - private Queue WindOutgoingPacketQueue; - private Queue CloudOutgoingPacketQueue; - private Queue TaskOutgoingPacketQueue; - private Queue TaskLowpriorityPacketQueue; - private Queue TextureOutgoingPacketQueue; - private Queue AssetOutgoingPacketQueue; - - private List Empty = new List(); - // m_log.Info("[THROTTLE]: Entering Throttle"); - // private Dictionary PendingAcks = new Dictionary(); - // private Dictionary NeedAck = new Dictionary(); - - // All throttle times and number of bytes are calculated by dividing by this value - // This value also determines how many times per throttletimems the timer will run - // If throttleimems is 1000 ms, then the timer will fire every 1000/7 milliseconds - - private float throttleMultiplier = 2.0f; // Default value really doesn't matter. - private int throttleTimeDivisor = 7; - - private int throttletimems = 1000; - - internal LLPacketThrottle ResendThrottle; - internal LLPacketThrottle LandThrottle; - internal LLPacketThrottle WindThrottle; - internal LLPacketThrottle CloudThrottle; - internal LLPacketThrottle TaskThrottle; - internal LLPacketThrottle AssetThrottle; - internal LLPacketThrottle TextureThrottle; - internal LLPacketThrottle TotalThrottle; - - private Dictionary contents = new Dictionary(); - - // private long LastThrottle; - // private long ThrottleInterval; - private Timer throttleTimer; - - private UUID m_agentId; - - public event QueueEmpty OnQueueEmpty; - - public LLPacketQueue(UUID agentId, ClientStackUserSettings userSettings) - { - // While working on this, the BlockingQueue had me fooled for a bit. - // The Blocking queue causes the thread to stop until there's something - // in it to process. it's an on-purpose threadlock though because - // without it, the clientloop will suck up all sim resources. - - SendQueue = new OpenSim.Framework.BlockingQueue(); - - IncomingPacketQueue = new Queue(); - OutgoingPacketQueue = new Queue(); - ResendOutgoingPacketQueue = new Queue(); - LandOutgoingPacketQueue = new Queue(); - WindOutgoingPacketQueue = new Queue(); - CloudOutgoingPacketQueue = new Queue(); - TaskOutgoingPacketQueue = new Queue(); - TaskLowpriorityPacketQueue = new Queue(); - TextureOutgoingPacketQueue = new Queue(); - AssetOutgoingPacketQueue = new Queue(); - - // Store the throttle multiplier for posterity. - throttleMultiplier = userSettings.ClientThrottleMultipler; - - - int throttleMaxBPS = 1500000; - if (userSettings.TotalThrottleSettings != null) - throttleMaxBPS = userSettings.TotalThrottleSettings.Max; - - // Set up the throttle classes (min, max, current) in bits per second - ResendThrottle = new LLPacketThrottle(5000, throttleMaxBPS / 15, 16000, userSettings.ClientThrottleMultipler); - LandThrottle = new LLPacketThrottle(1000, throttleMaxBPS / 15, 2000, userSettings.ClientThrottleMultipler); - WindThrottle = new LLPacketThrottle(0, throttleMaxBPS / 15, 0, userSettings.ClientThrottleMultipler); - CloudThrottle = new LLPacketThrottle(0, throttleMaxBPS / 15, 0, userSettings.ClientThrottleMultipler); - TaskThrottle = new LLPacketThrottle(1000, throttleMaxBPS / 2, 3000, userSettings.ClientThrottleMultipler); - AssetThrottle = new LLPacketThrottle(1000, throttleMaxBPS / 2, 1000, userSettings.ClientThrottleMultipler); - TextureThrottle = new LLPacketThrottle(1000, throttleMaxBPS / 2, 4000, userSettings.ClientThrottleMultipler); - - - // Total Throttle trumps all - it is the number of bits in total that are allowed to go out per second. - - - ThrottleSettings totalThrottleSettings = userSettings.TotalThrottleSettings; - if (null == totalThrottleSettings) - { - totalThrottleSettings = new ThrottleSettings(0, throttleMaxBPS, 28000); - } - - TotalThrottle - = new LLPacketThrottle( - totalThrottleSettings.Min, totalThrottleSettings.Max, totalThrottleSettings.Current, - userSettings.ClientThrottleMultipler); - - throttleTimer = new Timer((int)(throttletimems / throttleTimeDivisor)); - throttleTimer.Elapsed += ThrottleTimerElapsed; - throttleTimer.Start(); - - // TIMERS needed for this - // LastThrottle = DateTime.Now.Ticks; - // ThrottleInterval = (long)(throttletimems/throttleTimeDivisor); - - m_agentId = agentId; - - if (StatsManager.SimExtraStats != null) - { - StatsManager.SimExtraStats.RegisterPacketQueueStatsProvider(m_agentId, this); - } - } - - /* STANDARD QUEUE MANIPULATION INTERFACES */ - - public void Enqueue(LLQueItem item) - { - if (!m_enabled) - { - return; - } - // We could micro lock, but that will tend to actually - // probably be worse than just synchronizing on SendQueue - - if (item == null) - { - SendQueue.Enqueue(item); - return; - } - - if (item.Incoming) - { - SendQueue.PriorityEnqueue(item); - return; - } - - if (item.Sequence != 0) - lock (contents) - { - if (contents.ContainsKey(item.Sequence)) - contents[item.Sequence] += 1; - else - contents.Add(item.Sequence, 1); - } - - lock (this) - { - switch (item.throttleType & ThrottleOutPacketType.TypeMask) - { - case ThrottleOutPacketType.Resend: - ThrottleCheck(ref ResendThrottle, ref ResendOutgoingPacketQueue, item, ThrottleOutPacketType.Resend); - break; - case ThrottleOutPacketType.Texture: - ThrottleCheck(ref TextureThrottle, ref TextureOutgoingPacketQueue, item, ThrottleOutPacketType.Texture); - break; - case ThrottleOutPacketType.Task: - if ((item.throttleType & ThrottleOutPacketType.LowPriority) != 0) - ThrottleCheck(ref TaskThrottle, ref TaskLowpriorityPacketQueue, item, ThrottleOutPacketType.Task); - else - ThrottleCheck(ref TaskThrottle, ref TaskOutgoingPacketQueue, item, ThrottleOutPacketType.Task); - break; - case ThrottleOutPacketType.Land: - ThrottleCheck(ref LandThrottle, ref LandOutgoingPacketQueue, item, ThrottleOutPacketType.Land); - break; - case ThrottleOutPacketType.Asset: - ThrottleCheck(ref AssetThrottle, ref AssetOutgoingPacketQueue, item, ThrottleOutPacketType.Asset); - break; - case ThrottleOutPacketType.Cloud: - ThrottleCheck(ref CloudThrottle, ref CloudOutgoingPacketQueue, item, ThrottleOutPacketType.Cloud); - break; - case ThrottleOutPacketType.Wind: - ThrottleCheck(ref WindThrottle, ref WindOutgoingPacketQueue, item, ThrottleOutPacketType.Wind); - break; - - default: - // Acknowledgements and other such stuff should go directly to the blocking Queue - // Throttling them may and likely 'will' be problematic - SendQueue.PriorityEnqueue(item); - break; - } - } - } - - public LLQueItem Dequeue() - { - while (true) - { - LLQueItem item = SendQueue.Dequeue(); - if (item == null) - return null; - if (item.Incoming) - return item; - item.TickCount = System.Environment.TickCount; - if (item.Sequence == 0) - return item; - lock (contents) - { - if (contents.ContainsKey(item.Sequence)) - { - if (contents[item.Sequence] == 1) - contents.Remove(item.Sequence); - else - contents[item.Sequence] -= 1; - return item; - } - } - } - } - - public void Cancel(uint sequence) - { - lock (contents) contents.Remove(sequence); - } - - public bool Contains(uint sequence) - { - lock (contents) return contents.ContainsKey(sequence); - } - - public void Flush() - { - lock (this) - { - // These categories do not contain transactional packets so we can safely drop any pending data in them - LandOutgoingPacketQueue.Clear(); - WindOutgoingPacketQueue.Clear(); - CloudOutgoingPacketQueue.Clear(); - TextureOutgoingPacketQueue.Clear(); - AssetOutgoingPacketQueue.Clear(); - - // Now comes the fun part.. we dump all remaining resend and task packets into the send queue - while (ResendOutgoingPacketQueue.Count > 0 || TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) - { - if (ResendOutgoingPacketQueue.Count > 0) - SendQueue.Enqueue(ResendOutgoingPacketQueue.Dequeue()); - - if (TaskOutgoingPacketQueue.Count > 0) - SendQueue.PriorityEnqueue(TaskOutgoingPacketQueue.Dequeue()); - - if (TaskLowpriorityPacketQueue.Count > 0) - SendQueue.Enqueue(TaskLowpriorityPacketQueue.Dequeue()); - } - } - } - - public void WipeClean() - { - lock (this) - { - ResendOutgoingPacketQueue.Clear(); - LandOutgoingPacketQueue.Clear(); - WindOutgoingPacketQueue.Clear(); - CloudOutgoingPacketQueue.Clear(); - TaskOutgoingPacketQueue.Clear(); - TaskLowpriorityPacketQueue.Clear(); - TextureOutgoingPacketQueue.Clear(); - AssetOutgoingPacketQueue.Clear(); - SendQueue.Clear(); - lock (contents) contents.Clear(); - } - } - - public void Close() - { - Dispose(); - } - - public void Dispose() - { - Flush(); - WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby - - m_enabled = false; - throttleTimer.Stop(); - throttleTimer.Close(); - - if (StatsManager.SimExtraStats != null) - { - StatsManager.SimExtraStats.DeregisterPacketQueueStatsProvider(m_agentId); - } - } - - private void ResetCounters() - { - ResendThrottle.Reset(); - LandThrottle.Reset(); - WindThrottle.Reset(); - CloudThrottle.Reset(); - TaskThrottle.Reset(); - AssetThrottle.Reset(); - TextureThrottle.Reset(); - TotalThrottle.Reset(); - } - - private bool PacketsWaiting() - { - return (ResendOutgoingPacketQueue.Count > 0 || - LandOutgoingPacketQueue.Count > 0 || - WindOutgoingPacketQueue.Count > 0 || - CloudOutgoingPacketQueue.Count > 0 || - TaskOutgoingPacketQueue.Count > 0 || - TaskLowpriorityPacketQueue.Count > 0 || - AssetOutgoingPacketQueue.Count > 0 || - TextureOutgoingPacketQueue.Count > 0); - } - - public void ProcessThrottle() - { - // I was considering this.. Will an event fire if the thread it's on is blocked? - - // Then I figured out.. it doesn't really matter.. because this thread won't be blocked for long - // The General overhead of the UDP protocol gets sent to the queue un-throttled by this - // so This'll pick up about around the right time. - - int MaxThrottleLoops = 4550; // 50*7 packets can be dequeued at once. - int throttleLoops = 0; - List e; - - // We're going to dequeue all of the saved up packets until - // we've hit the throttle limit or there's no more packets to send - lock (this) - { - // this variable will be true if there was work done in the last execution of the - // loop, since each pass through the loop checks the queue length, we no longer - // need the check on entering the loop - bool qchanged = true; - - ResetCounters(); - - while (TotalThrottle.UnderLimit() && qchanged && throttleLoops <= MaxThrottleLoops) - { - qchanged = false; // We will break out of the loop if no work was accomplished - - throttleLoops++; - //Now comes the fun part.. we dump all our elements into m_packetQueue that we've saved up. - if ((ResendOutgoingPacketQueue.Count > 0) && ResendThrottle.UnderLimit()) - { - LLQueItem qpack = ResendOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - ResendThrottle.AddBytes(qpack.Length); - - qchanged = true; - } - - if ((LandOutgoingPacketQueue.Count > 0) && LandThrottle.UnderLimit()) - { - LLQueItem qpack = LandOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - LandThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (LandOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Land)) - Empty.Add(ThrottleOutPacketType.Land); - } - - if ((WindOutgoingPacketQueue.Count > 0) && WindThrottle.UnderLimit()) - { - LLQueItem qpack = WindOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - WindThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (WindOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Wind)) - Empty.Add(ThrottleOutPacketType.Wind); - } - - if ((CloudOutgoingPacketQueue.Count > 0) && CloudThrottle.UnderLimit()) - { - LLQueItem qpack = CloudOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - CloudThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (CloudOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Cloud)) - Empty.Add(ThrottleOutPacketType.Cloud); - } - - if ((TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) && TaskThrottle.UnderLimit()) - { - LLQueItem qpack; - if (TaskOutgoingPacketQueue.Count > 0) - { - qpack = TaskOutgoingPacketQueue.Dequeue(); - SendQueue.PriorityEnqueue(qpack); - } - else - { - qpack = TaskLowpriorityPacketQueue.Dequeue(); - SendQueue.Enqueue(qpack); - } - - TotalThrottle.AddBytes(qpack.Length); - TaskThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (TaskOutgoingPacketQueue.Count == 0 && TaskLowpriorityPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Task)) - Empty.Add(ThrottleOutPacketType.Task); - } - - if ((TextureOutgoingPacketQueue.Count > 0) && TextureThrottle.UnderLimit()) - { - LLQueItem qpack = TextureOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - TextureThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (TextureOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Texture)) - Empty.Add(ThrottleOutPacketType.Texture); - } - - if ((AssetOutgoingPacketQueue.Count > 0) && AssetThrottle.UnderLimit()) - { - LLQueItem qpack = AssetOutgoingPacketQueue.Dequeue(); - - SendQueue.Enqueue(qpack); - TotalThrottle.AddBytes(qpack.Length); - AssetThrottle.AddBytes(qpack.Length); - qchanged = true; - - if (AssetOutgoingPacketQueue.Count == 0 && !Empty.Contains(ThrottleOutPacketType.Asset)) - Empty.Add(ThrottleOutPacketType.Asset); - } - } - // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); - - e = new List(Empty); - Empty.Clear(); - } - - foreach (ThrottleOutPacketType t in e) - { - if (GetQueueCount(t) == 0) - TriggerOnQueueEmpty(t); - } - } - - private void TriggerOnQueueEmpty(ThrottleOutPacketType queue) - { - QueueEmpty handlerQueueEmpty = OnQueueEmpty; - - if (handlerQueueEmpty != null) - handlerQueueEmpty(queue); - } - - private void ThrottleTimerElapsed(object sender, ElapsedEventArgs e) - { - // just to change the signature, and that ProcessThrottle - // will be used elsewhere possibly - ProcessThrottle(); - } - - private void ThrottleCheck(ref LLPacketThrottle throttle, ref Queue q, LLQueItem item, ThrottleOutPacketType itemType) - { - // The idea.. is if the packet throttle queues are empty - // and the client is under throttle for the type. Queue - // it up directly. This basically short cuts having to - // wait for the timer to fire to put things into the - // output queue - - if ((q.Count == 0) && (throttle.UnderLimit())) - { - try - { - Monitor.Enter(this); - throttle.AddBytes(item.Length); - TotalThrottle.AddBytes(item.Length); - SendQueue.Enqueue(item); - lock (this) - { - if (!Empty.Contains(itemType)) - Empty.Add(itemType); - } - } - catch (Exception e) - { - // Probably a serialization exception - m_log.WarnFormat("ThrottleCheck: {0}", e.ToString()); - } - finally - { - Monitor.Pulse(this); - Monitor.Exit(this); - } - } - else - { - q.Enqueue(item); - } - } - - private static int ScaleThrottle(int value, int curmax, int newmax) - { - return (int)((value / (float)curmax) * newmax); - } - - public byte[] GetThrottlesPacked(float multiplier) - { - int singlefloat = 4; - float tResend = ResendThrottle.Throttle*multiplier; - float tLand = LandThrottle.Throttle*multiplier; - float tWind = WindThrottle.Throttle*multiplier; - float tCloud = CloudThrottle.Throttle*multiplier; - float tTask = TaskThrottle.Throttle*multiplier; - float tTexture = TextureThrottle.Throttle*multiplier; - float tAsset = AssetThrottle.Throttle*multiplier; - - byte[] throttles = new byte[singlefloat*7]; - int i = 0; - Buffer.BlockCopy(BitConverter.GetBytes(tResend), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tLand), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tWind), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tCloud), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tTask), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tTexture), 0, throttles, singlefloat*i, singlefloat); - i++; - Buffer.BlockCopy(BitConverter.GetBytes(tAsset), 0, throttles, singlefloat*i, singlefloat); - - return throttles; - } - - public void SetThrottleFromClient(byte[] throttle) - { - // From mantis http://opensimulator.org/mantis/view.php?id=1374 - // it appears that sometimes we are receiving empty throttle byte arrays. - // TODO: Investigate this behaviour - if (throttle.Length == 0) - { - m_log.Warn("[PACKET QUEUE]: SetThrottleFromClient unexpectedly received a throttle byte array containing no elements!"); - return; - } - - int tResend = -1; - int tLand = -1; - int tWind = -1; - int tCloud = -1; - int tTask = -1; - int tTexture = -1; - int tAsset = -1; - int tall = -1; - int singlefloat = 4; - - //Agent Throttle Block contains 7 single floatingpoint values. - int j = 0; - - // Some Systems may be big endian... - // it might be smart to do this check more often... - if (!BitConverter.IsLittleEndian) - for (int i = 0; i < 7; i++) - Array.Reverse(throttle, j + i*singlefloat, singlefloat); - - // values gotten from OpenMetaverse.org/wiki/Throttle. Thanks MW_ - // bytes - // Convert to integer, since.. the full fp space isn't used. - tResend = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tLand = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tWind = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tCloud = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tTask = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tTexture = (int) BitConverter.ToSingle(throttle, j); - j += singlefloat; - tAsset = (int) BitConverter.ToSingle(throttle, j); - - tall = tResend + tLand + tWind + tCloud + tTask + tTexture + tAsset; - - /* - m_log.Info("[CLIENT]: Client AgentThrottle - Got throttle:resendbits=" + tResend + - " landbits=" + tLand + - " windbits=" + tWind + - " cloudbits=" + tCloud + - " taskbits=" + tTask + - " texturebits=" + tTexture + - " Assetbits=" + tAsset + - " Allbits=" + tall); - */ - - - // Total Sanity - // Make sure that the client sent sane total values. - - // If the client didn't send acceptable values.... - // Scale the clients values down until they are acceptable. - - if (tall <= TotalThrottle.Max) - { - ResendThrottle.Throttle = tResend; - LandThrottle.Throttle = tLand; - WindThrottle.Throttle = tWind; - CloudThrottle.Throttle = tCloud; - TaskThrottle.Throttle = tTask; - TextureThrottle.Throttle = tTexture; - AssetThrottle.Throttle = tAsset; - TotalThrottle.Throttle = tall; - } -// else if (tall < 1) -// { -// // client is stupid, penalize him by minning everything -// ResendThrottle.Throttle = ResendThrottle.Min; -// LandThrottle.Throttle = LandThrottle.Min; -// WindThrottle.Throttle = WindThrottle.Min; -// CloudThrottle.Throttle = CloudThrottle.Min; -// TaskThrottle.Throttle = TaskThrottle.Min; -// TextureThrottle.Throttle = TextureThrottle.Min; -// AssetThrottle.Throttle = AssetThrottle.Min; -// TotalThrottle.Throttle = TotalThrottle.Min; -// } - else - { - // we're over so figure out percentages and use those - ResendThrottle.Throttle = tResend; - - LandThrottle.Throttle = ScaleThrottle(tLand, tall, TotalThrottle.Max); - WindThrottle.Throttle = ScaleThrottle(tWind, tall, TotalThrottle.Max); - CloudThrottle.Throttle = ScaleThrottle(tCloud, tall, TotalThrottle.Max); - TaskThrottle.Throttle = ScaleThrottle(tTask, tall, TotalThrottle.Max); - TextureThrottle.Throttle = ScaleThrottle(tTexture, tall, TotalThrottle.Max); - AssetThrottle.Throttle = ScaleThrottle(tAsset, tall, TotalThrottle.Max); - TotalThrottle.Throttle = TotalThrottle.Max; - } - // effectively wiggling the slider causes things reset -// ResetCounters(); // DO NOT reset, better to send less for one period than more - } - - // See IPullStatsProvider - public string GetStats() - { - return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", - SendQueue.Count(), - IncomingPacketQueue.Count, - OutgoingPacketQueue.Count, - ResendOutgoingPacketQueue.Count, - LandOutgoingPacketQueue.Count, - WindOutgoingPacketQueue.Count, - CloudOutgoingPacketQueue.Count, - TaskOutgoingPacketQueue.Count, - TextureOutgoingPacketQueue.Count, - AssetOutgoingPacketQueue.Count); - } - - public LLQueItem[] GetQueueArray() - { - return SendQueue.GetQueueArray(); - } - - public float ThrottleMultiplier - { - get { return throttleMultiplier; } - } - - public int GetQueueCount(ThrottleOutPacketType queue) - { - switch (queue) - { - case ThrottleOutPacketType.Land: - return LandOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Wind: - return WindOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Cloud: - return CloudOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Task: - return TaskOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Texture: - return TextureOutgoingPacketQueue.Count; - case ThrottleOutPacketType.Asset: - return AssetOutgoingPacketQueue.Count; - } - - return 0; - } - } -} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketServer.cs deleted file mode 100644 index f08b7be002..0000000000 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketServer.cs +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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.Net; -using System.Net.Sockets; -using OpenMetaverse; -using OpenMetaverse.Packets; -using OpenSim.Framework; - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - /// - /// This class sets up new client stacks. It also handles the immediate distribution of incoming packets to - /// client stacks - /// - public class LLPacketServer - { -// private static readonly log4net.ILog m_log -// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - protected readonly LLUDPServer m_networkHandler; - protected IScene m_scene; - - /// - /// Tweakable user settings - /// - private ClientStackUserSettings m_userSettings; - - public LLPacketServer(LLUDPServer networkHandler, ClientStackUserSettings userSettings) - { - m_userSettings = userSettings; - m_networkHandler = networkHandler; - - m_networkHandler.RegisterPacketServer(this); - } - - public IScene LocalScene - { - set { m_scene = value; } - } - - /// - /// Process an incoming packet. - /// - /// - /// - public virtual void InPacket(uint circuitCode, Packet packet) - { - m_scene.ClientManager.InPacket(circuitCode, packet); - } - - /// - /// Create a new client circuit - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - protected virtual IClientAPI CreateNewCircuit( - EndPoint remoteEP, IScene scene, - LLPacketServer packServer, AuthenticateResponse sessionInfo, - UUID agentId, UUID sessionId, uint circuitCode, EndPoint proxyEP) - { - return - new LLClientView( - remoteEP, scene, packServer, sessionInfo, agentId, sessionId, circuitCode, proxyEP, - m_userSettings); - } - - /// - /// Check whether a given client is authorized to connect. - /// - /// - /// - /// - /// - public virtual bool IsClientAuthorized( - UseCircuitCodePacket useCircuit, AgentCircuitManager circuitManager, out AuthenticateResponse sessionInfo) - { - UUID agentId = useCircuit.CircuitCode.ID; - UUID sessionId = useCircuit.CircuitCode.SessionID; - uint circuitCode = useCircuit.CircuitCode.Code; - - sessionInfo = circuitManager.AuthenticateSession(sessionId, agentId, circuitCode); - - if (!sessionInfo.Authorised) - return false; - - return true; - } - - /// - /// Add a new client circuit. We assume that is has already passed an authorization check - /// - /// - /// - /// - /// - /// - /// - /// true if a new circuit was created, false if a circuit with the given circuit code already existed - /// - public virtual bool AddNewClient( - EndPoint epSender, UseCircuitCodePacket useCircuit, - AuthenticateResponse sessionInfo, EndPoint proxyEP) - { - IClientAPI newuser; - uint circuitCode = useCircuit.CircuitCode.Code; - - if (m_scene.ClientManager.TryGetClient(circuitCode, out newuser)) - { - // The circuit is already known to the scene. This not actually a problem since this will currently - // occur if a client is crossing borders (hence upgrading its circuit). However, we shouldn't - // really by trying to add a new client if this is the case. - return false; - } - - UUID agentId = useCircuit.CircuitCode.ID; - UUID sessionId = useCircuit.CircuitCode.SessionID; - - newuser - = CreateNewCircuit( - epSender, m_scene, this, sessionInfo, agentId, sessionId, circuitCode, proxyEP); - - m_scene.ClientManager.Add(circuitCode, newuser); - - newuser.OnViewerEffect += m_scene.ClientManager.ViewerEffectHandler; - newuser.OnLogout += LogoutHandler; - newuser.OnConnectionClosed += CloseClient; - - newuser.Start(); - - return true; - } - - public void LogoutHandler(IClientAPI client) - { - client.SendLogoutPacket(); - CloseClient(client); - } - - /// - /// Send a packet to the given circuit - /// - /// - /// - /// - /// - public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode) - { - m_networkHandler.SendPacketTo(buffer, size, flags, circuitcode); - } - - /// - /// Close a client circuit only - /// - /// - public virtual void CloseCircuit(uint circuitcode) - { - m_networkHandler.RemoveClientCircuit(circuitcode); - } - - /// - /// Completely close down the given client. - /// - /// - public virtual void CloseClient(IClientAPI client) - { - //m_log.Info("PacketServer:CloseClient()"); - - CloseCircuit(client.CircuitCode); - m_scene.ClientManager.Remove(client.CircuitCode); - client.Close(false); - } - } -} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs new file mode 100644 index 0000000000..ad01135d67 --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -0,0 +1,370 @@ +/* + * 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; +using System.Collections.Generic; +using System.Net; +using OpenSim.Framework; +using OpenMetaverse; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + public delegate void QueueEmpty(ThrottleOutPacketType category); + + public class LLUDPClient + { + /// The number of packet categories to throttle on. If a throttle category is added + /// or removed, this number must also change + const int THROTTLE_CATEGORY_COUNT = 7; + + public event QueueEmpty OnQueueEmpty; + + /// AgentID for this client + public readonly UUID AgentID; + /// The remote address of the connected client + public readonly IPEndPoint RemoteEndPoint; + /// Circuit code that this client is connected on + public readonly uint CircuitCode; + /// Sequence numbers of packets we've received (for duplicate checking) + public readonly IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200); + /// Packets we have sent that need to be ACKed by the client + public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); + /// ACKs that are queued up, waiting to be sent to the client + public readonly LocklessQueue PendingAcks = new LocklessQueue(); + + /// Reference to the IClientAPI for this client + public LLClientView ClientAPI; + /// Current packet sequence number + public int CurrentSequence; + /// Current ping sequence number + public byte CurrentPingSequence; + /// True when this connection is alive, otherwise false + public bool IsConnected = true; + /// True when this connection is paused, otherwise false + public bool IsPaused = true; + /// Environment.TickCount when the last packet was received for this client + public int TickLastPacketReceived; + + /// Timer granularity. This is set to the measured resolution of Environment.TickCount + public readonly float G; + /// Smoothed round-trip time. A smoothed average of the round-trip time for sending a + /// reliable packet to the client and receiving an ACK + public float SRTT; + /// Round-trip time variance. Measures the consistency of round-trip times + public float RTTVAR; + /// Retransmission timeout. Packets that have not been acknowledged in this number of + /// milliseconds or longer will be resent + /// Calculated from and using the + /// guidelines in RFC 2988 + public int RTO; + /// Number of bytes received since the last acknowledgement was sent out. This is used + /// to loosely follow the TCP delayed ACK algorithm in RFC 1122 (4.2.3.2) + public int BytesSinceLastACK; + + /// Throttle bucket for this agent's connection + private readonly TokenBucket throttle; + /// Throttle buckets for each packet category + private readonly TokenBucket[] throttleCategories; + /// Throttle rate defaults and limits + private readonly ThrottleRates defaultThrottleRates; + /// Outgoing queues for throttled packets + private readonly LocklessQueue[] packetOutboxes = new LocklessQueue[THROTTLE_CATEGORY_COUNT]; + /// A container that can hold one packet for each outbox, used to store + /// dequeued packets that are being held for throttling + private readonly OutgoingPacket[] nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; + /// An optimization to store the length of dequeued packets being held + /// for throttling. This avoids expensive calls to Packet.Length + private readonly int[] nextPacketLengths = new int[THROTTLE_CATEGORY_COUNT]; + /// A reference to the LLUDPServer that is managing this client + private readonly LLUDPServer udpServer; + + public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint) + { + udpServer = server; + AgentID = agentID; + RemoteEndPoint = remoteEndPoint; + CircuitCode = circuitCode; + defaultThrottleRates = rates; + + for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) + packetOutboxes[i] = new LocklessQueue(); + + throttle = new TokenBucket(parentThrottle, 0, 0); + throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; + throttleCategories[(int)ThrottleOutPacketType.Resend] = new TokenBucket(throttle, rates.ResendLimit, rates.Resend); + throttleCategories[(int)ThrottleOutPacketType.Land] = new TokenBucket(throttle, rates.LandLimit, rates.Land); + throttleCategories[(int)ThrottleOutPacketType.Wind] = new TokenBucket(throttle, rates.WindLimit, rates.Wind); + throttleCategories[(int)ThrottleOutPacketType.Cloud] = new TokenBucket(throttle, rates.CloudLimit, rates.Cloud); + throttleCategories[(int)ThrottleOutPacketType.Task] = new TokenBucket(throttle, rates.TaskLimit, rates.Task); + throttleCategories[(int)ThrottleOutPacketType.Texture] = new TokenBucket(throttle, rates.TextureLimit, rates.Texture); + throttleCategories[(int)ThrottleOutPacketType.Asset] = new TokenBucket(throttle, rates.AssetLimit, rates.Asset); + + // Set the granularity variable used for retransmission calculations to + // the measured resolution of Environment.TickCount + G = server.TickCountResolution; + + // Default the retransmission timeout to three seconds + RTO = 3000; + } + + public void Shutdown() + { + IsConnected = false; + } + + public ClientInfo GetClientInfo() + { + // TODO: This data structure is wrong in so many ways + ClientInfo info = new ClientInfo(); + info.pendingAcks = new Dictionary(); + info.needAck = new Dictionary(); + + info.resendThrottle = throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate; + info.landThrottle = throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; + info.windThrottle = throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; + info.cloudThrottle = throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; + info.taskThrottle = throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; + info.assetThrottle = throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; + info.textureThrottle = throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; + info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + + info.taskThrottle + info.assetThrottle + info.textureThrottle; + + return info; + } + + public void SetClientInfo(ClientInfo info) + { + } + + public string GetStats() + { + return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0); + } + + public void SetThrottles(byte[] throttleData) + { + byte[] adjData; + int pos = 0; + + if (!BitConverter.IsLittleEndian) + { + byte[] newData = new byte[7 * 4]; + Buffer.BlockCopy(throttleData, 0, newData, 0, 7 * 4); + + for (int i = 0; i < 7; i++) + Array.Reverse(newData, i * 4, 4); + + adjData = newData; + } + else + { + adjData = throttleData; + } + + int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; + int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; + int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; + int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; + int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; + int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; + int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); + + resend = (resend <= defaultThrottleRates.ResendLimit) ? resend : defaultThrottleRates.ResendLimit; + land = (land <= defaultThrottleRates.LandLimit) ? land : defaultThrottleRates.LandLimit; + wind = (wind <= defaultThrottleRates.WindLimit) ? wind : defaultThrottleRates.WindLimit; + cloud = (cloud <= defaultThrottleRates.CloudLimit) ? cloud : defaultThrottleRates.CloudLimit; + task = (task <= defaultThrottleRates.TaskLimit) ? task : defaultThrottleRates.TaskLimit; + texture = (texture <= defaultThrottleRates.TextureLimit) ? texture : defaultThrottleRates.TextureLimit; + asset = (asset <= defaultThrottleRates.AssetLimit) ? asset : defaultThrottleRates.AssetLimit; + + SetThrottle(ThrottleOutPacketType.Resend, resend); + SetThrottle(ThrottleOutPacketType.Land, land); + SetThrottle(ThrottleOutPacketType.Wind, wind); + SetThrottle(ThrottleOutPacketType.Cloud, cloud); + SetThrottle(ThrottleOutPacketType.Task, task); + SetThrottle(ThrottleOutPacketType.Texture, texture); + SetThrottle(ThrottleOutPacketType.Asset, asset); + } + + public byte[] GetThrottlesPacked() + { + byte[] data = new byte[7 * 4]; + int i = 0; + + Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Land].DripRate), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Task].DripRate), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate), 0, data, i, 4); i += 4; + Buffer.BlockCopy(Utils.FloatToBytes((float)throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate), 0, data, i, 4); i += 4; + + return data; + } + + public void SetThrottle(ThrottleOutPacketType category, int rate) + { + int i = (int)category; + if (i >= 0 && i < throttleCategories.Length) + { + TokenBucket bucket = throttleCategories[(int)category]; + bucket.MaxBurst = rate; + bucket.DripRate = rate; + } + } + + public bool EnqueueOutgoing(OutgoingPacket packet) + { + int category = (int)packet.Category; + + if (category >= 0 && category < packetOutboxes.Length) + { + LocklessQueue queue = packetOutboxes[category]; + TokenBucket bucket = throttleCategories[category]; + + if (throttleCategories[category].RemoveTokens(packet.Buffer.DataLength)) + { + // Enough tokens were removed from the bucket, the packet will not be queued + return false; + } + else + { + // Not enough tokens in the bucket, queue this packet + queue.Enqueue(packet); + return true; + } + } + else + { + // We don't have a token bucket for this category, so it will not be queued + return false; + } + } + + /// + /// Loops through all of the packet queues for this client and tries to send + /// any outgoing packets, obeying the throttling bucket limits + /// + /// This function is only called from a synchronous loop in the + /// UDPServer so we don't need to bother making this thread safe + /// True if any packets were sent, otherwise false + public bool DequeueOutgoing() + { + OutgoingPacket packet; + LocklessQueue queue; + TokenBucket bucket; + bool packetSent = false; + + for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) + { + bucket = throttleCategories[i]; + + if (nextPackets[i] != null) + { + // This bucket was empty the last time we tried to send a packet, + // leaving a dequeued packet still waiting to be sent out. Try to + // send it again + if (bucket.RemoveTokens(nextPacketLengths[i])) + { + // Send the packet + udpServer.SendPacketFinal(nextPackets[i]); + nextPackets[i] = null; + packetSent = true; + } + } + else + { + // No dequeued packet waiting to be sent, try to pull one off + // this queue + queue = packetOutboxes[i]; + if (queue.Dequeue(out packet)) + { + // A packet was pulled off the queue. See if we have + // enough tokens in the bucket to send it out + if (bucket.RemoveTokens(packet.Buffer.DataLength)) + { + // Send the packet + udpServer.SendPacketFinal(packet); + packetSent = true; + } + else + { + // Save the dequeued packet and the length calculation for + // the next iteration + nextPackets[i] = packet; + nextPacketLengths[i] = packet.Buffer.DataLength; + } + } + else + { + // No packets in this queue. Fire the queue empty callback + QueueEmpty callback = OnQueueEmpty; + if (callback != null) + callback((ThrottleOutPacketType)i); + } + } + } + + return packetSent; + } + + public void UpdateRoundTrip(float r) + { + const float ALPHA = 0.125f; + const float BETA = 0.25f; + const float K = 4.0f; + + if (RTTVAR == 0.0f) + { + // First RTT measurement + SRTT = r; + RTTVAR = r * 0.5f; + } + else + { + // Subsequence RTT measurement + RTTVAR = (1.0f - BETA) * RTTVAR + BETA * Math.Abs(SRTT - r); + SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r; + } + + // Always round retransmission timeout up to two seconds + RTO = Math.Max(2000, (int)(SRTT + Math.Max(G, K * RTTVAR))); + //Logger.Debug("Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " + + // RTTVAR + " based on new RTT of " + r + "ms"); + } + } +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs new file mode 100644 index 0000000000..7d2da68d2d --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs @@ -0,0 +1,185 @@ +/* + * 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; +using System.Collections.Generic; +using System.Net; +using OpenSim.Framework; +using OpenMetaverse; + +using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + public sealed class UDPClientCollection + { + Dictionary Dictionary1; + Dictionary Dictionary2; + LLUDPClient[] Array; + ReaderWriterLockImpl rwLock = new ReaderWriterLockImpl(); + + public UDPClientCollection() + { + Dictionary1 = new Dictionary(); + Dictionary2 = new Dictionary(); + Array = new LLUDPClient[0]; + } + + public UDPClientCollection(int capacity) + { + Dictionary1 = new Dictionary(capacity); + Dictionary2 = new Dictionary(capacity); + Array = new LLUDPClient[0]; + } + + public void Add(UUID key1, IPEndPoint key2, LLUDPClient value) + { + rwLock.EnterWriteLock(); + + try + { + if (Dictionary1.ContainsKey(key1)) + { + if (!Dictionary2.ContainsKey(key2)) + throw new ArgumentException("key1 exists in the dictionary but not key2"); + } + else if (Dictionary2.ContainsKey(key2)) + { + if (!Dictionary1.ContainsKey(key1)) + throw new ArgumentException("key2 exists in the dictionary but not key1"); + } + + Dictionary1[key1] = value; + Dictionary2[key2] = value; + + LLUDPClient[] oldArray = Array; + int oldLength = oldArray.Length; + + LLUDPClient[] newArray = new LLUDPClient[oldLength + 1]; + for (int i = 0; i < oldLength; i++) + newArray[i] = oldArray[i]; + newArray[oldLength] = value; + + Array = newArray; + } + finally { rwLock.ExitWriteLock(); } + } + + public bool Remove(UUID key1, IPEndPoint key2) + { + rwLock.EnterWriteLock(); + + try + { + LLUDPClient value; + if (Dictionary1.TryGetValue(key1, out value)) + { + Dictionary1.Remove(key1); + Dictionary2.Remove(key2); + + LLUDPClient[] oldArray = Array; + int oldLength = oldArray.Length; + + LLUDPClient[] newArray = new LLUDPClient[oldLength - 1]; + int j = 0; + for (int i = 0; i < oldLength; i++) + { + if (oldArray[i] != value) + newArray[j++] = oldArray[i]; + } + + Array = newArray; + return true; + } + } + finally { rwLock.ExitWriteLock(); } + + return false; + } + + public void Clear() + { + rwLock.EnterWriteLock(); + + try + { + Dictionary1.Clear(); + Dictionary2.Clear(); + Array = new LLUDPClient[0]; + } + finally { rwLock.ExitWriteLock(); } + } + + public int Count + { + get { return Array.Length; } + } + + public bool ContainsKey(UUID key) + { + return Dictionary1.ContainsKey(key); + } + + public bool ContainsKey(IPEndPoint key) + { + return Dictionary2.ContainsKey(key); + } + + public bool TryGetValue(UUID key, out LLUDPClient value) + { + bool success; + bool doLock = !rwLock.IsUpgradeableReadLockHeld; + if (doLock) rwLock.EnterReadLock(); + + try { success = Dictionary1.TryGetValue(key, out value); } + finally { if (doLock) rwLock.ExitReadLock(); } + + return success; + } + + public bool TryGetValue(IPEndPoint key, out LLUDPClient value) + { + bool success; + bool doLock = !rwLock.IsUpgradeableReadLockHeld; + if (doLock) rwLock.EnterReadLock(); + + try { success = Dictionary2.TryGetValue(key, out value); } + finally { if (doLock) rwLock.ExitReadLock(); } + + return success; + } + + public void ForEach(Action action) + { + bool doLock = !rwLock.IsUpgradeableReadLockHeld; + if (doLock) rwLock.EnterUpgradeableReadLock(); + + try { Parallel.ForEach(Array, action); } + finally { if (doLock) rwLock.ExitUpgradeableReadLock(); } + } + } +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 7964c505b3..348615e728 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -35,6 +35,7 @@ using log4net; using Nini.Config; using OpenMetaverse.Packets; using OpenSim.Framework; +using OpenSim.Framework.Statistics; using OpenSim.Region.Framework.Scenes; using OpenMetaverse; @@ -190,31 +191,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public void RemoveClient(LLUDPClient udpClient) - { - IClientAPI client; - - if (m_scene.ClientManager.TryGetClient(udpClient.CircuitCode, out client)) - RemoveClient(client); - else - m_log.Warn("[LLUDPSERVER]: Failed to lookup IClientAPI for LLUDPClient " + udpClient.AgentID); - } - - public void SetClientPaused(UUID agentID, bool paused) - { - LLUDPClient client; - if (clients.TryGetValue(agentID, out client)) - { - client.IsPaused = paused; - } - else - { - m_log.Warn("[LLUDPSERVER]: Attempted to pause/unpause unknown agent " + agentID); - } - } - public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) { + // CoarseLocationUpdate packets cannot be split in an automated way + if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting) + allowSplitting = false; + if (allowSplitting && packet.HasVariableBlocks) { byte[][] datas = packet.ToBytesMultiple(); @@ -251,6 +233,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendPacket(LLUDPClient client, Packet packet, ThrottleOutPacketType category, bool allowSplitting) { + // CoarseLocationUpdate packets cannot be split in an automated way + if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting) + allowSplitting = false; + if (allowSplitting && packet.HasVariableBlocks) { byte[][] datas = packet.ToBytesMultiple(); @@ -339,6 +325,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + public void SendPing(LLUDPClient client) + { + IClientAPI api = client.ClientAPI; + if (api != null) + api.SendStartPingCheck(client.CurrentPingSequence++); + } + public void ResendUnacked(LLUDPClient client) { if (client.NeedAcks.Count > 0) @@ -387,9 +380,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP //FIXME: Make 60 an .ini setting if (Environment.TickCount - client.TickLastPacketReceived > 1000 * 60) { - m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + client.RemoteEndPoint); + m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + client.ClientAPI.Name); - RemoveClient(client); + RemoveClient(client.ClientAPI); return; } } @@ -590,8 +583,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP LLUDPClient client = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); clients.Add(agentID, client.RemoteEndPoint, client); - // Create the IClientAPI - IClientAPI clientApi = new LLClientView(remoteEndPoint, m_scene, this, client, sessionInfo, agentID, sessionID, circuitCode); + // Create the LLClientView + LLClientView clientApi = new LLClientView(remoteEndPoint, m_scene, this, client, sessionInfo, agentID, sessionID, circuitCode); clientApi.OnViewerEffect += m_scene.ClientManager.ViewerEffectHandler; clientApi.OnLogout += LogoutHandler; clientApi.OnConnectionClosed += RemoveClient; @@ -618,23 +611,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP private void IncomingPacketHandler() { - IncomingPacket incomingPacket = new IncomingPacket(); - Packet packet = null; - LLUDPClient client = null; + // Set this culture for the thread that incoming packets are received + // on to en-US to avoid number parsing issues + Culture.SetCurrentCulture(); + + IncomingPacket incomingPacket = default(IncomingPacket); while (base.IsRunning) { - // Reset packet to null for the check below - packet = null; - if (packetInbox.Dequeue(100, ref incomingPacket)) - { - packet = incomingPacket.Packet; - client = incomingPacket.Client; - - if (packet != null && client != null) - client.ClientAPI.ProcessInPacket(packet); - } + Util.FireAndForget(ProcessInPacket, incomingPacket); } if (packetInbox.Count > 0) @@ -642,32 +628,98 @@ namespace OpenSim.Region.ClientStack.LindenUDP packetInbox.Clear(); } + private void ProcessInPacket(object state) + { + IncomingPacket incomingPacket = (IncomingPacket)state; + Packet packet = incomingPacket.Packet; + LLUDPClient client = incomingPacket.Client; + + if (packet != null && client != null) + { + try + { + client.ClientAPI.ProcessInPacket(packet); + } + catch (ThreadAbortException) + { + throw; + } + catch (Exception e) + { + if (StatsManager.SimExtraStats != null) + StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); + + // Don't let a failure in an individual client thread crash the whole sim. + m_log.ErrorFormat("[LLUDPSERVER]: Client thread for {0} {1} crashed. Logging them out", client.ClientAPI.Name, client.AgentID); + m_log.Error(e.Message, e); + + try + { + // Make an attempt to alert the user that their session has crashed + AgentAlertMessagePacket alert = client.ClientAPI.BuildAgentAlertPacket( + "Unfortunately the session for this client on the server has crashed.\n" + + "Any further actions taken will not be processed.\n" + + "Please relog", true); + + SendPacket(client, alert, ThrottleOutPacketType.Unknown, false); + + // TODO: There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to + // listeners yet, though. + client.ClientAPI.SendLogoutPacket(); + RemoveClient(client.ClientAPI); + } + catch (ThreadAbortException) + { + throw; + } + catch (Exception e2) + { + m_log.Error("[LLUDPSERVER]: Further exception thrown on forced session logout for " + client.ClientAPI.Name); + m_log.Error(e2.Message, e2); + } + } + } + } + private void OutgoingPacketHandler() { + // Set this culture for the thread that outgoing packets are sent + // on to en-US to avoid number parsing issues + Culture.SetCurrentCulture(); + int now = Environment.TickCount; int elapsedMS = 0; int elapsed100MS = 0; + int elapsed500MS = 0; while (base.IsRunning) { bool resendUnacked = false; bool sendAcks = false; + bool sendPings = false; bool packetSent = false; elapsedMS += Environment.TickCount - now; - // Check for packets that need to be resent every 100ms + // Check for pending outgoing resends every 100ms if (elapsedMS >= 100) { resendUnacked = true; elapsedMS -= 100; ++elapsed100MS; } - // Check for ACKs that need to be sent out every 500ms + // Check for pending outgoing ACKs every 500ms if (elapsed100MS >= 5) { sendAcks = true; elapsed100MS = 0; + ++elapsed500MS; + } + // Send pings to clients every 2000ms + if (elapsed500MS >= 4) + { + sendPings = true; + elapsed500MS = 0; } clients.ForEach( @@ -679,6 +731,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP ResendUnacked(client); if (sendAcks) SendAcks(client); + if (sendPings) + SendPing(client); } ); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUtil.cs b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs similarity index 65% rename from OpenSim/Region/ClientStack/LindenUDP/LLUtil.cs rename to OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs index 066b19d031..69b0c5fc20 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUtil.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -26,31 +26,31 @@ */ using System; -using System.Collections.Generic; -using System.Net; +using OpenSim.Framework; using OpenMetaverse; -using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim; - namespace OpenSim.Region.ClientStack.LindenUDP { - public class LLUtil + public sealed class OutgoingPacket { - /// - /// Convert a string to bytes suitable for use in an LL UDP packet. - /// - /// Truncated to 254 characters if necessary - /// - public static byte[] StringToPacketBytes(string s) + /// Client this packet is destined for + public LLUDPClient Client; + /// Packet data to send + public UDPPacketBuffer Buffer; + /// Sequence number of the wrapped packet + public uint SequenceNumber; + /// Number of times this packet has been resent + public int ResendCount; + /// Environment.TickCount when this packet was last sent over the wire + public int TickCount; + /// Category this packet belongs to + public ThrottleOutPacketType Category; + + public OutgoingPacket(LLUDPClient client, UDPPacketBuffer buffer, ThrottleOutPacketType category) { - // Anything more than 254 will cause libsecondlife to barf - // (libsl 1550) adds an \0 on the Utils.StringToBytes conversion if it isn't present - if (s.Length > 254) - { - s = s.Remove(254); - } - - return Utils.StringToBytes(s); + Client = client; + Buffer = buffer; + Category = category; } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs new file mode 100644 index 0000000000..ffa20d5f02 --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs @@ -0,0 +1,76 @@ +/* + * 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; +using Nini.Config; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + public sealed class ThrottleRates + { + public int Resend; + public int Land; + public int Wind; + public int Cloud; + public int Task; + public int Texture; + public int Asset; + + public int ResendLimit; + public int LandLimit; + public int WindLimit; + public int CloudLimit; + public int TaskLimit; + public int TextureLimit; + public int AssetLimit; + + public ThrottleRates(IConfigSource config) + { + try + { + IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; + + Resend = throttleConfig.GetInt("ResendDefault", 12500); + Land = throttleConfig.GetInt("LandDefault", 500); + Wind = throttleConfig.GetInt("WindDefault", 500); + Cloud = throttleConfig.GetInt("CloudDefault", 500); + Task = throttleConfig.GetInt("TaskDefault", 500); + Texture = throttleConfig.GetInt("TextureDefault", 500); + Asset = throttleConfig.GetInt("AssetDefault", 500); + + ResendLimit = throttleConfig.GetInt("ResendLimit", 18750); + LandLimit = throttleConfig.GetInt("LandLimit", 29750); + WindLimit = throttleConfig.GetInt("WindLimit", 18750); + CloudLimit = throttleConfig.GetInt("CloudLimit", 18750); + TaskLimit = throttleConfig.GetInt("TaskLimit", 55750); + TextureLimit = throttleConfig.GetInt("TextureLimit", 55750); + AssetLimit = throttleConfig.GetInt("AssetLimit", 27500); + } + catch (Exception) { } + } + } +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs new file mode 100644 index 0000000000..16c00355b1 --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -0,0 +1,114 @@ +/* + * 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; +using System.Collections.Generic; +using System.Net; +using OpenMetaverse; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + public sealed class UnackedPacketCollection + { + public object SyncRoot = new object(); + + SortedDictionary packets; + + public int Count { get { return packets.Count; } } + + public UnackedPacketCollection() + { + packets = new SortedDictionary(); + } + + public bool Add(OutgoingPacket packet) + { + lock (SyncRoot) + { + if (!packets.ContainsKey(packet.SequenceNumber)) + { + packets.Add(packet.SequenceNumber, packet); + return true; + } + return false; + } + } + + public bool RemoveUnsafe(uint sequenceNumber) + { + return packets.Remove(sequenceNumber); + } + + public bool RemoveUnsafe(uint sequenceNumber, out OutgoingPacket packet) + { + if (packets.TryGetValue(sequenceNumber, out packet)) + { + packets.Remove(sequenceNumber); + return true; + } + + return false; + } + + public OutgoingPacket GetOldest() + { + lock (SyncRoot) + { + using (SortedDictionary.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) + return e.Current; + } + } + + public List GetExpiredPackets(int timeout) + { + List expiredPackets = null; + + lock (SyncRoot) + { + int now = Environment.TickCount; + foreach (OutgoingPacket packet in packets.Values) + { + if (packet.TickCount == 0) + continue; + + if (now - packet.TickCount >= timeout) + { + if (expiredPackets == null) + expiredPackets = new List(); + expiredPackets.Add(packet); + } + else + { + break; + } + } + } + + return expiredPackets; + } + } +} From 2519f071f2c592aeea0414c8b2871e5df623271c Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 02:50:59 -0700 Subject: [PATCH 03/36] Fixing a few compile errors in the previous commit --- .../MXP/PacketHandler/MXPPacketServer.cs | 1 - .../Framework/Servers/BaseOpenSimServer.cs | 27 +--- OpenSim/Framework/Tests/ThreadTrackerTests.cs | 140 +----------------- .../HttpRequest/ScriptsHttpRequests.cs | 1 - .../Scripting/XMLRPC/XMLRPCModule.cs | 1 - .../World/WorldMap/WorldMapModule.cs | 2 - OpenSim/Region/Framework/Scenes/Scene.cs | 2 - .../Avatar/Chat/IRCConnector.cs | 1 - .../ContentManagementSystem/CMController.cs | 1 - .../DotNetEngine/EventQueueThreadClass.cs | 1 - .../DotNetEngine/MaintenanceThread.cs | 1 - .../Api/Implementation/AsyncCommandManager.cs | 1 - OpenSim/TestSuite/BotManager.cs | 1 - OpenSim/Tools/pCampBot/BotManager.cs | 1 - 14 files changed, 8 insertions(+), 173 deletions(-) diff --git a/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs b/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs index 332ff7048a..4910ab1749 100644 --- a/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs +++ b/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs @@ -89,7 +89,6 @@ namespace OpenSim.Client.MXP.PacketHandler m_clientThread.Name = "MXPThread"; m_clientThread.IsBackground = true; m_clientThread.Start(); - ThreadTracker.Add(m_clientThread); } public void StartListener() diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 56155ddd59..8e58980b6e 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; @@ -109,9 +110,8 @@ namespace OpenSim.Framework.Servers m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); m_periodicDiagnosticsTimer.Enabled = true; - // Add ourselves to thread monitoring. This thread will go on to become the console listening thread + // This thread will go on to become the console listening thread Thread.CurrentThread.Name = "ConsoleThread"; - ThreadTracker.Add(Thread.CurrentThread); ILoggerRepository repository = LogManager.GetRepository(); IAppender[] appenders = repository.GetAppenders(); @@ -235,7 +235,7 @@ namespace OpenSim.Framework.Servers { StringBuilder sb = new StringBuilder(); - List threads = ThreadTracker.GetThreads(); + ProcessThreadCollection threads = ThreadTracker.GetThreads(); if (threads == null) { sb.Append("OpenSim thread tracking is only enabled in DEBUG mode."); @@ -243,25 +243,10 @@ namespace OpenSim.Framework.Servers else { sb.Append(threads.Count + " threads are being tracked:" + Environment.NewLine); - foreach (Thread t in threads) + foreach (ProcessThread t in threads) { - if (t.IsAlive) - { - sb.Append( - "ID: " + t.ManagedThreadId + ", Name: " + t.Name + ", Alive: " + t.IsAlive - + ", Pri: " + t.Priority + ", State: " + t.ThreadState + Environment.NewLine); - } - else - { - try - { - sb.Append("ID: " + t.ManagedThreadId + ", Name: " + t.Name + ", DEAD" + Environment.NewLine); - } - catch - { - sb.Append("THREAD ERROR" + Environment.NewLine); - } - } + sb.Append("ID: " + t.Id + ", TotalProcessorTime: " + t.TotalProcessorTime + ", TimeRunning: " + + (DateTime.Now - t.StartTime) + ", Pri: " + t.CurrentPriority + ", State: " + t.ThreadState + Environment.NewLine); } } int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; diff --git a/OpenSim/Framework/Tests/ThreadTrackerTests.cs b/OpenSim/Framework/Tests/ThreadTrackerTests.cs index 15d5b73314..7eb83e6421 100644 --- a/OpenSim/Framework/Tests/ThreadTrackerTests.cs +++ b/OpenSim/Framework/Tests/ThreadTrackerTests.cs @@ -41,7 +41,7 @@ namespace OpenSim.Framework.Tests [Test] public void DefaultThreadTrackerTest() { - List lThread = ThreadTracker.GetThreads(); + System.Diagnostics.ProcessThreadCollection lThread = ThreadTracker.GetThreads(); /* foreach (Thread t in lThread) @@ -50,143 +50,7 @@ namespace OpenSim.Framework.Tests } */ - Assert.That(lThread.Count == 1); - Assert.That(lThread[0].Name == "ThreadTrackerThread"); + Assert.That(lThread.Count > 0); } - - /// - /// Validate that adding a thread to the thread tracker works - /// Validate that removing a thread from the thread tracker also works. - /// - [Test] - public void AddThreadToThreadTrackerTestAndRemoveTest() - { - Thread t = new Thread(run); - t.Name = "TestThread"; - t.Priority = ThreadPriority.BelowNormal; - t.IsBackground = true; - t.SetApartmentState(ApartmentState.MTA); - t.Start(); - ThreadTracker.Add(t); - - List lThread = ThreadTracker.GetThreads(); - - Assert.That(lThread.Count == 2); - - foreach (Thread tr in lThread) - { - Assert.That((tr.Name == "ThreadTrackerThread" || tr.Name == "TestThread")); - } - running = false; - ThreadTracker.Remove(t); - - lThread = ThreadTracker.GetThreads(); - - Assert.That(lThread.Count == 1); - - foreach (Thread tr in lThread) - { - Assert.That((tr.Name == "ThreadTrackerThread")); - } - - - } - - /// - /// Test a dead thread removal by aborting it and setting it's last seen active date to 50 seconds - /// - [Test] - public void DeadThreadTest() - { - Thread t = new Thread(run2); - t.Name = "TestThread"; - t.Priority = ThreadPriority.BelowNormal; - t.IsBackground = true; - t.SetApartmentState(ApartmentState.MTA); - t.Start(); - ThreadTracker.Add(t); - t.Abort(); - Thread.Sleep(5000); - ThreadTracker.m_Threads[1].LastSeenActive = DateTime.Now.Ticks - (50*10000000); - ThreadTracker.CleanUp(); - List lThread = ThreadTracker.GetThreads(); - - Assert.That(lThread.Count == 1); - - foreach (Thread tr in lThread) - { - Assert.That((tr.Name == "ThreadTrackerThread")); - } - } - - [Test] - public void UnstartedThreadTest() - { - Thread t = new Thread(run2); - t.Name = "TestThread"; - t.Priority = ThreadPriority.BelowNormal; - t.IsBackground = true; - t.SetApartmentState(ApartmentState.MTA); - ThreadTracker.Add(t); - ThreadTracker.m_Threads[1].LastSeenActive = DateTime.Now.Ticks - (50 * 10000000); - ThreadTracker.CleanUp(); - List lThread = ThreadTracker.GetThreads(); - - Assert.That(lThread.Count == 1); - - foreach (Thread tr in lThread) - { - Assert.That((tr.Name == "ThreadTrackerThread")); - } - } - - [Test] - public void NullThreadTest() - { - Thread t = null; - ThreadTracker.Add(t); - - List lThread = ThreadTracker.GetThreads(); - - Assert.That(lThread.Count == 1); - - foreach (Thread tr in lThread) - { - Assert.That((tr.Name == "ThreadTrackerThread")); - } - } - - - /// - /// Worker thread 0 - /// - /// - public void run(object o) - { - while (running) - { - Thread.Sleep(5000); - } - } - - /// - /// Worker thread 1 - /// - /// - public void run2(object o) - { - try - { - while (running2) - { - Thread.Sleep(5000); - } - - } - catch (ThreadAbortException) - { - } - } - } } diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 45e724db18..d78931a524 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -323,7 +323,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest httpThread.IsBackground = true; _finished = false; httpThread.Start(); - ThreadTracker.Add(httpThread); } /* diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index 8a169f89c3..97899a7af4 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs @@ -639,7 +639,6 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC httpThread.IsBackground = true; _finished = false; httpThread.Start(); - ThreadTracker.Add(httpThread); } /* diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 05ed70a15d..4fb4c5149f 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -345,7 +345,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap mapItemReqThread.Priority = ThreadPriority.BelowNormal; mapItemReqThread.SetApartmentState(ApartmentState.MTA); mapItemReqThread.Start(); - ThreadTracker.Add(mapItemReqThread); } /// @@ -447,7 +446,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // end gracefully if (st.agentID == UUID.Zero) { - ThreadTracker.Remove(mapItemReqThread); break; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 606135b516..30c2223fcc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -901,7 +901,6 @@ namespace OpenSim.Region.Framework.Scenes //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); if (HeartbeatThread != null) { - ThreadTracker.Remove(HeartbeatThread); HeartbeatThread.Abort(); HeartbeatThread = null; } @@ -910,7 +909,6 @@ namespace OpenSim.Region.Framework.Scenes HeartbeatThread.SetApartmentState(ApartmentState.MTA); HeartbeatThread.Name = string.Format("Heartbeat for region {0}", RegionInfo.RegionName); HeartbeatThread.Priority = ThreadPriority.AboveNormal; - ThreadTracker.Add(HeartbeatThread); HeartbeatThread.Start(); } diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index 9273fb579a..cd401a6096 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs @@ -360,7 +360,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat m_listener.Name = "IRCConnectorListenerThread"; m_listener.IsBackground = true; m_listener.Start(); - ThreadTracker.Add(m_listener); // This is the message order recommended by RFC 2812 if (m_password != null) diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs index 7202601f00..16fe9e9be3 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs @@ -152,7 +152,6 @@ namespace OpenSim.Region.OptionalModules.ContentManagement m_thread.Name = "Content Management"; m_thread.IsBackground = true; m_thread.Start(); - ThreadTracker.Add(m_thread); m_state = State.NONE; } } diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs index 0feb967838..583d2ffb73 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs @@ -138,7 +138,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine EventQueueThread.Priority = MyThreadPriority; EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; EventQueueThread.Start(); - ThreadTracker.Add(EventQueueThread); // Look at this... Don't you wish everyone did that solid // coding everywhere? :P diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs index 8bafe77ecc..7ffdb1a413 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/MaintenanceThread.cs @@ -97,7 +97,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine MaintenanceThreadThread.Name = "ScriptMaintenanceThread"; MaintenanceThreadThread.IsBackground = true; MaintenanceThreadThread.Start(); - ThreadTracker.Add(MaintenanceThreadThread); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs index e4545241c1..1607d34d22 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs @@ -142,7 +142,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api cmdHandlerThread.Priority = ThreadPriority.BelowNormal; cmdHandlerThread.IsBackground = true; cmdHandlerThread.Start(); - ThreadTracker.Add(cmdHandlerThread); } } diff --git a/OpenSim/TestSuite/BotManager.cs b/OpenSim/TestSuite/BotManager.cs index 62e0ec743a..55ba687290 100644 --- a/OpenSim/TestSuite/BotManager.cs +++ b/OpenSim/TestSuite/BotManager.cs @@ -115,7 +115,6 @@ namespace OpenSim.TestSuite m_td[pos].IsBackground = true; m_td[pos].Start(); m_lBot.Add(pb); - ThreadTracker.Add(m_td[pos]); } /// diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 3f4e6ed92a..614b350011 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -149,7 +149,6 @@ namespace pCampBot m_td[pos].IsBackground = true; m_td[pos].Start(); m_lBot.Add(pb); - ThreadTracker.Add(m_td[pos]); } /// From 3db4d38645260b0299e082b47b010dddf569bf31 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 6 Oct 2009 09:54:15 -0700 Subject: [PATCH 04/36] Removing dependencies on System.Runtime.Remoting. --- .../CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs | 4 ++++ prebuild.xml | 6 ------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs index 44e850bae3..6c89ac8c0d 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionCache.cs @@ -61,6 +61,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid private void OnRegionUp(GridRegion otherRegion) { + // This shouldn't happen + if (otherRegion == null) + return; + m_log.DebugFormat("[REGION CACHE]: (on region {0}) Region {1} is up @ {2}-{3}", m_scene.RegionInfo.RegionName, otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY); diff --git a/prebuild.xml b/prebuild.xml index f863ab64c6..e58b81b348 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -724,7 +724,6 @@ - @@ -805,7 +804,6 @@ - @@ -1539,7 +1537,6 @@ - @@ -1624,7 +1621,6 @@ - @@ -1682,7 +1678,6 @@ ../../../../bin/ - @@ -3590,7 +3585,6 @@ - From fb19d1ca0a7c6e82c540c4e8d22c82c09b7bec98 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 10:12:59 -0700 Subject: [PATCH 05/36] * Try/catch around EndInvoke() when Util.FireAndForget() returns to catch exceptions thrown in the async method * Added packet stats handling to the new LLUDP implementation * Attempting to avoid a race condition when creating a new LLUDPClient --- OpenSim/Framework/Util.cs | 4 +- .../ClientStack/LindenUDP/LLClientView.cs | 3 +- .../ClientStack/LindenUDP/LLUDPClient.cs | 40 +++-- .../ClientStack/LindenUDP/LLUDPServer.cs | 147 ++++++++++-------- 4 files changed, 115 insertions(+), 79 deletions(-) diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 189fa3853e..38729c6dc8 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1283,7 +1283,9 @@ namespace OpenSim.Framework { System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState; - callback.EndInvoke(ar); + try { callback.EndInvoke(ar); } + catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); } + ar.AsyncWaitHandle.Close(); } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 767020f27c..84e705a91d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -186,8 +186,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpServer = udpServer; m_udpClient = udpClient; m_udpClient.OnQueueEmpty += HandleQueueEmpty; - // FIXME: Implement this - //m_udpClient.OnPacketStats += PopulateStats; + m_udpClient.OnPacketStats += PopulateStats; RegisterLocalPacketHandlers(); } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index ad01135d67..f2e76d3998 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -33,6 +33,7 @@ using OpenMetaverse; namespace OpenSim.Region.ClientStack.LindenUDP { + public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); public delegate void QueueEmpty(ThrottleOutPacketType category); public class LLUDPClient @@ -41,6 +42,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// or removed, this number must also change const int THROTTLE_CATEGORY_COUNT = 7; + public event PacketStats OnPacketStats; public event QueueEmpty OnQueueEmpty; /// AgentID for this client @@ -84,6 +86,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Number of bytes received since the last acknowledgement was sent out. This is used /// to loosely follow the TCP delayed ACK algorithm in RFC 1122 (4.2.3.2) public int BytesSinceLastACK; + /// Number of packets received from this client + public int PacketsReceived; + /// Number of packets sent to this client + public int PacketsSent; + /// Total byte count of unacked packets sent to this client + public int UnackedBytes; + + /// Total number of received packets that we have reported to the OnPacketStats event(s) + private int m_packetsReceivedReported; + /// Total number of sent packets that we have reported to the OnPacketStats event(s) + private int m_packetsSentReported; /// Throttle bucket for this agent's connection private readonly TokenBucket throttle; @@ -162,17 +175,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP public string GetStats() { + // TODO: ??? return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0); + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + + public void SendPacketStats() + { + PacketStats callback = OnPacketStats; + if (callback != null) + { + int newPacketsReceived = PacketsReceived - m_packetsReceivedReported; + int newPacketsSent = PacketsSent - m_packetsSentReported; + + callback(newPacketsReceived, newPacketsSent, UnackedBytes); + + m_packetsReceivedReported += newPacketsReceived; + m_packetsSentReported += newPacketsSent; + } } public void SetThrottles(byte[] throttleData) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 348615e728..38890dae26 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -359,6 +359,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // is actually sent out again outgoingPacket.TickCount = 0; + // Bump up the resend count on this packet Interlocked.Increment(ref outgoingPacket.ResendCount); //Interlocked.Increment(ref Stats.ResentPackets); @@ -393,6 +394,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void Flush() { + // FIXME: Implement? + } + + internal void SendPacketFinal(OutgoingPacket outgoingPacket) + { + UDPPacketBuffer buffer = outgoingPacket.Buffer; + byte flags = buffer.Data[0]; + bool isResend = (flags & Helpers.MSG_RESENT) != 0; + bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; + LLUDPClient client = outgoingPacket.Client; + + // Keep track of when this packet was sent out (right now) + outgoingPacket.TickCount = Environment.TickCount; + + #region ACK Appending + + int dataLength = buffer.DataLength; + + // Keep appending ACKs until there is no room left in the packet or there are + // no more ACKs to append + uint ackCount = 0; + uint ack; + while (dataLength + 5 < buffer.Data.Length && client.PendingAcks.Dequeue(out ack)) + { + Utils.UIntToBytesBig(ack, buffer.Data, dataLength); + dataLength += 4; + ++ackCount; + } + + if (ackCount > 0) + { + // Set the last byte of the packet equal to the number of appended ACKs + buffer.Data[dataLength++] = (byte)ackCount; + // Set the appended ACKs flag on this packet + buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS); + } + + buffer.DataLength = dataLength; + + #endregion ACK Appending + + if (!isResend) + { + // Not a resend, assign a new sequence number + uint sequenceNumber = (uint)Interlocked.Increment(ref client.CurrentSequence); + Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1); + outgoingPacket.SequenceNumber = sequenceNumber; + + if (isReliable) + { + // Add this packet to the list of ACK responses we are waiting on from the server + client.NeedAcks.Add(outgoingPacket); + } + } + + // Stats tracking + Interlocked.Increment(ref client.PacketsSent); + if (isReliable) + Interlocked.Add(ref client.UnackedBytes, outgoingPacket.Buffer.DataLength); + + // Put the UDP payload on the wire + AsyncBeginSend(buffer); } protected override void PacketReceived(UDPPacketBuffer buffer) @@ -456,8 +519,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion UseCircuitCode Handling - //if (packet.Header.Resent) - // Interlocked.Increment(ref Stats.ReceivedResends); + // Stats tracking + Interlocked.Increment(ref client.PacketsReceived); #region ACK Receiving @@ -581,7 +644,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // Create the LLUDPClient LLUDPClient client = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); - clients.Add(agentID, client.RemoteEndPoint, client); // Create the LLClientView LLClientView clientApi = new LLClientView(remoteEndPoint, m_scene, this, client, sessionInfo, agentID, sessionID, circuitCode); @@ -589,12 +651,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP clientApi.OnLogout += LogoutHandler; clientApi.OnConnectionClosed += RemoveClient; - // Give LLUDPClient a reference to IClientAPI - client.ClientAPI = clientApi; - // Start the IClientAPI m_scene.ClientManager.Add(circuitCode, clientApi); clientApi.Start(); + + // Give LLUDPClient a reference to IClientAPI + client.ClientAPI = clientApi; + + // Add the new client to our list of tracked clients + clients.Add(agentID, client.RemoteEndPoint, client); } private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend) @@ -602,6 +667,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutgoingPacket ackedPacket; if (client.NeedAcks.RemoveUnsafe(ack, out ackedPacket) && !fromResend) { + // Update stats + Interlocked.Add(ref client.UnackedBytes, -ackedPacket.Buffer.DataLength); + // Calculate the round-trip time for this packet and its ACK int rtt = currentTime - ackedPacket.TickCount; if (rtt > 0) @@ -650,7 +718,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); // Don't let a failure in an individual client thread crash the whole sim. - m_log.ErrorFormat("[LLUDPSERVER]: Client thread for {0} {1} crashed. Logging them out", client.ClientAPI.Name, client.AgentID); + m_log.ErrorFormat("[LLUDPSERVER]: Client thread for {0} crashed. Logging them out", client.AgentID); m_log.Error(e.Message, e); try @@ -674,7 +742,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } catch (Exception e2) { - m_log.Error("[LLUDPSERVER]: Further exception thrown on forced session logout for " + client.ClientAPI.Name); + m_log.Error("[LLUDPSERVER]: Further exception thrown on forced session logout for " + client.AgentID); m_log.Error(e2.Message, e2); } } @@ -715,8 +783,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP elapsed100MS = 0; ++elapsed500MS; } - // Send pings to clients every 2000ms - if (elapsed500MS >= 4) + // Send pings to clients every 5000ms + if (elapsed500MS >= 10) { sendPings = true; elapsed500MS = 0; @@ -730,7 +798,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (resendUnacked) ResendUnacked(client); if (sendAcks) + { SendAcks(client); + client.SendPacketStats(); + } if (sendPings) SendPing(client); } @@ -746,61 +817,5 @@ namespace OpenSim.Region.ClientStack.LindenUDP client.SendLogoutPacket(); RemoveClient(client); } - - internal void SendPacketFinal(OutgoingPacket outgoingPacket) - { - UDPPacketBuffer buffer = outgoingPacket.Buffer; - byte flags = buffer.Data[0]; - bool isResend = (flags & Helpers.MSG_RESENT) != 0; - bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; - LLUDPClient client = outgoingPacket.Client; - - // Keep track of when this packet was sent out (right now) - outgoingPacket.TickCount = Environment.TickCount; - - #region ACK Appending - - int dataLength = buffer.DataLength; - - // Keep appending ACKs until there is no room left in the packet or there are - // no more ACKs to append - uint ackCount = 0; - uint ack; - while (dataLength + 5 < buffer.Data.Length && client.PendingAcks.Dequeue(out ack)) - { - Utils.UIntToBytesBig(ack, buffer.Data, dataLength); - dataLength += 4; - ++ackCount; - } - - if (ackCount > 0) - { - // Set the last byte of the packet equal to the number of appended ACKs - buffer.Data[dataLength++] = (byte)ackCount; - // Set the appended ACKs flag on this packet - buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS); - } - - buffer.DataLength = dataLength; - - #endregion ACK Appending - - if (!isResend) - { - // Not a resend, assign a new sequence number - uint sequenceNumber = (uint)Interlocked.Increment(ref client.CurrentSequence); - Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1); - outgoingPacket.SequenceNumber = sequenceNumber; - - if (isReliable) - { - // Add this packet to the list of ACK responses we are waiting on from the server - client.NeedAcks.Add(outgoingPacket); - } - } - - // Put the UDP payload on the wire - AsyncBeginSend(buffer); - } } } From 77b4abaa251929a4d6079d766f041f997071dc46 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 6 Oct 2009 11:08:11 -0700 Subject: [PATCH 06/36] * Removed verbose debug message * Restored HG inventory access which had been lost upon adding a 3rd argument to inventory and asset server handlers * Fixed a stupid bug in the InventoryConnector which was making move items do things twice --- .../Asset/AssetServiceInConnectorModule.cs | 2 +- .../Inventory/InventoryServiceInConnectorModule.cs | 2 +- OpenSim/Server/Base/ServerUtils.cs | 2 +- .../Handlers/Inventory/InventoryServerInConnector.cs | 1 + .../Connectors/Inventory/InventoryServiceConnector.cs | 7 ------- 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs index bb9a4b2aca..879cc70903 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs @@ -98,7 +98,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset m_log.Info("[RegionAssetService]: Starting..."); - Object[] args = new Object[] { m_Config, MainServer.Instance }; + Object[] args = new Object[] { m_Config, MainServer.Instance, string.Empty }; ServerUtils.LoadPlugin("OpenSim.Server.Handlers.dll:AssetServiceConnector", args); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs index c326818443..54c6d89073 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs @@ -98,7 +98,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory m_log.Info("[RegionInventoryService]: Starting..."); - Object[] args = new Object[] { m_Config, MainServer.Instance }; + Object[] args = new Object[] { m_Config, MainServer.Instance, String.Empty }; ServerUtils.LoadPlugin("OpenSim.Server.Handlers.dll:InventoryServiceInConnector", args); } diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 9d9735e439..0964caaed7 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -260,7 +260,7 @@ namespace OpenSim.Server.Base public static Dictionary ParseXmlResponse(string data) { - m_log.DebugFormat("[XXX]: received xml string: {0}", data); + //m_log.DebugFormat("[XXX]: received xml string: {0}", data); Dictionary ret = new Dictionary(); diff --git a/OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs b/OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs index ca452638ec..3c92209d80 100644 --- a/OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/InventoryServerInConnector.cs @@ -77,6 +77,7 @@ namespace OpenSim.Server.Handlers.Inventory m_doLookup = serverConfig.GetBoolean("SessionAuthentication", false); AddHttpHandlers(server); + m_log.Debug("[INVENTORY HANDLER]: handlers initialized"); } protected virtual void AddHttpHandlers(IHttpServer m_httpServer) diff --git a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs index 5443891539..e047f71437 100644 --- a/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/InventoryServiceConnector.cs @@ -416,13 +416,6 @@ namespace OpenSim.Services.Connectors e.Source, e.Message); } - foreach (InventoryItemBase item in items) - { - InventoryItemBase itm = this.QueryItem(userID, item, sessionID); - itm.Name = item.Name; - itm.Folder = item.Folder; - this.UpdateItem(userID, itm, sessionID); - } } private void MoveItemsCompleted(IAsyncResult iar) From 61b537215328499155c58f46e6338d459aba87ec Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 12:13:16 -0700 Subject: [PATCH 07/36] * Added missing references to prebuild.xml and commented out the LindenUDP tests until a new test harness is written * Clients are no longer disconnected when a packet handler crashes. We'll see how this works out in practice * Added documentation and cleanup, getting ready for the first public push * Deleted an old LLUDP file --- .../ClientStack/LindenUDP/IncomingPacket.cs | 17 ++- .../ClientStack/LindenUDP/LLPacketThrottle.cs | 128 ------------------ .../ClientStack/LindenUDP/LLUDPClient.cs | 56 +++++++- .../ClientStack/LindenUDP/LLUDPServer.cs | 103 ++++++-------- .../ClientStack/LindenUDP/OutgoingPacket.cs | 14 ++ .../ClientStack/LindenUDP/ThrottleRates.cs | 23 ++++ .../LindenUDP/UnackedPacketCollection.cs | 49 ++++++- prebuild.xml | 4 + 8 files changed, 199 insertions(+), 195 deletions(-) delete mode 100644 OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs diff --git a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs index dc0d62aaf2..90b3ede57c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs @@ -32,11 +32,26 @@ using OpenMetaverse.Packets; namespace OpenSim.Region.ClientStack.LindenUDP { - public struct IncomingPacket + /// + /// Holds a reference to a and a + /// for incoming packets + /// + public sealed class IncomingPacket { /// Client this packet came from public LLUDPClient Client; /// Packet data that has been received public Packet Packet; + + /// + /// Default constructor + /// + /// Reference to the client this packet came from + /// Packet data + public IncomingPacket(LLUDPClient client, Packet packet) + { + Client = client; + Packet = packet; + } } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs deleted file mode 100644 index 52effc5b6c..0000000000 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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. - */ - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - public class LLPacketThrottle - { - private readonly int m_maxAllowableThrottle; - private readonly int m_minAllowableThrottle; - private int m_currentThrottle; - private const int m_throttleTimeDivisor = 7; - private int m_currentBitsSent; - private int m_throttleBits; - - /// - /// Value with which to multiply all the throttle fields - /// - private float m_throttleMultiplier; - - public int Max - { - get { return m_maxAllowableThrottle; } - } - - public int Min - { - get { return m_minAllowableThrottle; } - } - - public int Current - { - get { return m_currentThrottle; } - } - - /// - /// Constructor. - /// - /// - /// - /// - /// - /// A parameter that's ends up multiplying all throttle settings. An alternative solution would have been - /// to multiply all the parameters by this before giving them to the constructor. But doing it this way - /// represents the fact that the multiplier is a hack that pumps data to clients much faster than the actual - /// settings that we are given. - /// - public LLPacketThrottle(int min, int max, int throttle, float throttleMultiplier) - { - m_throttleMultiplier = throttleMultiplier; - m_maxAllowableThrottle = max; - m_minAllowableThrottle = min; - m_currentThrottle = throttle; - m_currentBitsSent = 0; - - CalcBits(); - } - - /// - /// Calculate the actual throttle required. - /// - private void CalcBits() - { - m_throttleBits = (int)((float)m_currentThrottle * m_throttleMultiplier / (float)m_throttleTimeDivisor); - } - - public void Reset() - { - m_currentBitsSent = 0; - } - - public bool UnderLimit() - { - return m_currentBitsSent < m_throttleBits; - } - - public int AddBytes(int bytes) - { - m_currentBitsSent += bytes * 8; - return m_currentBitsSent; - } - - public int Throttle - { - get { return m_currentThrottle; } - set - { - if (value < m_minAllowableThrottle) - { - m_currentThrottle = m_minAllowableThrottle; - } - else if (value > m_maxAllowableThrottle) - { - m_currentThrottle = m_maxAllowableThrottle; - } - else - { - m_currentThrottle = value; - } - - CalcBits(); - } - } - } -} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index f2e76d3998..871e8e8a05 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -33,16 +33,40 @@ using OpenMetaverse; namespace OpenSim.Region.ClientStack.LindenUDP { + #region Delegates + + /// + /// Fired when updated networking stats are produced for this client + /// + /// Number of incoming packets received since this + /// event was last fired + /// Number of outgoing packets sent since this + /// event was last fired + /// Current total number of bytes in packets we + /// are waiting on ACKs for public delegate void PacketStats(int inPackets, int outPackets, int unAckedBytes); + /// + /// Fired when the queue for a packet category is empty. This event can be + /// hooked to put more data on the empty queue + /// + /// Category of the packet queue that is empty public delegate void QueueEmpty(ThrottleOutPacketType category); - public class LLUDPClient + #endregion Delegates + + /// + /// Tracks state for a client UDP connection and provides client-specific methods + /// + public sealed class LLUDPClient { /// The number of packet categories to throttle on. If a throttle category is added /// or removed, this number must also change const int THROTTLE_CATEGORY_COUNT = 7; + /// Fired when updated networking stats are produced for this client public event PacketStats OnPacketStats; + /// Fired when the queue for a packet category is empty. This event can be + /// hooked to put more data on the empty queue public event QueueEmpty OnQueueEmpty; /// AgentID for this client @@ -115,6 +139,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// A reference to the LLUDPServer that is managing this client private readonly LLUDPServer udpServer; + /// + /// Default constructor + /// + /// Reference to the UDP server this client is connected to + /// Default throttling rates and maximum throttle limits + /// Parent HTB (hierarchical token bucket) + /// that the child throttles will be governed by + /// Circuit code for this connection + /// AgentID for the connected agent + /// Remote endpoint for this connection public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint) { udpServer = server; @@ -144,14 +178,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP RTO = 3000; } + /// + /// Shuts down this client connection + /// public void Shutdown() { + // TODO: Do we need to invalidate the circuit? IsConnected = false; } + /// + /// Gets information about this client connection + /// + /// Information about the client connection public ClientInfo GetClientInfo() { - // TODO: This data structure is wrong in so many ways + // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists + // of pending and needed ACKs for every client every time some method wants information about + // this connection is a recipe for poor performance ClientInfo info = new ClientInfo(); info.pendingAcks = new Dictionary(); info.needAck = new Dictionary(); @@ -169,8 +213,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP return info; } + /// + /// Modifies the UDP throttles + /// + /// New throttling values public void SetClientInfo(ClientInfo info) { + // TODO: Allowing throttles to be manually set from this function seems like a reasonable + // idea. On the other hand, letting external code manipulate our ACK accounting is not + // going to happen + throw new NotImplementedException(); } public string GetStats() diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 38890dae26..c0a84a8372 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -41,7 +41,10 @@ using OpenMetaverse; namespace OpenSim.Region.ClientStack.LindenUDP { - public class LLUDPServerShim : IClientNetworkServer + /// + /// A shim around LLUDPServer that implements the IClientNetworkServer interface + /// + public sealed class LLUDPServerShim : IClientNetworkServer { LLUDPServer m_udpServer; @@ -80,6 +83,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + /// + /// The LLUDP server for a region. This handles incoming and outgoing + /// packets for all UDP connections to the region + /// public class LLUDPServer : UDPBase { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -152,6 +159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public new void Stop() { + m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); base.Stop(); } @@ -591,11 +599,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (packet.Type != PacketType.PacketAck) { // Inbox insertion - IncomingPacket incomingPacket; - incomingPacket.Client = client; - incomingPacket.Packet = packet; - - packetInbox.Enqueue(incomingPacket); + packetInbox.Enqueue(new IncomingPacket(client, packet)); } } @@ -683,7 +687,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // on to en-US to avoid number parsing issues Culture.SetCurrentCulture(); - IncomingPacket incomingPacket = default(IncomingPacket); + IncomingPacket incomingPacket = null; while (base.IsRunning) { @@ -696,59 +700,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP packetInbox.Clear(); } - private void ProcessInPacket(object state) - { - IncomingPacket incomingPacket = (IncomingPacket)state; - Packet packet = incomingPacket.Packet; - LLUDPClient client = incomingPacket.Client; - - if (packet != null && client != null) - { - try - { - client.ClientAPI.ProcessInPacket(packet); - } - catch (ThreadAbortException) - { - throw; - } - catch (Exception e) - { - if (StatsManager.SimExtraStats != null) - StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); - - // Don't let a failure in an individual client thread crash the whole sim. - m_log.ErrorFormat("[LLUDPSERVER]: Client thread for {0} crashed. Logging them out", client.AgentID); - m_log.Error(e.Message, e); - - try - { - // Make an attempt to alert the user that their session has crashed - AgentAlertMessagePacket alert = client.ClientAPI.BuildAgentAlertPacket( - "Unfortunately the session for this client on the server has crashed.\n" + - "Any further actions taken will not be processed.\n" + - "Please relog", true); - - SendPacket(client, alert, ThrottleOutPacketType.Unknown, false); - - // TODO: There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to - // listeners yet, though. - client.ClientAPI.SendLogoutPacket(); - RemoveClient(client.ClientAPI); - } - catch (ThreadAbortException) - { - throw; - } - catch (Exception e2) - { - m_log.Error("[LLUDPSERVER]: Further exception thrown on forced session logout for " + client.AgentID); - m_log.Error(e2.Message, e2); - } - } - } - } - private void OutgoingPacketHandler() { // Set this culture for the thread that outgoing packets are sent @@ -812,6 +763,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + private void ProcessInPacket(object state) + { + IncomingPacket incomingPacket = (IncomingPacket)state; + Packet packet = incomingPacket.Packet; + LLUDPClient client = incomingPacket.Client; + + // Sanity check + if (packet == null || client == null || client.ClientAPI == null) + { + m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", Client=\"{1}\", Client.ClientAPI=\"{2}\"", + packet, client, (client != null) ? client.ClientAPI : null); + } + + try + { + // Process this packet + client.ClientAPI.ProcessInPacket(packet); + } + catch (ThreadAbortException) + { + // If something is trying to abort the packet processing thread, take that as a hint that it's time to shut down + m_log.Info("[LLUDPSERVER]: Caught a thread abort, shutting down the LLUDP server"); + Stop(); + } + catch (Exception e) + { + // Don't let a failure in an individual client thread crash the whole sim. + m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", client.AgentID, packet.Type); + m_log.Error(e.Message, e); + } + } + private void LogoutHandler(IClientAPI client) { client.SendLogoutPacket(); diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs index 69b0c5fc20..1a1a1cb4e3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs @@ -31,6 +31,13 @@ using OpenMetaverse; namespace OpenSim.Region.ClientStack.LindenUDP { + /// + /// Holds a reference to the this packet is + /// destined for, along with the serialized packet data, sequence number + /// (if this is a resend), number of times this packet has been resent, + /// the time of the last resend, and the throttling category for this + /// packet + /// public sealed class OutgoingPacket { /// Client this packet is destined for @@ -46,6 +53,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Category this packet belongs to public ThrottleOutPacketType Category; + /// + /// Default constructor + /// + /// Reference to the client this packet is destined for + /// Serialized packet data. If the flags or sequence number + /// need to be updated, they will be injected directly into this binary buffer + /// Throttling category for this packet public OutgoingPacket(LLUDPClient client, UDPPacketBuffer buffer, ThrottleOutPacketType category) { Client = client; diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs index ffa20d5f02..858a03c097 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs @@ -30,24 +30,47 @@ using Nini.Config; namespace OpenSim.Region.ClientStack.LindenUDP { + /// + /// Holds drip rates and maximum burst rates for throttling with hierarchical + /// token buckets. The maximum burst rates set here are hard limits and can + /// not be overridden by client requests + /// public sealed class ThrottleRates { + /// Drip rate for resent packets public int Resend; + /// Drip rate for terrain packets public int Land; + /// Drip rate for wind packets public int Wind; + /// Drip rate for cloud packets public int Cloud; + /// Drip rate for task (state and transaction) packets public int Task; + /// Drip rate for texture packets public int Texture; + /// Drip rate for asset packets public int Asset; + /// Maximum burst rate for resent packets public int ResendLimit; + /// Maximum burst rate for land packets public int LandLimit; + /// Maximum burst rate for wind packets public int WindLimit; + /// Maximum burst rate for cloud packets public int CloudLimit; + /// Maximum burst rate for task (state and transaction) packets public int TaskLimit; + /// Maximum burst rate for texture packets public int TextureLimit; + /// Maximum burst rate for asset packets public int AssetLimit; + /// + /// Default constructor + /// + /// Config source to load defaults from public ThrottleRates(IConfigSource config) { try diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 16c00355b1..b7df84da69 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -32,19 +32,34 @@ using OpenMetaverse; namespace OpenSim.Region.ClientStack.LindenUDP { + /// + /// Special collection that is optimized for tracking unacknowledged packets + /// public sealed class UnackedPacketCollection { + /// Synchronization primitive. A lock must be acquired on this + /// object before calling any of the unsafe methods public object SyncRoot = new object(); - SortedDictionary packets; + /// Holds the actual unacked packet data, sorted by sequence number + private SortedDictionary packets = new SortedDictionary(); + /// Gets the total number of unacked packets public int Count { get { return packets.Count; } } + /// + /// Default constructor + /// public UnackedPacketCollection() { - packets = new SortedDictionary(); } + /// + /// Add an unacked packet to the collection + /// + /// Packet that is awaiting acknowledgement + /// True if the packet was successfully added, false if the + /// packet already existed in the collection public bool Add(OutgoingPacket packet) { lock (SyncRoot) @@ -58,11 +73,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + /// + /// Removes a packet from the collection without attempting to obtain a + /// lock first + /// + /// Sequence number of the packet to remove + /// True if the packet was found and removed, otherwise false public bool RemoveUnsafe(uint sequenceNumber) { return packets.Remove(sequenceNumber); } + /// + /// Removes a packet from the collection without attempting to obtain a + /// lock first + /// + /// Sequence number of the packet to remove + /// Returns the removed packet + /// True if the packet was found and removed, otherwise false public bool RemoveUnsafe(uint sequenceNumber, out OutgoingPacket packet) { if (packets.TryGetValue(sequenceNumber, out packet)) @@ -74,6 +102,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP return false; } + /// + /// Gets the packet with the lowest sequence number + /// + /// The packet with the lowest sequence number, or null if the + /// collection is empty public OutgoingPacket GetOldest() { lock (SyncRoot) @@ -83,7 +116,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public List GetExpiredPackets(int timeout) + /// + /// Returns a list of all of the packets with a TickCount older than + /// the specified timeout + /// + /// Number of ticks (milliseconds) before a + /// packet is considered expired + /// A list of all expired packets according to the given + /// expiration timeout + public List GetExpiredPackets(int timeoutMS) { List expiredPackets = null; @@ -95,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (packet.TickCount == 0) continue; - if (now - packet.TickCount >= timeout) + if (now - packet.TickCount >= timeoutMS) { if (expiredPackets == null) expiredPackets = new List(); diff --git a/prebuild.xml b/prebuild.xml index f863ab64c6..f35dcc37aa 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -131,6 +131,7 @@ ../../bin/ + @@ -1755,6 +1756,7 @@ ../../../../bin/ + @@ -3695,6 +3697,7 @@ + From 99c85b5ef541b83dc09e93c66232c3893e348e4b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 6 Oct 2009 20:32:33 +0100 Subject: [PATCH 08/36] * Change some more default ports to the robust default of 8003 * Make these use existing constants rather than hardcoding * These will probably go away soon anyway once all services are under ROBUST --- OpenSim/Framework/ConfigSettings.cs | 4 ++-- OpenSim/Framework/InventoryConfig.cs | 6 +++--- OpenSim/Tests/Clients/Grid/GridClient.cs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenSim/Framework/ConfigSettings.cs b/OpenSim/Framework/ConfigSettings.cs index 93efffae4b..32415e03e1 100644 --- a/OpenSim/Framework/ConfigSettings.cs +++ b/OpenSim/Framework/ConfigSettings.cs @@ -168,7 +168,7 @@ namespace OpenSim.Framework public const bool DefaultUserServerHttpSSL = false; public const uint DefaultMessageServerHttpPort = 8006; public const bool DefaultMessageServerHttpSSL = false; - public const uint DefaultGridServerHttpPort = 8001; - public const uint DefaultInventoryServerHttpPort = 8004; + public const uint DefaultGridServerHttpPort = 8003; + public const uint DefaultInventoryServerHttpPort = 8003; } } diff --git a/OpenSim/Framework/InventoryConfig.cs b/OpenSim/Framework/InventoryConfig.cs index f539d556d7..dd207ada1b 100644 --- a/OpenSim/Framework/InventoryConfig.cs +++ b/OpenSim/Framework/InventoryConfig.cs @@ -56,15 +56,15 @@ namespace OpenSim.Framework m_configMember.addConfigurationOption("default_inventory_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default Inventory Server URI (this server's external name)", - "http://127.0.0.1:8004", false); + "http://127.0.0.1:" + ConfigSettings.DefaultInventoryServerHttpPort, false); m_configMember.addConfigurationOption("default_user_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default User Server URI", - "http://127.0.0.1:8002", false); + "http://127.0.0.1:" + ConfigSettings.DefaultUserServerHttpPort, false); m_configMember.addConfigurationOption("default_asset_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default Asset Server URI", - "http://127.0.0.1:8003", false); + "http://127.0.0.1:" + ConfigSettings.DefaultAssetServerHttpPort, false); m_configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "DLL for database provider", "OpenSim.Data.MySQL.dll", false); m_configMember.addConfigurationOption("database_connect", ConfigurationOption.ConfigurationTypes.TYPE_STRING, diff --git a/OpenSim/Tests/Clients/Grid/GridClient.cs b/OpenSim/Tests/Clients/Grid/GridClient.cs index 8798c5ed5b..23d8593e40 100644 --- a/OpenSim/Tests/Clients/Grid/GridClient.cs +++ b/OpenSim/Tests/Clients/Grid/GridClient.cs @@ -55,7 +55,7 @@ namespace OpenSim.Tests.Clients.GridClient new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"); log4net.Config.BasicConfigurator.Configure(consoleAppender); - string serverURI = "http://127.0.0.1:8001"; + string serverURI = "http://127.0.0.1:" + ConfigSettings.DefaultGridServerHttpPort; GridServicesConnector m_Connector = new GridServicesConnector(serverURI); GridRegion r1 = CreateRegion("Test Region 1", 1000, 1000); From 25676ac5cf61a35f1e6e3cd7f7aba95c31bdf494 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 13:39:10 -0700 Subject: [PATCH 09/36] * Added a sanity check for Mono before trying to enumerate over an empty SortedDictionary * Changed the order of a log line from DotNetEngine so you can tell whether or not it is actually loading --- .../ClientStack/LindenUDP/UnackedPacketCollection.cs | 3 +++ OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index b7df84da69..6ecc0c80d2 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -111,6 +111,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lock (SyncRoot) { + if (packets.Count == 0) + return null; + using (SortedDictionary.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) return e.Current; } diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs index 3c91b29e7f..9806218497 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs @@ -129,10 +129,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine public void AddRegion(Scene Sceneworld) { - m_log.Info("[" + ScriptEngineName + "]: ScriptEngine initializing"); - - m_Scene = Sceneworld; - // Make sure we have config if (ConfigSource.Configs[ScriptEngineName] == null) ConfigSource.AddConfig(ScriptEngineName); @@ -143,6 +139,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine if (!m_enabled) return; + m_log.Info("[" + ScriptEngineName + "]: ScriptEngine initializing"); + + m_Scene = Sceneworld; + // Create all objects we'll be using m_EventQueueManager = new EventQueueManager(this); m_EventManager = new EventManager(this, true); From eb205ef4f02852ccb62103d307e70de80270f795 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 14:07:04 -0700 Subject: [PATCH 10/36] Added a debug line for nebadon --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b25be8ea84..ceff28b1ea 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1446,6 +1446,9 @@ namespace OpenSim.Region.Framework.Scenes m_log.Info("[SCENE]: Loading objects from datastore"); List PrimsFromDB = m_storageManager.DataStore.LoadObjects(regionID); + + m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count + " objects from the datastore"); + foreach (SceneObjectGroup group in PrimsFromDB) { if (group.RootPart == null) From a3a8691ebecf3a029e0e897786fde5051d3d6097 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 14:18:37 -0700 Subject: [PATCH 11/36] MySQLLegacyRegionData: Extreme Spam Edition(tm) --- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index fe0914b29b..d99bc30ff4 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -402,8 +402,12 @@ namespace OpenSim.Data.MySQL Dictionary prims = new Dictionary(); SceneObjectGroup grp = null; + m_log.Debug("[REGION DB]: Entering LoadObjects()"); + lock (m_Connection) { + m_log.Debug("[REGION DB]: Entered LoadObjects() lock"); + using (MySqlCommand cmd = m_Connection.CreateCommand()) { cmd.CommandText = "select *, " + @@ -419,6 +423,8 @@ namespace OpenSim.Data.MySQL { while (reader.Read()) { + m_log.Debug("[REGION DB]: LoadObjects() Read a prim"); + SceneObjectPart prim = BuildPrim(reader); if (reader["Shape"] is DBNull) prim.Shape = PrimitiveBaseShape.Default; From c8558065484bfc3758804c6140ce88ad2c5aed37 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 14:26:00 -0700 Subject: [PATCH 12/36] Reverting MySQLLegacyRegionData spam --- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index d99bc30ff4..fe0914b29b 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -402,12 +402,8 @@ namespace OpenSim.Data.MySQL Dictionary prims = new Dictionary(); SceneObjectGroup grp = null; - m_log.Debug("[REGION DB]: Entering LoadObjects()"); - lock (m_Connection) { - m_log.Debug("[REGION DB]: Entered LoadObjects() lock"); - using (MySqlCommand cmd = m_Connection.CreateCommand()) { cmd.CommandText = "select *, " + @@ -423,8 +419,6 @@ namespace OpenSim.Data.MySQL { while (reader.Read()) { - m_log.Debug("[REGION DB]: LoadObjects() Read a prim"); - SceneObjectPart prim = BuildPrim(reader); if (reader["Shape"] is DBNull) prim.Shape = PrimitiveBaseShape.Default; From 74fe284a20976923ab9112e7c32249aa59392d5f Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 14:50:46 -0700 Subject: [PATCH 13/36] Trying Melanie's fix --- .../ClientStack/LindenUDP/UnackedPacketCollection.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 6ecc0c80d2..39882fb294 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -111,11 +111,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lock (SyncRoot) { - if (packets.Count == 0) - return null; + OutgoingPacket p; using (SortedDictionary.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) - return e.Current; + p = e.Current; + + return p; } } From 9cb5db362123dda7d10ce2500926e2d3db9765f9 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 15:08:09 -0700 Subject: [PATCH 14/36] Applying the real fix (thank you for tracking that MSDN doc down Melanie) --- .../ClientStack/LindenUDP/UnackedPacketCollection.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 39882fb294..195ca57b9e 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -111,12 +111,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lock (SyncRoot) { - OutgoingPacket p; - using (SortedDictionary.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) - p = e.Current; - - return p; + { + if (e.MoveNext()) + return e.Current; + else + return null; + } } } From e992ca025571a891333a57012c2cd4419b6581e5 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 6 Oct 2009 15:39:53 -0700 Subject: [PATCH 15/36] Rewrote parts of the code that were double-locking different objects. This is about half of the code base reviewed. --- .../Cache/UserProfileCacheService.cs | 70 +++++------ .../ClientStack/LindenUDP/LLClientView.cs | 116 +++++++++++------- .../Avatar/Friends/FriendsModule.cs | 54 ++++---- .../Avatar/InstantMessage/PresenceModule.cs | 11 +- .../Transfer/InventoryTransferModule.cs | 15 +-- .../Scripting/EMailModules/EmailModule.cs | 37 +++--- .../World/Land/LandManagementModule.cs | 8 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 38 +++--- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 38 +++--- 9 files changed, 211 insertions(+), 176 deletions(-) diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs index 9e12d94849..b02cf5b58d 100644 --- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs +++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs @@ -128,24 +128,18 @@ namespace OpenSim.Framework.Communications.Cache /// null if no user details are found public CachedUserInfo GetUserDetails(string fname, string lname) { + CachedUserInfo userInfo; lock (m_userProfilesByName) - { - CachedUserInfo userInfo; - + { if (m_userProfilesByName.TryGetValue(string.Format(NAME_FORMAT, fname, lname), out userInfo)) - { return userInfo; - } - else - { - UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(fname, lname); - - if (userProfile != null) - return AddToCaches(userProfile); - else - return null; - } } + UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(fname, lname); + + if (userProfile != null) + return AddToCaches(userProfile); + else + return null; } /// @@ -160,20 +154,14 @@ namespace OpenSim.Framework.Communications.Cache return null; lock (m_userProfilesById) - { if (m_userProfilesById.ContainsKey(userID)) - { return m_userProfilesById[userID]; - } - else - { - UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID); - if (userProfile != null) - return AddToCaches(userProfile); - else - return null; - } - } + + UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID); + if (userProfile != null) + return AddToCaches(userProfile); + else + return null; } /// @@ -211,14 +199,10 @@ namespace OpenSim.Framework.Communications.Cache CachedUserInfo createdUserInfo = new CachedUserInfo(m_InventoryService, userProfile); lock (m_userProfilesById) - { m_userProfilesById[createdUserInfo.UserProfile.ID] = createdUserInfo; - - lock (m_userProfilesByName) - { - m_userProfilesByName[createdUserInfo.UserProfile.Name] = createdUserInfo; - } - } + + lock (m_userProfilesByName) + m_userProfilesByName[createdUserInfo.UserProfile.Name] = createdUserInfo; return createdUserInfo; } @@ -230,21 +214,25 @@ namespace OpenSim.Framework.Communications.Cache /// true if there was a profile to remove, false otherwise protected bool RemoveFromCaches(UUID userId) { + CachedUserInfo userInfo = null; lock (m_userProfilesById) { if (m_userProfilesById.ContainsKey(userId)) { - CachedUserInfo userInfo = m_userProfilesById[userId]; + userInfo = m_userProfilesById[userId]; m_userProfilesById.Remove(userId); - - lock (m_userProfilesByName) - { - m_userProfilesByName.Remove(userInfo.UserProfile.Name); - } - - return true; } } + + if (userInfo != null) + lock (m_userProfilesByName) + { + if (m_userProfilesByName.ContainsKey(userInfo.UserProfile.Name)) + { + m_userProfilesByName.Remove(userInfo.UserProfile.Name); + return true; + } + } return false; } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 00527290ad..fe37a0848a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3122,6 +3122,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP objectData.TextureAnim = textureanim; } + bool doUpdate = false; lock (m_primFullUpdates) { if (m_primFullUpdates.Count == 0) @@ -3130,8 +3131,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdates.Add(objectData); if (m_primFullUpdates.Count >= m_primFullUpdatesPerPacket) - ProcessPrimFullUpdates(this, null); + doUpdate = true; } + if (doUpdate) + ProcessPrimFullUpdates(this, null); } void HandleQueueEmpty(ThrottleOutPacketType queue) @@ -3152,35 +3155,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) { + bool stopTimer = false; lock (m_primFullUpdates) { if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) - { - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); + stopTimer = true; + } + if (stopTimer) + { + lock (m_primFullUpdateTimer) + m_primFullUpdateTimer.Stop(); + return; + } - return; - } + ObjectUpdatePacket outPacket = + (ObjectUpdatePacket)PacketPool.Instance.GetPacket( + PacketType.ObjectUpdate); - ObjectUpdatePacket outPacket = - (ObjectUpdatePacket)PacketPool.Instance.GetPacket( - PacketType.ObjectUpdate); + outPacket.RegionData.RegionHandle = + Scene.RegionInfo.RegionHandle; + outPacket.RegionData.TimeDilation = + (ushort)(Scene.TimeDilation * ushort.MaxValue); - outPacket.RegionData.RegionHandle = - Scene.RegionInfo.RegionHandle; - outPacket.RegionData.TimeDilation = - (ushort)(Scene.TimeDilation * ushort.MaxValue); + int max = m_primFullUpdates.Count; + if (max > m_primFullUpdatesPerPacket) + max = m_primFullUpdatesPerPacket; - int max = m_primFullUpdates.Count; - if (max > m_primFullUpdatesPerPacket) - max = m_primFullUpdatesPerPacket; + int count = 0; + int size = 0; - int count = 0; - int size = 0; - - byte[] zerobuffer = new byte[1024]; - byte[] blockbuffer = new byte[1024]; + byte[] zerobuffer = new byte[1024]; + byte[] blockbuffer = new byte[1024]; + lock (m_primFullUpdates) + { for (count = 0 ; count < max ; count++) { int length = 0; @@ -3204,9 +3212,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); + stopTimer = true; } + + if (stopTimer) + lock (m_primFullUpdateTimer) + m_primFullUpdateTimer.Stop(); } /// @@ -3225,6 +3236,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity, state); + bool doUpdate = false; lock (m_primTerseUpdates) { if (m_primTerseUpdates.Count == 0) @@ -3233,43 +3245,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primTerseUpdates.Add(objectData); if (m_primTerseUpdates.Count >= m_primTerseUpdatesPerPacket) - ProcessPrimTerseUpdates(this, null); + doUpdate = true; } + if (doUpdate) + ProcessPrimTerseUpdates(this, null); } void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) { + bool stopTimer = false; lock (m_primTerseUpdates) { if (m_primTerseUpdates.Count == 0) - { - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); + stopTimer = true; + } + if (stopTimer) + { + lock (m_primTerseUpdateTimer) + m_primTerseUpdateTimer.Stop(); - return; - } + return; + } - ImprovedTerseObjectUpdatePacket outPacket = - (ImprovedTerseObjectUpdatePacket) - PacketPool.Instance.GetPacket( - PacketType.ImprovedTerseObjectUpdate); + ImprovedTerseObjectUpdatePacket outPacket = + (ImprovedTerseObjectUpdatePacket) + PacketPool.Instance.GetPacket( + PacketType.ImprovedTerseObjectUpdate); - outPacket.RegionData.RegionHandle = - Scene.RegionInfo.RegionHandle; - outPacket.RegionData.TimeDilation = - (ushort)(Scene.TimeDilation * ushort.MaxValue); + outPacket.RegionData.RegionHandle = + Scene.RegionInfo.RegionHandle; + outPacket.RegionData.TimeDilation = + (ushort)(Scene.TimeDilation * ushort.MaxValue); - int max = m_primTerseUpdates.Count; - if (max > m_primTerseUpdatesPerPacket) - max = m_primTerseUpdatesPerPacket; + int max = m_primTerseUpdates.Count; + if (max > m_primTerseUpdatesPerPacket) + max = m_primTerseUpdatesPerPacket; - int count = 0; - int size = 0; + int count = 0; + int size = 0; - byte[] zerobuffer = new byte[1024]; - byte[] blockbuffer = new byte[1024]; + byte[] zerobuffer = new byte[1024]; + byte[] blockbuffer = new byte[1024]; - for (count = 0 ; count < max ; count++) + lock (m_primTerseUpdates) + { + for (count = 0; count < max; count++) { int length = 0; m_primTerseUpdates[count].ToBytes(blockbuffer, ref length); @@ -3294,9 +3314,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); if (m_primTerseUpdates.Count == 0) - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); + stopTimer = true; } + if (stopTimer) + lock (m_primTerseUpdateTimer) + m_primTerseUpdateTimer.Stop(); } public void FlushPrimUpdates() diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index fc7d63aa06..4abad81979 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -442,42 +442,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private ScenePresence GetRootPresenceFromAgentID(UUID AgentID) { - ScenePresence returnAgent = null; + List scenes = null; lock (m_scenes) - { - ScenePresence queryagent = null; - foreach (Scene scene in m_scenes.Values) - { - queryagent = scene.GetScenePresence(AgentID); - if (queryagent != null) - { - if (!queryagent.IsChildAgent) - { - returnAgent = queryagent; - break; - } - } - } - } - return returnAgent; - } + scenes = new List(m_scenes.Values); - private ScenePresence GetAnyPresenceFromAgentID(UUID AgentID) - { ScenePresence returnAgent = null; - lock (m_scenes) + ScenePresence queryagent = null; + foreach (Scene scene in scenes) { - ScenePresence queryagent = null; - foreach (Scene scene in m_scenes.Values) + queryagent = scene.GetScenePresence(AgentID); + if (queryagent != null) { - queryagent = scene.GetScenePresence(AgentID); - if (queryagent != null) + if (!queryagent.IsChildAgent) { returnAgent = queryagent; break; } } } + + return returnAgent; + } + + private ScenePresence GetAnyPresenceFromAgentID(UUID AgentID) + { + List scenes = null; + lock (m_scenes) + scenes = new List(m_scenes.Values); + + ScenePresence returnAgent = null; + ScenePresence queryagent = null; + foreach (Scene scene in m_scenes.Values) + { + queryagent = scene.GetScenePresence(AgentID); + if (queryagent != null) + { + returnAgent = queryagent; + break; + } + } + return returnAgent; } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs index ad05babec3..42dd7ffbcd 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs @@ -290,13 +290,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // get the agent. This should work every time, as we just got a packet from it ScenePresence agent = null; + List scenes = null; lock (m_Scenes) + scenes = new List(m_Scenes); + + foreach (Scene scene in scenes) { - foreach (Scene scene in m_Scenes) - { - agent = scene.GetScenePresence(agentID); - if (agent != null) break; - } + agent = scene.GetScenePresence(agentID); + if (agent != null) break; } // just to be paranoid... diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index d9a021fc02..e6e0483f55 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -111,16 +111,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer private Scene FindClientScene(UUID agentId) { + List scenes = null; lock (m_Scenelist) + scenes = new List(m_Scenelist); + + foreach (Scene scene in scenes) { - foreach (Scene scene in m_Scenelist) + ScenePresence presence = scene.GetScenePresence(agentId); + if (presence != null) { - ScenePresence presence = scene.GetScenePresence(agentId); - if (presence != null) - { - if (!presence.IsChildAgent) - return scene; - } + if (!presence.IsChildAgent) + return scene; } } return null; diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index 83f004dc60..f9f01fea6b 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -198,19 +198,20 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules private SceneObjectPart findPrim(UUID objectID, out string ObjectRegionName) { + List scenes = null; lock (m_Scenes) + scenes = new List(m_Scenes.Values); + + foreach (Scene s in scenes) { - foreach (Scene s in m_Scenes.Values) + SceneObjectPart part = s.GetSceneObjectPart(objectID); + if (part != null) { - SceneObjectPart part = s.GetSceneObjectPart(objectID); - if (part != null) - { - ObjectRegionName = s.RegionInfo.RegionName; - uint localX = (s.RegionInfo.RegionLocX * (int)Constants.RegionSize); - uint localY = (s.RegionInfo.RegionLocY * (int)Constants.RegionSize); - ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")"; - return part; - } + ObjectRegionName = s.RegionInfo.RegionName; + uint localX = (s.RegionInfo.RegionLocX * (int)Constants.RegionSize); + uint localY = (s.RegionInfo.RegionLocY * (int)Constants.RegionSize); + ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")"; + return part; } } ObjectRegionName = string.Empty; @@ -363,6 +364,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules public Email GetNextEmail(UUID objectID, string sender, string subject) { List queue = null; + List removal = new List(); lock (m_LastGetEmailCall) { @@ -375,7 +377,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules // Hopefully this isn't too time consuming. If it is, we can always push it into a worker thread. DateTime now = DateTime.Now; - List removal = new List(); foreach (UUID uuid in m_LastGetEmailCall.Keys) { if ((now - m_LastGetEmailCall[uuid]) > m_QueueTimeout) @@ -383,15 +384,15 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules removal.Add(uuid); } } + } - foreach (UUID remove in removal) - { + foreach (UUID remove in removal) + { + lock (m_LastGetEmailCall) m_LastGetEmailCall.Remove(remove); - lock (m_MailQueues) - { - m_MailQueues.Remove(remove); - } - } + + lock (m_MailQueues) + m_MailQueues.Remove(remove); } lock (m_MailQueues) diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index d2b5cb19e5..0fed1bd384 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -187,14 +187,16 @@ namespace OpenSim.Region.CoreModules.World.Land LandData newData = data.Copy(); newData.LocalID = local_id; + ILandObject land = null; lock (m_landList) { if (m_landList.ContainsKey(local_id)) { m_landList[local_id].LandData = newData; - m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); + land = m_landList[local_id]; } } + m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, land); } public bool AllowedForcefulBans @@ -504,6 +506,7 @@ namespace OpenSim.Region.CoreModules.World.Land /// Land.localID of the peice of land to remove. public void removeLandObject(int local_id) { + UUID id = UUID.Zero; lock (m_landList) { for (int x = 0; x < 64; x++) @@ -520,9 +523,10 @@ namespace OpenSim.Region.CoreModules.World.Land } } - m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].LandData.GlobalID); + id = m_landList[local_id].LandData.GlobalID; m_landList.Remove(local_id); } + m_scene.EventManager.TriggerLandObjectRemoved(id); } private void performFinalLandJoin(ILandObject master, ILandObject slave) diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 5b571c7227..df9473d538 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -122,12 +122,13 @@ namespace OpenSim.Region.Framework.Scenes public bool InventoryDeQueueAndDelete() { DeleteToInventoryHolder x = null; + int left = 0; try { lock (m_inventoryDeletes) { - int left = m_inventoryDeletes.Count; + left = m_inventoryDeletes.Count; if (left > 0) { x = m_inventoryDeletes.Dequeue(); @@ -136,24 +137,27 @@ namespace OpenSim.Region.Framework.Scenes m_inventoryDeletes.Enqueue(x); return true; } - - m_log.DebugFormat( - "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left); - - try - { - m_scene.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient); - if (x.permissionToDelete) - m_scene.DeleteSceneObject(x.objectGroup, false); - } - catch (Exception e) - { - m_log.DebugFormat("Exception background sending object: " + e); - } - - return true; } } + + if (left > 0) + { + m_log.DebugFormat( + "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left); + + try + { + m_scene.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient); + if (x.permissionToDelete) + m_scene.DeleteSceneObject(x.objectGroup, false); + } + catch (Exception e) + { + m_log.DebugFormat("Exception background sending object: " + e); + } + + return true; + } } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 54ac79288a..20b3b5cbce 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -297,34 +297,44 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.AttachToScene(m_parentScene); + List parts = null; + bool found = false; lock (sceneObject) { if (!Entities.ContainsKey(sceneObject.UUID)) { + found = true; Entities.Add(sceneObject); m_numPrim += sceneObject.Children.Count; if (attachToBackup) sceneObject.AttachToBackup(); - if (OnObjectCreate != null) - OnObjectCreate(sceneObject); - - lock (m_dictionary_lock) - { - SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; - SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; - foreach (SceneObjectPart part in sceneObject.Children.Values) - { - SceneObjectGroupsByFullID[part.UUID] = sceneObject; - SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; - } - } + parts = new List(sceneObject.Children.Values); - return true; } } + if (found) + { + lock (m_dictionary_lock) + { + SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; + foreach (SceneObjectPart part in parts) + { + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + } + } + + if (OnObjectCreate != null) + OnObjectCreate(sceneObject); + + return true; + } + + return false; } From 7199976d486eccb101b2942fe93a16df444bf73a Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 15:51:56 -0700 Subject: [PATCH 16/36] Checks the number of ThreadPool and IOCP threads on startup and bumps up the numbers to .NET defaults of 500/1000 if need be --- OpenSim/Region/Application/Application.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 33b01e5976..555baa4a0e 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -91,6 +91,18 @@ namespace OpenSim m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config"); } + // Increase the number of IOCP threads available. Mono defaults to a tragically low number + int workerThreads, iocpThreads; + System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); + m_log.InfoFormat("[OPENSIM MAIN]: Runtime gave us {0} worker threads and {1} IOCP threads", workerThreads, iocpThreads); + if (workerThreads < 500 || iocpThreads < 1000) + { + workerThreads = 500; + iocpThreads = 1000; + m_log.Info("[OPENSIM MAIN]: Bumping up to 500 worker threads and 1000 IOCP threads"); + System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads); + } + // Check if the system is compatible with OpenSimulator. // Ensures that the minimum system requirements are met m_log.Info("Performing compatibility checks... "); From 312438f145aa7286df365e37df423e743dd85db0 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 15:55:39 -0700 Subject: [PATCH 17/36] Commented noisy debugging about packet splitting --- OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index c0a84a8372..2c5ad85432 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -210,8 +210,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[][] datas = packet.ToBytesMultiple(); int packetCount = datas.Length; - if (packetCount > 1) - m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); + //if (packetCount > 1) + // m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); for (int i = 0; i < packetCount; i++) { @@ -250,8 +250,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[][] datas = packet.ToBytesMultiple(); int packetCount = datas.Length; - if (packetCount > 1) - m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); + //if (packetCount > 1) + // m_log.Debug("[LLUDPSERVER]: Split " + packet.Type + " packet into " + packetCount + " packets"); for (int i = 0; i < packetCount; i++) { From 9618c196c274fefda4437eff6d25c7a12e7a3ee1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 7 Oct 2009 01:44:36 +0100 Subject: [PATCH 18/36] Revert "Merging in diva's locking fixes" This reverts commit 832cc685138b2244529f10b54b373c34adb4a633. --- .../Cache/UserProfileCacheService.cs | 66 ++++++---- OpenSim/Framework/ConfigSettings.cs | 4 +- OpenSim/Framework/InventoryConfig.cs | 6 +- .../ClientStack/LindenUDP/LLClientView.cs | 116 +++++++----------- .../Avatar/Friends/FriendsModule.cs | 58 ++++----- .../Avatar/InstantMessage/PresenceModule.cs | 11 +- .../Transfer/InventoryTransferModule.cs | 15 ++- .../Scripting/EMailModules/EmailModule.cs | 37 +++--- .../World/Land/LandManagementModule.cs | 8 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 36 +++--- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 36 ++---- OpenSim/Tests/Clients/Grid/GridClient.cs | 2 +- 12 files changed, 180 insertions(+), 215 deletions(-) diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs index b02cf5b58d..9e12d94849 100644 --- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs +++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs @@ -128,18 +128,24 @@ namespace OpenSim.Framework.Communications.Cache /// null if no user details are found public CachedUserInfo GetUserDetails(string fname, string lname) { - CachedUserInfo userInfo; lock (m_userProfilesByName) - { + { + CachedUserInfo userInfo; + if (m_userProfilesByName.TryGetValue(string.Format(NAME_FORMAT, fname, lname), out userInfo)) + { return userInfo; + } + else + { + UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(fname, lname); + + if (userProfile != null) + return AddToCaches(userProfile); + else + return null; + } } - UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(fname, lname); - - if (userProfile != null) - return AddToCaches(userProfile); - else - return null; } /// @@ -154,14 +160,20 @@ namespace OpenSim.Framework.Communications.Cache return null; lock (m_userProfilesById) + { if (m_userProfilesById.ContainsKey(userID)) + { return m_userProfilesById[userID]; - - UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID); - if (userProfile != null) - return AddToCaches(userProfile); - else - return null; + } + else + { + UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID); + if (userProfile != null) + return AddToCaches(userProfile); + else + return null; + } + } } /// @@ -199,10 +211,14 @@ namespace OpenSim.Framework.Communications.Cache CachedUserInfo createdUserInfo = new CachedUserInfo(m_InventoryService, userProfile); lock (m_userProfilesById) + { m_userProfilesById[createdUserInfo.UserProfile.ID] = createdUserInfo; - - lock (m_userProfilesByName) - m_userProfilesByName[createdUserInfo.UserProfile.Name] = createdUserInfo; + + lock (m_userProfilesByName) + { + m_userProfilesByName[createdUserInfo.UserProfile.Name] = createdUserInfo; + } + } return createdUserInfo; } @@ -214,25 +230,21 @@ namespace OpenSim.Framework.Communications.Cache /// true if there was a profile to remove, false otherwise protected bool RemoveFromCaches(UUID userId) { - CachedUserInfo userInfo = null; lock (m_userProfilesById) { if (m_userProfilesById.ContainsKey(userId)) { - userInfo = m_userProfilesById[userId]; + CachedUserInfo userInfo = m_userProfilesById[userId]; m_userProfilesById.Remove(userId); - } - } - - if (userInfo != null) - lock (m_userProfilesByName) - { - if (m_userProfilesByName.ContainsKey(userInfo.UserProfile.Name)) + + lock (m_userProfilesByName) { m_userProfilesByName.Remove(userInfo.UserProfile.Name); - return true; } + + return true; } + } return false; } diff --git a/OpenSim/Framework/ConfigSettings.cs b/OpenSim/Framework/ConfigSettings.cs index 32415e03e1..93efffae4b 100644 --- a/OpenSim/Framework/ConfigSettings.cs +++ b/OpenSim/Framework/ConfigSettings.cs @@ -168,7 +168,7 @@ namespace OpenSim.Framework public const bool DefaultUserServerHttpSSL = false; public const uint DefaultMessageServerHttpPort = 8006; public const bool DefaultMessageServerHttpSSL = false; - public const uint DefaultGridServerHttpPort = 8003; - public const uint DefaultInventoryServerHttpPort = 8003; + public const uint DefaultGridServerHttpPort = 8001; + public const uint DefaultInventoryServerHttpPort = 8004; } } diff --git a/OpenSim/Framework/InventoryConfig.cs b/OpenSim/Framework/InventoryConfig.cs index dd207ada1b..f539d556d7 100644 --- a/OpenSim/Framework/InventoryConfig.cs +++ b/OpenSim/Framework/InventoryConfig.cs @@ -56,15 +56,15 @@ namespace OpenSim.Framework m_configMember.addConfigurationOption("default_inventory_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default Inventory Server URI (this server's external name)", - "http://127.0.0.1:" + ConfigSettings.DefaultInventoryServerHttpPort, false); + "http://127.0.0.1:8004", false); m_configMember.addConfigurationOption("default_user_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default User Server URI", - "http://127.0.0.1:" + ConfigSettings.DefaultUserServerHttpPort, false); + "http://127.0.0.1:8002", false); m_configMember.addConfigurationOption("default_asset_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default Asset Server URI", - "http://127.0.0.1:" + ConfigSettings.DefaultAssetServerHttpPort, false); + "http://127.0.0.1:8003", false); m_configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "DLL for database provider", "OpenSim.Data.MySQL.dll", false); m_configMember.addConfigurationOption("database_connect", ConfigurationOption.ConfigurationTypes.TYPE_STRING, diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 60dab5f78c..84e705a91d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3546,7 +3546,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP objectData.TextureAnim = textureanim; } - bool doUpdate = false; lock (m_primFullUpdates) { if (m_primFullUpdates.Count == 0) @@ -3555,10 +3554,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdates.Add(objectData); if (m_primFullUpdates.Count >= m_primFullUpdatesPerPacket) - doUpdate = true; + ProcessPrimFullUpdates(this, null); } - if (doUpdate) - ProcessPrimFullUpdates(this, null); } void HandleQueueEmpty(ThrottleOutPacketType queue) @@ -3579,40 +3576,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) { - bool stopTimer = false; lock (m_primFullUpdates) { if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) - stopTimer = true; - } - if (stopTimer) - { - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); - return; - } + { + lock (m_primFullUpdateTimer) + m_primFullUpdateTimer.Stop(); - ObjectUpdatePacket outPacket = - (ObjectUpdatePacket)PacketPool.Instance.GetPacket( - PacketType.ObjectUpdate); + return; + } - outPacket.RegionData.RegionHandle = - Scene.RegionInfo.RegionHandle; - outPacket.RegionData.TimeDilation = - (ushort)(Scene.TimeDilation * ushort.MaxValue); + ObjectUpdatePacket outPacket = + (ObjectUpdatePacket)PacketPool.Instance.GetPacket( + PacketType.ObjectUpdate); - int max = m_primFullUpdates.Count; - if (max > m_primFullUpdatesPerPacket) - max = m_primFullUpdatesPerPacket; + outPacket.RegionData.RegionHandle = + Scene.RegionInfo.RegionHandle; + outPacket.RegionData.TimeDilation = + (ushort)(Scene.TimeDilation * ushort.MaxValue); - int count = 0; - int size = 0; + int max = m_primFullUpdates.Count; + if (max > m_primFullUpdatesPerPacket) + max = m_primFullUpdatesPerPacket; - byte[] zerobuffer = new byte[1024]; - byte[] blockbuffer = new byte[1024]; + int count = 0; + int size = 0; + + byte[] zerobuffer = new byte[1024]; + byte[] blockbuffer = new byte[1024]; - lock (m_primFullUpdates) - { for (count = 0 ; count < max ; count++) { int length = 0; @@ -3636,12 +3628,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(outPacket, ThrottleOutPacketType.Task); if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) - stopTimer = true; + lock (m_primFullUpdateTimer) + m_primFullUpdateTimer.Stop(); } - - if (stopTimer) - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); } /// @@ -3660,7 +3649,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity, state); - bool doUpdate = false; lock (m_primTerseUpdates) { if (m_primTerseUpdates.Count == 0) @@ -3669,51 +3657,43 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primTerseUpdates.Add(objectData); if (m_primTerseUpdates.Count >= m_primTerseUpdatesPerPacket) - doUpdate = true; + ProcessPrimTerseUpdates(this, null); } - if (doUpdate) - ProcessPrimTerseUpdates(this, null); } void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) { - bool stopTimer = false; lock (m_primTerseUpdates) { if (m_primTerseUpdates.Count == 0) - stopTimer = true; - } - if (stopTimer) - { - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); + { + lock (m_primTerseUpdateTimer) + m_primTerseUpdateTimer.Stop(); - return; - } + return; + } - ImprovedTerseObjectUpdatePacket outPacket = - (ImprovedTerseObjectUpdatePacket) - PacketPool.Instance.GetPacket( - PacketType.ImprovedTerseObjectUpdate); + ImprovedTerseObjectUpdatePacket outPacket = + (ImprovedTerseObjectUpdatePacket) + PacketPool.Instance.GetPacket( + PacketType.ImprovedTerseObjectUpdate); - outPacket.RegionData.RegionHandle = - Scene.RegionInfo.RegionHandle; - outPacket.RegionData.TimeDilation = - (ushort)(Scene.TimeDilation * ushort.MaxValue); + outPacket.RegionData.RegionHandle = + Scene.RegionInfo.RegionHandle; + outPacket.RegionData.TimeDilation = + (ushort)(Scene.TimeDilation * ushort.MaxValue); - int max = m_primTerseUpdates.Count; - if (max > m_primTerseUpdatesPerPacket) - max = m_primTerseUpdatesPerPacket; + int max = m_primTerseUpdates.Count; + if (max > m_primTerseUpdatesPerPacket) + max = m_primTerseUpdatesPerPacket; - int count = 0; - int size = 0; + int count = 0; + int size = 0; - byte[] zerobuffer = new byte[1024]; - byte[] blockbuffer = new byte[1024]; + byte[] zerobuffer = new byte[1024]; + byte[] blockbuffer = new byte[1024]; - lock (m_primTerseUpdates) - { - for (count = 0; count < max; count++) + for (count = 0 ; count < max ; count++) { int length = 0; m_primTerseUpdates[count].ToBytes(blockbuffer, ref length); @@ -3738,11 +3718,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(outPacket, ThrottleOutPacketType.Task); if (m_primTerseUpdates.Count == 0) - stopTimer = true; + lock (m_primTerseUpdateTimer) + m_primTerseUpdateTimer.Stop(); } - if (stopTimer) - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); } public void FlushPrimUpdates() diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 4abad81979..fc7d63aa06 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -442,46 +442,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private ScenePresence GetRootPresenceFromAgentID(UUID AgentID) { - List scenes = null; - lock (m_scenes) - scenes = new List(m_scenes.Values); - ScenePresence returnAgent = null; - ScenePresence queryagent = null; - foreach (Scene scene in scenes) + lock (m_scenes) { - queryagent = scene.GetScenePresence(AgentID); - if (queryagent != null) + ScenePresence queryagent = null; + foreach (Scene scene in m_scenes.Values) { - if (!queryagent.IsChildAgent) + queryagent = scene.GetScenePresence(AgentID); + if (queryagent != null) + { + if (!queryagent.IsChildAgent) + { + returnAgent = queryagent; + break; + } + } + } + } + return returnAgent; + } + + private ScenePresence GetAnyPresenceFromAgentID(UUID AgentID) + { + ScenePresence returnAgent = null; + lock (m_scenes) + { + ScenePresence queryagent = null; + foreach (Scene scene in m_scenes.Values) + { + queryagent = scene.GetScenePresence(AgentID); + if (queryagent != null) { returnAgent = queryagent; break; } } } - - return returnAgent; - } - - private ScenePresence GetAnyPresenceFromAgentID(UUID AgentID) - { - List scenes = null; - lock (m_scenes) - scenes = new List(m_scenes.Values); - - ScenePresence returnAgent = null; - ScenePresence queryagent = null; - foreach (Scene scene in m_scenes.Values) - { - queryagent = scene.GetScenePresence(AgentID); - if (queryagent != null) - { - returnAgent = queryagent; - break; - } - } - return returnAgent; } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs index 42dd7ffbcd..ad05babec3 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs @@ -290,14 +290,13 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // get the agent. This should work every time, as we just got a packet from it ScenePresence agent = null; - List scenes = null; lock (m_Scenes) - scenes = new List(m_Scenes); - - foreach (Scene scene in scenes) { - agent = scene.GetScenePresence(agentID); - if (agent != null) break; + foreach (Scene scene in m_Scenes) + { + agent = scene.GetScenePresence(agentID); + if (agent != null) break; + } } // just to be paranoid... diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index e6e0483f55..d9a021fc02 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -111,17 +111,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer private Scene FindClientScene(UUID agentId) { - List scenes = null; lock (m_Scenelist) - scenes = new List(m_Scenelist); - - foreach (Scene scene in scenes) { - ScenePresence presence = scene.GetScenePresence(agentId); - if (presence != null) + foreach (Scene scene in m_Scenelist) { - if (!presence.IsChildAgent) - return scene; + ScenePresence presence = scene.GetScenePresence(agentId); + if (presence != null) + { + if (!presence.IsChildAgent) + return scene; + } } } return null; diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index f9f01fea6b..83f004dc60 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -198,20 +198,19 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules private SceneObjectPart findPrim(UUID objectID, out string ObjectRegionName) { - List scenes = null; lock (m_Scenes) - scenes = new List(m_Scenes.Values); - - foreach (Scene s in scenes) { - SceneObjectPart part = s.GetSceneObjectPart(objectID); - if (part != null) + foreach (Scene s in m_Scenes.Values) { - ObjectRegionName = s.RegionInfo.RegionName; - uint localX = (s.RegionInfo.RegionLocX * (int)Constants.RegionSize); - uint localY = (s.RegionInfo.RegionLocY * (int)Constants.RegionSize); - ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")"; - return part; + SceneObjectPart part = s.GetSceneObjectPart(objectID); + if (part != null) + { + ObjectRegionName = s.RegionInfo.RegionName; + uint localX = (s.RegionInfo.RegionLocX * (int)Constants.RegionSize); + uint localY = (s.RegionInfo.RegionLocY * (int)Constants.RegionSize); + ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")"; + return part; + } } } ObjectRegionName = string.Empty; @@ -364,7 +363,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules public Email GetNextEmail(UUID objectID, string sender, string subject) { List queue = null; - List removal = new List(); lock (m_LastGetEmailCall) { @@ -377,6 +375,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules // Hopefully this isn't too time consuming. If it is, we can always push it into a worker thread. DateTime now = DateTime.Now; + List removal = new List(); foreach (UUID uuid in m_LastGetEmailCall.Keys) { if ((now - m_LastGetEmailCall[uuid]) > m_QueueTimeout) @@ -384,15 +383,15 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules removal.Add(uuid); } } - } - foreach (UUID remove in removal) - { - lock (m_LastGetEmailCall) + foreach (UUID remove in removal) + { m_LastGetEmailCall.Remove(remove); - - lock (m_MailQueues) - m_MailQueues.Remove(remove); + lock (m_MailQueues) + { + m_MailQueues.Remove(remove); + } + } } lock (m_MailQueues) diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 0fed1bd384..d2b5cb19e5 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -187,16 +187,14 @@ namespace OpenSim.Region.CoreModules.World.Land LandData newData = data.Copy(); newData.LocalID = local_id; - ILandObject land = null; lock (m_landList) { if (m_landList.ContainsKey(local_id)) { m_landList[local_id].LandData = newData; - land = m_landList[local_id]; + m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); } } - m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, land); } public bool AllowedForcefulBans @@ -506,7 +504,6 @@ namespace OpenSim.Region.CoreModules.World.Land /// Land.localID of the peice of land to remove. public void removeLandObject(int local_id) { - UUID id = UUID.Zero; lock (m_landList) { for (int x = 0; x < 64; x++) @@ -523,10 +520,9 @@ namespace OpenSim.Region.CoreModules.World.Land } } - id = m_landList[local_id].LandData.GlobalID; + m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].LandData.GlobalID); m_landList.Remove(local_id); } - m_scene.EventManager.TriggerLandObjectRemoved(id); } private void performFinalLandJoin(ILandObject master, ILandObject slave) diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index df9473d538..5b571c7227 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -122,13 +122,12 @@ namespace OpenSim.Region.Framework.Scenes public bool InventoryDeQueueAndDelete() { DeleteToInventoryHolder x = null; - int left = 0; try { lock (m_inventoryDeletes) { - left = m_inventoryDeletes.Count; + int left = m_inventoryDeletes.Count; if (left > 0) { x = m_inventoryDeletes.Dequeue(); @@ -137,26 +136,23 @@ namespace OpenSim.Region.Framework.Scenes m_inventoryDeletes.Enqueue(x); return true; } - } - } - if (left > 0) - { - m_log.DebugFormat( - "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left); - - try - { - m_scene.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient); - if (x.permissionToDelete) - m_scene.DeleteSceneObject(x.objectGroup, false); + m_log.DebugFormat( + "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left); + + try + { + m_scene.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient); + if (x.permissionToDelete) + m_scene.DeleteSceneObject(x.objectGroup, false); + } + catch (Exception e) + { + m_log.DebugFormat("Exception background sending object: " + e); + } + + return true; } - catch (Exception e) - { - m_log.DebugFormat("Exception background sending object: " + e); - } - - return true; } } catch (Exception e) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 20b3b5cbce..54ac79288a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -297,44 +297,34 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.AttachToScene(m_parentScene); - List parts = null; - bool found = false; lock (sceneObject) { if (!Entities.ContainsKey(sceneObject.UUID)) { - found = true; Entities.Add(sceneObject); m_numPrim += sceneObject.Children.Count; if (attachToBackup) sceneObject.AttachToBackup(); - parts = new List(sceneObject.Children.Values); - - } - } - - if (found) - { - lock (m_dictionary_lock) - { - SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; - SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; - foreach (SceneObjectPart part in parts) + if (OnObjectCreate != null) + OnObjectCreate(sceneObject); + + lock (m_dictionary_lock) { - SceneObjectGroupsByFullID[part.UUID] = sceneObject; - SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + } } + + return true; } - - if (OnObjectCreate != null) - OnObjectCreate(sceneObject); - - return true; } - return false; } diff --git a/OpenSim/Tests/Clients/Grid/GridClient.cs b/OpenSim/Tests/Clients/Grid/GridClient.cs index 23d8593e40..8798c5ed5b 100644 --- a/OpenSim/Tests/Clients/Grid/GridClient.cs +++ b/OpenSim/Tests/Clients/Grid/GridClient.cs @@ -55,7 +55,7 @@ namespace OpenSim.Tests.Clients.GridClient new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"); log4net.Config.BasicConfigurator.Configure(consoleAppender); - string serverURI = "http://127.0.0.1:" + ConfigSettings.DefaultGridServerHttpPort; + string serverURI = "http://127.0.0.1:8001"; GridServicesConnector m_Connector = new GridServicesConnector(serverURI); GridRegion r1 = CreateRegion("Test Region 1", 1000, 1000); From 89d23a1fa23cb191e7ebde047311adcadf3b2e45 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 7 Oct 2009 01:45:49 +0100 Subject: [PATCH 19/36] Revert "Rewrote parts of the code that were double-locking different objects. This is about half of the code base reviewed." This reverts commit e992ca025571a891333a57012c2cd4419b6581e5. --- .../Cache/UserProfileCacheService.cs | 66 ++++++---- .../ClientStack/LindenUDP/LLClientView.cs | 116 +++++++----------- .../Avatar/Friends/FriendsModule.cs | 58 ++++----- .../Avatar/InstantMessage/PresenceModule.cs | 11 +- .../Transfer/InventoryTransferModule.cs | 15 ++- .../Scripting/EMailModules/EmailModule.cs | 37 +++--- .../World/Land/LandManagementModule.cs | 8 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 36 +++--- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 36 ++---- 9 files changed, 174 insertions(+), 209 deletions(-) diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs index b02cf5b58d..9e12d94849 100644 --- a/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs +++ b/OpenSim/Framework/Communications/Cache/UserProfileCacheService.cs @@ -128,18 +128,24 @@ namespace OpenSim.Framework.Communications.Cache /// null if no user details are found public CachedUserInfo GetUserDetails(string fname, string lname) { - CachedUserInfo userInfo; lock (m_userProfilesByName) - { + { + CachedUserInfo userInfo; + if (m_userProfilesByName.TryGetValue(string.Format(NAME_FORMAT, fname, lname), out userInfo)) + { return userInfo; + } + else + { + UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(fname, lname); + + if (userProfile != null) + return AddToCaches(userProfile); + else + return null; + } } - UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(fname, lname); - - if (userProfile != null) - return AddToCaches(userProfile); - else - return null; } /// @@ -154,14 +160,20 @@ namespace OpenSim.Framework.Communications.Cache return null; lock (m_userProfilesById) + { if (m_userProfilesById.ContainsKey(userID)) + { return m_userProfilesById[userID]; - - UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID); - if (userProfile != null) - return AddToCaches(userProfile); - else - return null; + } + else + { + UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID); + if (userProfile != null) + return AddToCaches(userProfile); + else + return null; + } + } } /// @@ -199,10 +211,14 @@ namespace OpenSim.Framework.Communications.Cache CachedUserInfo createdUserInfo = new CachedUserInfo(m_InventoryService, userProfile); lock (m_userProfilesById) + { m_userProfilesById[createdUserInfo.UserProfile.ID] = createdUserInfo; - - lock (m_userProfilesByName) - m_userProfilesByName[createdUserInfo.UserProfile.Name] = createdUserInfo; + + lock (m_userProfilesByName) + { + m_userProfilesByName[createdUserInfo.UserProfile.Name] = createdUserInfo; + } + } return createdUserInfo; } @@ -214,25 +230,21 @@ namespace OpenSim.Framework.Communications.Cache /// true if there was a profile to remove, false otherwise protected bool RemoveFromCaches(UUID userId) { - CachedUserInfo userInfo = null; lock (m_userProfilesById) { if (m_userProfilesById.ContainsKey(userId)) { - userInfo = m_userProfilesById[userId]; + CachedUserInfo userInfo = m_userProfilesById[userId]; m_userProfilesById.Remove(userId); - } - } - - if (userInfo != null) - lock (m_userProfilesByName) - { - if (m_userProfilesByName.ContainsKey(userInfo.UserProfile.Name)) + + lock (m_userProfilesByName) { m_userProfilesByName.Remove(userInfo.UserProfile.Name); - return true; } + + return true; } + } return false; } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index fe37a0848a..00527290ad 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3122,7 +3122,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP objectData.TextureAnim = textureanim; } - bool doUpdate = false; lock (m_primFullUpdates) { if (m_primFullUpdates.Count == 0) @@ -3131,10 +3130,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdates.Add(objectData); if (m_primFullUpdates.Count >= m_primFullUpdatesPerPacket) - doUpdate = true; + ProcessPrimFullUpdates(this, null); } - if (doUpdate) - ProcessPrimFullUpdates(this, null); } void HandleQueueEmpty(ThrottleOutPacketType queue) @@ -3155,40 +3152,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) { - bool stopTimer = false; lock (m_primFullUpdates) { if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) - stopTimer = true; - } - if (stopTimer) - { - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); - return; - } + { + lock (m_primFullUpdateTimer) + m_primFullUpdateTimer.Stop(); - ObjectUpdatePacket outPacket = - (ObjectUpdatePacket)PacketPool.Instance.GetPacket( - PacketType.ObjectUpdate); + return; + } - outPacket.RegionData.RegionHandle = - Scene.RegionInfo.RegionHandle; - outPacket.RegionData.TimeDilation = - (ushort)(Scene.TimeDilation * ushort.MaxValue); + ObjectUpdatePacket outPacket = + (ObjectUpdatePacket)PacketPool.Instance.GetPacket( + PacketType.ObjectUpdate); - int max = m_primFullUpdates.Count; - if (max > m_primFullUpdatesPerPacket) - max = m_primFullUpdatesPerPacket; + outPacket.RegionData.RegionHandle = + Scene.RegionInfo.RegionHandle; + outPacket.RegionData.TimeDilation = + (ushort)(Scene.TimeDilation * ushort.MaxValue); - int count = 0; - int size = 0; + int max = m_primFullUpdates.Count; + if (max > m_primFullUpdatesPerPacket) + max = m_primFullUpdatesPerPacket; - byte[] zerobuffer = new byte[1024]; - byte[] blockbuffer = new byte[1024]; + int count = 0; + int size = 0; + + byte[] zerobuffer = new byte[1024]; + byte[] blockbuffer = new byte[1024]; - lock (m_primFullUpdates) - { for (count = 0 ; count < max ; count++) { int length = 0; @@ -3212,12 +3204,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) - stopTimer = true; + lock (m_primFullUpdateTimer) + m_primFullUpdateTimer.Stop(); } - - if (stopTimer) - lock (m_primFullUpdateTimer) - m_primFullUpdateTimer.Stop(); } /// @@ -3236,7 +3225,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP CreatePrimImprovedBlock(localID, position, rotation, velocity, rotationalvelocity, state); - bool doUpdate = false; lock (m_primTerseUpdates) { if (m_primTerseUpdates.Count == 0) @@ -3245,51 +3233,43 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primTerseUpdates.Add(objectData); if (m_primTerseUpdates.Count >= m_primTerseUpdatesPerPacket) - doUpdate = true; + ProcessPrimTerseUpdates(this, null); } - if (doUpdate) - ProcessPrimTerseUpdates(this, null); } void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) { - bool stopTimer = false; lock (m_primTerseUpdates) { if (m_primTerseUpdates.Count == 0) - stopTimer = true; - } - if (stopTimer) - { - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); + { + lock (m_primTerseUpdateTimer) + m_primTerseUpdateTimer.Stop(); - return; - } + return; + } - ImprovedTerseObjectUpdatePacket outPacket = - (ImprovedTerseObjectUpdatePacket) - PacketPool.Instance.GetPacket( - PacketType.ImprovedTerseObjectUpdate); + ImprovedTerseObjectUpdatePacket outPacket = + (ImprovedTerseObjectUpdatePacket) + PacketPool.Instance.GetPacket( + PacketType.ImprovedTerseObjectUpdate); - outPacket.RegionData.RegionHandle = - Scene.RegionInfo.RegionHandle; - outPacket.RegionData.TimeDilation = - (ushort)(Scene.TimeDilation * ushort.MaxValue); + outPacket.RegionData.RegionHandle = + Scene.RegionInfo.RegionHandle; + outPacket.RegionData.TimeDilation = + (ushort)(Scene.TimeDilation * ushort.MaxValue); - int max = m_primTerseUpdates.Count; - if (max > m_primTerseUpdatesPerPacket) - max = m_primTerseUpdatesPerPacket; + int max = m_primTerseUpdates.Count; + if (max > m_primTerseUpdatesPerPacket) + max = m_primTerseUpdatesPerPacket; - int count = 0; - int size = 0; + int count = 0; + int size = 0; - byte[] zerobuffer = new byte[1024]; - byte[] blockbuffer = new byte[1024]; + byte[] zerobuffer = new byte[1024]; + byte[] blockbuffer = new byte[1024]; - lock (m_primTerseUpdates) - { - for (count = 0; count < max; count++) + for (count = 0 ; count < max ; count++) { int length = 0; m_primTerseUpdates[count].ToBytes(blockbuffer, ref length); @@ -3314,11 +3294,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); if (m_primTerseUpdates.Count == 0) - stopTimer = true; + lock (m_primTerseUpdateTimer) + m_primTerseUpdateTimer.Stop(); } - if (stopTimer) - lock (m_primTerseUpdateTimer) - m_primTerseUpdateTimer.Stop(); } public void FlushPrimUpdates() diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 4abad81979..fc7d63aa06 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -442,46 +442,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private ScenePresence GetRootPresenceFromAgentID(UUID AgentID) { - List scenes = null; - lock (m_scenes) - scenes = new List(m_scenes.Values); - ScenePresence returnAgent = null; - ScenePresence queryagent = null; - foreach (Scene scene in scenes) + lock (m_scenes) { - queryagent = scene.GetScenePresence(AgentID); - if (queryagent != null) + ScenePresence queryagent = null; + foreach (Scene scene in m_scenes.Values) { - if (!queryagent.IsChildAgent) + queryagent = scene.GetScenePresence(AgentID); + if (queryagent != null) + { + if (!queryagent.IsChildAgent) + { + returnAgent = queryagent; + break; + } + } + } + } + return returnAgent; + } + + private ScenePresence GetAnyPresenceFromAgentID(UUID AgentID) + { + ScenePresence returnAgent = null; + lock (m_scenes) + { + ScenePresence queryagent = null; + foreach (Scene scene in m_scenes.Values) + { + queryagent = scene.GetScenePresence(AgentID); + if (queryagent != null) { returnAgent = queryagent; break; } } } - - return returnAgent; - } - - private ScenePresence GetAnyPresenceFromAgentID(UUID AgentID) - { - List scenes = null; - lock (m_scenes) - scenes = new List(m_scenes.Values); - - ScenePresence returnAgent = null; - ScenePresence queryagent = null; - foreach (Scene scene in m_scenes.Values) - { - queryagent = scene.GetScenePresence(AgentID); - if (queryagent != null) - { - returnAgent = queryagent; - break; - } - } - return returnAgent; } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs index 42dd7ffbcd..ad05babec3 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs @@ -290,14 +290,13 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // get the agent. This should work every time, as we just got a packet from it ScenePresence agent = null; - List scenes = null; lock (m_Scenes) - scenes = new List(m_Scenes); - - foreach (Scene scene in scenes) { - agent = scene.GetScenePresence(agentID); - if (agent != null) break; + foreach (Scene scene in m_Scenes) + { + agent = scene.GetScenePresence(agentID); + if (agent != null) break; + } } // just to be paranoid... diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index e6e0483f55..d9a021fc02 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -111,17 +111,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer private Scene FindClientScene(UUID agentId) { - List scenes = null; lock (m_Scenelist) - scenes = new List(m_Scenelist); - - foreach (Scene scene in scenes) { - ScenePresence presence = scene.GetScenePresence(agentId); - if (presence != null) + foreach (Scene scene in m_Scenelist) { - if (!presence.IsChildAgent) - return scene; + ScenePresence presence = scene.GetScenePresence(agentId); + if (presence != null) + { + if (!presence.IsChildAgent) + return scene; + } } } return null; diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index f9f01fea6b..83f004dc60 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -198,20 +198,19 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules private SceneObjectPart findPrim(UUID objectID, out string ObjectRegionName) { - List scenes = null; lock (m_Scenes) - scenes = new List(m_Scenes.Values); - - foreach (Scene s in scenes) { - SceneObjectPart part = s.GetSceneObjectPart(objectID); - if (part != null) + foreach (Scene s in m_Scenes.Values) { - ObjectRegionName = s.RegionInfo.RegionName; - uint localX = (s.RegionInfo.RegionLocX * (int)Constants.RegionSize); - uint localY = (s.RegionInfo.RegionLocY * (int)Constants.RegionSize); - ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")"; - return part; + SceneObjectPart part = s.GetSceneObjectPart(objectID); + if (part != null) + { + ObjectRegionName = s.RegionInfo.RegionName; + uint localX = (s.RegionInfo.RegionLocX * (int)Constants.RegionSize); + uint localY = (s.RegionInfo.RegionLocY * (int)Constants.RegionSize); + ObjectRegionName = ObjectRegionName + " (" + localX + ", " + localY + ")"; + return part; + } } } ObjectRegionName = string.Empty; @@ -364,7 +363,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules public Email GetNextEmail(UUID objectID, string sender, string subject) { List queue = null; - List removal = new List(); lock (m_LastGetEmailCall) { @@ -377,6 +375,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules // Hopefully this isn't too time consuming. If it is, we can always push it into a worker thread. DateTime now = DateTime.Now; + List removal = new List(); foreach (UUID uuid in m_LastGetEmailCall.Keys) { if ((now - m_LastGetEmailCall[uuid]) > m_QueueTimeout) @@ -384,15 +383,15 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules removal.Add(uuid); } } - } - foreach (UUID remove in removal) - { - lock (m_LastGetEmailCall) + foreach (UUID remove in removal) + { m_LastGetEmailCall.Remove(remove); - - lock (m_MailQueues) - m_MailQueues.Remove(remove); + lock (m_MailQueues) + { + m_MailQueues.Remove(remove); + } + } } lock (m_MailQueues) diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 0fed1bd384..d2b5cb19e5 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -187,16 +187,14 @@ namespace OpenSim.Region.CoreModules.World.Land LandData newData = data.Copy(); newData.LocalID = local_id; - ILandObject land = null; lock (m_landList) { if (m_landList.ContainsKey(local_id)) { m_landList[local_id].LandData = newData; - land = m_landList[local_id]; + m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); } } - m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, land); } public bool AllowedForcefulBans @@ -506,7 +504,6 @@ namespace OpenSim.Region.CoreModules.World.Land /// Land.localID of the peice of land to remove. public void removeLandObject(int local_id) { - UUID id = UUID.Zero; lock (m_landList) { for (int x = 0; x < 64; x++) @@ -523,10 +520,9 @@ namespace OpenSim.Region.CoreModules.World.Land } } - id = m_landList[local_id].LandData.GlobalID; + m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].LandData.GlobalID); m_landList.Remove(local_id); } - m_scene.EventManager.TriggerLandObjectRemoved(id); } private void performFinalLandJoin(ILandObject master, ILandObject slave) diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index df9473d538..5b571c7227 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -122,13 +122,12 @@ namespace OpenSim.Region.Framework.Scenes public bool InventoryDeQueueAndDelete() { DeleteToInventoryHolder x = null; - int left = 0; try { lock (m_inventoryDeletes) { - left = m_inventoryDeletes.Count; + int left = m_inventoryDeletes.Count; if (left > 0) { x = m_inventoryDeletes.Dequeue(); @@ -137,26 +136,23 @@ namespace OpenSim.Region.Framework.Scenes m_inventoryDeletes.Enqueue(x); return true; } - } - } - if (left > 0) - { - m_log.DebugFormat( - "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left); - - try - { - m_scene.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient); - if (x.permissionToDelete) - m_scene.DeleteSceneObject(x.objectGroup, false); + m_log.DebugFormat( + "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left); + + try + { + m_scene.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient); + if (x.permissionToDelete) + m_scene.DeleteSceneObject(x.objectGroup, false); + } + catch (Exception e) + { + m_log.DebugFormat("Exception background sending object: " + e); + } + + return true; } - catch (Exception e) - { - m_log.DebugFormat("Exception background sending object: " + e); - } - - return true; } } catch (Exception e) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 20b3b5cbce..54ac79288a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -297,44 +297,34 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.AttachToScene(m_parentScene); - List parts = null; - bool found = false; lock (sceneObject) { if (!Entities.ContainsKey(sceneObject.UUID)) { - found = true; Entities.Add(sceneObject); m_numPrim += sceneObject.Children.Count; if (attachToBackup) sceneObject.AttachToBackup(); - parts = new List(sceneObject.Children.Values); - - } - } - - if (found) - { - lock (m_dictionary_lock) - { - SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; - SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; - foreach (SceneObjectPart part in parts) + if (OnObjectCreate != null) + OnObjectCreate(sceneObject); + + lock (m_dictionary_lock) { - SceneObjectGroupsByFullID[part.UUID] = sceneObject; - SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + } } + + return true; } - - if (OnObjectCreate != null) - OnObjectCreate(sceneObject); - - return true; } - return false; } From b5b53dd3ebb331c5d235df161fe9cefc405c3660 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 6 Oct 2009 19:55:35 -0700 Subject: [PATCH 20/36] * One more debug message on FetchInventoryDescendants * More streams close on finally --- .../Communications/Clients/RegionClient.cs | 79 +++++++++++++++---- .../Framework/Scenes/Scene.Inventory.cs | 1 + 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/OpenSim/Framework/Communications/Clients/RegionClient.cs b/OpenSim/Framework/Communications/Clients/RegionClient.cs index 10be06912a..220a9b6a27 100644 --- a/OpenSim/Framework/Communications/Clients/RegionClient.cs +++ b/OpenSim/Framework/Communications/Clients/RegionClient.cs @@ -124,9 +124,11 @@ namespace OpenSim.Framework.Communications.Clients // Let's wait for the response //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall"); + WebResponse webResponse = null; + StreamReader sr = null; try { - WebResponse webResponse = AgentCreateRequest.GetResponse(); + webResponse = AgentCreateRequest.GetResponse(); if (webResponse == null) { m_log.Info("[REST COMMS]: Null reply on DoCreateChildAgentCall post"); @@ -134,11 +136,10 @@ namespace OpenSim.Framework.Communications.Clients else { - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); string response = sr.ReadToEnd().Trim(); - sr.Close(); m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", response); - + if (!String.IsNullOrEmpty(response)) { try @@ -167,6 +168,11 @@ namespace OpenSim.Framework.Communications.Clients m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateChildAgentCall {0}", ex.Message); // ignore, really } + finally + { + if (sr != null) + sr.Close(); + } return true; @@ -246,15 +252,17 @@ namespace OpenSim.Framework.Communications.Clients // Let's wait for the response //m_log.Info("[REST COMMS]: Waiting for a reply after ChildAgentUpdate"); + WebResponse webResponse = null; + StreamReader sr = null; try { - WebResponse webResponse = ChildUpdateRequest.GetResponse(); + webResponse = ChildUpdateRequest.GetResponse(); if (webResponse == null) { m_log.Info("[REST COMMS]: Null reply on ChilAgentUpdate post"); } - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); //reply = sr.ReadToEnd().Trim(); sr.ReadToEnd().Trim(); sr.Close(); @@ -266,6 +274,11 @@ namespace OpenSim.Framework.Communications.Clients m_log.InfoFormat("[REST COMMS]: exception on reply of ChilAgentUpdate {0}", ex.Message); // ignore, really } + finally + { + if (sr != null) + sr.Close(); + } return true; } @@ -284,6 +297,7 @@ namespace OpenSim.Framework.Communications.Clients HttpWebResponse webResponse = null; string reply = string.Empty; + StreamReader sr = null; try { webResponse = (HttpWebResponse)request.GetResponse(); @@ -292,9 +306,8 @@ namespace OpenSim.Framework.Communications.Clients m_log.Info("[REST COMMS]: Null reply on agent get "); } - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); reply = sr.ReadToEnd().Trim(); - sr.Close(); //Console.WriteLine("[REST COMMS]: ChilAgentUpdate reply was " + reply); @@ -305,6 +318,11 @@ namespace OpenSim.Framework.Communications.Clients // ignore, really return false; } + finally + { + if (sr != null) + sr.Close(); + } if (webResponse.StatusCode == HttpStatusCode.OK) { @@ -333,6 +351,7 @@ namespace OpenSim.Framework.Communications.Clients request.Method = "DELETE"; request.Timeout = 10000; + StreamReader sr = null; try { WebResponse webResponse = request.GetResponse(); @@ -341,7 +360,7 @@ namespace OpenSim.Framework.Communications.Clients m_log.Info("[REST COMMS]: Null reply on agent delete "); } - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); //reply = sr.ReadToEnd().Trim(); sr.ReadToEnd().Trim(); sr.Close(); @@ -353,6 +372,11 @@ namespace OpenSim.Framework.Communications.Clients m_log.InfoFormat("[REST COMMS]: exception on reply of agent delete {0}", ex.Message); // ignore, really } + finally + { + if (sr != null) + sr.Close(); + } return true; } @@ -377,6 +401,7 @@ namespace OpenSim.Framework.Communications.Clients request.Method = "DELETE"; request.Timeout = 10000; + StreamReader sr = null; try { WebResponse webResponse = request.GetResponse(); @@ -385,7 +410,7 @@ namespace OpenSim.Framework.Communications.Clients m_log.Info("[REST COMMS]: Null reply on agent delete "); } - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); //reply = sr.ReadToEnd().Trim(); sr.ReadToEnd().Trim(); sr.Close(); @@ -397,6 +422,11 @@ namespace OpenSim.Framework.Communications.Clients m_log.InfoFormat("[REST COMMS]: exception on reply of agent delete {0}", ex.Message); // ignore, really } + finally + { + if (sr != null) + sr.Close(); + } return true; } @@ -463,6 +493,7 @@ namespace OpenSim.Framework.Communications.Clients // Let's wait for the response //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall"); + StreamReader sr = null; try { WebResponse webResponse = ObjectCreateRequest.GetResponse(); @@ -471,10 +502,9 @@ namespace OpenSim.Framework.Communications.Clients m_log.Info("[REST COMMS]: Null reply on DoCreateObjectCall post"); } - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); //reply = sr.ReadToEnd().Trim(); sr.ReadToEnd().Trim(); - sr.Close(); //m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", reply); } @@ -483,6 +513,11 @@ namespace OpenSim.Framework.Communications.Clients m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateObjectCall {0}", ex.Message); // ignore, really } + finally + { + if (sr != null) + sr.Close(); + } return true; @@ -542,6 +577,7 @@ namespace OpenSim.Framework.Communications.Clients // Let's wait for the response //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall"); + StreamReader sr = null; try { WebResponse webResponse = ObjectCreateRequest.GetResponse(); @@ -550,11 +586,10 @@ namespace OpenSim.Framework.Communications.Clients m_log.Info("[REST COMMS]: Null reply on DoCreateObjectCall post"); } - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); sr.ReadToEnd().Trim(); sr.ReadToEnd().Trim(); - sr.Close(); - + //m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", reply); } @@ -563,6 +598,11 @@ namespace OpenSim.Framework.Communications.Clients m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateObjectCall {0}", ex.Message); // ignore, really } + finally + { + if (sr != null) + sr.Close(); + } return true; @@ -630,6 +670,7 @@ namespace OpenSim.Framework.Communications.Clients // Let's wait for the response //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall"); + StreamReader sr = null; try { WebResponse webResponse = HelloNeighbourRequest.GetResponse(); @@ -638,10 +679,9 @@ namespace OpenSim.Framework.Communications.Clients m_log.Info("[REST COMMS]: Null reply on DoHelloNeighbourCall post"); } - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); //reply = sr.ReadToEnd().Trim(); sr.ReadToEnd().Trim(); - sr.Close(); //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); } @@ -650,6 +690,11 @@ namespace OpenSim.Framework.Communications.Clients m_log.InfoFormat("[REST COMMS]: exception on reply of DoHelloNeighbourCall {0}", ex.Message); // ignore, really } + finally + { + if (sr != null) + sr.Close(); + } return true; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index a4460e42a1..191722848f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1168,6 +1168,7 @@ namespace OpenSim.Region.Framework.Scenes private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems) { + m_log.DebugFormat("[AGENT INVENTORY]: Send Inventory Folder {0} Update to {1} {2}", folder.Name, client.FirstName, client.LastName); InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID); client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, fetchFolders, fetchItems); } From 58c33fbc890a4320b6323b379917bb9615968946 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 6 Oct 2009 21:32:15 -0700 Subject: [PATCH 21/36] Uncommented log message on CAPs FetchInventoryDescendants --- OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index e561efbff0..f6d8eace88 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -477,9 +477,9 @@ namespace OpenSim.Region.Framework.Scenes public InventoryCollection HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder, out int version) { -// m_log.DebugFormat( -// "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", -// fetchFolders, fetchItems, folderID, agentID); + m_log.DebugFormat( + "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", + fetchFolders, fetchItems, folderID, agentID); // FIXME MAYBE: We're not handling sortOrder! From adc208e56872c293f31ca2a3521775b5c6b297f2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 7 Oct 2009 04:36:36 +0100 Subject: [PATCH 22/36] Replace LLClientView on the branch with master. UNCOMPILABLE! --- .../ClientStack/LindenUDP/LLClientView.cs | 3248 ++++++++++------- 1 file changed, 1907 insertions(+), 1341 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 84e705a91d..00527290ad 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -58,180 +58,526 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector { - // LLClientView Only - public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args); - - /// Used to adjust Sun Orbit values so Linden based viewers properly position sun - private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static Dictionary PacketHandlers = new Dictionary(); //Global/static handlers for all clients - private readonly LLUDPServer m_udpServer; - private readonly LLUDPClient m_udpClient; + /* static variables */ + public static SynchronizeClientHandler SynchronizeClient; + /* private variables */ private readonly UUID m_sessionId; - private readonly UUID m_secureSessionId; - private readonly UUID m_agentId; - private readonly uint m_circuitCode; - private readonly byte[] m_channelVersion = Utils.EmptyBytes; - private readonly Dictionary m_defaultAnimations = new Dictionary(); - private readonly IGroupsModule m_GroupsModule; + private readonly UUID m_secureSessionId = UUID.Zero; + private int m_debugPacketLevel; + + //private readonly IAssetCache m_assetCache; private int m_cachedTextureSerial; + private Timer m_clientPingTimer; + private Timer m_avatarTerseUpdateTimer; private List m_avatarTerseUpdates = new List(); + private Timer m_primTerseUpdateTimer; private List m_primTerseUpdates = new List(); private Timer m_primFullUpdateTimer; - private List m_primFullUpdates = new List(); + private List m_primFullUpdates = + new List(); + + private bool m_clientBlocked; + + private int m_probesWithNoIngressPackets; + + private readonly UUID m_agentId; + private readonly uint m_circuitCode; private int m_moneyBalance; + private readonly ILLPacketHandler m_PacketHandler; + private int m_animationSequenceNumber = 1; + + private readonly byte[] m_channelVersion = Utils.StringToBytes("OpenSimulator Server"); // Dummy value needed by libSL + + private readonly Dictionary m_defaultAnimations = new Dictionary(); + private bool m_SendLogoutPacketWhenClosing = true; - private AgentUpdateArgs lastarg; - private bool m_IsActive = true; + + private int m_inPacketsChecked; + + // Used to adjust Sun Orbit values so Linden based viewers properly position sun + private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; + + + /* protected variables */ + + protected static Dictionary PacketHandlers = + new Dictionary(); //Global/static handlers for all clients protected Dictionary m_packetHandlers = new Dictionary(); protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers + protected IScene m_scene; + + protected LLPacketServer m_networkServer; + protected LLImageManager m_imageManager; + + /* public variables */ protected string m_firstName; protected string m_lastName; protected Thread m_clientThread; protected Vector3 m_startpos; protected EndPoint m_userEndPoint; + protected EndPoint m_proxyEndPoint; protected UUID m_activeGroupID = UUID.Zero; protected string m_activeGroupName = String.Empty; protected ulong m_activeGroupPowers; protected Dictionary m_groupPowers = new Dictionary(); - protected int m_terrainCheckerCount; - - // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet - protected int m_primTerseUpdatesPerPacket = 10; - protected int m_primFullUpdatesPerPacket = 14; - protected int m_primTerseUpdateRate = 10; - protected int m_primFullUpdateRate = 14; - protected int m_textureSendLimit = 20; - protected int m_textureDataLimit = 10; protected int m_avatarTerseUpdateRate = 50; protected int m_avatarTerseUpdatesPerPacket = 5; + + // LL uses these limits, apparently. Compressed terse would be + // 23, but we don't have that yet + // + protected int m_primTerseUpdatesPerPacket = 10; + protected int m_primFullUpdatesPerPacket = 14; + + protected int m_primTerseUpdateRate = 10; + protected int m_primFullUpdateRate = 14; + + protected int m_textureSendLimit = 20; + protected int m_textureDataLimit = 10; + protected int m_packetMTU = 1400; + protected IAssetService m_assetService; - #region Properties + // LLClientView Only + public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args); + + /* Instantiated Designated Event Delegates */ + //- used so we don't create new objects for each incoming packet and then toss it out later */ + + private GenericMessage handlerGenericMessage; + private RequestAvatarProperties handlerRequestAvatarProperties; //OnRequestAvatarProperties; + private UpdateAvatarProperties handlerUpdateAvatarProperties; // OnUpdateAvatarProperties; + private ChatMessage handlerChatFromClient; //OnChatFromClient; + private ChatMessage handlerChatFromClient2; //OnChatFromClient; + private ImprovedInstantMessage handlerInstantMessage; //OnInstantMessage; + private FriendActionDelegate handlerApproveFriendRequest; //OnApproveFriendRequest; + private FriendshipTermination handlerTerminateFriendship; //OnTerminateFriendship; + private RezObject handlerRezObject; //OnRezObject; + private DeRezObject handlerDeRezObject; //OnDeRezObject; + private ModifyTerrain handlerModifyTerrain; + private BakeTerrain handlerBakeTerrain; + private EstateChangeInfo handlerEstateChangeInfo; + private Action handlerRegionHandShakeReply; //OnRegionHandShakeReply; + private GenericCall2 handlerRequestWearables; //OnRequestWearables; + private Action handlerRequestAvatarsData; //OnRequestAvatarsData; + private SetAppearance handlerSetAppearance; //OnSetAppearance; + private AvatarNowWearing handlerAvatarNowWearing; //OnAvatarNowWearing; + private RezSingleAttachmentFromInv handlerRezSingleAttachment; //OnRezSingleAttachmentFromInv; + private RezMultipleAttachmentsFromInv handlerRezMultipleAttachments; //OnRezMultipleAttachmentsFromInv; + private UUIDNameRequest handlerDetachAttachmentIntoInv; // Detach attachment! + private ObjectAttach handlerObjectAttach; //OnObjectAttach; + private SetAlwaysRun handlerSetAlwaysRun; //OnSetAlwaysRun; + private GenericCall2 handlerCompleteMovementToRegion; //OnCompleteMovementToRegion; + private UpdateAgent handlerAgentUpdate; //OnAgentUpdate; + private StartAnim handlerStartAnim; + private StopAnim handlerStopAnim; + private AgentRequestSit handlerAgentRequestSit; //OnAgentRequestSit; + private AgentSit handlerAgentSit; //OnAgentSit; + private AvatarPickerRequest handlerAvatarPickerRequest; //OnAvatarPickerRequest; + private FetchInventory handlerAgentDataUpdateRequest; //OnAgentDataUpdateRequest; + private TeleportLocationRequest handlerSetStartLocationRequest; //OnSetStartLocationRequest; + private TeleportLandmarkRequest handlerTeleportLandmarkRequest; //OnTeleportLandmarkRequest; + private LinkObjects handlerLinkObjects; //OnLinkObjects; + private DelinkObjects handlerDelinkObjects; //OnDelinkObjects; + private AddNewPrim handlerAddPrim; //OnAddPrim; + private UpdateShape handlerUpdatePrimShape; //null; + private ObjectExtraParams handlerUpdateExtraParams; //OnUpdateExtraParams; + private ObjectDuplicate handlerObjectDuplicate; + private ObjectDuplicateOnRay handlerObjectDuplicateOnRay; + private ObjectRequest handlerObjectRequest; + private ObjectSelect handlerObjectSelect; + private ObjectDeselect handlerObjectDeselect; + private ObjectIncludeInSearch handlerObjectIncludeInSearch; + private UpdatePrimFlags handlerUpdatePrimFlags; //OnUpdatePrimFlags; + private UpdatePrimTexture handlerUpdatePrimTexture; + private GrabObject handlerGrabObject; //OnGrabObject; + private MoveObject handlerGrabUpdate; //OnGrabUpdate; + private DeGrabObject handlerDeGrabObject; //OnDeGrabObject; + private SpinStart handlerSpinStart; //OnSpinStart; + private SpinObject handlerSpinUpdate; //OnSpinUpdate; + private SpinStop handlerSpinStop; //OnSpinStop; + private GenericCall7 handlerObjectDescription; + private GenericCall7 handlerObjectName; + private GenericCall7 handlerObjectClickAction; + private GenericCall7 handlerObjectMaterial; + private ObjectPermissions handlerObjectPermissions; + private RequestObjectPropertiesFamily handlerRequestObjectPropertiesFamily; //OnRequestObjectPropertiesFamily; + //private TextureRequest handlerTextureRequest; + private UDPAssetUploadRequest handlerAssetUploadRequest; //OnAssetUploadRequest; + private RequestXfer handlerRequestXfer; //OnRequestXfer; + private XferReceive handlerXferReceive; //OnXferReceive; + private ConfirmXfer handlerConfirmXfer; //OnConfirmXfer; + private AbortXfer handlerAbortXfer; + private CreateInventoryFolder handlerCreateInventoryFolder; //OnCreateNewInventoryFolder; + private UpdateInventoryFolder handlerUpdateInventoryFolder; + private MoveInventoryFolder handlerMoveInventoryFolder; + private CreateNewInventoryItem handlerCreateNewInventoryItem; //OnCreateNewInventoryItem; + private FetchInventory handlerFetchInventory; + private FetchInventoryDescendents handlerFetchInventoryDescendents; //OnFetchInventoryDescendents; + private PurgeInventoryDescendents handlerPurgeInventoryDescendents; //OnPurgeInventoryDescendents; + private UpdateInventoryItem handlerUpdateInventoryItem; + private CopyInventoryItem handlerCopyInventoryItem; + private MoveInventoryItem handlerMoveInventoryItem; + private RemoveInventoryItem handlerRemoveInventoryItem; + private RemoveInventoryFolder handlerRemoveInventoryFolder; + private RequestTaskInventory handlerRequestTaskInventory; //OnRequestTaskInventory; + private UpdateTaskInventory handlerUpdateTaskInventory; //OnUpdateTaskInventory; + private MoveTaskInventory handlerMoveTaskItem; + private RemoveTaskInventory handlerRemoveTaskItem; //OnRemoveTaskItem; + private RezScript handlerRezScript; //OnRezScript; + private RequestMapBlocks handlerRequestMapBlocks; //OnRequestMapBlocks; + private RequestMapName handlerMapNameRequest; //OnMapNameRequest; + private TeleportLocationRequest handlerTeleportLocationRequest; //OnTeleportLocationRequest; + private MoneyBalanceRequest handlerMoneyBalanceRequest; //OnMoneyBalanceRequest; + private UUIDNameRequest handlerNameRequest; + private ParcelAccessListRequest handlerParcelAccessListRequest; //OnParcelAccessListRequest; + private ParcelAccessListUpdateRequest handlerParcelAccessListUpdateRequest; //OnParcelAccessListUpdateRequest; + private ParcelPropertiesRequest handlerParcelPropertiesRequest; //OnParcelPropertiesRequest; + private ParcelDivideRequest handlerParcelDivideRequest; //OnParcelDivideRequest; + private ParcelJoinRequest handlerParcelJoinRequest; //OnParcelJoinRequest; + private ParcelPropertiesUpdateRequest handlerParcelPropertiesUpdateRequest; //OnParcelPropertiesUpdateRequest; + private ParcelSelectObjects handlerParcelSelectObjects; //OnParcelSelectObjects; + private ParcelObjectOwnerRequest handlerParcelObjectOwnerRequest; //OnParcelObjectOwnerRequest; + private ParcelAbandonRequest handlerParcelAbandonRequest; + private ParcelGodForceOwner handlerParcelGodForceOwner; + private ParcelReclaim handlerParcelReclaim; + private RequestTerrain handlerRequestTerrain; + private RequestTerrain handlerUploadTerrain; + private ParcelReturnObjectsRequest handlerParcelReturnObjectsRequest; + private RegionInfoRequest handlerRegionInfoRequest; //OnRegionInfoRequest; + private EstateCovenantRequest handlerEstateCovenantRequest; //OnEstateCovenantRequest; + private RequestGodlikePowers handlerReqGodlikePowers; //OnRequestGodlikePowers; + private GodKickUser handlerGodKickUser; //OnGodKickUser; + private ViewerEffectEventHandler handlerViewerEffect; //OnViewerEffect; + private Action handlerLogout; //OnLogout; + private MoneyTransferRequest handlerMoneyTransferRequest; //OnMoneyTransferRequest; + private ParcelBuy handlerParcelBuy; + private EconomyDataRequest handlerEconomoyDataRequest; + + private UpdateVector handlerUpdatePrimSinglePosition; //OnUpdatePrimSinglePosition; + private UpdatePrimSingleRotation handlerUpdatePrimSingleRotation; //OnUpdatePrimSingleRotation; + private UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition; //OnUpdatePrimSingleRotation; + private UpdateVector handlerUpdatePrimScale; //OnUpdatePrimScale; + private UpdateVector handlerUpdatePrimGroupScale; //OnUpdateGroupScale; + private UpdateVector handlerUpdateVector; //OnUpdatePrimGroupPosition; + private UpdatePrimRotation handlerUpdatePrimRotation; //OnUpdatePrimGroupRotation; + // private UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; //OnUpdatePrimGroupMouseRotation; + // private RequestAsset handlerRequestAsset; // OnRequestAsset; + private UUIDNameRequest handlerTeleportHomeRequest; + + private RegionHandleRequest handlerRegionHandleRequest; // OnRegionHandleRequest + private ParcelInfoRequest handlerParcelInfoRequest; // OnParcelInfoRequest + + private ScriptAnswer handlerScriptAnswer; + private RequestPayPrice handlerRequestPayPrice; + private ObjectSaleInfo handlerObjectSaleInfo; + private ObjectBuy handlerObjectBuy; + //private BuyObjectInventory handlerBuyObjectInventory; + private ObjectDeselect handlerObjectDetach; + private ObjectDrop handlerObjectDrop; + private AgentSit handlerOnUndo; + + private ForceReleaseControls handlerForceReleaseControls; + + private GodLandStatRequest handlerLandStatRequest; + + private UUIDNameRequest handlerUUIDGroupNameRequest; + + private ParcelDeedToGroup handlerParcelDeedToGroup; + + private RequestObjectPropertiesFamily handlerObjectGroupRequest; + private ScriptReset handlerScriptReset; + private GetScriptRunning handlerGetScriptRunning; + private SetScriptRunning handlerSetScriptRunning; + private UpdateVector handlerAutoPilotGo; + //Gesture + private ActivateGesture handlerActivateGesture; + private DeactivateGesture handlerDeactivateGesture; + //Sound + private SoundTrigger handlerSoundTrigger; + private ObjectOwner handlerObjectOwner; + + private DirPlacesQuery handlerDirPlacesQuery; + private DirFindQuery handlerDirFindQuery; + private DirLandQuery handlerDirLandQuery; + private DirPopularQuery handlerDirPopularQuery; + private DirClassifiedQuery handlerDirClassifiedQuery; + private ParcelSetOtherCleanTime handlerParcelSetOtherCleanTime; + + private MapItemRequest handlerMapItemRequest; + + private StartLure handlerStartLure; + private TeleportLureRequest handlerTeleportLureRequest; + + private NetworkStats handlerNetworkStatsUpdate; + + private ClassifiedInfoRequest handlerClassifiedInfoRequest; + private ClassifiedInfoUpdate handlerClassifiedInfoUpdate; + private ClassifiedDelete handlerClassifiedDelete; + private ClassifiedDelete handlerClassifiedGodDelete; + + private EventNotificationAddRequest handlerEventNotificationAddRequest; + private EventNotificationRemoveRequest handlerEventNotificationRemoveRequest; + private EventGodDelete handlerEventGodDelete; + + private ParcelDwellRequest handlerParcelDwellRequest; + + private UserInfoRequest handlerUserInfoRequest; + private UpdateUserInfo handlerUpdateUserInfo; + + private RetrieveInstantMessages handlerRetrieveInstantMessages; + + private PickDelete handlerPickDelete; + private PickGodDelete handlerPickGodDelete; + private PickInfoUpdate handlerPickInfoUpdate; + private AvatarNotesUpdate handlerAvatarNotesUpdate; + + private MuteListRequest handlerMuteListRequest; + + //private AvatarInterestUpdate handlerAvatarInterestUpdate; + + private PlacesQuery handlerPlacesQuery; + + private readonly IGroupsModule m_GroupsModule; + + private AgentUpdateArgs lastarg = null; + + //private TerrainUnacked handlerUnackedTerrain = null; + + //** + + /* Properties */ + + public UUID SecureSessionId + { + get { return m_secureSessionId; } + } + + public IScene Scene + { + get { return m_scene; } + } + + public UUID SessionId + { + get { return m_sessionId; } + } - public UUID SecureSessionId { get { return m_secureSessionId; } } - public IScene Scene { get { return m_scene; } } - public UUID SessionId { get { return m_sessionId; } } public Vector3 StartPos { get { return m_startpos; } set { m_startpos = value; } } - public UUID AgentId { get { return m_agentId; } } - public UUID ActiveGroupId { get { return m_activeGroupID; } } - public string ActiveGroupName { get { return m_activeGroupName; } } - public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } - public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } + + public UUID AgentId + { + get { return m_agentId; } + } + + public UUID ActiveGroupId + { + get { return m_activeGroupID; } + } + + public string ActiveGroupName + { + get { return m_activeGroupName; } + } + + public ulong ActiveGroupPowers + { + get { return m_activeGroupPowers; } + } + + public bool IsGroupMember(UUID groupID) + { + return m_groupPowers.ContainsKey(groupID); + } + + public ulong GetGroupPowers(UUID groupID) + { + if (groupID == m_activeGroupID) + return m_activeGroupPowers; + + if (m_groupPowers.ContainsKey(groupID)) + return m_groupPowers[groupID]; + + return 0; + } + + /// + /// This is a utility method used by single states to not duplicate kicks and blue card of death messages. + /// + public bool ChildAgentStatus() + { + return m_scene.PresenceChildStatus(AgentId); + } + /// /// First name of the agent/avatar represented by the client /// - public string FirstName { get { return m_firstName; } } + public string FirstName + { + get { return m_firstName; } + } + /// /// Last name of the agent/avatar represented by the client /// - public string LastName { get { return m_lastName; } } + public string LastName + { + get { return m_lastName; } + } + /// /// Full name of the client (first name and last name) /// - public string Name { get { return FirstName + " " + LastName; } } - public uint CircuitCode { get { return m_circuitCode; } } - public int MoneyBalance { get { return m_moneyBalance; } } - public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } + public string Name + { + get { return FirstName + " " + LastName; } + } + + public uint CircuitCode + { + get { return m_circuitCode; } + } + + public int MoneyBalance + { + get { return m_moneyBalance; } + } + + public int NextAnimationSequenceNumber + { + get { return m_animationSequenceNumber++; } + } + + public ILLPacketHandler PacketHandler + { + get { return m_PacketHandler; } + } + + bool m_IsActive = true; + public bool IsActive { get { return m_IsActive; } set { m_IsActive = value; } } - public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } - #endregion Properties + public bool SendLogoutPacketWhenClosing + { + set { m_SendLogoutPacketWhenClosing = value; } + } + + /* METHODS */ /// /// Constructor /// - public LLClientView(EndPoint remoteEP, IScene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, - UUID agentId, UUID sessionId, uint circuitCode) + public LLClientView( + EndPoint remoteEP, IScene scene, LLPacketServer packServer, + AuthenticateResponse sessionInfo, UUID agentId, UUID sessionId, uint circuitCode, EndPoint proxyEP, + ClientStackUserSettings userSettings) { - RegisterInterface(this); - RegisterInterface(this); - RegisterInterface(this); - + // Should be called first? + RegisterInterfaces(); + + m_GroupsModule = scene.RequestModuleInterface(); + m_moneyBalance = 1000; + + m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); + InitDefaultAnimations(); m_scene = scene; + //m_assetCache = assetCache; + m_assetService = m_scene.RequestModuleInterface(); - m_GroupsModule = scene.RequestModuleInterface(); - m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface()); - m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); + + m_networkServer = packServer; + m_agentId = agentId; m_sessionId = sessionId; - m_secureSessionId = sessionInfo.LoginInfo.SecureSession; m_circuitCode = circuitCode; + m_userEndPoint = remoteEP; + m_proxyEndPoint = proxyEP; + m_firstName = sessionInfo.LoginInfo.First; m_lastName = sessionInfo.LoginInfo.Last; m_startpos = sessionInfo.LoginInfo.StartPos; - m_moneyBalance = 1000; - m_udpServer = udpServer; - m_udpClient = udpClient; - m_udpClient.OnQueueEmpty += HandleQueueEmpty; - m_udpClient.OnPacketStats += PopulateStats; + if (sessionInfo.LoginInfo.SecureSession != UUID.Zero) + { + m_secureSessionId = sessionInfo.LoginInfo.SecureSession; + } + + // While working on this, the BlockingQueue had me fooled for a bit. + // The Blocking queue causes the thread to stop until there's something + // in it to process. It's an on-purpose threadlock though because + // without it, the clientloop will suck up all sim resources. + + m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); + m_PacketHandler.SynchronizeClient = SynchronizeClient; + m_PacketHandler.OnPacketStats += PopulateStats; + m_PacketHandler.OnQueueEmpty += HandleQueueEmpty; + + if (scene.Config != null) + { + IConfig clientConfig = scene.Config.Configs["LLClient"]; + if (clientConfig != null) + { + m_PacketHandler.ReliableIsImportant = + clientConfig.GetBoolean("ReliableIsImportant", + false); + m_PacketHandler.MaxReliableResends = clientConfig.GetInt("MaxReliableResends", + m_PacketHandler.MaxReliableResends); + m_primTerseUpdatesPerPacket = clientConfig.GetInt("TerseUpdatesPerPacket", + m_primTerseUpdatesPerPacket); + m_primFullUpdatesPerPacket = clientConfig.GetInt("FullUpdatesPerPacket", + m_primFullUpdatesPerPacket); + + m_primTerseUpdateRate = clientConfig.GetInt("TerseUpdateRate", + m_primTerseUpdateRate); + m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", + m_primFullUpdateRate); + + m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", + m_textureSendLimit); + + m_textureDataLimit = clientConfig.GetInt("TextureDataLimit", + m_textureDataLimit); + + m_packetMTU = clientConfig.GetInt("PacketMTU", 1400); + } + } RegisterLocalPacketHandlers(); + m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface()); } - public void SetDebugPacketLevel(int newDebug) + public void SetDebugPacketLevel(int newDebugPacketLevel) { + m_debugPacketLevel = newDebugPacketLevel; } - #region Client Methods - - /// - /// Close down the client view. This *must* be the last method called, since the last # - /// statement of CloseCleanup() aborts the thread. - /// - /// - public void Close(bool shutdownCircuit) - { - m_log.DebugFormat( - "[CLIENT]: Close has been called with shutdownCircuit = {0} for {1} attached to scene {2}", - shutdownCircuit, Name, m_scene.RegionInfo.RegionName); - - if (m_imageManager != null) - m_imageManager.Close(); - - if (m_udpServer != null) - m_udpServer.Flush(); - - // raise an event on the packet server to Shutdown the circuit - // Now, if we raise the event then the packet server will call this method itself, so don't try cleanup - // here otherwise we'll end up calling it twice. - // FIXME: In truth, I might be wrong but this whole business of calling this method twice (with different args) looks - // horribly tangly. Hopefully it should be possible to greatly simplify it. - if (shutdownCircuit) - { - if (OnConnectionClosed != null) - OnConnectionClosed(this); - } - else - { - CloseCleanup(shutdownCircuit); - } - } + # region Client Methods private void CloseCleanup(bool shutdownCircuit) { + + m_scene.RemoveClient(AgentId); //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); @@ -244,6 +590,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP Thread.Sleep(2000); // Shut down timers. Thread Context of this method is murky. Lock all timers + if (m_clientPingTimer.Enabled) + lock (m_clientPingTimer) + m_clientPingTimer.Stop(); if (m_avatarTerseUpdateTimer.Enabled) lock (m_avatarTerseUpdateTimer) m_avatarTerseUpdateTimer.Stop(); @@ -276,21 +625,43 @@ namespace OpenSim.Region.ClientStack.LindenUDP // of the client thread regardless of where Close() is called. KillEndDone(); } + + Terminate(); + } - IsActive = false; + /// + /// Close down the client view. This *must* be the last method called, since the last # + /// statement of CloseCleanup() aborts the thread. + /// + /// + public void Close(bool shutdownCircuit) + { + m_clientPingTimer.Enabled = false; - m_avatarTerseUpdateTimer.Close(); - m_primTerseUpdateTimer.Close(); - m_primFullUpdateTimer.Close(); + m_log.DebugFormat( + "[CLIENT]: Close has been called with shutdownCircuit = {0} for {1} attached to scene {2}", + shutdownCircuit, Name, m_scene.RegionInfo.RegionName); - //m_udpServer.OnPacketStats -= PopulateStats; - m_udpClient.Shutdown(); + if (m_imageManager != null) + m_imageManager.Close(); - // wait for thread stoped - // m_clientThread.Join(); + if (m_PacketHandler != null) + m_PacketHandler.Flush(); - // delete circuit code - //m_networkServer.CloseClient(this); + // raise an event on the packet server to Shutdown the circuit + // Now, if we raise the event then the packet server will call this method itself, so don't try cleanup + // here otherwise we'll end up calling it twice. + // FIXME: In truth, I might be wrong but this whole business of calling this method twice (with different args) looks + // horribly tangly. Hopefully it should be possible to greatly simplify it. + if (shutdownCircuit) + { + if (OnConnectionClosed != null) + OnConnectionClosed(this); + } + else + { + CloseCleanup(shutdownCircuit); + } } public void Kick(string message) @@ -312,6 +683,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void Stop() { // Shut down timers. Thread Context is Murky, lock all timers! + if (m_clientPingTimer.Enabled) + lock (m_clientPingTimer) + m_clientPingTimer.Stop(); + if (m_avatarTerseUpdateTimer.Enabled) lock (m_avatarTerseUpdateTimer) m_avatarTerseUpdateTimer.Stop(); @@ -325,13 +700,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdateTimer.Stop(); } - #endregion Client Methods + public void Restart() + { + // re-construct + m_PacketHandler.Clear(); - #region Packet Handling + m_clientPingTimer = new Timer(5000); + m_clientPingTimer.Elapsed += CheckClientConnectivity; + m_clientPingTimer.Enabled = true; + + m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); + m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); + m_avatarTerseUpdateTimer.AutoReset = false; + + m_primTerseUpdateTimer = new Timer(m_primTerseUpdateRate); + m_primTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimTerseUpdates); + m_primTerseUpdateTimer.AutoReset = false; + + m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); + m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); + m_primFullUpdateTimer.AutoReset = false; + } + + private void Terminate() + { + IsActive = false; + + m_clientPingTimer.Close(); + m_avatarTerseUpdateTimer.Close(); + m_primTerseUpdateTimer.Close(); + m_primFullUpdateTimer.Close(); + + m_PacketHandler.OnPacketStats -= PopulateStats; + m_PacketHandler.Dispose(); + + // wait for thread stoped + // m_clientThread.Join(); + + // delete circuit code + //m_networkServer.CloseClient(this); + } + + #endregion + + # region Packet Handling public void PopulateStats(int inPackets, int outPackets, int unAckedBytes) { - NetworkStats handlerNetworkStatsUpdate = OnNetworkStatsUpdate; + handlerNetworkStatsUpdate = OnNetworkStatsUpdate; if (handlerNetworkStatsUpdate != null) { handlerNetworkStatsUpdate(inPackets, outPackets, unAckedBytes); @@ -412,7 +828,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return result; } - /*protected void DebugPacket(string direction, Packet packet) + protected void DebugPacket(string direction, Packet packet) { string info; @@ -438,9 +854,88 @@ namespace OpenSim.Region.ClientStack.LindenUDP } Console.WriteLine(m_circuitCode + ":" + direction + ": " + info); - }*/ + } - #endregion Packet Handling + /// + /// Main packet processing loop for the UDP component of the client session. Both incoming and outgoing + /// packets are processed here. + /// + protected virtual void ClientLoop() + { + m_log.DebugFormat( + "[CLIENT]: Entered main packet processing loop for {0} in {1}", Name, Scene.RegionInfo.RegionName); + + while (IsActive) + { + LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue(); + + if (nextPacket == null) { + m_log.DebugFormat("[CLIENT]: PacketQueue return null LLQueItem"); + continue; + } + + if (nextPacket.Incoming) + { + if (m_debugPacketLevel > 0) + DebugPacket("IN", nextPacket.Packet); + m_PacketHandler.ProcessInPacket(nextPacket); + } + else + { + if (m_debugPacketLevel > 0) + DebugPacket("OUT", nextPacket.Packet); + m_PacketHandler.ProcessOutPacket(nextPacket); + } + } + } + + # endregion + + protected int m_terrainCheckerCount; + + /// + /// Event handler for check client timer + /// Checks to ensure that the client is still connected. If the client has failed to respond to many pings + /// in succession then close down the connection. + /// + /// + /// + protected void CheckClientConnectivity(object sender, ElapsedEventArgs e) + { + if (m_PacketHandler.PacketsReceived == m_inPacketsChecked) + { + // no packet came in since the last time we checked... + + m_probesWithNoIngressPackets++; + if ((m_probesWithNoIngressPackets > 30 && !m_clientBlocked) // agent active + || (m_probesWithNoIngressPackets > 90 && m_clientBlocked)) // agent paused + { + m_clientPingTimer.Enabled = false; + + m_log.WarnFormat( + "[CLIENT]: Client for agent {0} {1} has stopped responding to pings. Closing connection", + Name, AgentId); + + if (OnConnectionClosed != null) + { + OnConnectionClosed(this); + } + } + else + { + // this will normally trigger at least one packet (ping response) + SendStartPingCheck(0); + } + } + else + { + // Something received in the meantime - we can reset the counters + m_probesWithNoIngressPackets = 0; + // ... and store the current number of packets received to find out if another one got in on the next cycle + m_inPacketsChecked = m_PacketHandler.PacketsReceived; + } + + } # region Setup @@ -450,6 +945,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// protected virtual void InitNewClient() { + //this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache); + + // Ping the client regularly to check that it's still there + m_clientPingTimer = new Timer(5000); + m_clientPingTimer.Elapsed += CheckClientConnectivity; + m_clientPingTimer.Enabled = true; + m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); m_avatarTerseUpdateTimer.AutoReset = false; @@ -469,18 +971,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void Start() { - // This sets up all the timers - InitNewClient(); + m_clientThread = new Thread(RunUserSession); + m_clientThread.Name = "ClientThread"; + m_clientThread.IsBackground = true; + m_clientThread.Start(); + ThreadTracker.Add(m_clientThread); } /// /// Run a user session. This method lies at the base of the entire client thread. /// - protected void RunUserSession() + protected virtual void RunUserSession() { + //tell this thread we are using the culture set up for the sim (currently hardcoded to en_US) + //otherwise it will override this and use the system default + Culture.SetCurrentCulture(); + try { - + // This sets up all the timers + InitNewClient(); + ClientLoop(); } catch (Exception e) { @@ -504,7 +1015,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP + "Any further actions taken will not be processed.\n" + "Please relog", true); - m_udpServer.SendPacket(m_agentId, packet, ThrottleOutPacketType.Unknown, false); + LLQueItem item = new LLQueItem(); + item.Packet = packet; + item.Sequence = packet.Header.Sequence; + + m_PacketHandler.ProcessOutPacket(item); // There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to // listeners yet, though. @@ -522,8 +1037,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP # endregion - #region Events - + // Previously ClientView.API partial class public event GenericMessage OnGenericMessage; public event BinaryGenericMessage OnBinaryGenericMessage; public event Action OnLogout; @@ -683,10 +1197,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; public event UpdateVector OnAutoPilotGo; + public event TerrainUnacked OnUnackedTerrain; + public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; public event ObjectOwner OnObjectOwner; + public event DirPlacesQuery OnDirPlacesQuery; public event DirFindQuery OnDirFindQuery; public event DirLandQuery OnDirLandQuery; @@ -694,34 +1211,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event DirClassifiedQuery OnDirClassifiedQuery; public event EventInfoRequest OnEventInfoRequest; public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime; + public event MapItemRequest OnMapItemRequest; + public event OfferCallingCard OnOfferCallingCard; public event AcceptCallingCard OnAcceptCallingCard; public event DeclineCallingCard OnDeclineCallingCard; public event SoundTrigger OnSoundTrigger; + public event StartLure OnStartLure; public event TeleportLureRequest OnTeleportLureRequest; public event NetworkStats OnNetworkStatsUpdate; + public event ClassifiedInfoRequest OnClassifiedInfoRequest; public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; public event ClassifiedDelete OnClassifiedDelete; public event ClassifiedDelete OnClassifiedGodDelete; + public event EventNotificationAddRequest OnEventNotificationAddRequest; public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; public event EventGodDelete OnEventGodDelete; + public event ParcelDwellRequest OnParcelDwellRequest; + public event UserInfoRequest OnUserInfoRequest; public event UpdateUserInfo OnUpdateUserInfo; + public event RetrieveInstantMessages OnRetrieveInstantMessages; + public event PickDelete OnPickDelete; public event PickGodDelete OnPickGodDelete; public event PickInfoUpdate OnPickInfoUpdate; public event AvatarNotesUpdate OnAvatarNotesUpdate; - public event MuteListRequest OnMuteListRequest; - public event AvatarInterestUpdate OnAvatarInterestUpdate; - public event PlacesQuery OnPlacesQuery; - #endregion Events + public event MuteListRequest OnMuteListRequest; + + //public event AvatarInterestUpdate OnAvatarInterestUpdate; + + public event PlacesQuery OnPlacesQuery; public void ActivateGesture(UUID assetId, UUID gestureId) { @@ -1323,13 +1850,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendStartPingCheck(byte seq) { StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); - pc.Header.Reliable = false; - - OutgoingPacket oldestPacket = m_udpClient.NeedAcks.GetOldest(); - pc.PingID.PingID = seq; - pc.PingID.OldestUnacked = (oldestPacket != null) ? oldestPacket.SequenceNumber : 0; - + pc.Header.Reliable = false; OutPacket(pc, ThrottleOutPacketType.Unknown); } @@ -1405,12 +1927,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP descend.ItemData[i].AssetID = item.AssetID; descend.ItemData[i].CreatorID = item.CreatorIdAsUuid; descend.ItemData[i].BaseMask = item.BasePermissions; - descend.ItemData[i].Description = Util.StringToBytes256(item.Description); + descend.ItemData[i].Description = LLUtil.StringToPacketBytes(item.Description); descend.ItemData[i].EveryoneMask = item.EveryOnePermissions; descend.ItemData[i].OwnerMask = item.CurrentPermissions; descend.ItemData[i].FolderID = item.Folder; descend.ItemData[i].InvType = (sbyte)item.InvType; - descend.ItemData[i].Name = Util.StringToBytes256(item.Name); + descend.ItemData[i].Name = LLUtil.StringToPacketBytes(item.Name); descend.ItemData[i].NextOwnerMask = item.NextPermissions; descend.ItemData[i].OwnerID = item.Owner; descend.ItemData[i].Type = (sbyte)item.AssetType; @@ -1491,7 +2013,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { descend.FolderData[i] = new InventoryDescendentsPacket.FolderDataBlock(); descend.FolderData[i].FolderID = folder.ID; - descend.FolderData[i].Name = Util.StringToBytes256(folder.Name); + descend.FolderData[i].Name = LLUtil.StringToPacketBytes(folder.Name); descend.FolderData[i].ParentID = folder.ParentID; descend.FolderData[i].Type = (sbyte)folder.Type; @@ -1606,11 +2128,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP inventoryReply.InventoryData[0].BaseMask = item.BasePermissions; inventoryReply.InventoryData[0].CreationDate = item.CreationDate; - inventoryReply.InventoryData[0].Description = Util.StringToBytes256(item.Description); + inventoryReply.InventoryData[0].Description = LLUtil.StringToPacketBytes(item.Description); inventoryReply.InventoryData[0].EveryoneMask = item.EveryOnePermissions; inventoryReply.InventoryData[0].FolderID = item.Folder; inventoryReply.InventoryData[0].InvType = (sbyte)item.InvType; - inventoryReply.InventoryData[0].Name = Util.StringToBytes256(item.Name); + inventoryReply.InventoryData[0].Name = LLUtil.StringToPacketBytes(item.Name); inventoryReply.InventoryData[0].NextOwnerMask = item.NextPermissions; inventoryReply.InventoryData[0].OwnerID = item.Owner; inventoryReply.InventoryData[0].OwnerMask = item.CurrentPermissions; @@ -1735,7 +2257,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP folderBlock.FolderID = folder.ID; folderBlock.ParentID = folder.ParentID; folderBlock.Type = -1; - folderBlock.Name = Util.StringToBytes256(folder.Name); + folderBlock.Name = LLUtil.StringToPacketBytes(folder.Name); return folderBlock; } @@ -1753,11 +2275,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP itemBlock.AssetID = item.AssetID; itemBlock.CreatorID = item.CreatorIdAsUuid; itemBlock.BaseMask = item.BasePermissions; - itemBlock.Description = Util.StringToBytes256(item.Description); + itemBlock.Description = LLUtil.StringToPacketBytes(item.Description); itemBlock.EveryoneMask = item.EveryOnePermissions; itemBlock.FolderID = item.Folder; itemBlock.InvType = (sbyte)item.InvType; - itemBlock.Name = Util.StringToBytes256(item.Name); + itemBlock.Name = LLUtil.StringToPacketBytes(item.Name); itemBlock.NextOwnerMask = item.NextPermissions; itemBlock.OwnerID = item.Owner; itemBlock.OwnerMask = item.CurrentPermissions; @@ -1817,11 +2339,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP bulkUpdate.ItemData[0].CreatorID = item.CreatorIdAsUuid; bulkUpdate.ItemData[0].BaseMask = item.BasePermissions; bulkUpdate.ItemData[0].CreationDate = item.CreationDate; - bulkUpdate.ItemData[0].Description = Util.StringToBytes256(item.Description); + bulkUpdate.ItemData[0].Description = LLUtil.StringToPacketBytes(item.Description); bulkUpdate.ItemData[0].EveryoneMask = item.EveryOnePermissions; bulkUpdate.ItemData[0].FolderID = item.Folder; bulkUpdate.ItemData[0].InvType = (sbyte)item.InvType; - bulkUpdate.ItemData[0].Name = Util.StringToBytes256(item.Name); + bulkUpdate.ItemData[0].Name = LLUtil.StringToPacketBytes(item.Name); bulkUpdate.ItemData[0].NextOwnerMask = item.NextPermissions; bulkUpdate.ItemData[0].OwnerID = item.Owner; bulkUpdate.ItemData[0].OwnerMask = item.CurrentPermissions; @@ -1864,11 +2386,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP InventoryReply.InventoryData[0].AssetID = Item.AssetID; InventoryReply.InventoryData[0].CreatorID = Item.CreatorIdAsUuid; InventoryReply.InventoryData[0].BaseMask = Item.BasePermissions; - InventoryReply.InventoryData[0].Description = Util.StringToBytes256(Item.Description); + InventoryReply.InventoryData[0].Description = LLUtil.StringToPacketBytes(Item.Description); InventoryReply.InventoryData[0].EveryoneMask = Item.EveryOnePermissions; InventoryReply.InventoryData[0].FolderID = Item.Folder; InventoryReply.InventoryData[0].InvType = (sbyte)Item.InvType; - InventoryReply.InventoryData[0].Name = Util.StringToBytes256(Item.Name); + InventoryReply.InventoryData[0].Name = LLUtil.StringToPacketBytes(Item.Name); InventoryReply.InventoryData[0].NextOwnerMask = Item.NextPermissions; InventoryReply.InventoryData[0].OwnerID = Item.Owner; InventoryReply.InventoryData[0].OwnerMask = Item.CurrentPermissions; @@ -2035,7 +2557,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// /// - public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) + protected AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) { AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); alertPack.AgentData.AgentID = AgentId; @@ -2246,953 +2768,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(avatarReply, ThrottleOutPacketType.Task); } - /// - /// Send the client an Estate message blue box pop-down with a single OK button - /// - /// - /// - /// - /// - public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message) - { - if (!ChildAgentStatus()) - SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3())); - - //SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch()); - } - - public void SendLogoutPacket() - { - // I know this is a bit of a hack, however there are times when you don't - // want to send this, but still need to do the rest of the shutdown process - // this method gets called from the packet server.. which makes it practically - // impossible to do any other way. - - if (m_SendLogoutPacketWhenClosing) - { - LogoutReplyPacket logReply = (LogoutReplyPacket)PacketPool.Instance.GetPacket(PacketType.LogoutReply); - // TODO: don't create new blocks if recycling an old packet - logReply.AgentData.AgentID = AgentId; - logReply.AgentData.SessionID = SessionId; - logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; - logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); - logReply.InventoryData[0].ItemID = UUID.Zero; - - OutPacket(logReply, ThrottleOutPacketType.Task); - } - } - - public void SendHealth(float health) - { - HealthMessagePacket healthpacket = (HealthMessagePacket)PacketPool.Instance.GetPacket(PacketType.HealthMessage); - healthpacket.HealthData.Health = health; - OutPacket(healthpacket, ThrottleOutPacketType.Task); - } - - public void SendAgentOnline(UUID[] agentIDs) - { - OnlineNotificationPacket onp = new OnlineNotificationPacket(); - OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length]; - for (int i = 0; i < agentIDs.Length; i++) - { - OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); - onpbl.AgentID = agentIDs[i]; - onpb[i] = onpbl; - } - onp.AgentBlock = onpb; - onp.Header.Reliable = true; - OutPacket(onp, ThrottleOutPacketType.Task); - } - - public void SendAgentOffline(UUID[] agentIDs) - { - OfflineNotificationPacket offp = new OfflineNotificationPacket(); - OfflineNotificationPacket.AgentBlockBlock[] offpb = new OfflineNotificationPacket.AgentBlockBlock[agentIDs.Length]; - for (int i = 0; i < agentIDs.Length; i++) - { - OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); - onpbl.AgentID = agentIDs[i]; - offpb[i] = onpbl; - } - offp.AgentBlock = offpb; - offp.Header.Reliable = true; - OutPacket(offp, ThrottleOutPacketType.Task); - } - - public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, - Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) - { - AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); - avatarSitResponse.SitObject.ID = TargetID; - if (CameraAtOffset != Vector3.Zero) - { - avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset; - avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset; - } - avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook; - avatarSitResponse.SitTransform.AutoPilot = autopilot; - avatarSitResponse.SitTransform.SitPosition = OffsetPos; - avatarSitResponse.SitTransform.SitRotation = SitOrientation; - - OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); - } - - public void SendAdminResponse(UUID Token, uint AdminLevel) - { - GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket(); - GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock(); - GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock(); - - adb.AgentID = AgentId; - adb.SessionID = SessionId; // More security - gdb.GodLevel = (byte)AdminLevel; - gdb.Token = Token; - //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock; - respondPacket.GrantData = gdb; - respondPacket.AgentData = adb; - OutPacket(respondPacket, ThrottleOutPacketType.Task); - } - - public void SendGroupMembership(GroupMembershipData[] GroupMembership) - { - m_groupPowers.Clear(); - - AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket(); - AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[GroupMembership.Length]; - for (int i = 0; i < GroupMembership.Length; i++) - { - m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; - - AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock(); - Group.AcceptNotices = GroupMembership[i].AcceptNotices; - Group.Contribution = GroupMembership[i].Contribution; - Group.GroupID = GroupMembership[i].GroupID; - Group.GroupInsigniaID = GroupMembership[i].GroupPicture; - Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); - Group.GroupPowers = GroupMembership[i].GroupPowers; - Groups[i] = Group; - - - } - Groupupdate.GroupData = Groups; - Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock(); - Groupupdate.AgentData.AgentID = AgentId; - OutPacket(Groupupdate, ThrottleOutPacketType.Task); - - try - { - IEventQueue eq = Scene.RequestModuleInterface(); - if (eq != null) - { - eq.GroupMembership(Groupupdate, this.AgentId); - } - } - catch (Exception ex) - { - m_log.Error("Unable to send group membership data via eventqueue - exception: " + ex.ToString()); - m_log.Warn("sending group membership data via UDP"); - OutPacket(Groupupdate, ThrottleOutPacketType.Task); - } - } - - - public void SendGroupNameReply(UUID groupLLUID, string GroupName) - { - UUIDGroupNameReplyPacket pack = new UUIDGroupNameReplyPacket(); - UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; - UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); - uidnamebloc.ID = groupLLUID; - uidnamebloc.GroupName = Utils.StringToBytes(GroupName); - uidnameblock[0] = uidnamebloc; - pack.UUIDNameBlock = uidnameblock; - OutPacket(pack, ThrottleOutPacketType.Task); - } - - public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia) - { - LandStatReplyPacket lsrp = new LandStatReplyPacket(); - // LandStatReplyPacket.RequestDataBlock lsreqdpb = new LandStatReplyPacket.RequestDataBlock(); - LandStatReplyPacket.ReportDataBlock[] lsrepdba = new LandStatReplyPacket.ReportDataBlock[lsrpia.Length]; - //LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); - // lsrepdb. - lsrp.RequestData.ReportType = reportType; - lsrp.RequestData.RequestFlags = requestFlags; - lsrp.RequestData.TotalObjectCount = resultCount; - for (int i = 0; i < lsrpia.Length; i++) - { - LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); - lsrepdb.LocationX = lsrpia[i].LocationX; - lsrepdb.LocationY = lsrpia[i].LocationY; - lsrepdb.LocationZ = lsrpia[i].LocationZ; - lsrepdb.Score = lsrpia[i].Score; - lsrepdb.TaskID = lsrpia[i].TaskID; - lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; - lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); - lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); - lsrepdba[i] = lsrepdb; - } - lsrp.ReportData = lsrepdba; - OutPacket(lsrp, ThrottleOutPacketType.Task); - } - - public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running) - { - ScriptRunningReplyPacket scriptRunningReply = new ScriptRunningReplyPacket(); - scriptRunningReply.Script.ObjectID = objectID; - scriptRunningReply.Script.ItemID = itemID; - scriptRunningReply.Script.Running = running; - - OutPacket(scriptRunningReply, ThrottleOutPacketType.Task); - } - - public void SendAsset(AssetRequestToClient req) - { - //m_log.Debug("sending asset " + req.RequestAssetID); - TransferInfoPacket Transfer = new TransferInfoPacket(); - Transfer.TransferInfo.ChannelType = 2; - Transfer.TransferInfo.Status = 0; - Transfer.TransferInfo.TargetType = 0; - if (req.AssetRequestSource == 2) - { - Transfer.TransferInfo.Params = new byte[20]; - Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - int assType = req.AssetInf.Type; - Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); - } - else if (req.AssetRequestSource == 3) - { - Transfer.TransferInfo.Params = req.Params; - // Transfer.TransferInfo.Params = new byte[100]; - //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); - } - Transfer.TransferInfo.Size = req.AssetInf.Data.Length; - Transfer.TransferInfo.TransferID = req.TransferRequestID; - Transfer.Header.Zerocoded = true; - OutPacket(Transfer, ThrottleOutPacketType.Asset); - - if (req.NumPackets == 1) - { - TransferPacketPacket TransferPacket = new TransferPacketPacket(); - TransferPacket.TransferData.Packet = 0; - TransferPacket.TransferData.ChannelType = 2; - TransferPacket.TransferData.TransferID = req.TransferRequestID; - TransferPacket.TransferData.Data = req.AssetInf.Data; - TransferPacket.TransferData.Status = 1; - TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, ThrottleOutPacketType.Asset); - } - else - { - int processedLength = 0; - int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; - int packetNumber = 0; - - while (processedLength < req.AssetInf.Data.Length) - { - TransferPacketPacket TransferPacket = new TransferPacketPacket(); - TransferPacket.TransferData.Packet = packetNumber; - TransferPacket.TransferData.ChannelType = 2; - TransferPacket.TransferData.TransferID = req.TransferRequestID; - - int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); - byte[] chunk = new byte[chunkSize]; - Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); - - TransferPacket.TransferData.Data = chunk; - - // 0 indicates more packets to come, 1 indicates last packet - if (req.AssetInf.Data.Length - processedLength > maxChunkSize) - { - TransferPacket.TransferData.Status = 0; - } - else - { - TransferPacket.TransferData.Status = 1; - } - TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, ThrottleOutPacketType.Asset); - - processedLength += chunkSize; - packetNumber++; - } - } - } - - public void SendTexture(AssetBase TextureAsset) - { - - } - - public void SendRegionHandle(UUID regionID, ulong handle) - { - RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply); - reply.ReplyBlock.RegionID = regionID; - reply.ReplyBlock.RegionHandle = handle; - OutPacket(reply, ThrottleOutPacketType.Land); - } - - public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) - { - ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); - reply.AgentData.AgentID = m_agentId; - reply.Data.ParcelID = parcelID; - reply.Data.OwnerID = land.OwnerID; - reply.Data.Name = Utils.StringToBytes(land.Name); - reply.Data.Desc = Utils.StringToBytes(land.Description); - reply.Data.ActualArea = land.Area; - reply.Data.BillableArea = land.Area; // TODO: what is this? - - // Bit 0: Mature, bit 7: on sale, other bits: no idea - reply.Data.Flags = (byte)( - ((land.Flags & (uint)ParcelFlags.MaturePublish) != 0 ? (1 << 0) : 0) + - ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0)); - - Vector3 pos = land.UserLocation; - if (pos.Equals(Vector3.Zero)) - { - pos = (land.AABBMax + land.AABBMin) * 0.5f; - } - reply.Data.GlobalX = info.RegionLocX * Constants.RegionSize + x; - reply.Data.GlobalY = info.RegionLocY * Constants.RegionSize + y; - reply.Data.GlobalZ = pos.Z; - reply.Data.SimName = Utils.StringToBytes(info.RegionName); - reply.Data.SnapshotID = land.SnapshotID; - reply.Data.Dwell = land.Dwell; - reply.Data.SalePrice = land.SalePrice; - reply.Data.AuctionID = (int)land.AuctionID; - - OutPacket(reply, ThrottleOutPacketType.Land); - } - - public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt) - { - ScriptTeleportRequestPacket packet = (ScriptTeleportRequestPacket)PacketPool.Instance.GetPacket(PacketType.ScriptTeleportRequest); - - packet.Data.ObjectName = Utils.StringToBytes(objName); - packet.Data.SimName = Utils.StringToBytes(simName); - packet.Data.SimPosition = pos; - packet.Data.LookAt = lookAt; - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data) - { - DirPlacesReplyPacket packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply); - - packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock(); - - packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; - packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); - - packet.QueryReplies = - new DirPlacesReplyPacket.QueryRepliesBlock[data.Length]; - - packet.StatusData = new DirPlacesReplyPacket.StatusDataBlock[ - data.Length]; - - packet.AgentData.AgentID = AgentId; - - packet.QueryData[0].QueryID = queryID; - - int i = 0; - foreach (DirPlacesReplyData d in data) - { - packet.QueryReplies[i] = - new DirPlacesReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirPlacesReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = Utils.StringToBytes(d.name); - packet.QueryReplies[i].ForSale = d.forSale; - packet.QueryReplies[i].Auction = d.auction; - packet.QueryReplies[i].Dwell = d.dwell; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data) - { - DirPeopleReplyPacket packet = (DirPeopleReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPeopleReply); - - packet.AgentData = new DirPeopleReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirPeopleReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirPeopleReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirPeopleReplyData d in data) - { - packet.QueryReplies[i] = new DirPeopleReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].AgentID = d.agentID; - packet.QueryReplies[i].FirstName = - Utils.StringToBytes(d.firstName); - packet.QueryReplies[i].LastName = - Utils.StringToBytes(d.lastName); - packet.QueryReplies[i].Group = - Utils.StringToBytes(d.group); - packet.QueryReplies[i].Online = d.online; - packet.QueryReplies[i].Reputation = d.reputation; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data) - { - DirEventsReplyPacket packet = (DirEventsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirEventsReply); - - packet.AgentData = new DirEventsReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirEventsReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirEventsReplyPacket.QueryRepliesBlock[ - data.Length]; - - packet.StatusData = new DirEventsReplyPacket.StatusDataBlock[ - data.Length]; - - int i = 0; - foreach (DirEventsReplyData d in data) - { - packet.QueryReplies[i] = new DirEventsReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirEventsReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].OwnerID = d.ownerID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].EventID = d.eventID; - packet.QueryReplies[i].Date = - Utils.StringToBytes(d.date); - packet.QueryReplies[i].UnixTime = d.unixTime; - packet.QueryReplies[i].EventFlags = d.eventFlags; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data) - { - DirGroupsReplyPacket packet = (DirGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirGroupsReply); - - packet.AgentData = new DirGroupsReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirGroupsReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirGroupsReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirGroupsReplyData d in data) - { - packet.QueryReplies[i] = new DirGroupsReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].GroupID = d.groupID; - packet.QueryReplies[i].GroupName = - Utils.StringToBytes(d.groupName); - packet.QueryReplies[i].Members = d.members; - packet.QueryReplies[i].SearchOrder = d.searchOrder; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data) - { - DirClassifiedReplyPacket packet = (DirClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirClassifiedReply); - - packet.AgentData = new DirClassifiedReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirClassifiedReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirClassifiedReplyPacket.QueryRepliesBlock[ - data.Length]; - packet.StatusData = new DirClassifiedReplyPacket.StatusDataBlock[ - data.Length]; - - int i = 0; - foreach (DirClassifiedReplyData d in data) - { - packet.QueryReplies[i] = new DirClassifiedReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirClassifiedReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].ClassifiedID = d.classifiedID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].ClassifiedFlags = d.classifiedFlags; - packet.QueryReplies[i].CreationDate = d.creationDate; - packet.QueryReplies[i].ExpirationDate = d.expirationDate; - packet.QueryReplies[i].PriceForListing = d.price; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirLandReply(UUID queryID, DirLandReplyData[] data) - { - DirLandReplyPacket packet = (DirLandReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirLandReply); - - packet.AgentData = new DirLandReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirLandReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirLandReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirLandReplyData d in data) - { - packet.QueryReplies[i] = new DirLandReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].Auction = d.auction; - packet.QueryReplies[i].ForSale = d.forSale; - packet.QueryReplies[i].SalePrice = d.salePrice; - packet.QueryReplies[i].ActualArea = d.actualArea; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data) - { - DirPopularReplyPacket packet = (DirPopularReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPopularReply); - - packet.AgentData = new DirPopularReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirPopularReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirPopularReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirPopularReplyData d in data) - { - packet.QueryReplies[i] = new DirPopularReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].Dwell = d.dwell; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendEventInfoReply(EventData data) - { - EventInfoReplyPacket packet = (EventInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.EventInfoReply); - - packet.AgentData = new EventInfoReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.EventData = new EventInfoReplyPacket.EventDataBlock(); - packet.EventData.EventID = data.eventID; - packet.EventData.Creator = Utils.StringToBytes(data.creator); - packet.EventData.Name = Utils.StringToBytes(data.name); - packet.EventData.Category = Utils.StringToBytes(data.category); - packet.EventData.Desc = Utils.StringToBytes(data.description); - packet.EventData.Date = Utils.StringToBytes(data.date); - packet.EventData.DateUTC = data.dateUTC; - packet.EventData.Duration = data.duration; - packet.EventData.Cover = data.cover; - packet.EventData.Amount = data.amount; - packet.EventData.SimName = Utils.StringToBytes(data.simName); - packet.EventData.GlobalPos = new Vector3d(data.globalPos); - packet.EventData.EventFlags = data.eventFlags; - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags) - { - MapItemReplyPacket mirplk = new MapItemReplyPacket(); - mirplk.AgentData.AgentID = AgentId; - mirplk.RequestData.ItemType = mapitemtype; - mirplk.Data = new MapItemReplyPacket.DataBlock[replies.Length]; - for (int i = 0; i < replies.Length; i++) - { - MapItemReplyPacket.DataBlock mrdata = new MapItemReplyPacket.DataBlock(); - mrdata.X = replies[i].x; - mrdata.Y = replies[i].y; - mrdata.ID = replies[i].id; - mrdata.Extra = replies[i].Extra; - mrdata.Extra2 = replies[i].Extra2; - mrdata.Name = Utils.StringToBytes(replies[i].name); - mirplk.Data[i] = mrdata; - } - //m_log.Debug(mirplk.ToString()); - OutPacket(mirplk, ThrottleOutPacketType.Task); - - } - - public void SendOfferCallingCard(UUID srcID, UUID transactionID) - { - // a bit special, as this uses AgentID to store the source instead - // of the destination. The destination (the receiver) goes into destID - OfferCallingCardPacket p = (OfferCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.OfferCallingCard); - p.AgentData.AgentID = srcID; - p.AgentData.SessionID = UUID.Zero; - p.AgentBlock.DestID = AgentId; - p.AgentBlock.TransactionID = transactionID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAcceptCallingCard(UUID transactionID) - { - AcceptCallingCardPacket p = (AcceptCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.AcceptCallingCard); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = UUID.Zero; - p.FolderData = new AcceptCallingCardPacket.FolderDataBlock[1]; - p.FolderData[0] = new AcceptCallingCardPacket.FolderDataBlock(); - p.FolderData[0].FolderID = UUID.Zero; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendDeclineCallingCard(UUID transactionID) - { - DeclineCallingCardPacket p = (DeclineCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.DeclineCallingCard); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = UUID.Zero; - p.TransactionBlock.TransactionID = transactionID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendTerminateFriend(UUID exFriendID) - { - TerminateFriendshipPacket p = (TerminateFriendshipPacket)PacketPool.Instance.GetPacket(PacketType.TerminateFriendship); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = SessionId; - p.ExBlock.OtherID = exFriendID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) - { - AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); - - p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - p.AgentData.AvatarID = avatarID; - - p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; - int i = 0; - foreach (GroupMembershipData m in data) - { - p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); - p.GroupData[i].GroupPowers = m.GroupPowers; - p.GroupData[i].AcceptNotices = m.AcceptNotices; - p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); - p.GroupData[i].GroupID = m.GroupID; - p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); - p.GroupData[i].GroupInsigniaID = m.GroupPicture; - i++; - } - - p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); - p.NewGroupData.ListInProfile = true; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendJoinGroupReply(UUID groupID, bool success) - { - JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply); - - p.AgentData = new JoinGroupReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - - p.GroupData = new JoinGroupReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - p.GroupData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success) - { - EjectGroupMemberReplyPacket p = (EjectGroupMemberReplyPacket)PacketPool.Instance.GetPacket(PacketType.EjectGroupMemberReply); - - p.AgentData = new EjectGroupMemberReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = agentID; - - p.GroupData = new EjectGroupMemberReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - - p.EjectData = new EjectGroupMemberReplyPacket.EjectDataBlock(); - p.EjectData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendLeaveGroupReply(UUID groupID, bool success) - { - LeaveGroupReplyPacket p = (LeaveGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.LeaveGroupReply); - - p.AgentData = new LeaveGroupReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - - p.GroupData = new LeaveGroupReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - p.GroupData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name) - { - if (classifiedID.Length != name.Length) - return; - - AvatarClassifiedReplyPacket ac = - (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarClassifiedReply); - - ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); - ac.AgentData.AgentID = AgentId; - ac.AgentData.TargetID = targetID; - - ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifiedID.Length]; - int i; - for (i = 0; i < classifiedID.Length; i++) - { - ac.Data[i].ClassifiedID = classifiedID[i]; - ac.Data[i].Name = Utils.StringToBytes(name[i]); - } - - OutPacket(ac, ThrottleOutPacketType.Task); - } - - public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price) - { - ClassifiedInfoReplyPacket cr = - (ClassifiedInfoReplyPacket)PacketPool.Instance.GetPacket( - PacketType.ClassifiedInfoReply); - - cr.AgentData = new ClassifiedInfoReplyPacket.AgentDataBlock(); - cr.AgentData.AgentID = AgentId; - - cr.Data = new ClassifiedInfoReplyPacket.DataBlock(); - cr.Data.ClassifiedID = classifiedID; - cr.Data.CreatorID = creatorID; - cr.Data.CreationDate = creationDate; - cr.Data.ExpirationDate = expirationDate; - cr.Data.Category = category; - cr.Data.Name = Utils.StringToBytes(name); - cr.Data.Desc = Utils.StringToBytes(description); - cr.Data.ParcelID = parcelID; - cr.Data.ParentEstate = parentEstate; - cr.Data.SnapshotID = snapshotID; - cr.Data.SimName = Utils.StringToBytes(simName); - cr.Data.PosGlobal = new Vector3d(globalPos); - cr.Data.ParcelName = Utils.StringToBytes(parcelName); - cr.Data.ClassifiedFlags = classifiedFlags; - cr.Data.PriceForListing = price; - - OutPacket(cr, ThrottleOutPacketType.Task); - } - - public void SendAgentDropGroup(UUID groupID) - { - AgentDropGroupPacket dg = - (AgentDropGroupPacket)PacketPool.Instance.GetPacket( - PacketType.AgentDropGroup); - - dg.AgentData = new AgentDropGroupPacket.AgentDataBlock(); - dg.AgentData.AgentID = AgentId; - dg.AgentData.GroupID = groupID; - - OutPacket(dg, ThrottleOutPacketType.Task); - } - - public void SendAvatarNotesReply(UUID targetID, string text) - { - AvatarNotesReplyPacket an = - (AvatarNotesReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarNotesReply); - - an.AgentData = new AvatarNotesReplyPacket.AgentDataBlock(); - an.AgentData.AgentID = AgentId; - - an.Data = new AvatarNotesReplyPacket.DataBlock(); - an.Data.TargetID = targetID; - an.Data.Notes = Utils.StringToBytes(text); - - OutPacket(an, ThrottleOutPacketType.Task); - } - - public void SendAvatarPicksReply(UUID targetID, Dictionary picks) - { - AvatarPicksReplyPacket ap = - (AvatarPicksReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarPicksReply); - - ap.AgentData = new AvatarPicksReplyPacket.AgentDataBlock(); - ap.AgentData.AgentID = AgentId; - ap.AgentData.TargetID = targetID; - - ap.Data = new AvatarPicksReplyPacket.DataBlock[picks.Count]; - - int i = 0; - foreach (KeyValuePair pick in picks) - { - ap.Data[i] = new AvatarPicksReplyPacket.DataBlock(); - ap.Data[i].PickID = pick.Key; - ap.Data[i].PickName = Utils.StringToBytes(pick.Value); - i++; - } - - OutPacket(ap, ThrottleOutPacketType.Task); - } - - public void SendAvatarClassifiedReply(UUID targetID, Dictionary classifieds) - { - AvatarClassifiedReplyPacket ac = - (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarClassifiedReply); - - ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); - ac.AgentData.AgentID = AgentId; - ac.AgentData.TargetID = targetID; - - ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifieds.Count]; - - int i = 0; - foreach (KeyValuePair classified in classifieds) - { - ac.Data[i] = new AvatarClassifiedReplyPacket.DataBlock(); - ac.Data[i].ClassifiedID = classified.Key; - ac.Data[i].Name = Utils.StringToBytes(classified.Value); - i++; - } - - OutPacket(ac, ThrottleOutPacketType.Task); - } - - public void SendParcelDwellReply(int localID, UUID parcelID, float dwell) - { - ParcelDwellReplyPacket pd = - (ParcelDwellReplyPacket)PacketPool.Instance.GetPacket( - PacketType.ParcelDwellReply); - - pd.AgentData = new ParcelDwellReplyPacket.AgentDataBlock(); - pd.AgentData.AgentID = AgentId; - - pd.Data = new ParcelDwellReplyPacket.DataBlock(); - pd.Data.LocalID = localID; - pd.Data.ParcelID = parcelID; - pd.Data.Dwell = dwell; - - OutPacket(pd, ThrottleOutPacketType.Land); - } - - public void SendUserInfoReply(bool imViaEmail, bool visible, string email) - { - UserInfoReplyPacket ur = - (UserInfoReplyPacket)PacketPool.Instance.GetPacket( - PacketType.UserInfoReply); - - string Visible = "hidden"; - if (visible) - Visible = "default"; - - ur.AgentData = new UserInfoReplyPacket.AgentDataBlock(); - ur.AgentData.AgentID = AgentId; - - ur.UserData = new UserInfoReplyPacket.UserDataBlock(); - ur.UserData.IMViaEMail = imViaEmail; - ur.UserData.DirectoryVisibility = Utils.StringToBytes(Visible); - ur.UserData.EMail = Utils.StringToBytes(email); - - OutPacket(ur, ThrottleOutPacketType.Task); - } - - public void SendCreateGroupReply(UUID groupID, bool success, string message) - { - CreateGroupReplyPacket createGroupReply = (CreateGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.CreateGroupReply); - - createGroupReply.AgentData = - new CreateGroupReplyPacket.AgentDataBlock(); - createGroupReply.ReplyData = - new CreateGroupReplyPacket.ReplyDataBlock(); - - createGroupReply.AgentData.AgentID = AgentId; - createGroupReply.ReplyData.GroupID = groupID; - - createGroupReply.ReplyData.Success = success; - createGroupReply.ReplyData.Message = Utils.StringToBytes(message); - OutPacket(createGroupReply, ThrottleOutPacketType.Task); - } - - public void SendUseCachedMuteList() - { - UseCachedMuteListPacket useCachedMuteList = (UseCachedMuteListPacket)PacketPool.Instance.GetPacket(PacketType.UseCachedMuteList); - - useCachedMuteList.AgentData = new UseCachedMuteListPacket.AgentDataBlock(); - useCachedMuteList.AgentData.AgentID = AgentId; - - OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); - } - - public void SendMuteListUpdate(string filename) - { - MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); - - muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock(); - muteListUpdate.MuteData.AgentID = AgentId; - muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename); - - OutPacket(muteListUpdate, ThrottleOutPacketType.Task); - } - - public void SendPickInfoReply(UUID pickID, UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) - { - PickInfoReplyPacket pickInfoReply = (PickInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.PickInfoReply); - - pickInfoReply.AgentData = new PickInfoReplyPacket.AgentDataBlock(); - pickInfoReply.AgentData.AgentID = AgentId; - - pickInfoReply.Data = new PickInfoReplyPacket.DataBlock(); - pickInfoReply.Data.PickID = pickID; - pickInfoReply.Data.CreatorID = creatorID; - pickInfoReply.Data.TopPick = topPick; - pickInfoReply.Data.ParcelID = parcelID; - pickInfoReply.Data.Name = Utils.StringToBytes(name); - pickInfoReply.Data.Desc = Utils.StringToBytes(desc); - pickInfoReply.Data.SnapshotID = snapshotID; - pickInfoReply.Data.User = Utils.StringToBytes(user); - pickInfoReply.Data.OriginalName = Utils.StringToBytes(originalName); - pickInfoReply.Data.SimName = Utils.StringToBytes(simName); - pickInfoReply.Data.PosGlobal = new Vector3d(posGlobal); - pickInfoReply.Data.SortOrder = sortOrder; - pickInfoReply.Data.Enabled = enabled; - - OutPacket(pickInfoReply, ThrottleOutPacketType.Task); - } - - #endregion Scene/Avatar to Client + #endregion // Gesture @@ -3488,7 +3064,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP objectData.FullID = objectID; objectData.OwnerID = ownerID; - objectData.Text = Util.StringToBytes256(text); + objectData.Text = LLUtil.StringToPacketBytes(text); objectData.TextColor[0] = color[0]; objectData.TextColor[1] = color[1]; objectData.TextColor[2] = color[2]; @@ -3625,7 +3201,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } outPacket.Header.Zerocoded = true; - OutPacket(outPacket, ThrottleOutPacketType.Task); + OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) lock (m_primFullUpdateTimer) @@ -3715,7 +3291,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP outPacket.Header.Reliable = false; outPacket.Header.Zerocoded = true; - OutPacket(outPacket, ThrottleOutPacketType.Task); + OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); if (m_primTerseUpdates.Count == 0) lock (m_primTerseUpdateTimer) @@ -3866,8 +3442,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP objPropDB.SalePrice = SalePrice; objPropDB.Category = Category; objPropDB.LastOwnerID = LastOwnerID; - objPropDB.Name = Util.StringToBytes256(ObjectName); - objPropDB.Description = Util.StringToBytes256(Description); + objPropDB.Name = LLUtil.StringToPacketBytes(ObjectName); + objPropDB.Description = LLUtil.StringToPacketBytes(Description); objPropFamilyPack.ObjectData = objPropDB; objPropFamilyPack.Header.Zerocoded = true; OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task); @@ -3901,11 +3477,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP proper.ObjectData[0].OwnerID = UUID.Zero; else proper.ObjectData[0].OwnerID = OwnerUUID; - proper.ObjectData[0].TouchName = Util.StringToBytes256(TouchTitle); + proper.ObjectData[0].TouchName = LLUtil.StringToPacketBytes(TouchTitle); proper.ObjectData[0].TextureID = TextureID; - proper.ObjectData[0].SitName = Util.StringToBytes256(SitTitle); - proper.ObjectData[0].Name = Util.StringToBytes256(ItemName); - proper.ObjectData[0].Description = Util.StringToBytes256(ItemDescription); + proper.ObjectData[0].SitName = LLUtil.StringToPacketBytes(SitTitle); + proper.ObjectData[0].Name = LLUtil.StringToPacketBytes(ItemName); + proper.ObjectData[0].Description = LLUtil.StringToPacketBytes(ItemDescription); proper.ObjectData[0].OwnerMask = OwnerMask; proper.ObjectData[0].NextOwnerMask = NextOwnerMask; proper.ObjectData[0].GroupMask = GroupMask; @@ -4146,11 +3722,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP updatePacket.ParcelData.MediaAutoScale = landData.MediaAutoScale; updatePacket.ParcelData.MediaID = landData.MediaID; - updatePacket.ParcelData.MediaURL = Util.StringToBytes256(landData.MediaURL); - updatePacket.ParcelData.MusicURL = Util.StringToBytes256(landData.MusicURL); - updatePacket.ParcelData.Name = Util.StringToBytes256(landData.Name); + updatePacket.ParcelData.MediaURL = LLUtil.StringToPacketBytes(landData.MediaURL); + updatePacket.ParcelData.MusicURL = LLUtil.StringToPacketBytes(landData.MusicURL); + updatePacket.ParcelData.Name = Utils.StringToBytes(landData.Name); updatePacket.ParcelData.OtherCleanTime = landData.OtherCleanTime; - updatePacket.ParcelData.OtherCount = 0; //TODO: Unimplemented + updatePacket.ParcelData.OtherCount = 0; //unemplemented updatePacket.ParcelData.OtherPrims = landData.OtherPrims; updatePacket.ParcelData.OwnerID = landData.OwnerID; updatePacket.ParcelData.OwnerPrims = landData.OwnerPrims; @@ -4158,18 +3734,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP updatePacket.ParcelData.ParcelPrimBonus = simObjectBonusFactor; updatePacket.ParcelData.PassHours = landData.PassHours; updatePacket.ParcelData.PassPrice = landData.PassPrice; - updatePacket.ParcelData.PublicCount = 0; //TODO: Unimplemented + updatePacket.ParcelData.PublicCount = 0; //unemplemented - updatePacket.ParcelData.RegionDenyAnonymous = (regionFlags & (uint)RegionFlags.DenyAnonymous) > 0; - updatePacket.ParcelData.RegionDenyIdentified = (regionFlags & (uint)RegionFlags.DenyIdentified) > 0; - updatePacket.ParcelData.RegionDenyTransacted = (regionFlags & (uint)RegionFlags.DenyTransacted) > 0; - updatePacket.ParcelData.RegionPushOverride = (regionFlags & (uint)RegionFlags.RestrictPushObject) > 0; + updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint)RegionFlags.DenyAnonymous) > + 0); + updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint)RegionFlags.DenyIdentified) > + 0); + updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint)RegionFlags.DenyTransacted) > + 0); + updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint)RegionFlags.RestrictPushObject) > + 0); updatePacket.ParcelData.RentPrice = 0; updatePacket.ParcelData.RequestResult = request_result; updatePacket.ParcelData.SalePrice = landData.SalePrice; updatePacket.ParcelData.SelectedPrims = landData.SelectedPrims; - updatePacket.ParcelData.SelfCount = 0; //TODO: Unimplemented + updatePacket.ParcelData.SelfCount = 0; //unemplemented updatePacket.ParcelData.SequenceID = sequence_id; if (landData.SimwideArea > 0) { @@ -4662,25 +4242,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task); } - public ulong GetGroupPowers(UUID groupID) - { - if (groupID == m_activeGroupID) - return m_activeGroupPowers; - - if (m_groupPowers.ContainsKey(groupID)) - return m_groupPowers[groupID]; - - return 0; - } - - /// - /// This is a utility method used by single states to not duplicate kicks and blue card of death messages. - /// - public bool ChildAgentStatus() - { - return m_scene.PresenceChildStatus(AgentId); - } - #endregion /// @@ -4699,8 +4260,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); } - #region Packet Handlers - private bool HandleMoneyTransferRequest(IClientAPI sender, Packet Pack) { MoneyTransferRequestPacket money = (MoneyTransferRequestPacket) Pack; @@ -4708,7 +4267,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (money.MoneyData.SourceID == sender.AgentId && money.AgentData.AgentID == sender.AgentId && money.AgentData.SessionID == sender.SessionId) { - MoneyTransferRequest handlerMoneyTransferRequest = OnMoneyTransferRequest; + handlerMoneyTransferRequest = OnMoneyTransferRequest; if (handlerMoneyTransferRequest != null) { handlerMoneyTransferRequest(money.MoneyData.SourceID, money.MoneyData.DestID, @@ -4727,7 +4286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelBuyPacket parcel = (ParcelBuyPacket) Pack; if (parcel.AgentData.AgentID == AgentId && parcel.AgentData.SessionID == SessionId) { - ParcelBuy handlerParcelBuy = OnParcelBuy; + handlerParcelBuy = OnParcelBuy; if (handlerParcelBuy != null) { handlerParcelBuy(parcel.AgentData.AgentID, parcel.Data.GroupID, parcel.Data.Final, @@ -4748,7 +4307,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < upack.UUIDNameBlock.Length; i++) { - UUIDNameRequest handlerUUIDGroupNameRequest = OnUUIDGroupNameRequest; + handlerUUIDGroupNameRequest = OnUUIDGroupNameRequest; if (handlerUUIDGroupNameRequest != null) { handlerUUIDGroupNameRequest(upack.UUIDNameBlock[i].ID, this); @@ -4764,7 +4323,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_genericPacketHandlers.Count == 0) return false; if (gmpack.AgentData.SessionID != SessionId) return false; - GenericMessage handlerGenericMessage = null; + handlerGenericMessage = null; string method = Util.FieldToString(gmpack.MethodData.Method).ToLower().Trim(); @@ -4805,7 +4364,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectGroupPacket ogpack = (ObjectGroupPacket)Pack; if (ogpack.AgentData.SessionID != SessionId) return false; - RequestObjectPropertiesFamily handlerObjectGroupRequest = OnObjectGroupRequest; + handlerObjectGroupRequest = OnObjectGroupRequest; if (handlerObjectGroupRequest != null) { for (int i = 0; i < ogpack.ObjectData.Length; i++) @@ -4820,7 +4379,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { ViewerEffectPacket viewer = (ViewerEffectPacket)Pack; if (viewer.AgentData.SessionID != SessionId) return false; - ViewerEffectEventHandler handlerViewerEffect = OnViewerEffect; + handlerViewerEffect = OnViewerEffect; if (handlerViewerEffect != null) { int length = viewer.Effect.Length; @@ -4844,8 +4403,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } - #endregion Packet Handlers - public void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question) { ScriptQuestionPacket scriptQuestion = (ScriptQuestionPacket)PacketPool.Instance.GetPacket(PacketType.ScriptQuestion); @@ -4911,7 +4468,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.InfoFormat("[CLIENT]: Got a logout request for {0} in {1}", Name, Scene.RegionInfo.RegionName); - Action handlerLogout = OnLogout; + handlerLogout = OnLogout; if (handlerLogout != null) { @@ -4993,7 +4550,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 1: Vector3 pos1 = new Vector3(block.Data, 0); - UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; + handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; if (handlerUpdatePrimSinglePosition != null) { // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); @@ -5003,7 +4560,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 2: Quaternion rot1 = new Quaternion(block.Data, 0, true); - UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; + handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; if (handlerUpdatePrimSingleRotation != null) { // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W); @@ -5014,7 +4571,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Vector3 rotPos = new Vector3(block.Data, 0); Quaternion rot2 = new Quaternion(block.Data, 12, true); - UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; + handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; if (handlerUpdatePrimSingleRotationPosition != null) { // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z); @@ -5026,7 +4583,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 20: Vector3 scale4 = new Vector3(block.Data, 0); - UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; + handlerUpdatePrimScale = OnUpdatePrimScale; if (handlerUpdatePrimScale != null) { // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z); @@ -5054,7 +4611,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 9: Vector3 pos2 = new Vector3(block.Data, 0); - UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; + handlerUpdateVector = OnUpdatePrimGroupPosition; if (handlerUpdateVector != null) { @@ -5065,7 +4622,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 10: Quaternion rot3 = new Quaternion(block.Data, 0, true); - UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; + handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; if (handlerUpdatePrimRotation != null) { // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W); @@ -5088,7 +4645,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 28: Vector3 scale7 = new Vector3(block.Data, 0); - UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; + handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; if (handlerUpdatePrimGroupScale != null) { // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z); @@ -5208,40 +4765,45 @@ namespace OpenSim.Region.ClientStack.LindenUDP } /// - /// Sets the throttles from values supplied by the client + /// returns a byte array of the client set throttles Gets multiplied by the multiplier + /// + /// + /// non 1 multiplier for subdividing the throttles between individual regions + /// + public byte[] GetThrottlesPacked(float multiplier) + { + return m_PacketHandler.PacketQueue.GetThrottlesPacked(multiplier); + } + /// + /// sets the throttles from values supplied by the client /// /// public void SetChildAgentThrottle(byte[] throttles) { - m_udpClient.SetThrottles(throttles); + m_PacketHandler.PacketQueue.SetThrottleFromClient(throttles); } /// - /// Get the current throttles for this client as a packed byte array - /// - /// Unused - /// - public byte[] GetThrottlesPacked(float multiplier) - { - return m_udpClient.GetThrottlesPacked(); - } - - /// - /// Cruft? + /// Method gets called when a new packet has arrived from the UDP + /// server. This happens after it's been decoded into a libsl object. /// + /// object containing the packet. public virtual void InPacket(object NewPack) { - throw new NotImplementedException(); + // Cast NewPack to Packet. + m_PacketHandler.InPacket((Packet) NewPack); } /// - /// This is the starting point for sending a simulator packet out to the client + /// This is the starting point for sending a simulator packet out to the client. + /// + /// Please do not call this from outside the LindenUDP client stack. /// - /// Packet to send - /// Throttling category for the packet - private void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) + /// + /// Corresponds to the type of data that is going out. Enum + public void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType) { - m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); + m_PacketHandler.OutPacket(NewPack, throttlePacketType); } public bool AddMoney(int debit) @@ -5285,7 +4847,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; } - UpdateVector handlerAutoPilotGo = OnAutoPilotGo; + handlerAutoPilotGo = OnAutoPilotGo; if (handlerAutoPilotGo != null) { handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this); @@ -5337,7 +4899,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - RequestAvatarProperties handlerRequestAvatarProperties = OnRequestAvatarProperties; + handlerRequestAvatarProperties = OnRequestAvatarProperties; if (handlerRequestAvatarProperties != null) { handlerRequestAvatarProperties(this, avatarProperties.AgentData.AvatarID); @@ -5378,7 +4940,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP args.Sender = this; args.SenderUUID = this.AgentId; - ChatMessage handlerChatFromClient = OnChatFromClient; + handlerChatFromClient = OnChatFromClient; if (handlerChatFromClient != null) handlerChatFromClient(this, args); } @@ -5396,7 +4958,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - UpdateAvatarProperties handlerUpdateAvatarProperties = OnUpdateAvatarProperties; + handlerUpdateAvatarProperties = OnUpdateAvatarProperties; if (handlerUpdateAvatarProperties != null) { AvatarPropertiesUpdatePacket.PropertiesDataBlock Properties = avatarProps.PropertiesData; @@ -5436,7 +4998,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP args.Position = new Vector3(); args.Scene = Scene; args.Sender = this; - ChatMessage handlerChatFromClient2 = OnChatFromClient; + handlerChatFromClient2 = OnChatFromClient; if (handlerChatFromClient2 != null) handlerChatFromClient2(this, args); } @@ -5457,7 +5019,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName); string IMmessage = Utils.BytesToString(msgpack.MessageBlock.Message); - ImprovedInstantMessage handlerInstantMessage = OnInstantMessage; + handlerInstantMessage = OnInstantMessage; if (handlerInstantMessage != null) { @@ -5500,7 +5062,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP callingCardFolders.Add(afriendpack.FolderData[fi].FolderID); } - FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest; + handlerApproveFriendRequest = OnApproveFriendRequest; if (handlerApproveFriendRequest != null) { handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders); @@ -5543,7 +5105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID listOwnerAgentID = tfriendpack.AgentData.AgentID; UUID exFriendID = tfriendpack.ExBlock.OtherID; - FriendshipTermination handlerTerminateFriendship = OnTerminateFriendship; + handlerTerminateFriendship = OnTerminateFriendship; if (handlerTerminateFriendship != null) { handlerTerminateFriendship(this, listOwnerAgentID, exFriendID); @@ -5562,7 +5124,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - RezObject handlerRezObject = OnRezObject; + handlerRezObject = OnRezObject; if (handlerRezObject != null) { handlerRezObject(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd, @@ -5585,7 +5147,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - DeRezObject handlerDeRezObject = OnDeRezObject; + handlerDeRezObject = OnDeRezObject; if (handlerDeRezObject != null) { List deRezIDs = new List(); @@ -5624,7 +5186,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { for (int i = 0; i < modify.ParcelData.Length; i++) { - ModifyTerrain handlerModifyTerrain = OnModifyTerrain; + handlerModifyTerrain = OnModifyTerrain; if (handlerModifyTerrain != null) { handlerModifyTerrain(AgentId, modify.ModifyBlock.Height, modify.ModifyBlock.Seconds, @@ -5641,7 +5203,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RegionHandshakeReply: - Action handlerRegionHandShakeReply = OnRegionHandShakeReply; + handlerRegionHandShakeReply = OnRegionHandShakeReply; if (handlerRegionHandShakeReply != null) { handlerRegionHandShakeReply(this); @@ -5650,14 +5212,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.AgentWearablesRequest: - GenericCall2 handlerRequestWearables = OnRequestWearables; + handlerRequestWearables = OnRequestWearables; if (handlerRequestWearables != null) { handlerRequestWearables(); } - Action handlerRequestAvatarsData = OnRequestAvatarsData; + handlerRequestAvatarsData = OnRequestAvatarsData; if (handlerRequestAvatarsData != null) { @@ -5678,7 +5240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - SetAppearance handlerSetAppearance = OnSetAppearance; + handlerSetAppearance = OnSetAppearance; if (handlerSetAppearance != null) { // Temporarily protect ourselves from the mantis #951 failure. @@ -5729,7 +5291,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP wearingArgs.NowWearing.Add(wearable); } - AvatarNowWearing handlerAvatarNowWearing = OnAvatarNowWearing; + handlerAvatarNowWearing = OnAvatarNowWearing; if (handlerAvatarNowWearing != null) { handlerAvatarNowWearing(this, wearingArgs); @@ -5738,7 +5300,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.RezSingleAttachmentFromInv: - RezSingleAttachmentFromInv handlerRezSingleAttachment = OnRezSingleAttachmentFromInv; + handlerRezSingleAttachment = OnRezSingleAttachmentFromInv; if (handlerRezSingleAttachment != null) { RezSingleAttachmentFromInvPacket rez = (RezSingleAttachmentFromInvPacket)Pack; @@ -5759,7 +5321,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.RezMultipleAttachmentsFromInv: - RezMultipleAttachmentsFromInv handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv; + handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv; if (handlerRezMultipleAttachments != null) { RezMultipleAttachmentsFromInvPacket rez = (RezMultipleAttachmentsFromInvPacket)Pack; @@ -5770,7 +5332,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.DetachAttachmentIntoInv: - UUIDNameRequest handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv; + handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv; if (handlerDetachAttachmentIntoInv != null) { DetachAttachmentIntoInvPacket detachtoInv = (DetachAttachmentIntoInvPacket)Pack; @@ -5800,7 +5362,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ObjectAttach handlerObjectAttach = OnObjectAttach; + handlerObjectAttach = OnObjectAttach; if (handlerObjectAttach != null) { @@ -5827,7 +5389,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int j = 0; j < dett.ObjectData.Length; j++) { uint obj = dett.ObjectData[j].ObjectLocalID; - ObjectDeselect handlerObjectDetach = OnObjectDetach; + handlerObjectDetach = OnObjectDetach; if (handlerObjectDetach != null) { handlerObjectDetach(obj, this); @@ -5851,7 +5413,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int j = 0; j < dropp.ObjectData.Length; j++) { uint obj = dropp.ObjectData[j].ObjectLocalID; - ObjectDrop handlerObjectDrop = OnObjectDrop; + handlerObjectDrop = OnObjectDrop; if (handlerObjectDrop != null) { handlerObjectDrop(obj, this); @@ -5871,14 +5433,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - SetAlwaysRun handlerSetAlwaysRun = OnSetAlwaysRun; + handlerSetAlwaysRun = OnSetAlwaysRun; if (handlerSetAlwaysRun != null) handlerSetAlwaysRun(this, run.AgentData.AlwaysRun); break; case PacketType.CompleteAgentMovement: - GenericCall2 handlerCompleteMovementToRegion = OnCompleteMovementToRegion; + handlerCompleteMovementToRegion = OnCompleteMovementToRegion; if (handlerCompleteMovementToRegion != null) { handlerCompleteMovementToRegion(); @@ -5947,7 +5509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP arg.HeadRotation = x.HeadRotation; arg.SessionID = x.SessionID; arg.State = x.State; - UpdateAgent handlerAgentUpdate = OnAgentUpdate; + handlerAgentUpdate = OnAgentUpdate; lastarg = arg; // save this set of arguments for nexttime if (handlerAgentUpdate != null) OnAgentUpdate(this, arg); @@ -5970,8 +5532,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - StartAnim handlerStartAnim = null; - StopAnim handlerStopAnim = null; + handlerStartAnim = null; + handlerStopAnim = null; for (int i = 0; i < AgentAni.AnimationList.Length; i++) { @@ -6008,7 +5570,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; + handlerAgentRequestSit = OnAgentRequestSit; if (handlerAgentRequestSit != null) handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); @@ -6029,7 +5591,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - AgentSit handlerAgentSit = OnAgentSit; + handlerAgentSit = OnAgentSit; if (handlerAgentSit != null) { OnAgentSit(this, agentSit.AgentData.AgentID); @@ -6047,7 +5609,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - SoundTrigger handlerSoundTrigger = OnSoundTrigger; + handlerSoundTrigger = OnSoundTrigger; if (handlerSoundTrigger != null) { handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, soundTriggerPacket.SoundData.OwnerID, @@ -6074,7 +5636,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AvatarPickerRequestPacket.DataBlock querydata = avRequestQuery.Data; //m_log.Debug("Agent Sends:" + Utils.BytesToString(querydata.Name)); - AvatarPickerRequest handlerAvatarPickerRequest = OnAvatarPickerRequest; + handlerAvatarPickerRequest = OnAvatarPickerRequest; if (handlerAvatarPickerRequest != null) { handlerAvatarPickerRequest(this, Requestdata.AgentID, Requestdata.QueryID, @@ -6094,7 +5656,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - FetchInventory handlerAgentDataUpdateRequest = OnAgentDataUpdateRequest; + handlerAgentDataUpdateRequest = OnAgentDataUpdateRequest; if (handlerAgentDataUpdateRequest != null) { @@ -6104,7 +5666,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.UserInfoRequest: - UserInfoRequest handlerUserInfoRequest = OnUserInfoRequest; + handlerUserInfoRequest = OnUserInfoRequest; if (handlerUserInfoRequest != null) { handlerUserInfoRequest(this); @@ -6127,7 +5689,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - UpdateUserInfo handlerUpdateUserInfo = OnUpdateUserInfo; + handlerUpdateUserInfo = OnUpdateUserInfo; if (handlerUpdateUserInfo != null) { bool visible = true; @@ -6156,7 +5718,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (avSetStartLocationRequestPacket.AgentData.AgentID == AgentId && avSetStartLocationRequestPacket.AgentData.SessionID == SessionId) { - TeleportLocationRequest handlerSetStartLocationRequest = OnSetStartLocationRequest; + handlerSetStartLocationRequest = OnSetStartLocationRequest; if (handlerSetStartLocationRequest != null) { handlerSetStartLocationRequest(this, 0, avSetStartLocationRequestPacket.StartLocationData.LocationPos, @@ -6178,21 +5740,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - m_udpClient.SetThrottles(atpack.Throttle.Throttles); + m_PacketHandler.PacketQueue.SetThrottleFromClient(atpack.Throttle.Throttles); break; case PacketType.AgentPause: - m_udpClient.IsPaused = true; + m_probesWithNoIngressPackets = 0; + m_clientBlocked = true; break; case PacketType.AgentResume: - m_udpClient.IsPaused = false; - SendStartPingCheck(m_udpClient.CurrentPingSequence++); + m_probesWithNoIngressPackets = 0; + m_clientBlocked = false; + SendStartPingCheck(0); break; case PacketType.ForceScriptControlRelease: - ForceReleaseControls handlerForceReleaseControls = OnForceReleaseControls; + handlerForceReleaseControls = OnForceReleaseControls; if (handlerForceReleaseControls != null) { handlerForceReleaseControls(this, AgentId); @@ -6226,7 +5790,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP childrenprims.Add(link.ObjectData[i].ObjectLocalID); } } - LinkObjects handlerLinkObjects = OnLinkObjects; + handlerLinkObjects = OnLinkObjects; if (handlerLinkObjects != null) { handlerLinkObjects(this, parentprimid, childrenprims); @@ -6254,7 +5818,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { prims.Add(delink.ObjectData[i].ObjectLocalID); } - DelinkObjects handlerDelinkObjects = OnDelinkObjects; + handlerDelinkObjects = OnDelinkObjects; if (handlerDelinkObjects != null) { handlerDelinkObjects(prims); @@ -6286,7 +5850,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //Check to see if adding the prim is allowed; useful for any module wanting to restrict the //object from rezing initially - AddNewPrim handlerAddPrim = OnAddPrim; + handlerAddPrim = OnAddPrim; if (handlerAddPrim != null) handlerAddPrim(AgentId, ActiveGroupId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape, addPacket.ObjectData.BypassRaycast, addPacket.ObjectData.RayStart, addPacket.ObjectData.RayTargetID, addPacket.ObjectData.RayEndIsIntersection); } @@ -6304,7 +5868,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - UpdateShape handlerUpdatePrimShape = null; + handlerUpdatePrimShape = null; for (int i = 0; i < shapePacket.ObjectData.Length; i++) { handlerUpdatePrimShape = OnUpdatePrimShape; @@ -6349,7 +5913,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ObjectExtraParams handlerUpdateExtraParams = OnUpdateExtraParams; + handlerUpdateExtraParams = OnUpdateExtraParams; if (handlerUpdateExtraParams != null) { for (int i = 0 ; i < extraPar.ObjectData.Length ; i++) @@ -6374,7 +5938,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectDuplicatePacket.AgentDataBlock AgentandGroupData = dupe.AgentData; - ObjectDuplicate handlerObjectDuplicate = null; + handlerObjectDuplicate = null; for (int i = 0; i < dupe.ObjectData.Length; i++) { @@ -6401,7 +5965,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ObjectRequest handlerObjectRequest = null; + handlerObjectRequest = null; for (int i = 0; i < incomingRequest.ObjectData.Length; i++) { @@ -6424,7 +5988,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ObjectSelect handlerObjectSelect = null; + handlerObjectSelect = null; for (int i = 0; i < incomingselect.ObjectData.Length; i++) { @@ -6447,7 +6011,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ObjectDeselect handlerObjectDeselect = null; + handlerObjectDeselect = null; for (int i = 0; i < incomingdeselect.ObjectData.Length; i++) { @@ -6474,7 +6038,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < position.ObjectData.Length; i++) { - UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; + handlerUpdateVector = OnUpdatePrimGroupPosition; if (handlerUpdateVector != null) handlerUpdateVector(position.ObjectData[i].ObjectLocalID, position.ObjectData[i].Position, this); } @@ -6495,7 +6059,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < scale.ObjectData.Length; i++) { - UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; + handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; if (handlerUpdatePrimGroupScale != null) handlerUpdatePrimGroupScale(scale.ObjectData[i].ObjectLocalID, scale.ObjectData[i].Scale, this); } @@ -6516,7 +6080,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < rotation.ObjectData.Length; i++) { - UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; + handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; if (handlerUpdatePrimRotation != null) handlerUpdatePrimRotation(rotation.ObjectData[i].ObjectLocalID, rotation.ObjectData[i].Rotation, this); } @@ -6534,7 +6098,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - UpdatePrimFlags handlerUpdatePrimFlags = OnUpdatePrimFlags; + handlerUpdatePrimFlags = OnUpdatePrimFlags; if (handlerUpdatePrimFlags != null) { @@ -6551,7 +6115,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ObjectImage: ObjectImagePacket imagePack = (ObjectImagePacket)Pack; - UpdatePrimTexture handlerUpdatePrimTexture = null; + handlerUpdatePrimTexture = null; for (int i = 0; i < imagePack.ObjectData.Length; i++) { handlerUpdatePrimTexture = OnUpdatePrimTexture; @@ -6574,7 +6138,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - GrabObject handlerGrabObject = OnGrabObject; + handlerGrabObject = OnGrabObject; if (handlerGrabObject != null) { @@ -6608,7 +6172,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - MoveObject handlerGrabUpdate = OnGrabUpdate; + handlerGrabUpdate = OnGrabUpdate; if (handlerGrabUpdate != null) { @@ -6643,7 +6207,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - DeGrabObject handlerDeGrabObject = OnDeGrabObject; + handlerDeGrabObject = OnDeGrabObject; if (handlerDeGrabObject != null) { List touchArgs = new List(); @@ -6677,7 +6241,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - SpinStart handlerSpinStart = OnSpinStart; + handlerSpinStart = OnSpinStart; if (handlerSpinStart != null) { handlerSpinStart(spinStart.ObjectData.ObjectID, this); @@ -6701,7 +6265,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP spinUpdate.ObjectData.Rotation.GetAxisAngle(out axis, out angle); //m_log.Warn("[CLIENT]: ObjectSpinUpdate packet rot axis:" + axis + " angle:" + angle); - SpinObject handlerSpinUpdate = OnSpinUpdate; + handlerSpinUpdate = OnSpinUpdate; if (handlerSpinUpdate != null) { handlerSpinUpdate(spinUpdate.ObjectData.ObjectID, spinUpdate.ObjectData.Rotation, this); @@ -6720,7 +6284,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - SpinStop handlerSpinStop = OnSpinStop; + handlerSpinStop = OnSpinStop; if (handlerSpinStop != null) { handlerSpinStop(spinStop.ObjectData.ObjectID, this); @@ -6739,7 +6303,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - GenericCall7 handlerObjectDescription = null; + handlerObjectDescription = null; for (int i = 0; i < objDes.ObjectData.Length; i++) { @@ -6763,7 +6327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - GenericCall7 handlerObjectName = null; + handlerObjectName = null; for (int i = 0; i < objName.ObjectData.Length; i++) { handlerObjectName = OnObjectName; @@ -6791,7 +6355,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID AgentID = newobjPerms.AgentData.AgentID; UUID SessionID = newobjPerms.AgentData.SessionID; - ObjectPermissions handlerObjectPermissions = null; + handlerObjectPermissions = null; for (int i = 0; i < newobjPerms.ObjectData.Length; i++) { @@ -6840,7 +6404,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < undoitem.ObjectData.Length; i++) { UUID objiD = undoitem.ObjectData[i].ObjectID; - AgentSit handlerOnUndo = OnUndo; + handlerOnUndo = OnUndo; if (handlerOnUndo != null) { handlerOnUndo(this, objiD); @@ -6861,7 +6425,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ObjectDuplicateOnRay handlerObjectDuplicateOnRay = null; + handlerObjectDuplicateOnRay = null; + for (int i = 0; i < dupeOnRay.ObjectData.Length; i++) { @@ -6891,7 +6456,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP RequestObjectPropertiesFamilyPacket.ObjectDataBlock packObjBlock = packToolTip.ObjectData; - RequestObjectPropertiesFamily handlerRequestObjectPropertiesFamily = OnRequestObjectPropertiesFamily; + handlerRequestObjectPropertiesFamily = OnRequestObjectPropertiesFamily; if (handlerRequestObjectPropertiesFamily != null) { @@ -6903,7 +6468,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ObjectIncludeInSearch: //This lets us set objects to appear in search (stuff like DataSnapshot, etc) ObjectIncludeInSearchPacket packInSearch = (ObjectIncludeInSearchPacket)Pack; - ObjectIncludeInSearch handlerObjectIncludeInSearch = null; + handlerObjectIncludeInSearch = null; #region Packet Session and User Check if (m_checkPackets) @@ -6940,7 +6505,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ScriptAnswer handlerScriptAnswer = OnScriptAnswer; + handlerScriptAnswer = OnScriptAnswer; if (handlerScriptAnswer != null) { handlerScriptAnswer(this, scriptAnswer.Data.TaskID, scriptAnswer.Data.ItemID, scriptAnswer.Data.Questions); @@ -6959,7 +6524,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - GenericCall7 handlerObjectClickAction = OnObjectClickAction; + handlerObjectClickAction = OnObjectClickAction; if (handlerObjectClickAction != null) { foreach (ObjectClickActionPacket.ObjectDataBlock odata in ocpacket.ObjectData) @@ -6983,7 +6548,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - GenericCall7 handlerObjectMaterial = OnObjectMaterial; + handlerObjectMaterial = OnObjectMaterial; if (handlerObjectMaterial != null) { foreach (ObjectMaterialPacket.ObjectDataBlock odata in ompacket.ObjectData) @@ -7137,7 +6702,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // m_log.Debug("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionId).ToString()); UUID temp = UUID.Combine(request.AssetBlock.TransactionID, SecureSessionId); - UDPAssetUploadRequest handlerAssetUploadRequest = OnAssetUploadRequest; + handlerAssetUploadRequest = OnAssetUploadRequest; if (handlerAssetUploadRequest != null) { @@ -7150,7 +6715,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RequestXfer: RequestXferPacket xferReq = (RequestXferPacket)Pack; - RequestXfer handlerRequestXfer = OnRequestXfer; + handlerRequestXfer = OnRequestXfer; if (handlerRequestXfer != null) { @@ -7160,7 +6725,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.SendXferPacket: SendXferPacketPacket xferRec = (SendXferPacketPacket)Pack; - XferReceive handlerXferReceive = OnXferReceive; + handlerXferReceive = OnXferReceive; if (handlerXferReceive != null) { handlerXferReceive(this, xferRec.XferID.ID, xferRec.XferID.Packet, xferRec.DataPacket.Data); @@ -7169,7 +6734,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ConfirmXferPacket: ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket)Pack; - ConfirmXfer handlerConfirmXfer = OnConfirmXfer; + handlerConfirmXfer = OnConfirmXfer; if (handlerConfirmXfer != null) { handlerConfirmXfer(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet); @@ -7177,7 +6742,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.AbortXfer: AbortXferPacket abortXfer = (AbortXferPacket)Pack; - AbortXfer handlerAbortXfer = OnAbortXfer; + handlerAbortXfer = OnAbortXfer; if (handlerAbortXfer != null) { handlerAbortXfer(this, abortXfer.XferID.ID); @@ -7196,7 +6761,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - CreateInventoryFolder handlerCreateInventoryFolder = OnCreateNewInventoryFolder; + handlerCreateInventoryFolder = OnCreateNewInventoryFolder; if (handlerCreateInventoryFolder != null) { handlerCreateInventoryFolder(this, invFolder.FolderData.FolderID, @@ -7219,7 +6784,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - UpdateInventoryFolder handlerUpdateInventoryFolder = null; + handlerUpdateInventoryFolder = null; for (int i = 0; i < invFolderx.FolderData.Length; i++) { @@ -7248,7 +6813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - MoveInventoryFolder handlerMoveInventoryFolder = null; + handlerMoveInventoryFolder = null; for (int i = 0; i < invFoldery.InventoryData.Length; i++) { @@ -7273,7 +6838,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - CreateNewInventoryItem handlerCreateNewInventoryItem = OnCreateNewInventoryItem; + handlerCreateNewInventoryItem = OnCreateNewInventoryItem; if (handlerCreateNewInventoryItem != null) { handlerCreateNewInventoryItem(this, createItem.InventoryBlock.TransactionID, @@ -7302,7 +6867,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - FetchInventory handlerFetchInventory = null; + handlerFetchInventory = null; for (int i = 0; i < FetchInventoryx.InventoryData.Length; i++) { @@ -7328,7 +6893,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - FetchInventoryDescendents handlerFetchInventoryDescendents = OnFetchInventoryDescendents; + handlerFetchInventoryDescendents = OnFetchInventoryDescendents; if (handlerFetchInventoryDescendents != null) { handlerFetchInventoryDescendents(this, Fetch.InventoryData.FolderID, Fetch.InventoryData.OwnerID, @@ -7348,7 +6913,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - PurgeInventoryDescendents handlerPurgeInventoryDescendents = OnPurgeInventoryDescendents; + handlerPurgeInventoryDescendents = OnPurgeInventoryDescendents; if (handlerPurgeInventoryDescendents != null) { handlerPurgeInventoryDescendents(this, Purge.InventoryData.FolderID); @@ -7368,7 +6933,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnUpdateInventoryItem != null) { - UpdateInventoryItem handlerUpdateInventoryItem = null; + handlerUpdateInventoryItem = null; for (int i = 0; i < inventoryItemUpdate.InventoryData.Length; i++) { handlerUpdateInventoryItem = OnUpdateInventoryItem; @@ -7390,13 +6955,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP itemUpd.SalePrice = inventoryItemUpdate.InventoryData[i].SalePrice; itemUpd.SaleType = inventoryItemUpdate.InventoryData[i].SaleType; itemUpd.Flags = inventoryItemUpdate.InventoryData[i].Flags; - + /* + OnUpdateInventoryItem(this, inventoryItemUpdate.InventoryData[i].TransactionID, + inventoryItemUpdate.InventoryData[i].ItemID, + Util.FieldToString(inventoryItemUpdate.InventoryData[i].Name), + Util.FieldToString(inventoryItemUpdate.InventoryData[i].Description), + inventoryItemUpdate.InventoryData[i].NextOwnerMask); + */ OnUpdateInventoryItem(this, inventoryItemUpdate.InventoryData[i].TransactionID, inventoryItemUpdate.InventoryData[i].ItemID, itemUpd); } } } + //m_log.Debug(Pack.ToString()); + /*for (int i = 0; i < inventoryItemUpdate.InventoryData.Length; i++) + { + if (inventoryItemUpdate.InventoryData[i].TransactionID != UUID.Zero) + { + AssetBase asset = m_assetCache.GetAsset(inventoryItemUpdate.InventoryData[i].TransactionID.Combine(this.SecureSessionId)); + if (asset != null) + { + // m_log.Debug("updating inventory item, found asset" + asset.FullID.ToString() + " already in cache"); + m_inventoryCache.UpdateInventoryItemAsset(this, inventoryItemUpdate.InventoryData[i].ItemID, asset); + } + else + { + asset = this.UploadAssets.AddUploadToAssetCache(inventoryItemUpdate.InventoryData[i].TransactionID); + if (asset != null) + { + //m_log.Debug("updating inventory item, adding asset" + asset.FullID.ToString() + " to cache"); + m_inventoryCache.UpdateInventoryItemAsset(this, inventoryItemUpdate.InventoryData[i].ItemID, asset); + } + else + { + //m_log.Debug("trying to update inventory item, but asset is null"); + } + } + } + else + { + m_inventoryCache.UpdateInventoryItemDetails(this, inventoryItemUpdate.InventoryData[i].ItemID, inventoryItemUpdate.InventoryData[i]); ; + } + }*/ break; case PacketType.CopyInventoryItem: CopyInventoryItemPacket copyitem = (CopyInventoryItemPacket)Pack; @@ -7410,7 +7011,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - CopyInventoryItem handlerCopyInventoryItem = null; + handlerCopyInventoryItem = null; if (OnCopyInventoryItem != null) { foreach (CopyInventoryItemPacket.InventoryDataBlock datablock in copyitem.InventoryData) @@ -7439,7 +7040,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnMoveInventoryItem != null) { - MoveInventoryItem handlerMoveInventoryItem = null; + handlerMoveInventoryItem = null; InventoryItemBase itm = null; List items = new List(); foreach (MoveInventoryItemPacket.InventoryDataBlock datablock in moveitem.InventoryData) @@ -7472,7 +7073,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryItem != null) { - RemoveInventoryItem handlerRemoveInventoryItem = null; + handlerRemoveInventoryItem = null; List uuids = new List(); foreach (RemoveInventoryItemPacket.InventoryDataBlock datablock in removeItem.InventoryData) { @@ -7500,7 +7101,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryFolder != null) { - RemoveInventoryFolder handlerRemoveInventoryFolder = null; + handlerRemoveInventoryFolder = null; List uuids = new List(); foreach (RemoveInventoryFolderPacket.FolderDataBlock datablock in removeFolder.FolderData) { @@ -7525,7 +7126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion if (OnRemoveInventoryFolder != null) { - RemoveInventoryFolder handlerRemoveInventoryFolder = null; + handlerRemoveInventoryFolder = null; List uuids = new List(); foreach (RemoveInventoryObjectsPacket.FolderDataBlock datablock in removeObject.FolderData) { @@ -7540,7 +7141,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryItem != null) { - RemoveInventoryItem handlerRemoveInventoryItem = null; + handlerRemoveInventoryItem = null; List uuids = new List(); foreach (RemoveInventoryObjectsPacket.ItemDataBlock datablock in removeObject.ItemData) { @@ -7565,7 +7166,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - RequestTaskInventory handlerRequestTaskInventory = OnRequestTaskInventory; + handlerRequestTaskInventory = OnRequestTaskInventory; if (handlerRequestTaskInventory != null) { handlerRequestTaskInventory(this, requesttask.InventoryData.LocalID); @@ -7587,7 +7188,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (updatetask.UpdateData.Key == 0) { - UpdateTaskInventory handlerUpdateTaskInventory = OnUpdateTaskInventory; + handlerUpdateTaskInventory = OnUpdateTaskInventory; if (handlerUpdateTaskInventory != null) { TaskInventoryItem newTaskItem = new TaskInventoryItem(); @@ -7631,7 +7232,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - RemoveTaskInventory handlerRemoveTaskItem = OnRemoveTaskItem; + handlerRemoveTaskItem = OnRemoveTaskItem; if (handlerRemoveTaskItem != null) { @@ -7653,7 +7254,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - MoveTaskInventory handlerMoveTaskItem = OnMoveTaskItem; + handlerMoveTaskItem = OnMoveTaskItem; if (handlerMoveTaskItem != null) { @@ -7678,7 +7279,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - RezScript handlerRezScript = OnRezScript; + handlerRezScript = OnRezScript; InventoryItemBase item = new InventoryItemBase(); item.ID = rezScriptx.InventoryBlock.ItemID; item.Folder = rezScriptx.InventoryBlock.FolderID; @@ -7721,7 +7322,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - RequestMapBlocks handlerRequestMapBlocks = OnRequestMapBlocks; + handlerRequestMapBlocks = OnRequestMapBlocks; if (handlerRequestMapBlocks != null) { handlerRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, @@ -7742,7 +7343,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP string mapName = Util.UTF8.GetString(map.NameData.Name, 0, map.NameData.Name.Length - 1); - RequestMapName handlerMapNameRequest = OnMapNameRequest; + handlerMapNameRequest = OnMapNameRequest; if (handlerMapNameRequest != null) { handlerMapNameRequest(this, mapName); @@ -7793,7 +7394,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { // Teleport home request - UUIDNameRequest handlerTeleportHomeRequest = OnTeleportHomeRequest; + handlerTeleportHomeRequest = OnTeleportHomeRequest; if (handlerTeleportHomeRequest != null) { handlerTeleportHomeRequest(AgentId, this); @@ -7801,7 +7402,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; } - TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; + handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; if (handlerTeleportLandmarkRequest != null) { handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position); @@ -7832,7 +7433,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - TeleportLocationRequest handlerTeleportLocationRequest = OnTeleportLocationRequest; + handlerTeleportLocationRequest = OnTeleportLocationRequest; if (handlerTeleportLocationRequest != null) { handlerTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position, @@ -7855,7 +7456,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock) { - UUIDNameRequest handlerNameRequest = OnNameFromUUIDRequest; + handlerNameRequest = OnNameFromUUIDRequest; if (handlerNameRequest != null) { handlerNameRequest(UUIDBlock.ID, this); @@ -7868,7 +7469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RegionHandleRequest: RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; - RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; + handlerRegionHandleRequest = OnRegionHandleRequest; if (handlerRegionHandleRequest != null) { handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); @@ -7887,7 +7488,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelInfoRequest handlerParcelInfoRequest = OnParcelInfoRequest; + handlerParcelInfoRequest = OnParcelInfoRequest; if (handlerParcelInfoRequest != null) { handlerParcelInfoRequest(this, pirPack.Data.ParcelID); @@ -7906,7 +7507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelAccessListRequest handlerParcelAccessListRequest = OnParcelAccessListRequest; + handlerParcelAccessListRequest = OnParcelAccessListRequest; if (handlerParcelAccessListRequest != null) { @@ -7938,7 +7539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP entries.Add(entry); } - ParcelAccessListUpdateRequest handlerParcelAccessListUpdateRequest = OnParcelAccessListUpdateRequest; + handlerParcelAccessListUpdateRequest = OnParcelAccessListUpdateRequest; if (handlerParcelAccessListUpdateRequest != null) { handlerParcelAccessListUpdateRequest(updatePacket.AgentData.AgentID, @@ -7959,7 +7560,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelPropertiesRequest handlerParcelPropertiesRequest = OnParcelPropertiesRequest; + handlerParcelPropertiesRequest = OnParcelPropertiesRequest; if (handlerParcelPropertiesRequest != null) { handlerParcelPropertiesRequest((int)Math.Round(propertiesRequest.ParcelData.West), @@ -7982,7 +7583,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelDivideRequest handlerParcelDivideRequest = OnParcelDivideRequest; + handlerParcelDivideRequest = OnParcelDivideRequest; if (handlerParcelDivideRequest != null) { handlerParcelDivideRequest((int)Math.Round(landDivide.ParcelData.West), @@ -8003,7 +7604,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelJoinRequest handlerParcelJoinRequest = OnParcelJoinRequest; + handlerParcelJoinRequest = OnParcelJoinRequest; if (handlerParcelJoinRequest != null) { @@ -8025,7 +7626,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelPropertiesUpdateRequest handlerParcelPropertiesUpdateRequest = OnParcelPropertiesUpdateRequest; + handlerParcelPropertiesUpdateRequest = OnParcelPropertiesUpdateRequest; if (handlerParcelPropertiesUpdateRequest != null) { @@ -8071,7 +7672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP returnIDs.Add(rb.ReturnID); } - ParcelSelectObjects handlerParcelSelectObjects = OnParcelSelectObjects; + handlerParcelSelectObjects = OnParcelSelectObjects; if (handlerParcelSelectObjects != null) { @@ -8092,7 +7693,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelObjectOwnerRequest handlerParcelObjectOwnerRequest = OnParcelObjectOwnerRequest; + handlerParcelObjectOwnerRequest = OnParcelObjectOwnerRequest; if (handlerParcelObjectOwnerRequest != null) { @@ -8111,7 +7712,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelGodForceOwner handlerParcelGodForceOwner = OnParcelGodForceOwner; + handlerParcelGodForceOwner = OnParcelGodForceOwner; if (handlerParcelGodForceOwner != null) { handlerParcelGodForceOwner(godForceOwnerPacket.Data.LocalID, godForceOwnerPacket.Data.OwnerID, this); @@ -8129,7 +7730,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelAbandonRequest handlerParcelAbandonRequest = OnParcelAbandonRequest; + handlerParcelAbandonRequest = OnParcelAbandonRequest; if (handlerParcelAbandonRequest != null) { handlerParcelAbandonRequest(releasePacket.Data.LocalID, this); @@ -8147,7 +7748,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelReclaim handlerParcelReclaim = OnParcelReclaim; + handlerParcelReclaim = OnParcelReclaim; if (handlerParcelReclaim != null) { handlerParcelReclaim(reclaimPacket.Data.LocalID, this); @@ -8176,7 +7777,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int parceliterator = 0; parceliterator < parcelReturnObjects.TaskIDs.Length; parceliterator++) puserselectedTaskIDs[parceliterator] = parcelReturnObjects.TaskIDs[parceliterator].TaskID; - ParcelReturnObjectsRequest handlerParcelReturnObjectsRequest = OnParcelReturnObjectsRequest; + handlerParcelReturnObjectsRequest = OnParcelReturnObjectsRequest; if (handlerParcelReturnObjectsRequest != null) { handlerParcelReturnObjectsRequest(parcelReturnObjects.ParcelData.LocalID, parcelReturnObjects.ParcelData.ReturnType, puserselectedOwnerIDs, puserselectedTaskIDs, this); @@ -8196,7 +7797,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelSetOtherCleanTime handlerParcelSetOtherCleanTime = OnParcelSetOtherCleanTime; + handlerParcelSetOtherCleanTime = OnParcelSetOtherCleanTime; if (handlerParcelSetOtherCleanTime != null) { handlerParcelSetOtherCleanTime(this, @@ -8217,7 +7818,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - GodLandStatRequest handlerLandStatRequest = OnLandStatRequest; + handlerLandStatRequest = OnLandStatRequest; if (handlerLandStatRequest != null) { handlerLandStatRequest(lsrp.RequestData.ParcelLocalID, lsrp.RequestData.ReportType, lsrp.RequestData.RequestFlags, Utils.BytesToString(lsrp.RequestData.Filter), this); @@ -8237,7 +7838,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ParcelDwellRequest handlerParcelDwellRequest = OnParcelDwellRequest; + handlerParcelDwellRequest = OnParcelDwellRequest; if (handlerParcelDwellRequest != null) { handlerParcelDwellRequest(dwellrq.Data.LocalID, this); @@ -8481,7 +8082,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (Utils.BytesToString(messagePacket.ParamList[0].Parameter) == "bake") { - BakeTerrain handlerBakeTerrain = OnBakeTerrain; + handlerBakeTerrain = OnBakeTerrain; if (handlerBakeTerrain != null) { handlerBakeTerrain(this); @@ -8491,7 +8092,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (messagePacket.ParamList.Length > 1) { - RequestTerrain handlerRequestTerrain = OnRequestTerrain; + handlerRequestTerrain = OnRequestTerrain; if (handlerRequestTerrain != null) { handlerRequestTerrain(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter)); @@ -8502,7 +8103,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (messagePacket.ParamList.Length > 1) { - RequestTerrain handlerUploadTerrain = OnUploadTerrain; + handlerUploadTerrain = OnUploadTerrain; if (handlerUploadTerrain != null) { handlerUploadTerrain(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter)); @@ -8524,7 +8125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UInt32 param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter)); UInt32 param2 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[2].Parameter)); - EstateChangeInfo handlerEstateChangeInfo = OnEstateChangeInfo; + handlerEstateChangeInfo = OnEstateChangeInfo; if (handlerEstateChangeInfo != null) { handlerEstateChangeInfo(this, invoice, SenderID, param1, param2); @@ -8558,7 +8159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - RegionInfoRequest handlerRegionInfoRequest = OnRegionInfoRequest; + handlerRegionInfoRequest = OnRegionInfoRequest; if (handlerRegionInfoRequest != null) { handlerRegionInfoRequest(this); @@ -8569,7 +8170,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //EstateCovenantRequestPacket.AgentDataBlock epack = // ((EstateCovenantRequestPacket)Pack).AgentData; - EstateCovenantRequest handlerEstateCovenantRequest = OnEstateCovenantRequest; + handlerEstateCovenantRequest = OnEstateCovenantRequest; if (handlerEstateCovenantRequest != null) { handlerEstateCovenantRequest(this); @@ -8587,7 +8188,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP RequestGodlikePowersPacket.AgentDataBlock ablock = rglpPack.AgentData; - RequestGodlikePowers handlerReqGodlikePowers = OnRequestGodlikePowers; + handlerReqGodlikePowers = OnRequestGodlikePowers; if (handlerReqGodlikePowers != null) { @@ -8600,7 +8201,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (gkupack.UserInfo.GodSessionID == SessionId && AgentId == gkupack.UserInfo.GodID) { - GodKickUser handlerGodKickUser = OnGodKickUser; + handlerGodKickUser = OnGodKickUser; if (handlerGodKickUser != null) { handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID, @@ -8640,7 +8241,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - MoneyBalanceRequest handlerMoneyBalanceRequest = OnMoneyBalanceRequest; + handlerMoneyBalanceRequest = OnMoneyBalanceRequest; if (handlerMoneyBalanceRequest != null) { @@ -8651,7 +8252,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.EconomyDataRequest: - EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; + handlerEconomoyDataRequest = OnEconomyDataRequest; if (handlerEconomoyDataRequest != null) { handlerEconomoyDataRequest(AgentId); @@ -8660,7 +8261,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RequestPayPrice: RequestPayPricePacket requestPayPricePacket = (RequestPayPricePacket)Pack; - RequestPayPrice handlerRequestPayPrice = OnRequestPayPrice; + handlerRequestPayPrice = OnRequestPayPrice; if (handlerRequestPayPrice != null) { handlerRequestPayPrice(this, requestPayPricePacket.ObjectData.ObjectID); @@ -8679,7 +8280,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ObjectSaleInfo handlerObjectSaleInfo = OnObjectSaleInfo; + handlerObjectSaleInfo = OnObjectSaleInfo; if (handlerObjectSaleInfo != null) { foreach (ObjectSaleInfoPacket.ObjectDataBlock d @@ -8707,7 +8308,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ObjectBuy handlerObjectBuy = OnObjectBuy; + handlerObjectBuy = OnObjectBuy; if (handlerObjectBuy != null) { @@ -8733,7 +8334,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.GetScriptRunning: GetScriptRunningPacket scriptRunning = (GetScriptRunningPacket)Pack; - GetScriptRunning handlerGetScriptRunning = OnGetScriptRunning; + handlerGetScriptRunning = OnGetScriptRunning; if (handlerGetScriptRunning != null) { handlerGetScriptRunning(this, scriptRunning.Script.ObjectID, scriptRunning.Script.ItemID); @@ -8752,7 +8353,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - SetScriptRunning handlerSetScriptRunning = OnSetScriptRunning; + handlerSetScriptRunning = OnSetScriptRunning; if (handlerSetScriptRunning != null) { handlerSetScriptRunning(this, setScriptRunning.Script.ObjectID, setScriptRunning.Script.ItemID, setScriptRunning.Script.Running); @@ -8771,7 +8372,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ScriptReset handlerScriptReset = OnScriptReset; + handlerScriptReset = OnScriptReset; if (handlerScriptReset != null) { handlerScriptReset(this, scriptResetPacket.Script.ObjectID, scriptResetPacket.Script.ItemID); @@ -8794,7 +8395,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ActivateGesture handlerActivateGesture = OnActivateGesture; + handlerActivateGesture = OnActivateGesture; if (handlerActivateGesture != null) { handlerActivateGesture(this, @@ -8817,7 +8418,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - DeactivateGesture handlerDeactivateGesture = OnDeactivateGesture; + handlerDeactivateGesture = OnDeactivateGesture; if (handlerDeactivateGesture != null) { handlerDeactivateGesture(this, deactivateGesturePacket.Data[0].ItemID); @@ -8840,7 +8441,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP foreach (ObjectOwnerPacket.ObjectDataBlock d in objectOwnerPacket.ObjectData) localIDs.Add(d.ObjectLocalID); - ObjectOwner handlerObjectOwner = OnObjectOwner; + handlerObjectOwner = OnObjectOwner; if (handlerObjectOwner != null) { handlerObjectOwner(this, objectOwnerPacket.HeaderData.OwnerID, objectOwnerPacket.HeaderData.GroupID, localIDs); @@ -8853,14 +8454,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region unimplemented handlers case PacketType.StartPingCheck: - StartPingCheckPacket pingStart = (StartPingCheckPacket)Pack; - CompletePingCheckPacket pingComplete = new CompletePingCheckPacket(); - pingComplete.PingID.PingID = pingStart.PingID.PingID; - m_udpServer.SendPacket(m_udpClient, pingComplete, ThrottleOutPacketType.Unknown, false); + // Send the client the ping response back + // Pass the same PingID in the matching packet + // Handled In the packet processing + //m_log.Debug("[CLIENT]: possibly unhandled StartPingCheck packet"); break; - case PacketType.CompletePingCheck: - // TODO: Do stats tracking or something with these? + // TODO: Perhaps this should be processed on the Sim to determine whether or not to drop a dead client + //m_log.Warn("[CLIENT]: unhandled CompletePingCheck packet"); break; case PacketType.ViewerStats: @@ -8881,7 +8482,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion //m_log.Debug(mirpk.ToString()); - MapItemRequest handlerMapItemRequest = OnMapItemRequest; + handlerMapItemRequest = OnMapItemRequest; if (handlerMapItemRequest != null) { handlerMapItemRequest(this,mirpk.AgentData.Flags, mirpk.AgentData.EstateID, @@ -8908,7 +8509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - MuteListRequest handlerMuteListRequest = OnMuteListRequest; + handlerMuteListRequest = OnMuteListRequest; if (handlerMuteListRequest != null) { handlerMuteListRequest(this, muteListRequest.MuteData.MuteCRC); @@ -8945,7 +8546,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - DirPlacesQuery handlerDirPlacesQuery = OnDirPlacesQuery; + handlerDirPlacesQuery = OnDirPlacesQuery; if (handlerDirPlacesQuery != null) { handlerDirPlacesQuery(this, @@ -8971,7 +8572,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - DirFindQuery handlerDirFindQuery = OnDirFindQuery; + handlerDirFindQuery = OnDirFindQuery; if (handlerDirFindQuery != null) { handlerDirFindQuery(this, @@ -8994,7 +8595,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - DirLandQuery handlerDirLandQuery = OnDirLandQuery; + handlerDirLandQuery = OnDirLandQuery; if (handlerDirLandQuery != null) { handlerDirLandQuery(this, @@ -9018,7 +8619,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - DirPopularQuery handlerDirPopularQuery = OnDirPopularQuery; + handlerDirPopularQuery = OnDirPopularQuery; if (handlerDirPopularQuery != null) { handlerDirPopularQuery(this, @@ -9038,7 +8639,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - DirClassifiedQuery handlerDirClassifiedQuery = OnDirClassifiedQuery; + handlerDirClassifiedQuery = OnDirClassifiedQuery; if (handlerDirClassifiedQuery != null) { handlerDirClassifiedQuery(this, @@ -9554,7 +9155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelDeedToGroupPacket parcelDeedToGroup = (ParcelDeedToGroupPacket)Pack; if (m_GroupsModule != null) { - ParcelDeedToGroup handlerParcelDeedToGroup = OnParcelDeedToGroup; + handlerParcelDeedToGroup = OnParcelDeedToGroup; if (handlerParcelDeedToGroup != null) { handlerParcelDeedToGroup(parcelDeedToGroup.Data.LocalID, parcelDeedToGroup.Data.GroupID,this); @@ -9798,7 +9399,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - StartLure handlerStartLure = OnStartLure; + handlerStartLure = OnStartLure; if (handlerStartLure != null) handlerStartLure(startLureRequest.Info.LureType, Utils.BytesToString( @@ -9820,7 +9421,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - TeleportLureRequest handlerTeleportLureRequest = OnTeleportLureRequest; + handlerTeleportLureRequest = OnTeleportLureRequest; if (handlerTeleportLureRequest != null) handlerTeleportLureRequest( teleportLureRequest.Info.LureID, @@ -9841,7 +9442,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ClassifiedInfoRequest handlerClassifiedInfoRequest = OnClassifiedInfoRequest; + handlerClassifiedInfoRequest = OnClassifiedInfoRequest; if (handlerClassifiedInfoRequest != null) handlerClassifiedInfoRequest( classifiedInfoRequest.Data.ClassifiedID, @@ -9861,7 +9462,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ClassifiedInfoUpdate handlerClassifiedInfoUpdate = OnClassifiedInfoUpdate; + handlerClassifiedInfoUpdate = OnClassifiedInfoUpdate; if (handlerClassifiedInfoUpdate != null) handlerClassifiedInfoUpdate( classifiedInfoUpdate.Data.ClassifiedID, @@ -9893,7 +9494,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ClassifiedDelete handlerClassifiedDelete = OnClassifiedDelete; + handlerClassifiedDelete = OnClassifiedDelete; if (handlerClassifiedDelete != null) handlerClassifiedDelete( classifiedDelete.Data.ClassifiedID, @@ -9913,7 +9514,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; + handlerClassifiedGodDelete = OnClassifiedGodDelete; if (handlerClassifiedGodDelete != null) handlerClassifiedGodDelete( classifiedGodDelete.Data.ClassifiedID, @@ -9933,7 +9534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - EventGodDelete handlerEventGodDelete = OnEventGodDelete; + handlerEventGodDelete = OnEventGodDelete; if (handlerEventGodDelete != null) handlerEventGodDelete( eventGodDelete.EventData.EventID, @@ -9958,7 +9559,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - EventNotificationAddRequest handlerEventNotificationAddRequest = OnEventNotificationAddRequest; + handlerEventNotificationAddRequest = OnEventNotificationAddRequest; if (handlerEventNotificationAddRequest != null) handlerEventNotificationAddRequest( eventNotificationAdd.EventData.EventID, this); @@ -9977,7 +9578,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - EventNotificationRemoveRequest handlerEventNotificationRemoveRequest = OnEventNotificationRemoveRequest; + handlerEventNotificationRemoveRequest = OnEventNotificationRemoveRequest; if (handlerEventNotificationRemoveRequest != null) handlerEventNotificationRemoveRequest( eventNotificationRemove.EventData.EventID, this); @@ -9995,7 +9596,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - RetrieveInstantMessages handlerRetrieveInstantMessages = OnRetrieveInstantMessages; + handlerRetrieveInstantMessages = OnRetrieveInstantMessages; if (handlerRetrieveInstantMessages != null) handlerRetrieveInstantMessages(this); break; @@ -10013,7 +9614,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - PickDelete handlerPickDelete = OnPickDelete; + handlerPickDelete = OnPickDelete; if (handlerPickDelete != null) handlerPickDelete(this, pickDelete.Data.PickID); break; @@ -10030,7 +9631,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - PickGodDelete handlerPickGodDelete = OnPickGodDelete; + handlerPickGodDelete = OnPickGodDelete; if (handlerPickGodDelete != null) handlerPickGodDelete(this, pickGodDelete.AgentData.AgentID, @@ -10050,7 +9651,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - PickInfoUpdate handlerPickInfoUpdate = OnPickInfoUpdate; + handlerPickInfoUpdate = OnPickInfoUpdate; if (handlerPickInfoUpdate != null) handlerPickInfoUpdate(this, pickInfoUpdate.Data.PickID, @@ -10075,7 +9676,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - AvatarNotesUpdate handlerAvatarNotesUpdate = OnAvatarNotesUpdate; + handlerAvatarNotesUpdate = OnAvatarNotesUpdate; if (handlerAvatarNotesUpdate != null) handlerAvatarNotesUpdate(this, avatarNotesUpdate.Data.TargetID, @@ -10092,7 +9693,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP PlacesQueryPacket placesQueryPacket = (PlacesQueryPacket)Pack; - PlacesQuery handlerPlacesQuery = OnPlacesQuery; + handlerPlacesQuery = OnPlacesQuery; if (handlerPlacesQuery != null) handlerPlacesQuery(placesQueryPacket.AgentData.QueryID, @@ -10146,28 +9747,306 @@ namespace OpenSim.Region.ClientStack.LindenUDP //shape.Textures = ntex; return shape; } - + + /// + /// Send the client an Estate message blue box pop-down with a single OK button + /// + /// + /// + /// + /// + public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message) + { + if (!ChildAgentStatus()) + SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3())); + + //SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch()); + } + + public void SendLogoutPacket() + { + // I know this is a bit of a hack, however there are times when you don't + // want to send this, but still need to do the rest of the shutdown process + // this method gets called from the packet server.. which makes it practically + // impossible to do any other way. + + if (m_SendLogoutPacketWhenClosing) + { + LogoutReplyPacket logReply = (LogoutReplyPacket)PacketPool.Instance.GetPacket(PacketType.LogoutReply); + // TODO: don't create new blocks if recycling an old packet + logReply.AgentData.AgentID = AgentId; + logReply.AgentData.SessionID = SessionId; + logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; + logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); + logReply.InventoryData[0].ItemID = UUID.Zero; + + OutPacket(logReply, ThrottleOutPacketType.Task); + } + } + + public void SendHealth(float health) + { + HealthMessagePacket healthpacket = (HealthMessagePacket)PacketPool.Instance.GetPacket(PacketType.HealthMessage); + healthpacket.HealthData.Health = health; + OutPacket(healthpacket, ThrottleOutPacketType.Task); + } + + public void SendAgentOnline(UUID[] agentIDs) + { + OnlineNotificationPacket onp = new OnlineNotificationPacket(); + OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length]; + for (int i = 0; i < agentIDs.Length; i++) + { + OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); + onpbl.AgentID = agentIDs[i]; + onpb[i] = onpbl; + } + onp.AgentBlock = onpb; + onp.Header.Reliable = true; + OutPacket(onp, ThrottleOutPacketType.Task); + } + + public void SendAgentOffline(UUID[] agentIDs) + { + OfflineNotificationPacket offp = new OfflineNotificationPacket(); + OfflineNotificationPacket.AgentBlockBlock[] offpb = new OfflineNotificationPacket.AgentBlockBlock[agentIDs.Length]; + for (int i = 0; i < agentIDs.Length; i++) + { + OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); + onpbl.AgentID = agentIDs[i]; + offpb[i] = onpbl; + } + offp.AgentBlock = offpb; + offp.Header.Reliable = true; + OutPacket(offp, ThrottleOutPacketType.Task); + } + + public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, + Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) + { + AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); + avatarSitResponse.SitObject.ID = TargetID; + if (CameraAtOffset != Vector3.Zero) + { + avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset; + avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset; + } + avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook; + avatarSitResponse.SitTransform.AutoPilot = autopilot; + avatarSitResponse.SitTransform.SitPosition = OffsetPos; + avatarSitResponse.SitTransform.SitRotation = SitOrientation; + + OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); + } + + public void SendAdminResponse(UUID Token, uint AdminLevel) + { + GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket(); + GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock(); + GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock(); + + adb.AgentID = AgentId; + adb.SessionID = SessionId; // More security + gdb.GodLevel = (byte)AdminLevel; + gdb.Token = Token; + //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock; + respondPacket.GrantData = gdb; + respondPacket.AgentData = adb; + OutPacket(respondPacket, ThrottleOutPacketType.Task); + } + + public void SendGroupMembership(GroupMembershipData[] GroupMembership) + { + m_groupPowers.Clear(); + + AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket(); + AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[GroupMembership.Length]; + for (int i = 0; i < GroupMembership.Length; i++) + { + m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; + + AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock(); + Group.AcceptNotices = GroupMembership[i].AcceptNotices; + Group.Contribution = GroupMembership[i].Contribution; + Group.GroupID = GroupMembership[i].GroupID; + Group.GroupInsigniaID = GroupMembership[i].GroupPicture; + Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); + Group.GroupPowers = GroupMembership[i].GroupPowers; + Groups[i] = Group; + + + } + Groupupdate.GroupData = Groups; + Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock(); + Groupupdate.AgentData.AgentID = AgentId; + OutPacket(Groupupdate, ThrottleOutPacketType.Task); + + try + { + IEventQueue eq = Scene.RequestModuleInterface(); + if (eq != null) + { + eq.GroupMembership(Groupupdate, this.AgentId); + } + } + catch (Exception ex) + { + m_log.Error("Unable to send group membership data via eventqueue - exception: " + ex.ToString()); + m_log.Warn("sending group membership data via UDP"); + OutPacket(Groupupdate, ThrottleOutPacketType.Task); + } + } + + + public void SendGroupNameReply(UUID groupLLUID, string GroupName) + { + UUIDGroupNameReplyPacket pack = new UUIDGroupNameReplyPacket(); + UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; + UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); + uidnamebloc.ID = groupLLUID; + uidnamebloc.GroupName = Utils.StringToBytes(GroupName); + uidnameblock[0] = uidnamebloc; + pack.UUIDNameBlock = uidnameblock; + OutPacket(pack, ThrottleOutPacketType.Task); + } + + public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia) + { + LandStatReplyPacket lsrp = new LandStatReplyPacket(); + // LandStatReplyPacket.RequestDataBlock lsreqdpb = new LandStatReplyPacket.RequestDataBlock(); + LandStatReplyPacket.ReportDataBlock[] lsrepdba = new LandStatReplyPacket.ReportDataBlock[lsrpia.Length]; + //LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); + // lsrepdb. + lsrp.RequestData.ReportType = reportType; + lsrp.RequestData.RequestFlags = requestFlags; + lsrp.RequestData.TotalObjectCount = resultCount; + for (int i = 0; i < lsrpia.Length; i++) + { + LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); + lsrepdb.LocationX = lsrpia[i].LocationX; + lsrepdb.LocationY = lsrpia[i].LocationY; + lsrepdb.LocationZ = lsrpia[i].LocationZ; + lsrepdb.Score = lsrpia[i].Score; + lsrepdb.TaskID = lsrpia[i].TaskID; + lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; + lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); + lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); + lsrepdba[i] = lsrepdb; + } + lsrp.ReportData = lsrepdba; + OutPacket(lsrp, ThrottleOutPacketType.Task); + } + + public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running) + { + ScriptRunningReplyPacket scriptRunningReply = new ScriptRunningReplyPacket(); + scriptRunningReply.Script.ObjectID = objectID; + scriptRunningReply.Script.ItemID = itemID; + scriptRunningReply.Script.Running = running; + + OutPacket(scriptRunningReply, ThrottleOutPacketType.Task); + } + + public void SendAsset(AssetRequestToClient req) + { + //m_log.Debug("sending asset " + req.RequestAssetID); + TransferInfoPacket Transfer = new TransferInfoPacket(); + Transfer.TransferInfo.ChannelType = 2; + Transfer.TransferInfo.Status = 0; + Transfer.TransferInfo.TargetType = 0; + if (req.AssetRequestSource == 2) + { + Transfer.TransferInfo.Params = new byte[20]; + Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + int assType = req.AssetInf.Type; + Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); + } + else if (req.AssetRequestSource == 3) + { + Transfer.TransferInfo.Params = req.Params; + // Transfer.TransferInfo.Params = new byte[100]; + //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); + } + Transfer.TransferInfo.Size = req.AssetInf.Data.Length; + Transfer.TransferInfo.TransferID = req.TransferRequestID; + Transfer.Header.Zerocoded = true; + OutPacket(Transfer, ThrottleOutPacketType.Asset); + + if (req.NumPackets == 1) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = 0; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + TransferPacket.TransferData.Data = req.AssetInf.Data; + TransferPacket.TransferData.Status = 1; + TransferPacket.Header.Zerocoded = true; + OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + } + else + { + int processedLength = 0; + int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; + int packetNumber = 0; + + while (processedLength < req.AssetInf.Data.Length) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = packetNumber; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + + int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); + byte[] chunk = new byte[chunkSize]; + Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); + + TransferPacket.TransferData.Data = chunk; + + // 0 indicates more packets to come, 1 indicates last packet + if (req.AssetInf.Data.Length - processedLength > maxChunkSize) + { + TransferPacket.TransferData.Status = 0; + } + else + { + TransferPacket.TransferData.Status = 1; + } + TransferPacket.Header.Zerocoded = true; + OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + + processedLength += chunkSize; + packetNumber++; + } + } + } + + public void SendTexture(AssetBase TextureAsset) + { + + } + public ClientInfo GetClientInfo() { - ClientInfo info = m_udpClient.GetClientInfo(); + ClientInfo info = m_PacketHandler.GetClientInfo(); info.userEP = m_userEndPoint; - info.proxyEP = null; + info.proxyEP = m_proxyEndPoint; info.agentcircuit = new sAgentCircuitData(RequestClientInfo()); return info; } - public void SetClientInfo(ClientInfo info) - { - m_udpClient.SetClientInfo(info); - } - public EndPoint GetClientEP() { return m_userEndPoint; } + public void SetClientInfo(ClientInfo info) + { + m_PacketHandler.SetClientInfo(info); + } + #region Media Parcel Members public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time) @@ -10200,6 +10079,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion + #region Camera public void SendSetFollowCamProperties (UUID objectID, SortedDictionary parameters) @@ -10229,12 +10109,70 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion + public void SendRegionHandle(UUID regionID, ulong handle) { + RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply); + reply.ReplyBlock.RegionID = regionID; + reply.ReplyBlock.RegionHandle = handle; + OutPacket(reply, ThrottleOutPacketType.Land); + } + + public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) + { + ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); + reply.AgentData.AgentID = m_agentId; + reply.Data.ParcelID = parcelID; + reply.Data.OwnerID = land.OwnerID; + reply.Data.Name = Utils.StringToBytes(land.Name); + reply.Data.Desc = Utils.StringToBytes(land.Description); + reply.Data.ActualArea = land.Area; + reply.Data.BillableArea = land.Area; // TODO: what is this? + + // Bit 0: Mature, bit 7: on sale, other bits: no idea + reply.Data.Flags = (byte)( + ((land.Flags & (uint)ParcelFlags.MaturePublish) != 0 ? (1 << 0) : 0) + + ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0)); + + Vector3 pos = land.UserLocation; + if (pos.Equals(Vector3.Zero)) + { + pos = (land.AABBMax + land.AABBMin) * 0.5f; + } + reply.Data.GlobalX = info.RegionLocX * Constants.RegionSize + x; + reply.Data.GlobalY = info.RegionLocY * Constants.RegionSize + y; + reply.Data.GlobalZ = pos.Z; + reply.Data.SimName = Utils.StringToBytes(info.RegionName); + reply.Data.SnapshotID = land.SnapshotID; + reply.Data.Dwell = land.Dwell; + reply.Data.SalePrice = land.SalePrice; + reply.Data.AuctionID = (int)land.AuctionID; + + OutPacket(reply, ThrottleOutPacketType.Land); + } + + public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt) + { + ScriptTeleportRequestPacket packet = (ScriptTeleportRequestPacket)PacketPool.Instance.GetPacket(PacketType.ScriptTeleportRequest); + + packet.Data.ObjectName = Utils.StringToBytes(objName); + packet.Data.SimName = Utils.StringToBytes(simName); + packet.Data.SimPosition = pos; + packet.Data.LookAt = lookAt; + + OutPacket(packet, ThrottleOutPacketType.Task); + } + public void SetClientOption(string option, string value) { switch (option) { - default: - break; + case "ReliableIsImportant": + bool val; + + if (bool.TryParse(value, out val)) + m_PacketHandler.ReliableIsImportant = val; + break; + default: + break; } } @@ -10242,15 +10180,571 @@ namespace OpenSim.Region.ClientStack.LindenUDP { switch (option) { + case "ReliableIsImportant": + return m_PacketHandler.ReliableIsImportant.ToString(); + default: break; } return string.Empty; } + public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data) + { + DirPlacesReplyPacket packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply); + + packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock(); + + packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; + packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); + + packet.QueryReplies = + new DirPlacesReplyPacket.QueryRepliesBlock[data.Length]; + + packet.StatusData = new DirPlacesReplyPacket.StatusDataBlock[ + data.Length]; + + packet.AgentData.AgentID = AgentId; + + packet.QueryData[0].QueryID = queryID; + + int i = 0; + foreach (DirPlacesReplyData d in data) + { + packet.QueryReplies[i] = + new DirPlacesReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirPlacesReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = Utils.StringToBytes(d.name); + packet.QueryReplies[i].ForSale = d.forSale; + packet.QueryReplies[i].Auction = d.auction; + packet.QueryReplies[i].Dwell = d.dwell; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data) + { + DirPeopleReplyPacket packet = (DirPeopleReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPeopleReply); + + packet.AgentData = new DirPeopleReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirPeopleReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirPeopleReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirPeopleReplyData d in data) + { + packet.QueryReplies[i] = new DirPeopleReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].AgentID = d.agentID; + packet.QueryReplies[i].FirstName = + Utils.StringToBytes(d.firstName); + packet.QueryReplies[i].LastName = + Utils.StringToBytes(d.lastName); + packet.QueryReplies[i].Group = + Utils.StringToBytes(d.group); + packet.QueryReplies[i].Online = d.online; + packet.QueryReplies[i].Reputation = d.reputation; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data) + { + DirEventsReplyPacket packet = (DirEventsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirEventsReply); + + packet.AgentData = new DirEventsReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirEventsReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirEventsReplyPacket.QueryRepliesBlock[ + data.Length]; + + packet.StatusData = new DirEventsReplyPacket.StatusDataBlock[ + data.Length]; + + int i = 0; + foreach (DirEventsReplyData d in data) + { + packet.QueryReplies[i] = new DirEventsReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirEventsReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].OwnerID = d.ownerID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].EventID = d.eventID; + packet.QueryReplies[i].Date = + Utils.StringToBytes(d.date); + packet.QueryReplies[i].UnixTime = d.unixTime; + packet.QueryReplies[i].EventFlags = d.eventFlags; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data) + { + DirGroupsReplyPacket packet = (DirGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirGroupsReply); + + packet.AgentData = new DirGroupsReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirGroupsReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirGroupsReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirGroupsReplyData d in data) + { + packet.QueryReplies[i] = new DirGroupsReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].GroupID = d.groupID; + packet.QueryReplies[i].GroupName = + Utils.StringToBytes(d.groupName); + packet.QueryReplies[i].Members = d.members; + packet.QueryReplies[i].SearchOrder = d.searchOrder; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data) + { + DirClassifiedReplyPacket packet = (DirClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirClassifiedReply); + + packet.AgentData = new DirClassifiedReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirClassifiedReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirClassifiedReplyPacket.QueryRepliesBlock[ + data.Length]; + packet.StatusData = new DirClassifiedReplyPacket.StatusDataBlock[ + data.Length]; + + int i = 0; + foreach (DirClassifiedReplyData d in data) + { + packet.QueryReplies[i] = new DirClassifiedReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirClassifiedReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].ClassifiedID = d.classifiedID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].ClassifiedFlags = d.classifiedFlags; + packet.QueryReplies[i].CreationDate = d.creationDate; + packet.QueryReplies[i].ExpirationDate = d.expirationDate; + packet.QueryReplies[i].PriceForListing = d.price; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirLandReply(UUID queryID, DirLandReplyData[] data) + { + DirLandReplyPacket packet = (DirLandReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirLandReply); + + packet.AgentData = new DirLandReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirLandReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirLandReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirLandReplyData d in data) + { + packet.QueryReplies[i] = new DirLandReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].Auction = d.auction; + packet.QueryReplies[i].ForSale = d.forSale; + packet.QueryReplies[i].SalePrice = d.salePrice; + packet.QueryReplies[i].ActualArea = d.actualArea; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data) + { + DirPopularReplyPacket packet = (DirPopularReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPopularReply); + + packet.AgentData = new DirPopularReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirPopularReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirPopularReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirPopularReplyData d in data) + { + packet.QueryReplies[i] = new DirPopularReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].Dwell = d.dwell; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendEventInfoReply(EventData data) + { + EventInfoReplyPacket packet = (EventInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.EventInfoReply); + + packet.AgentData = new EventInfoReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.EventData = new EventInfoReplyPacket.EventDataBlock(); + packet.EventData.EventID = data.eventID; + packet.EventData.Creator = Utils.StringToBytes(data.creator); + packet.EventData.Name = Utils.StringToBytes(data.name); + packet.EventData.Category = Utils.StringToBytes(data.category); + packet.EventData.Desc = Utils.StringToBytes(data.description); + packet.EventData.Date = Utils.StringToBytes(data.date); + packet.EventData.DateUTC = data.dateUTC; + packet.EventData.Duration = data.duration; + packet.EventData.Cover = data.cover; + packet.EventData.Amount = data.amount; + packet.EventData.SimName = Utils.StringToBytes(data.simName); + packet.EventData.GlobalPos = new Vector3d(data.globalPos); + packet.EventData.EventFlags = data.eventFlags; + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags) + { + MapItemReplyPacket mirplk = new MapItemReplyPacket(); + mirplk.AgentData.AgentID = AgentId; + mirplk.RequestData.ItemType = mapitemtype; + mirplk.Data = new MapItemReplyPacket.DataBlock[replies.Length]; + for (int i = 0; i < replies.Length; i++) + { + MapItemReplyPacket.DataBlock mrdata = new MapItemReplyPacket.DataBlock(); + mrdata.X = replies[i].x; + mrdata.Y = replies[i].y; + mrdata.ID = replies[i].id; + mrdata.Extra = replies[i].Extra; + mrdata.Extra2 = replies[i].Extra2; + mrdata.Name = Utils.StringToBytes(replies[i].name); + mirplk.Data[i] = mrdata; + } + //m_log.Debug(mirplk.ToString()); + OutPacket(mirplk, ThrottleOutPacketType.Task); + + } + + public void SendOfferCallingCard(UUID srcID, UUID transactionID) + { + // a bit special, as this uses AgentID to store the source instead + // of the destination. The destination (the receiver) goes into destID + OfferCallingCardPacket p = (OfferCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.OfferCallingCard); + p.AgentData.AgentID = srcID; + p.AgentData.SessionID = UUID.Zero; + p.AgentBlock.DestID = AgentId; + p.AgentBlock.TransactionID = transactionID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAcceptCallingCard(UUID transactionID) + { + AcceptCallingCardPacket p = (AcceptCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.AcceptCallingCard); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = UUID.Zero; + p.FolderData = new AcceptCallingCardPacket.FolderDataBlock[1]; + p.FolderData[0] = new AcceptCallingCardPacket.FolderDataBlock(); + p.FolderData[0].FolderID = UUID.Zero; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendDeclineCallingCard(UUID transactionID) + { + DeclineCallingCardPacket p = (DeclineCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.DeclineCallingCard); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = UUID.Zero; + p.TransactionBlock.TransactionID = transactionID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendTerminateFriend(UUID exFriendID) + { + TerminateFriendshipPacket p = (TerminateFriendshipPacket)PacketPool.Instance.GetPacket(PacketType.TerminateFriendship); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = SessionId; + p.ExBlock.OtherID = exFriendID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) + { + AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); + + p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + p.AgentData.AvatarID = avatarID; + + p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; + int i = 0; + foreach (GroupMembershipData m in data) + { + p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); + p.GroupData[i].GroupPowers = m.GroupPowers; + p.GroupData[i].AcceptNotices = m.AcceptNotices; + p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); + p.GroupData[i].GroupID = m.GroupID; + p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); + p.GroupData[i].GroupInsigniaID = m.GroupPicture; + i++; + } + + p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); + p.NewGroupData.ListInProfile = true; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendJoinGroupReply(UUID groupID, bool success) + { + JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply); + + p.AgentData = new JoinGroupReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + + p.GroupData = new JoinGroupReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + p.GroupData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success) + { + EjectGroupMemberReplyPacket p = (EjectGroupMemberReplyPacket)PacketPool.Instance.GetPacket(PacketType.EjectGroupMemberReply); + + p.AgentData = new EjectGroupMemberReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = agentID; + + p.GroupData = new EjectGroupMemberReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + + p.EjectData = new EjectGroupMemberReplyPacket.EjectDataBlock(); + p.EjectData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendLeaveGroupReply(UUID groupID, bool success) + { + LeaveGroupReplyPacket p = (LeaveGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.LeaveGroupReply); + + p.AgentData = new LeaveGroupReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + + p.GroupData = new LeaveGroupReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + p.GroupData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name) + { + if (classifiedID.Length != name.Length) + return; + + AvatarClassifiedReplyPacket ac = + (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarClassifiedReply); + + ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); + ac.AgentData.AgentID = AgentId; + ac.AgentData.TargetID = targetID; + + ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifiedID.Length]; + int i; + for (i = 0 ; i < classifiedID.Length ; i++) + { + ac.Data[i].ClassifiedID = classifiedID[i]; + ac.Data[i].Name = Utils.StringToBytes(name[i]); + } + + OutPacket(ac, ThrottleOutPacketType.Task); + } + + public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price) + { + ClassifiedInfoReplyPacket cr = + (ClassifiedInfoReplyPacket)PacketPool.Instance.GetPacket( + PacketType.ClassifiedInfoReply); + + cr.AgentData = new ClassifiedInfoReplyPacket.AgentDataBlock(); + cr.AgentData.AgentID = AgentId; + + cr.Data = new ClassifiedInfoReplyPacket.DataBlock(); + cr.Data.ClassifiedID = classifiedID; + cr.Data.CreatorID = creatorID; + cr.Data.CreationDate = creationDate; + cr.Data.ExpirationDate = expirationDate; + cr.Data.Category = category; + cr.Data.Name = Utils.StringToBytes(name); + cr.Data.Desc = Utils.StringToBytes(description); + cr.Data.ParcelID = parcelID; + cr.Data.ParentEstate = parentEstate; + cr.Data.SnapshotID = snapshotID; + cr.Data.SimName = Utils.StringToBytes(simName); + cr.Data.PosGlobal = new Vector3d(globalPos); + cr.Data.ParcelName = Utils.StringToBytes(parcelName); + cr.Data.ClassifiedFlags = classifiedFlags; + cr.Data.PriceForListing = price; + + OutPacket(cr, ThrottleOutPacketType.Task); + } + + public void SendAgentDropGroup(UUID groupID) + { + AgentDropGroupPacket dg = + (AgentDropGroupPacket)PacketPool.Instance.GetPacket( + PacketType.AgentDropGroup); + + dg.AgentData = new AgentDropGroupPacket.AgentDataBlock(); + dg.AgentData.AgentID = AgentId; + dg.AgentData.GroupID = groupID; + + OutPacket(dg, ThrottleOutPacketType.Task); + } + + public void SendAvatarNotesReply(UUID targetID, string text) + { + AvatarNotesReplyPacket an = + (AvatarNotesReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarNotesReply); + + an.AgentData = new AvatarNotesReplyPacket.AgentDataBlock(); + an.AgentData.AgentID = AgentId; + + an.Data = new AvatarNotesReplyPacket.DataBlock(); + an.Data.TargetID = targetID; + an.Data.Notes = Utils.StringToBytes(text); + + OutPacket(an, ThrottleOutPacketType.Task); + } + + public void SendAvatarPicksReply(UUID targetID, Dictionary picks) + { + AvatarPicksReplyPacket ap = + (AvatarPicksReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarPicksReply); + + ap.AgentData = new AvatarPicksReplyPacket.AgentDataBlock(); + ap.AgentData.AgentID = AgentId; + ap.AgentData.TargetID = targetID; + + ap.Data = new AvatarPicksReplyPacket.DataBlock[picks.Count]; + + int i = 0; + foreach (KeyValuePair pick in picks) + { + ap.Data[i] = new AvatarPicksReplyPacket.DataBlock(); + ap.Data[i].PickID = pick.Key; + ap.Data[i].PickName = Utils.StringToBytes(pick.Value); + i++; + } + + OutPacket(ap, ThrottleOutPacketType.Task); + } + + public void SendAvatarClassifiedReply(UUID targetID, Dictionary classifieds) + { + AvatarClassifiedReplyPacket ac = + (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarClassifiedReply); + + ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); + ac.AgentData.AgentID = AgentId; + ac.AgentData.TargetID = targetID; + + ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifieds.Count]; + + int i = 0; + foreach (KeyValuePair classified in classifieds) + { + ac.Data[i] = new AvatarClassifiedReplyPacket.DataBlock(); + ac.Data[i].ClassifiedID = classified.Key; + ac.Data[i].Name = Utils.StringToBytes(classified.Value); + i++; + } + + OutPacket(ac, ThrottleOutPacketType.Task); + } + + public void SendParcelDwellReply(int localID, UUID parcelID, float dwell) + { + ParcelDwellReplyPacket pd = + (ParcelDwellReplyPacket)PacketPool.Instance.GetPacket( + PacketType.ParcelDwellReply); + + pd.AgentData = new ParcelDwellReplyPacket.AgentDataBlock(); + pd.AgentData.AgentID = AgentId; + + pd.Data = new ParcelDwellReplyPacket.DataBlock(); + pd.Data.LocalID = localID; + pd.Data.ParcelID = parcelID; + pd.Data.Dwell = dwell; + + OutPacket(pd, ThrottleOutPacketType.Land); + } + + public void SendUserInfoReply(bool imViaEmail, bool visible, string email) + { + UserInfoReplyPacket ur = + (UserInfoReplyPacket)PacketPool.Instance.GetPacket( + PacketType.UserInfoReply); + + string Visible = "hidden"; + if (visible) + Visible = "default"; + + ur.AgentData = new UserInfoReplyPacket.AgentDataBlock(); + ur.AgentData.AgentID = AgentId; + + ur.UserData = new UserInfoReplyPacket.UserDataBlock(); + ur.UserData.IMViaEMail = imViaEmail; + ur.UserData.DirectoryVisibility = Utils.StringToBytes(Visible); + ur.UserData.EMail = Utils.StringToBytes(email); + + OutPacket(ur, ThrottleOutPacketType.Task); + } + public void KillEndDone() { - m_udpClient.Shutdown(); + KillPacket kp = new KillPacket(); + OutPacket(kp, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); } #region IClientCore @@ -10273,6 +10767,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + protected virtual void RegisterInterfaces() + { + RegisterInterface(this); + RegisterInterface(this); + RegisterInterface(this); + } + public bool TryGet(out T iface) { if (m_clientInterfaces.ContainsKey(typeof(T))) @@ -10320,14 +10821,78 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + public void SendCreateGroupReply(UUID groupID, bool success, string message) + { + CreateGroupReplyPacket createGroupReply = (CreateGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.CreateGroupReply); + + createGroupReply.AgentData = + new CreateGroupReplyPacket.AgentDataBlock(); + createGroupReply.ReplyData = + new CreateGroupReplyPacket.ReplyDataBlock(); + + createGroupReply.AgentData.AgentID = AgentId; + createGroupReply.ReplyData.GroupID = groupID; + + createGroupReply.ReplyData.Success = success; + createGroupReply.ReplyData.Message = Utils.StringToBytes(message); + OutPacket(createGroupReply, ThrottleOutPacketType.Task); + } + + public void SendUseCachedMuteList() + { + UseCachedMuteListPacket useCachedMuteList = (UseCachedMuteListPacket)PacketPool.Instance.GetPacket(PacketType.UseCachedMuteList); + + useCachedMuteList.AgentData = new UseCachedMuteListPacket.AgentDataBlock(); + useCachedMuteList.AgentData.AgentID = AgentId; + + OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); + } + + public void SendMuteListUpdate(string filename) + { + MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); + + muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock(); + muteListUpdate.MuteData.AgentID = AgentId; + muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename); + + OutPacket(muteListUpdate, ThrottleOutPacketType.Task); + } + + public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) + { + PickInfoReplyPacket pickInfoReply = (PickInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.PickInfoReply); + + pickInfoReply.AgentData = new PickInfoReplyPacket.AgentDataBlock(); + pickInfoReply.AgentData.AgentID = AgentId; + + pickInfoReply.Data = new PickInfoReplyPacket.DataBlock(); + pickInfoReply.Data.PickID = pickID; + pickInfoReply.Data.CreatorID = creatorID; + pickInfoReply.Data.TopPick = topPick; + pickInfoReply.Data.ParcelID = parcelID; + pickInfoReply.Data.Name = Utils.StringToBytes(name); + pickInfoReply.Data.Desc = Utils.StringToBytes(desc); + pickInfoReply.Data.SnapshotID = snapshotID; + pickInfoReply.Data.User = Utils.StringToBytes(user); + pickInfoReply.Data.OriginalName = Utils.StringToBytes(originalName); + pickInfoReply.Data.SimName = Utils.StringToBytes(simName); + pickInfoReply.Data.PosGlobal = new Vector3d(posGlobal); + pickInfoReply.Data.SortOrder = sortOrder; + pickInfoReply.Data.Enabled = enabled; + + OutPacket(pickInfoReply, ThrottleOutPacketType.Task); + } + public string Report() { - return m_udpClient.GetStats(); + LLPacketHandler handler = (LLPacketHandler) m_PacketHandler; + return handler.PacketQueue.GetStats(); } public string XReport(string uptime, string version) { - return String.Empty; + return ""; } public void MakeAssetRequest(TransferRequestPacket transferRequest) @@ -10416,6 +10981,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return numPackets; } + #region IClientIPEndpoint Members public IPAddress EndPoint From d33b6fef2b8d3898ab6411df3267d42d18e56d9b Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 7 Oct 2009 04:37:12 +0100 Subject: [PATCH 23/36] replace LLClientView with proper version --- .../ClientStack/LindenUDP/LLClientView.cs | 3236 +++++++---------- 1 file changed, 1335 insertions(+), 1901 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 00527290ad..84e705a91d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -58,526 +58,180 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector { + // LLClientView Only + public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args); + + /// Used to adjust Sun Orbit values so Linden based viewers properly position sun + private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + protected static Dictionary PacketHandlers = new Dictionary(); //Global/static handlers for all clients - /* static variables */ - public static SynchronizeClientHandler SynchronizeClient; - /* private variables */ + private readonly LLUDPServer m_udpServer; + private readonly LLUDPClient m_udpClient; private readonly UUID m_sessionId; - private readonly UUID m_secureSessionId = UUID.Zero; + private readonly UUID m_secureSessionId; + private readonly UUID m_agentId; + private readonly uint m_circuitCode; + private readonly byte[] m_channelVersion = Utils.EmptyBytes; + private readonly Dictionary m_defaultAnimations = new Dictionary(); + private readonly IGroupsModule m_GroupsModule; - private int m_debugPacketLevel; - - //private readonly IAssetCache m_assetCache; private int m_cachedTextureSerial; - private Timer m_clientPingTimer; - private Timer m_avatarTerseUpdateTimer; private List m_avatarTerseUpdates = new List(); - private Timer m_primTerseUpdateTimer; private List m_primTerseUpdates = new List(); private Timer m_primFullUpdateTimer; - private List m_primFullUpdates = - new List(); - - private bool m_clientBlocked; - - private int m_probesWithNoIngressPackets; - - private readonly UUID m_agentId; - private readonly uint m_circuitCode; + private List m_primFullUpdates = new List(); private int m_moneyBalance; - private readonly ILLPacketHandler m_PacketHandler; - private int m_animationSequenceNumber = 1; - - private readonly byte[] m_channelVersion = Utils.StringToBytes("OpenSimulator Server"); // Dummy value needed by libSL - - private readonly Dictionary m_defaultAnimations = new Dictionary(); - private bool m_SendLogoutPacketWhenClosing = true; - - private int m_inPacketsChecked; - - // Used to adjust Sun Orbit values so Linden based viewers properly position sun - private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f; - - - /* protected variables */ - - protected static Dictionary PacketHandlers = - new Dictionary(); //Global/static handlers for all clients + private AgentUpdateArgs lastarg; + private bool m_IsActive = true; protected Dictionary m_packetHandlers = new Dictionary(); protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers - protected IScene m_scene; - - protected LLPacketServer m_networkServer; - protected LLImageManager m_imageManager; - - /* public variables */ protected string m_firstName; protected string m_lastName; protected Thread m_clientThread; protected Vector3 m_startpos; protected EndPoint m_userEndPoint; - protected EndPoint m_proxyEndPoint; protected UUID m_activeGroupID = UUID.Zero; protected string m_activeGroupName = String.Empty; protected ulong m_activeGroupPowers; protected Dictionary m_groupPowers = new Dictionary(); - protected int m_avatarTerseUpdateRate = 50; - protected int m_avatarTerseUpdatesPerPacket = 5; + protected int m_terrainCheckerCount; - // LL uses these limits, apparently. Compressed terse would be - // 23, but we don't have that yet - // + // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet protected int m_primTerseUpdatesPerPacket = 10; protected int m_primFullUpdatesPerPacket = 14; - protected int m_primTerseUpdateRate = 10; protected int m_primFullUpdateRate = 14; - protected int m_textureSendLimit = 20; protected int m_textureDataLimit = 10; - + protected int m_avatarTerseUpdateRate = 50; + protected int m_avatarTerseUpdatesPerPacket = 5; protected int m_packetMTU = 1400; - protected IAssetService m_assetService; - // LLClientView Only - public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args); - - /* Instantiated Designated Event Delegates */ - //- used so we don't create new objects for each incoming packet and then toss it out later */ - - private GenericMessage handlerGenericMessage; - private RequestAvatarProperties handlerRequestAvatarProperties; //OnRequestAvatarProperties; - private UpdateAvatarProperties handlerUpdateAvatarProperties; // OnUpdateAvatarProperties; - private ChatMessage handlerChatFromClient; //OnChatFromClient; - private ChatMessage handlerChatFromClient2; //OnChatFromClient; - private ImprovedInstantMessage handlerInstantMessage; //OnInstantMessage; - private FriendActionDelegate handlerApproveFriendRequest; //OnApproveFriendRequest; - private FriendshipTermination handlerTerminateFriendship; //OnTerminateFriendship; - private RezObject handlerRezObject; //OnRezObject; - private DeRezObject handlerDeRezObject; //OnDeRezObject; - private ModifyTerrain handlerModifyTerrain; - private BakeTerrain handlerBakeTerrain; - private EstateChangeInfo handlerEstateChangeInfo; - private Action handlerRegionHandShakeReply; //OnRegionHandShakeReply; - private GenericCall2 handlerRequestWearables; //OnRequestWearables; - private Action handlerRequestAvatarsData; //OnRequestAvatarsData; - private SetAppearance handlerSetAppearance; //OnSetAppearance; - private AvatarNowWearing handlerAvatarNowWearing; //OnAvatarNowWearing; - private RezSingleAttachmentFromInv handlerRezSingleAttachment; //OnRezSingleAttachmentFromInv; - private RezMultipleAttachmentsFromInv handlerRezMultipleAttachments; //OnRezMultipleAttachmentsFromInv; - private UUIDNameRequest handlerDetachAttachmentIntoInv; // Detach attachment! - private ObjectAttach handlerObjectAttach; //OnObjectAttach; - private SetAlwaysRun handlerSetAlwaysRun; //OnSetAlwaysRun; - private GenericCall2 handlerCompleteMovementToRegion; //OnCompleteMovementToRegion; - private UpdateAgent handlerAgentUpdate; //OnAgentUpdate; - private StartAnim handlerStartAnim; - private StopAnim handlerStopAnim; - private AgentRequestSit handlerAgentRequestSit; //OnAgentRequestSit; - private AgentSit handlerAgentSit; //OnAgentSit; - private AvatarPickerRequest handlerAvatarPickerRequest; //OnAvatarPickerRequest; - private FetchInventory handlerAgentDataUpdateRequest; //OnAgentDataUpdateRequest; - private TeleportLocationRequest handlerSetStartLocationRequest; //OnSetStartLocationRequest; - private TeleportLandmarkRequest handlerTeleportLandmarkRequest; //OnTeleportLandmarkRequest; - private LinkObjects handlerLinkObjects; //OnLinkObjects; - private DelinkObjects handlerDelinkObjects; //OnDelinkObjects; - private AddNewPrim handlerAddPrim; //OnAddPrim; - private UpdateShape handlerUpdatePrimShape; //null; - private ObjectExtraParams handlerUpdateExtraParams; //OnUpdateExtraParams; - private ObjectDuplicate handlerObjectDuplicate; - private ObjectDuplicateOnRay handlerObjectDuplicateOnRay; - private ObjectRequest handlerObjectRequest; - private ObjectSelect handlerObjectSelect; - private ObjectDeselect handlerObjectDeselect; - private ObjectIncludeInSearch handlerObjectIncludeInSearch; - private UpdatePrimFlags handlerUpdatePrimFlags; //OnUpdatePrimFlags; - private UpdatePrimTexture handlerUpdatePrimTexture; - private GrabObject handlerGrabObject; //OnGrabObject; - private MoveObject handlerGrabUpdate; //OnGrabUpdate; - private DeGrabObject handlerDeGrabObject; //OnDeGrabObject; - private SpinStart handlerSpinStart; //OnSpinStart; - private SpinObject handlerSpinUpdate; //OnSpinUpdate; - private SpinStop handlerSpinStop; //OnSpinStop; - private GenericCall7 handlerObjectDescription; - private GenericCall7 handlerObjectName; - private GenericCall7 handlerObjectClickAction; - private GenericCall7 handlerObjectMaterial; - private ObjectPermissions handlerObjectPermissions; - private RequestObjectPropertiesFamily handlerRequestObjectPropertiesFamily; //OnRequestObjectPropertiesFamily; - //private TextureRequest handlerTextureRequest; - private UDPAssetUploadRequest handlerAssetUploadRequest; //OnAssetUploadRequest; - private RequestXfer handlerRequestXfer; //OnRequestXfer; - private XferReceive handlerXferReceive; //OnXferReceive; - private ConfirmXfer handlerConfirmXfer; //OnConfirmXfer; - private AbortXfer handlerAbortXfer; - private CreateInventoryFolder handlerCreateInventoryFolder; //OnCreateNewInventoryFolder; - private UpdateInventoryFolder handlerUpdateInventoryFolder; - private MoveInventoryFolder handlerMoveInventoryFolder; - private CreateNewInventoryItem handlerCreateNewInventoryItem; //OnCreateNewInventoryItem; - private FetchInventory handlerFetchInventory; - private FetchInventoryDescendents handlerFetchInventoryDescendents; //OnFetchInventoryDescendents; - private PurgeInventoryDescendents handlerPurgeInventoryDescendents; //OnPurgeInventoryDescendents; - private UpdateInventoryItem handlerUpdateInventoryItem; - private CopyInventoryItem handlerCopyInventoryItem; - private MoveInventoryItem handlerMoveInventoryItem; - private RemoveInventoryItem handlerRemoveInventoryItem; - private RemoveInventoryFolder handlerRemoveInventoryFolder; - private RequestTaskInventory handlerRequestTaskInventory; //OnRequestTaskInventory; - private UpdateTaskInventory handlerUpdateTaskInventory; //OnUpdateTaskInventory; - private MoveTaskInventory handlerMoveTaskItem; - private RemoveTaskInventory handlerRemoveTaskItem; //OnRemoveTaskItem; - private RezScript handlerRezScript; //OnRezScript; - private RequestMapBlocks handlerRequestMapBlocks; //OnRequestMapBlocks; - private RequestMapName handlerMapNameRequest; //OnMapNameRequest; - private TeleportLocationRequest handlerTeleportLocationRequest; //OnTeleportLocationRequest; - private MoneyBalanceRequest handlerMoneyBalanceRequest; //OnMoneyBalanceRequest; - private UUIDNameRequest handlerNameRequest; - private ParcelAccessListRequest handlerParcelAccessListRequest; //OnParcelAccessListRequest; - private ParcelAccessListUpdateRequest handlerParcelAccessListUpdateRequest; //OnParcelAccessListUpdateRequest; - private ParcelPropertiesRequest handlerParcelPropertiesRequest; //OnParcelPropertiesRequest; - private ParcelDivideRequest handlerParcelDivideRequest; //OnParcelDivideRequest; - private ParcelJoinRequest handlerParcelJoinRequest; //OnParcelJoinRequest; - private ParcelPropertiesUpdateRequest handlerParcelPropertiesUpdateRequest; //OnParcelPropertiesUpdateRequest; - private ParcelSelectObjects handlerParcelSelectObjects; //OnParcelSelectObjects; - private ParcelObjectOwnerRequest handlerParcelObjectOwnerRequest; //OnParcelObjectOwnerRequest; - private ParcelAbandonRequest handlerParcelAbandonRequest; - private ParcelGodForceOwner handlerParcelGodForceOwner; - private ParcelReclaim handlerParcelReclaim; - private RequestTerrain handlerRequestTerrain; - private RequestTerrain handlerUploadTerrain; - private ParcelReturnObjectsRequest handlerParcelReturnObjectsRequest; - private RegionInfoRequest handlerRegionInfoRequest; //OnRegionInfoRequest; - private EstateCovenantRequest handlerEstateCovenantRequest; //OnEstateCovenantRequest; - private RequestGodlikePowers handlerReqGodlikePowers; //OnRequestGodlikePowers; - private GodKickUser handlerGodKickUser; //OnGodKickUser; - private ViewerEffectEventHandler handlerViewerEffect; //OnViewerEffect; - private Action handlerLogout; //OnLogout; - private MoneyTransferRequest handlerMoneyTransferRequest; //OnMoneyTransferRequest; - private ParcelBuy handlerParcelBuy; - private EconomyDataRequest handlerEconomoyDataRequest; - - private UpdateVector handlerUpdatePrimSinglePosition; //OnUpdatePrimSinglePosition; - private UpdatePrimSingleRotation handlerUpdatePrimSingleRotation; //OnUpdatePrimSingleRotation; - private UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition; //OnUpdatePrimSingleRotation; - private UpdateVector handlerUpdatePrimScale; //OnUpdatePrimScale; - private UpdateVector handlerUpdatePrimGroupScale; //OnUpdateGroupScale; - private UpdateVector handlerUpdateVector; //OnUpdatePrimGroupPosition; - private UpdatePrimRotation handlerUpdatePrimRotation; //OnUpdatePrimGroupRotation; - // private UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; //OnUpdatePrimGroupMouseRotation; - // private RequestAsset handlerRequestAsset; // OnRequestAsset; - private UUIDNameRequest handlerTeleportHomeRequest; - - private RegionHandleRequest handlerRegionHandleRequest; // OnRegionHandleRequest - private ParcelInfoRequest handlerParcelInfoRequest; // OnParcelInfoRequest - - private ScriptAnswer handlerScriptAnswer; - private RequestPayPrice handlerRequestPayPrice; - private ObjectSaleInfo handlerObjectSaleInfo; - private ObjectBuy handlerObjectBuy; - //private BuyObjectInventory handlerBuyObjectInventory; - private ObjectDeselect handlerObjectDetach; - private ObjectDrop handlerObjectDrop; - private AgentSit handlerOnUndo; - - private ForceReleaseControls handlerForceReleaseControls; - - private GodLandStatRequest handlerLandStatRequest; - - private UUIDNameRequest handlerUUIDGroupNameRequest; - - private ParcelDeedToGroup handlerParcelDeedToGroup; - - private RequestObjectPropertiesFamily handlerObjectGroupRequest; - private ScriptReset handlerScriptReset; - private GetScriptRunning handlerGetScriptRunning; - private SetScriptRunning handlerSetScriptRunning; - private UpdateVector handlerAutoPilotGo; - //Gesture - private ActivateGesture handlerActivateGesture; - private DeactivateGesture handlerDeactivateGesture; - //Sound - private SoundTrigger handlerSoundTrigger; - private ObjectOwner handlerObjectOwner; - - private DirPlacesQuery handlerDirPlacesQuery; - private DirFindQuery handlerDirFindQuery; - private DirLandQuery handlerDirLandQuery; - private DirPopularQuery handlerDirPopularQuery; - private DirClassifiedQuery handlerDirClassifiedQuery; - private ParcelSetOtherCleanTime handlerParcelSetOtherCleanTime; - - private MapItemRequest handlerMapItemRequest; - - private StartLure handlerStartLure; - private TeleportLureRequest handlerTeleportLureRequest; - - private NetworkStats handlerNetworkStatsUpdate; - - private ClassifiedInfoRequest handlerClassifiedInfoRequest; - private ClassifiedInfoUpdate handlerClassifiedInfoUpdate; - private ClassifiedDelete handlerClassifiedDelete; - private ClassifiedDelete handlerClassifiedGodDelete; - - private EventNotificationAddRequest handlerEventNotificationAddRequest; - private EventNotificationRemoveRequest handlerEventNotificationRemoveRequest; - private EventGodDelete handlerEventGodDelete; - - private ParcelDwellRequest handlerParcelDwellRequest; - - private UserInfoRequest handlerUserInfoRequest; - private UpdateUserInfo handlerUpdateUserInfo; - - private RetrieveInstantMessages handlerRetrieveInstantMessages; - - private PickDelete handlerPickDelete; - private PickGodDelete handlerPickGodDelete; - private PickInfoUpdate handlerPickInfoUpdate; - private AvatarNotesUpdate handlerAvatarNotesUpdate; - - private MuteListRequest handlerMuteListRequest; - - //private AvatarInterestUpdate handlerAvatarInterestUpdate; - - private PlacesQuery handlerPlacesQuery; - - private readonly IGroupsModule m_GroupsModule; - - private AgentUpdateArgs lastarg = null; - - //private TerrainUnacked handlerUnackedTerrain = null; - - //** - - /* Properties */ - - public UUID SecureSessionId - { - get { return m_secureSessionId; } - } - - public IScene Scene - { - get { return m_scene; } - } - - public UUID SessionId - { - get { return m_sessionId; } - } + #region Properties + public UUID SecureSessionId { get { return m_secureSessionId; } } + public IScene Scene { get { return m_scene; } } + public UUID SessionId { get { return m_sessionId; } } public Vector3 StartPos { get { return m_startpos; } set { m_startpos = value; } } - - public UUID AgentId - { - get { return m_agentId; } - } - - public UUID ActiveGroupId - { - get { return m_activeGroupID; } - } - - public string ActiveGroupName - { - get { return m_activeGroupName; } - } - - public ulong ActiveGroupPowers - { - get { return m_activeGroupPowers; } - } - - public bool IsGroupMember(UUID groupID) - { - return m_groupPowers.ContainsKey(groupID); - } - - public ulong GetGroupPowers(UUID groupID) - { - if (groupID == m_activeGroupID) - return m_activeGroupPowers; - - if (m_groupPowers.ContainsKey(groupID)) - return m_groupPowers[groupID]; - - return 0; - } - - /// - /// This is a utility method used by single states to not duplicate kicks and blue card of death messages. - /// - public bool ChildAgentStatus() - { - return m_scene.PresenceChildStatus(AgentId); - } - + public UUID AgentId { get { return m_agentId; } } + public UUID ActiveGroupId { get { return m_activeGroupID; } } + public string ActiveGroupName { get { return m_activeGroupName; } } + public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } + public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } /// /// First name of the agent/avatar represented by the client /// - public string FirstName - { - get { return m_firstName; } - } - + public string FirstName { get { return m_firstName; } } /// /// Last name of the agent/avatar represented by the client /// - public string LastName - { - get { return m_lastName; } - } - + public string LastName { get { return m_lastName; } } /// /// Full name of the client (first name and last name) /// - public string Name - { - get { return FirstName + " " + LastName; } - } - - public uint CircuitCode - { - get { return m_circuitCode; } - } - - public int MoneyBalance - { - get { return m_moneyBalance; } - } - - public int NextAnimationSequenceNumber - { - get { return m_animationSequenceNumber++; } - } - - public ILLPacketHandler PacketHandler - { - get { return m_PacketHandler; } - } - - bool m_IsActive = true; - + public string Name { get { return FirstName + " " + LastName; } } + public uint CircuitCode { get { return m_circuitCode; } } + public int MoneyBalance { get { return m_moneyBalance; } } + public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } public bool IsActive { get { return m_IsActive; } set { m_IsActive = value; } } + public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } - public bool SendLogoutPacketWhenClosing - { - set { m_SendLogoutPacketWhenClosing = value; } - } - - /* METHODS */ + #endregion Properties /// /// Constructor /// - public LLClientView( - EndPoint remoteEP, IScene scene, LLPacketServer packServer, - AuthenticateResponse sessionInfo, UUID agentId, UUID sessionId, uint circuitCode, EndPoint proxyEP, - ClientStackUserSettings userSettings) + public LLClientView(EndPoint remoteEP, IScene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, + UUID agentId, UUID sessionId, uint circuitCode) { - // Should be called first? - RegisterInterfaces(); - - m_GroupsModule = scene.RequestModuleInterface(); - m_moneyBalance = 1000; - - m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); - + RegisterInterface(this); + RegisterInterface(this); + RegisterInterface(this); + InitDefaultAnimations(); m_scene = scene; - //m_assetCache = assetCache; - m_assetService = m_scene.RequestModuleInterface(); - - m_networkServer = packServer; - + m_GroupsModule = scene.RequestModuleInterface(); + m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface()); + m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); m_agentId = agentId; m_sessionId = sessionId; + m_secureSessionId = sessionInfo.LoginInfo.SecureSession; m_circuitCode = circuitCode; - m_userEndPoint = remoteEP; - m_proxyEndPoint = proxyEP; - m_firstName = sessionInfo.LoginInfo.First; m_lastName = sessionInfo.LoginInfo.Last; m_startpos = sessionInfo.LoginInfo.StartPos; + m_moneyBalance = 1000; - if (sessionInfo.LoginInfo.SecureSession != UUID.Zero) - { - m_secureSessionId = sessionInfo.LoginInfo.SecureSession; - } - - // While working on this, the BlockingQueue had me fooled for a bit. - // The Blocking queue causes the thread to stop until there's something - // in it to process. It's an on-purpose threadlock though because - // without it, the clientloop will suck up all sim resources. - - m_PacketHandler = new LLPacketHandler(this, m_networkServer, userSettings); - m_PacketHandler.SynchronizeClient = SynchronizeClient; - m_PacketHandler.OnPacketStats += PopulateStats; - m_PacketHandler.OnQueueEmpty += HandleQueueEmpty; - - if (scene.Config != null) - { - IConfig clientConfig = scene.Config.Configs["LLClient"]; - if (clientConfig != null) - { - m_PacketHandler.ReliableIsImportant = - clientConfig.GetBoolean("ReliableIsImportant", - false); - m_PacketHandler.MaxReliableResends = clientConfig.GetInt("MaxReliableResends", - m_PacketHandler.MaxReliableResends); - m_primTerseUpdatesPerPacket = clientConfig.GetInt("TerseUpdatesPerPacket", - m_primTerseUpdatesPerPacket); - m_primFullUpdatesPerPacket = clientConfig.GetInt("FullUpdatesPerPacket", - m_primFullUpdatesPerPacket); - - m_primTerseUpdateRate = clientConfig.GetInt("TerseUpdateRate", - m_primTerseUpdateRate); - m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", - m_primFullUpdateRate); - - m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", - m_textureSendLimit); - - m_textureDataLimit = clientConfig.GetInt("TextureDataLimit", - m_textureDataLimit); - - m_packetMTU = clientConfig.GetInt("PacketMTU", 1400); - } - } + m_udpServer = udpServer; + m_udpClient = udpClient; + m_udpClient.OnQueueEmpty += HandleQueueEmpty; + m_udpClient.OnPacketStats += PopulateStats; RegisterLocalPacketHandlers(); - m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface()); } - public void SetDebugPacketLevel(int newDebugPacketLevel) + public void SetDebugPacketLevel(int newDebug) { - m_debugPacketLevel = newDebugPacketLevel; } - # region Client Methods + #region Client Methods + + /// + /// Close down the client view. This *must* be the last method called, since the last # + /// statement of CloseCleanup() aborts the thread. + /// + /// + public void Close(bool shutdownCircuit) + { + m_log.DebugFormat( + "[CLIENT]: Close has been called with shutdownCircuit = {0} for {1} attached to scene {2}", + shutdownCircuit, Name, m_scene.RegionInfo.RegionName); + + if (m_imageManager != null) + m_imageManager.Close(); + + if (m_udpServer != null) + m_udpServer.Flush(); + + // raise an event on the packet server to Shutdown the circuit + // Now, if we raise the event then the packet server will call this method itself, so don't try cleanup + // here otherwise we'll end up calling it twice. + // FIXME: In truth, I might be wrong but this whole business of calling this method twice (with different args) looks + // horribly tangly. Hopefully it should be possible to greatly simplify it. + if (shutdownCircuit) + { + if (OnConnectionClosed != null) + OnConnectionClosed(this); + } + else + { + CloseCleanup(shutdownCircuit); + } + } private void CloseCleanup(bool shutdownCircuit) { - - m_scene.RemoveClient(AgentId); //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); @@ -590,9 +244,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP Thread.Sleep(2000); // Shut down timers. Thread Context of this method is murky. Lock all timers - if (m_clientPingTimer.Enabled) - lock (m_clientPingTimer) - m_clientPingTimer.Stop(); if (m_avatarTerseUpdateTimer.Enabled) lock (m_avatarTerseUpdateTimer) m_avatarTerseUpdateTimer.Stop(); @@ -625,43 +276,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP // of the client thread regardless of where Close() is called. KillEndDone(); } - - Terminate(); - } - /// - /// Close down the client view. This *must* be the last method called, since the last # - /// statement of CloseCleanup() aborts the thread. - /// - /// - public void Close(bool shutdownCircuit) - { - m_clientPingTimer.Enabled = false; + IsActive = false; - m_log.DebugFormat( - "[CLIENT]: Close has been called with shutdownCircuit = {0} for {1} attached to scene {2}", - shutdownCircuit, Name, m_scene.RegionInfo.RegionName); + m_avatarTerseUpdateTimer.Close(); + m_primTerseUpdateTimer.Close(); + m_primFullUpdateTimer.Close(); - if (m_imageManager != null) - m_imageManager.Close(); + //m_udpServer.OnPacketStats -= PopulateStats; + m_udpClient.Shutdown(); - if (m_PacketHandler != null) - m_PacketHandler.Flush(); + // wait for thread stoped + // m_clientThread.Join(); - // raise an event on the packet server to Shutdown the circuit - // Now, if we raise the event then the packet server will call this method itself, so don't try cleanup - // here otherwise we'll end up calling it twice. - // FIXME: In truth, I might be wrong but this whole business of calling this method twice (with different args) looks - // horribly tangly. Hopefully it should be possible to greatly simplify it. - if (shutdownCircuit) - { - if (OnConnectionClosed != null) - OnConnectionClosed(this); - } - else - { - CloseCleanup(shutdownCircuit); - } + // delete circuit code + //m_networkServer.CloseClient(this); } public void Kick(string message) @@ -683,10 +312,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void Stop() { // Shut down timers. Thread Context is Murky, lock all timers! - if (m_clientPingTimer.Enabled) - lock (m_clientPingTimer) - m_clientPingTimer.Stop(); - if (m_avatarTerseUpdateTimer.Enabled) lock (m_avatarTerseUpdateTimer) m_avatarTerseUpdateTimer.Stop(); @@ -700,54 +325,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdateTimer.Stop(); } - public void Restart() - { - // re-construct - m_PacketHandler.Clear(); + #endregion Client Methods - m_clientPingTimer = new Timer(5000); - m_clientPingTimer.Elapsed += CheckClientConnectivity; - m_clientPingTimer.Enabled = true; - - m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); - m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); - m_avatarTerseUpdateTimer.AutoReset = false; - - m_primTerseUpdateTimer = new Timer(m_primTerseUpdateRate); - m_primTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimTerseUpdates); - m_primTerseUpdateTimer.AutoReset = false; - - m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); - m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); - m_primFullUpdateTimer.AutoReset = false; - } - - private void Terminate() - { - IsActive = false; - - m_clientPingTimer.Close(); - m_avatarTerseUpdateTimer.Close(); - m_primTerseUpdateTimer.Close(); - m_primFullUpdateTimer.Close(); - - m_PacketHandler.OnPacketStats -= PopulateStats; - m_PacketHandler.Dispose(); - - // wait for thread stoped - // m_clientThread.Join(); - - // delete circuit code - //m_networkServer.CloseClient(this); - } - - #endregion - - # region Packet Handling + #region Packet Handling public void PopulateStats(int inPackets, int outPackets, int unAckedBytes) { - handlerNetworkStatsUpdate = OnNetworkStatsUpdate; + NetworkStats handlerNetworkStatsUpdate = OnNetworkStatsUpdate; if (handlerNetworkStatsUpdate != null) { handlerNetworkStatsUpdate(inPackets, outPackets, unAckedBytes); @@ -828,7 +412,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return result; } - protected void DebugPacket(string direction, Packet packet) + /*protected void DebugPacket(string direction, Packet packet) { string info; @@ -854,88 +438,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP } Console.WriteLine(m_circuitCode + ":" + direction + ": " + info); - } + }*/ - /// - /// Main packet processing loop for the UDP component of the client session. Both incoming and outgoing - /// packets are processed here. - /// - protected virtual void ClientLoop() - { - m_log.DebugFormat( - "[CLIENT]: Entered main packet processing loop for {0} in {1}", Name, Scene.RegionInfo.RegionName); - - while (IsActive) - { - LLQueItem nextPacket = m_PacketHandler.PacketQueue.Dequeue(); - - if (nextPacket == null) { - m_log.DebugFormat("[CLIENT]: PacketQueue return null LLQueItem"); - continue; - } - - if (nextPacket.Incoming) - { - if (m_debugPacketLevel > 0) - DebugPacket("IN", nextPacket.Packet); - m_PacketHandler.ProcessInPacket(nextPacket); - } - else - { - if (m_debugPacketLevel > 0) - DebugPacket("OUT", nextPacket.Packet); - m_PacketHandler.ProcessOutPacket(nextPacket); - } - } - } - - # endregion - - protected int m_terrainCheckerCount; - - /// - /// Event handler for check client timer - /// Checks to ensure that the client is still connected. If the client has failed to respond to many pings - /// in succession then close down the connection. - /// - /// - /// - protected void CheckClientConnectivity(object sender, ElapsedEventArgs e) - { - if (m_PacketHandler.PacketsReceived == m_inPacketsChecked) - { - // no packet came in since the last time we checked... - - m_probesWithNoIngressPackets++; - if ((m_probesWithNoIngressPackets > 30 && !m_clientBlocked) // agent active - || (m_probesWithNoIngressPackets > 90 && m_clientBlocked)) // agent paused - { - m_clientPingTimer.Enabled = false; - - m_log.WarnFormat( - "[CLIENT]: Client for agent {0} {1} has stopped responding to pings. Closing connection", - Name, AgentId); - - if (OnConnectionClosed != null) - { - OnConnectionClosed(this); - } - } - else - { - // this will normally trigger at least one packet (ping response) - SendStartPingCheck(0); - } - } - else - { - // Something received in the meantime - we can reset the counters - m_probesWithNoIngressPackets = 0; - // ... and store the current number of packets received to find out if another one got in on the next cycle - m_inPacketsChecked = m_PacketHandler.PacketsReceived; - } - - } + #endregion Packet Handling # region Setup @@ -945,13 +450,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// protected virtual void InitNewClient() { - //this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache); - - // Ping the client regularly to check that it's still there - m_clientPingTimer = new Timer(5000); - m_clientPingTimer.Elapsed += CheckClientConnectivity; - m_clientPingTimer.Enabled = true; - m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); m_avatarTerseUpdateTimer.AutoReset = false; @@ -971,27 +469,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void Start() { - m_clientThread = new Thread(RunUserSession); - m_clientThread.Name = "ClientThread"; - m_clientThread.IsBackground = true; - m_clientThread.Start(); - ThreadTracker.Add(m_clientThread); + // This sets up all the timers + InitNewClient(); } /// /// Run a user session. This method lies at the base of the entire client thread. /// - protected virtual void RunUserSession() + protected void RunUserSession() { - //tell this thread we are using the culture set up for the sim (currently hardcoded to en_US) - //otherwise it will override this and use the system default - Culture.SetCurrentCulture(); - try { - // This sets up all the timers - InitNewClient(); - ClientLoop(); + } catch (Exception e) { @@ -1015,11 +504,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP + "Any further actions taken will not be processed.\n" + "Please relog", true); - LLQueItem item = new LLQueItem(); - item.Packet = packet; - item.Sequence = packet.Header.Sequence; - - m_PacketHandler.ProcessOutPacket(item); + m_udpServer.SendPacket(m_agentId, packet, ThrottleOutPacketType.Unknown, false); // There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to // listeners yet, though. @@ -1037,7 +522,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP # endregion - // Previously ClientView.API partial class + #region Events + public event GenericMessage OnGenericMessage; public event BinaryGenericMessage OnBinaryGenericMessage; public event Action OnLogout; @@ -1197,13 +683,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event GetScriptRunning OnGetScriptRunning; public event SetScriptRunning OnSetScriptRunning; public event UpdateVector OnAutoPilotGo; - public event TerrainUnacked OnUnackedTerrain; - public event ActivateGesture OnActivateGesture; public event DeactivateGesture OnDeactivateGesture; public event ObjectOwner OnObjectOwner; - public event DirPlacesQuery OnDirPlacesQuery; public event DirFindQuery OnDirFindQuery; public event DirLandQuery OnDirLandQuery; @@ -1211,45 +694,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event DirClassifiedQuery OnDirClassifiedQuery; public event EventInfoRequest OnEventInfoRequest; public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime; - public event MapItemRequest OnMapItemRequest; - public event OfferCallingCard OnOfferCallingCard; public event AcceptCallingCard OnAcceptCallingCard; public event DeclineCallingCard OnDeclineCallingCard; public event SoundTrigger OnSoundTrigger; - public event StartLure OnStartLure; public event TeleportLureRequest OnTeleportLureRequest; public event NetworkStats OnNetworkStatsUpdate; - public event ClassifiedInfoRequest OnClassifiedInfoRequest; public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; public event ClassifiedDelete OnClassifiedDelete; public event ClassifiedDelete OnClassifiedGodDelete; - public event EventNotificationAddRequest OnEventNotificationAddRequest; public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; public event EventGodDelete OnEventGodDelete; - public event ParcelDwellRequest OnParcelDwellRequest; - public event UserInfoRequest OnUserInfoRequest; public event UpdateUserInfo OnUpdateUserInfo; - public event RetrieveInstantMessages OnRetrieveInstantMessages; - public event PickDelete OnPickDelete; public event PickGodDelete OnPickGodDelete; public event PickInfoUpdate OnPickInfoUpdate; public event AvatarNotesUpdate OnAvatarNotesUpdate; - public event MuteListRequest OnMuteListRequest; - - //public event AvatarInterestUpdate OnAvatarInterestUpdate; - + public event AvatarInterestUpdate OnAvatarInterestUpdate; public event PlacesQuery OnPlacesQuery; + #endregion Events + public void ActivateGesture(UUID assetId, UUID gestureId) { } @@ -1850,8 +1323,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendStartPingCheck(byte seq) { StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); - pc.PingID.PingID = seq; pc.Header.Reliable = false; + + OutgoingPacket oldestPacket = m_udpClient.NeedAcks.GetOldest(); + + pc.PingID.PingID = seq; + pc.PingID.OldestUnacked = (oldestPacket != null) ? oldestPacket.SequenceNumber : 0; + OutPacket(pc, ThrottleOutPacketType.Unknown); } @@ -1927,12 +1405,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP descend.ItemData[i].AssetID = item.AssetID; descend.ItemData[i].CreatorID = item.CreatorIdAsUuid; descend.ItemData[i].BaseMask = item.BasePermissions; - descend.ItemData[i].Description = LLUtil.StringToPacketBytes(item.Description); + descend.ItemData[i].Description = Util.StringToBytes256(item.Description); descend.ItemData[i].EveryoneMask = item.EveryOnePermissions; descend.ItemData[i].OwnerMask = item.CurrentPermissions; descend.ItemData[i].FolderID = item.Folder; descend.ItemData[i].InvType = (sbyte)item.InvType; - descend.ItemData[i].Name = LLUtil.StringToPacketBytes(item.Name); + descend.ItemData[i].Name = Util.StringToBytes256(item.Name); descend.ItemData[i].NextOwnerMask = item.NextPermissions; descend.ItemData[i].OwnerID = item.Owner; descend.ItemData[i].Type = (sbyte)item.AssetType; @@ -2013,7 +1491,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { descend.FolderData[i] = new InventoryDescendentsPacket.FolderDataBlock(); descend.FolderData[i].FolderID = folder.ID; - descend.FolderData[i].Name = LLUtil.StringToPacketBytes(folder.Name); + descend.FolderData[i].Name = Util.StringToBytes256(folder.Name); descend.FolderData[i].ParentID = folder.ParentID; descend.FolderData[i].Type = (sbyte)folder.Type; @@ -2128,11 +1606,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP inventoryReply.InventoryData[0].BaseMask = item.BasePermissions; inventoryReply.InventoryData[0].CreationDate = item.CreationDate; - inventoryReply.InventoryData[0].Description = LLUtil.StringToPacketBytes(item.Description); + inventoryReply.InventoryData[0].Description = Util.StringToBytes256(item.Description); inventoryReply.InventoryData[0].EveryoneMask = item.EveryOnePermissions; inventoryReply.InventoryData[0].FolderID = item.Folder; inventoryReply.InventoryData[0].InvType = (sbyte)item.InvType; - inventoryReply.InventoryData[0].Name = LLUtil.StringToPacketBytes(item.Name); + inventoryReply.InventoryData[0].Name = Util.StringToBytes256(item.Name); inventoryReply.InventoryData[0].NextOwnerMask = item.NextPermissions; inventoryReply.InventoryData[0].OwnerID = item.Owner; inventoryReply.InventoryData[0].OwnerMask = item.CurrentPermissions; @@ -2257,7 +1735,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP folderBlock.FolderID = folder.ID; folderBlock.ParentID = folder.ParentID; folderBlock.Type = -1; - folderBlock.Name = LLUtil.StringToPacketBytes(folder.Name); + folderBlock.Name = Util.StringToBytes256(folder.Name); return folderBlock; } @@ -2275,11 +1753,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP itemBlock.AssetID = item.AssetID; itemBlock.CreatorID = item.CreatorIdAsUuid; itemBlock.BaseMask = item.BasePermissions; - itemBlock.Description = LLUtil.StringToPacketBytes(item.Description); + itemBlock.Description = Util.StringToBytes256(item.Description); itemBlock.EveryoneMask = item.EveryOnePermissions; itemBlock.FolderID = item.Folder; itemBlock.InvType = (sbyte)item.InvType; - itemBlock.Name = LLUtil.StringToPacketBytes(item.Name); + itemBlock.Name = Util.StringToBytes256(item.Name); itemBlock.NextOwnerMask = item.NextPermissions; itemBlock.OwnerID = item.Owner; itemBlock.OwnerMask = item.CurrentPermissions; @@ -2339,11 +1817,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP bulkUpdate.ItemData[0].CreatorID = item.CreatorIdAsUuid; bulkUpdate.ItemData[0].BaseMask = item.BasePermissions; bulkUpdate.ItemData[0].CreationDate = item.CreationDate; - bulkUpdate.ItemData[0].Description = LLUtil.StringToPacketBytes(item.Description); + bulkUpdate.ItemData[0].Description = Util.StringToBytes256(item.Description); bulkUpdate.ItemData[0].EveryoneMask = item.EveryOnePermissions; bulkUpdate.ItemData[0].FolderID = item.Folder; bulkUpdate.ItemData[0].InvType = (sbyte)item.InvType; - bulkUpdate.ItemData[0].Name = LLUtil.StringToPacketBytes(item.Name); + bulkUpdate.ItemData[0].Name = Util.StringToBytes256(item.Name); bulkUpdate.ItemData[0].NextOwnerMask = item.NextPermissions; bulkUpdate.ItemData[0].OwnerID = item.Owner; bulkUpdate.ItemData[0].OwnerMask = item.CurrentPermissions; @@ -2386,11 +1864,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP InventoryReply.InventoryData[0].AssetID = Item.AssetID; InventoryReply.InventoryData[0].CreatorID = Item.CreatorIdAsUuid; InventoryReply.InventoryData[0].BaseMask = Item.BasePermissions; - InventoryReply.InventoryData[0].Description = LLUtil.StringToPacketBytes(Item.Description); + InventoryReply.InventoryData[0].Description = Util.StringToBytes256(Item.Description); InventoryReply.InventoryData[0].EveryoneMask = Item.EveryOnePermissions; InventoryReply.InventoryData[0].FolderID = Item.Folder; InventoryReply.InventoryData[0].InvType = (sbyte)Item.InvType; - InventoryReply.InventoryData[0].Name = LLUtil.StringToPacketBytes(Item.Name); + InventoryReply.InventoryData[0].Name = Util.StringToBytes256(Item.Name); InventoryReply.InventoryData[0].NextOwnerMask = Item.NextPermissions; InventoryReply.InventoryData[0].OwnerID = Item.Owner; InventoryReply.InventoryData[0].OwnerMask = Item.CurrentPermissions; @@ -2557,7 +2035,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// /// - protected AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) + public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) { AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); alertPack.AgentData.AgentID = AgentId; @@ -2768,7 +2246,953 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(avatarReply, ThrottleOutPacketType.Task); } - #endregion + /// + /// Send the client an Estate message blue box pop-down with a single OK button + /// + /// + /// + /// + /// + public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message) + { + if (!ChildAgentStatus()) + SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3())); + + //SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch()); + } + + public void SendLogoutPacket() + { + // I know this is a bit of a hack, however there are times when you don't + // want to send this, but still need to do the rest of the shutdown process + // this method gets called from the packet server.. which makes it practically + // impossible to do any other way. + + if (m_SendLogoutPacketWhenClosing) + { + LogoutReplyPacket logReply = (LogoutReplyPacket)PacketPool.Instance.GetPacket(PacketType.LogoutReply); + // TODO: don't create new blocks if recycling an old packet + logReply.AgentData.AgentID = AgentId; + logReply.AgentData.SessionID = SessionId; + logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; + logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); + logReply.InventoryData[0].ItemID = UUID.Zero; + + OutPacket(logReply, ThrottleOutPacketType.Task); + } + } + + public void SendHealth(float health) + { + HealthMessagePacket healthpacket = (HealthMessagePacket)PacketPool.Instance.GetPacket(PacketType.HealthMessage); + healthpacket.HealthData.Health = health; + OutPacket(healthpacket, ThrottleOutPacketType.Task); + } + + public void SendAgentOnline(UUID[] agentIDs) + { + OnlineNotificationPacket onp = new OnlineNotificationPacket(); + OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length]; + for (int i = 0; i < agentIDs.Length; i++) + { + OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); + onpbl.AgentID = agentIDs[i]; + onpb[i] = onpbl; + } + onp.AgentBlock = onpb; + onp.Header.Reliable = true; + OutPacket(onp, ThrottleOutPacketType.Task); + } + + public void SendAgentOffline(UUID[] agentIDs) + { + OfflineNotificationPacket offp = new OfflineNotificationPacket(); + OfflineNotificationPacket.AgentBlockBlock[] offpb = new OfflineNotificationPacket.AgentBlockBlock[agentIDs.Length]; + for (int i = 0; i < agentIDs.Length; i++) + { + OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); + onpbl.AgentID = agentIDs[i]; + offpb[i] = onpbl; + } + offp.AgentBlock = offpb; + offp.Header.Reliable = true; + OutPacket(offp, ThrottleOutPacketType.Task); + } + + public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, + Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) + { + AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); + avatarSitResponse.SitObject.ID = TargetID; + if (CameraAtOffset != Vector3.Zero) + { + avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset; + avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset; + } + avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook; + avatarSitResponse.SitTransform.AutoPilot = autopilot; + avatarSitResponse.SitTransform.SitPosition = OffsetPos; + avatarSitResponse.SitTransform.SitRotation = SitOrientation; + + OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); + } + + public void SendAdminResponse(UUID Token, uint AdminLevel) + { + GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket(); + GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock(); + GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock(); + + adb.AgentID = AgentId; + adb.SessionID = SessionId; // More security + gdb.GodLevel = (byte)AdminLevel; + gdb.Token = Token; + //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock; + respondPacket.GrantData = gdb; + respondPacket.AgentData = adb; + OutPacket(respondPacket, ThrottleOutPacketType.Task); + } + + public void SendGroupMembership(GroupMembershipData[] GroupMembership) + { + m_groupPowers.Clear(); + + AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket(); + AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[GroupMembership.Length]; + for (int i = 0; i < GroupMembership.Length; i++) + { + m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; + + AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock(); + Group.AcceptNotices = GroupMembership[i].AcceptNotices; + Group.Contribution = GroupMembership[i].Contribution; + Group.GroupID = GroupMembership[i].GroupID; + Group.GroupInsigniaID = GroupMembership[i].GroupPicture; + Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); + Group.GroupPowers = GroupMembership[i].GroupPowers; + Groups[i] = Group; + + + } + Groupupdate.GroupData = Groups; + Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock(); + Groupupdate.AgentData.AgentID = AgentId; + OutPacket(Groupupdate, ThrottleOutPacketType.Task); + + try + { + IEventQueue eq = Scene.RequestModuleInterface(); + if (eq != null) + { + eq.GroupMembership(Groupupdate, this.AgentId); + } + } + catch (Exception ex) + { + m_log.Error("Unable to send group membership data via eventqueue - exception: " + ex.ToString()); + m_log.Warn("sending group membership data via UDP"); + OutPacket(Groupupdate, ThrottleOutPacketType.Task); + } + } + + + public void SendGroupNameReply(UUID groupLLUID, string GroupName) + { + UUIDGroupNameReplyPacket pack = new UUIDGroupNameReplyPacket(); + UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; + UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); + uidnamebloc.ID = groupLLUID; + uidnamebloc.GroupName = Utils.StringToBytes(GroupName); + uidnameblock[0] = uidnamebloc; + pack.UUIDNameBlock = uidnameblock; + OutPacket(pack, ThrottleOutPacketType.Task); + } + + public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia) + { + LandStatReplyPacket lsrp = new LandStatReplyPacket(); + // LandStatReplyPacket.RequestDataBlock lsreqdpb = new LandStatReplyPacket.RequestDataBlock(); + LandStatReplyPacket.ReportDataBlock[] lsrepdba = new LandStatReplyPacket.ReportDataBlock[lsrpia.Length]; + //LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); + // lsrepdb. + lsrp.RequestData.ReportType = reportType; + lsrp.RequestData.RequestFlags = requestFlags; + lsrp.RequestData.TotalObjectCount = resultCount; + for (int i = 0; i < lsrpia.Length; i++) + { + LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); + lsrepdb.LocationX = lsrpia[i].LocationX; + lsrepdb.LocationY = lsrpia[i].LocationY; + lsrepdb.LocationZ = lsrpia[i].LocationZ; + lsrepdb.Score = lsrpia[i].Score; + lsrepdb.TaskID = lsrpia[i].TaskID; + lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; + lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); + lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); + lsrepdba[i] = lsrepdb; + } + lsrp.ReportData = lsrepdba; + OutPacket(lsrp, ThrottleOutPacketType.Task); + } + + public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running) + { + ScriptRunningReplyPacket scriptRunningReply = new ScriptRunningReplyPacket(); + scriptRunningReply.Script.ObjectID = objectID; + scriptRunningReply.Script.ItemID = itemID; + scriptRunningReply.Script.Running = running; + + OutPacket(scriptRunningReply, ThrottleOutPacketType.Task); + } + + public void SendAsset(AssetRequestToClient req) + { + //m_log.Debug("sending asset " + req.RequestAssetID); + TransferInfoPacket Transfer = new TransferInfoPacket(); + Transfer.TransferInfo.ChannelType = 2; + Transfer.TransferInfo.Status = 0; + Transfer.TransferInfo.TargetType = 0; + if (req.AssetRequestSource == 2) + { + Transfer.TransferInfo.Params = new byte[20]; + Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + int assType = req.AssetInf.Type; + Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); + } + else if (req.AssetRequestSource == 3) + { + Transfer.TransferInfo.Params = req.Params; + // Transfer.TransferInfo.Params = new byte[100]; + //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); + } + Transfer.TransferInfo.Size = req.AssetInf.Data.Length; + Transfer.TransferInfo.TransferID = req.TransferRequestID; + Transfer.Header.Zerocoded = true; + OutPacket(Transfer, ThrottleOutPacketType.Asset); + + if (req.NumPackets == 1) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = 0; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + TransferPacket.TransferData.Data = req.AssetInf.Data; + TransferPacket.TransferData.Status = 1; + TransferPacket.Header.Zerocoded = true; + OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + } + else + { + int processedLength = 0; + int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; + int packetNumber = 0; + + while (processedLength < req.AssetInf.Data.Length) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = packetNumber; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + + int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); + byte[] chunk = new byte[chunkSize]; + Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); + + TransferPacket.TransferData.Data = chunk; + + // 0 indicates more packets to come, 1 indicates last packet + if (req.AssetInf.Data.Length - processedLength > maxChunkSize) + { + TransferPacket.TransferData.Status = 0; + } + else + { + TransferPacket.TransferData.Status = 1; + } + TransferPacket.Header.Zerocoded = true; + OutPacket(TransferPacket, ThrottleOutPacketType.Asset); + + processedLength += chunkSize; + packetNumber++; + } + } + } + + public void SendTexture(AssetBase TextureAsset) + { + + } + + public void SendRegionHandle(UUID regionID, ulong handle) + { + RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply); + reply.ReplyBlock.RegionID = regionID; + reply.ReplyBlock.RegionHandle = handle; + OutPacket(reply, ThrottleOutPacketType.Land); + } + + public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) + { + ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); + reply.AgentData.AgentID = m_agentId; + reply.Data.ParcelID = parcelID; + reply.Data.OwnerID = land.OwnerID; + reply.Data.Name = Utils.StringToBytes(land.Name); + reply.Data.Desc = Utils.StringToBytes(land.Description); + reply.Data.ActualArea = land.Area; + reply.Data.BillableArea = land.Area; // TODO: what is this? + + // Bit 0: Mature, bit 7: on sale, other bits: no idea + reply.Data.Flags = (byte)( + ((land.Flags & (uint)ParcelFlags.MaturePublish) != 0 ? (1 << 0) : 0) + + ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0)); + + Vector3 pos = land.UserLocation; + if (pos.Equals(Vector3.Zero)) + { + pos = (land.AABBMax + land.AABBMin) * 0.5f; + } + reply.Data.GlobalX = info.RegionLocX * Constants.RegionSize + x; + reply.Data.GlobalY = info.RegionLocY * Constants.RegionSize + y; + reply.Data.GlobalZ = pos.Z; + reply.Data.SimName = Utils.StringToBytes(info.RegionName); + reply.Data.SnapshotID = land.SnapshotID; + reply.Data.Dwell = land.Dwell; + reply.Data.SalePrice = land.SalePrice; + reply.Data.AuctionID = (int)land.AuctionID; + + OutPacket(reply, ThrottleOutPacketType.Land); + } + + public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt) + { + ScriptTeleportRequestPacket packet = (ScriptTeleportRequestPacket)PacketPool.Instance.GetPacket(PacketType.ScriptTeleportRequest); + + packet.Data.ObjectName = Utils.StringToBytes(objName); + packet.Data.SimName = Utils.StringToBytes(simName); + packet.Data.SimPosition = pos; + packet.Data.LookAt = lookAt; + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data) + { + DirPlacesReplyPacket packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply); + + packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock(); + + packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; + packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); + + packet.QueryReplies = + new DirPlacesReplyPacket.QueryRepliesBlock[data.Length]; + + packet.StatusData = new DirPlacesReplyPacket.StatusDataBlock[ + data.Length]; + + packet.AgentData.AgentID = AgentId; + + packet.QueryData[0].QueryID = queryID; + + int i = 0; + foreach (DirPlacesReplyData d in data) + { + packet.QueryReplies[i] = + new DirPlacesReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirPlacesReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = Utils.StringToBytes(d.name); + packet.QueryReplies[i].ForSale = d.forSale; + packet.QueryReplies[i].Auction = d.auction; + packet.QueryReplies[i].Dwell = d.dwell; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data) + { + DirPeopleReplyPacket packet = (DirPeopleReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPeopleReply); + + packet.AgentData = new DirPeopleReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirPeopleReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirPeopleReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirPeopleReplyData d in data) + { + packet.QueryReplies[i] = new DirPeopleReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].AgentID = d.agentID; + packet.QueryReplies[i].FirstName = + Utils.StringToBytes(d.firstName); + packet.QueryReplies[i].LastName = + Utils.StringToBytes(d.lastName); + packet.QueryReplies[i].Group = + Utils.StringToBytes(d.group); + packet.QueryReplies[i].Online = d.online; + packet.QueryReplies[i].Reputation = d.reputation; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data) + { + DirEventsReplyPacket packet = (DirEventsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirEventsReply); + + packet.AgentData = new DirEventsReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirEventsReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirEventsReplyPacket.QueryRepliesBlock[ + data.Length]; + + packet.StatusData = new DirEventsReplyPacket.StatusDataBlock[ + data.Length]; + + int i = 0; + foreach (DirEventsReplyData d in data) + { + packet.QueryReplies[i] = new DirEventsReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirEventsReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].OwnerID = d.ownerID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].EventID = d.eventID; + packet.QueryReplies[i].Date = + Utils.StringToBytes(d.date); + packet.QueryReplies[i].UnixTime = d.unixTime; + packet.QueryReplies[i].EventFlags = d.eventFlags; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data) + { + DirGroupsReplyPacket packet = (DirGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirGroupsReply); + + packet.AgentData = new DirGroupsReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirGroupsReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirGroupsReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirGroupsReplyData d in data) + { + packet.QueryReplies[i] = new DirGroupsReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].GroupID = d.groupID; + packet.QueryReplies[i].GroupName = + Utils.StringToBytes(d.groupName); + packet.QueryReplies[i].Members = d.members; + packet.QueryReplies[i].SearchOrder = d.searchOrder; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data) + { + DirClassifiedReplyPacket packet = (DirClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirClassifiedReply); + + packet.AgentData = new DirClassifiedReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirClassifiedReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirClassifiedReplyPacket.QueryRepliesBlock[ + data.Length]; + packet.StatusData = new DirClassifiedReplyPacket.StatusDataBlock[ + data.Length]; + + int i = 0; + foreach (DirClassifiedReplyData d in data) + { + packet.QueryReplies[i] = new DirClassifiedReplyPacket.QueryRepliesBlock(); + packet.StatusData[i] = new DirClassifiedReplyPacket.StatusDataBlock(); + packet.QueryReplies[i].ClassifiedID = d.classifiedID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].ClassifiedFlags = d.classifiedFlags; + packet.QueryReplies[i].CreationDate = d.creationDate; + packet.QueryReplies[i].ExpirationDate = d.expirationDate; + packet.QueryReplies[i].PriceForListing = d.price; + packet.StatusData[i].Status = d.Status; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirLandReply(UUID queryID, DirLandReplyData[] data) + { + DirLandReplyPacket packet = (DirLandReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirLandReply); + + packet.AgentData = new DirLandReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirLandReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirLandReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirLandReplyData d in data) + { + packet.QueryReplies[i] = new DirLandReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].Auction = d.auction; + packet.QueryReplies[i].ForSale = d.forSale; + packet.QueryReplies[i].SalePrice = d.salePrice; + packet.QueryReplies[i].ActualArea = d.actualArea; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data) + { + DirPopularReplyPacket packet = (DirPopularReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPopularReply); + + packet.AgentData = new DirPopularReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.QueryData = new DirPopularReplyPacket.QueryDataBlock(); + packet.QueryData.QueryID = queryID; + + packet.QueryReplies = new DirPopularReplyPacket.QueryRepliesBlock[ + data.Length]; + + int i = 0; + foreach (DirPopularReplyData d in data) + { + packet.QueryReplies[i] = new DirPopularReplyPacket.QueryRepliesBlock(); + packet.QueryReplies[i].ParcelID = d.parcelID; + packet.QueryReplies[i].Name = + Utils.StringToBytes(d.name); + packet.QueryReplies[i].Dwell = d.dwell; + i++; + } + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendEventInfoReply(EventData data) + { + EventInfoReplyPacket packet = (EventInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.EventInfoReply); + + packet.AgentData = new EventInfoReplyPacket.AgentDataBlock(); + packet.AgentData.AgentID = AgentId; + + packet.EventData = new EventInfoReplyPacket.EventDataBlock(); + packet.EventData.EventID = data.eventID; + packet.EventData.Creator = Utils.StringToBytes(data.creator); + packet.EventData.Name = Utils.StringToBytes(data.name); + packet.EventData.Category = Utils.StringToBytes(data.category); + packet.EventData.Desc = Utils.StringToBytes(data.description); + packet.EventData.Date = Utils.StringToBytes(data.date); + packet.EventData.DateUTC = data.dateUTC; + packet.EventData.Duration = data.duration; + packet.EventData.Cover = data.cover; + packet.EventData.Amount = data.amount; + packet.EventData.SimName = Utils.StringToBytes(data.simName); + packet.EventData.GlobalPos = new Vector3d(data.globalPos); + packet.EventData.EventFlags = data.eventFlags; + + OutPacket(packet, ThrottleOutPacketType.Task); + } + + public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags) + { + MapItemReplyPacket mirplk = new MapItemReplyPacket(); + mirplk.AgentData.AgentID = AgentId; + mirplk.RequestData.ItemType = mapitemtype; + mirplk.Data = new MapItemReplyPacket.DataBlock[replies.Length]; + for (int i = 0; i < replies.Length; i++) + { + MapItemReplyPacket.DataBlock mrdata = new MapItemReplyPacket.DataBlock(); + mrdata.X = replies[i].x; + mrdata.Y = replies[i].y; + mrdata.ID = replies[i].id; + mrdata.Extra = replies[i].Extra; + mrdata.Extra2 = replies[i].Extra2; + mrdata.Name = Utils.StringToBytes(replies[i].name); + mirplk.Data[i] = mrdata; + } + //m_log.Debug(mirplk.ToString()); + OutPacket(mirplk, ThrottleOutPacketType.Task); + + } + + public void SendOfferCallingCard(UUID srcID, UUID transactionID) + { + // a bit special, as this uses AgentID to store the source instead + // of the destination. The destination (the receiver) goes into destID + OfferCallingCardPacket p = (OfferCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.OfferCallingCard); + p.AgentData.AgentID = srcID; + p.AgentData.SessionID = UUID.Zero; + p.AgentBlock.DestID = AgentId; + p.AgentBlock.TransactionID = transactionID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAcceptCallingCard(UUID transactionID) + { + AcceptCallingCardPacket p = (AcceptCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.AcceptCallingCard); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = UUID.Zero; + p.FolderData = new AcceptCallingCardPacket.FolderDataBlock[1]; + p.FolderData[0] = new AcceptCallingCardPacket.FolderDataBlock(); + p.FolderData[0].FolderID = UUID.Zero; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendDeclineCallingCard(UUID transactionID) + { + DeclineCallingCardPacket p = (DeclineCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.DeclineCallingCard); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = UUID.Zero; + p.TransactionBlock.TransactionID = transactionID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendTerminateFriend(UUID exFriendID) + { + TerminateFriendshipPacket p = (TerminateFriendshipPacket)PacketPool.Instance.GetPacket(PacketType.TerminateFriendship); + p.AgentData.AgentID = AgentId; + p.AgentData.SessionID = SessionId; + p.ExBlock.OtherID = exFriendID; + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) + { + AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); + + p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + p.AgentData.AvatarID = avatarID; + + p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; + int i = 0; + foreach (GroupMembershipData m in data) + { + p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); + p.GroupData[i].GroupPowers = m.GroupPowers; + p.GroupData[i].AcceptNotices = m.AcceptNotices; + p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); + p.GroupData[i].GroupID = m.GroupID; + p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); + p.GroupData[i].GroupInsigniaID = m.GroupPicture; + i++; + } + + p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); + p.NewGroupData.ListInProfile = true; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendJoinGroupReply(UUID groupID, bool success) + { + JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply); + + p.AgentData = new JoinGroupReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + + p.GroupData = new JoinGroupReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + p.GroupData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success) + { + EjectGroupMemberReplyPacket p = (EjectGroupMemberReplyPacket)PacketPool.Instance.GetPacket(PacketType.EjectGroupMemberReply); + + p.AgentData = new EjectGroupMemberReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = agentID; + + p.GroupData = new EjectGroupMemberReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + + p.EjectData = new EjectGroupMemberReplyPacket.EjectDataBlock(); + p.EjectData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendLeaveGroupReply(UUID groupID, bool success) + { + LeaveGroupReplyPacket p = (LeaveGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.LeaveGroupReply); + + p.AgentData = new LeaveGroupReplyPacket.AgentDataBlock(); + p.AgentData.AgentID = AgentId; + + p.GroupData = new LeaveGroupReplyPacket.GroupDataBlock(); + p.GroupData.GroupID = groupID; + p.GroupData.Success = success; + + OutPacket(p, ThrottleOutPacketType.Task); + } + + public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name) + { + if (classifiedID.Length != name.Length) + return; + + AvatarClassifiedReplyPacket ac = + (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarClassifiedReply); + + ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); + ac.AgentData.AgentID = AgentId; + ac.AgentData.TargetID = targetID; + + ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifiedID.Length]; + int i; + for (i = 0; i < classifiedID.Length; i++) + { + ac.Data[i].ClassifiedID = classifiedID[i]; + ac.Data[i].Name = Utils.StringToBytes(name[i]); + } + + OutPacket(ac, ThrottleOutPacketType.Task); + } + + public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price) + { + ClassifiedInfoReplyPacket cr = + (ClassifiedInfoReplyPacket)PacketPool.Instance.GetPacket( + PacketType.ClassifiedInfoReply); + + cr.AgentData = new ClassifiedInfoReplyPacket.AgentDataBlock(); + cr.AgentData.AgentID = AgentId; + + cr.Data = new ClassifiedInfoReplyPacket.DataBlock(); + cr.Data.ClassifiedID = classifiedID; + cr.Data.CreatorID = creatorID; + cr.Data.CreationDate = creationDate; + cr.Data.ExpirationDate = expirationDate; + cr.Data.Category = category; + cr.Data.Name = Utils.StringToBytes(name); + cr.Data.Desc = Utils.StringToBytes(description); + cr.Data.ParcelID = parcelID; + cr.Data.ParentEstate = parentEstate; + cr.Data.SnapshotID = snapshotID; + cr.Data.SimName = Utils.StringToBytes(simName); + cr.Data.PosGlobal = new Vector3d(globalPos); + cr.Data.ParcelName = Utils.StringToBytes(parcelName); + cr.Data.ClassifiedFlags = classifiedFlags; + cr.Data.PriceForListing = price; + + OutPacket(cr, ThrottleOutPacketType.Task); + } + + public void SendAgentDropGroup(UUID groupID) + { + AgentDropGroupPacket dg = + (AgentDropGroupPacket)PacketPool.Instance.GetPacket( + PacketType.AgentDropGroup); + + dg.AgentData = new AgentDropGroupPacket.AgentDataBlock(); + dg.AgentData.AgentID = AgentId; + dg.AgentData.GroupID = groupID; + + OutPacket(dg, ThrottleOutPacketType.Task); + } + + public void SendAvatarNotesReply(UUID targetID, string text) + { + AvatarNotesReplyPacket an = + (AvatarNotesReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarNotesReply); + + an.AgentData = new AvatarNotesReplyPacket.AgentDataBlock(); + an.AgentData.AgentID = AgentId; + + an.Data = new AvatarNotesReplyPacket.DataBlock(); + an.Data.TargetID = targetID; + an.Data.Notes = Utils.StringToBytes(text); + + OutPacket(an, ThrottleOutPacketType.Task); + } + + public void SendAvatarPicksReply(UUID targetID, Dictionary picks) + { + AvatarPicksReplyPacket ap = + (AvatarPicksReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarPicksReply); + + ap.AgentData = new AvatarPicksReplyPacket.AgentDataBlock(); + ap.AgentData.AgentID = AgentId; + ap.AgentData.TargetID = targetID; + + ap.Data = new AvatarPicksReplyPacket.DataBlock[picks.Count]; + + int i = 0; + foreach (KeyValuePair pick in picks) + { + ap.Data[i] = new AvatarPicksReplyPacket.DataBlock(); + ap.Data[i].PickID = pick.Key; + ap.Data[i].PickName = Utils.StringToBytes(pick.Value); + i++; + } + + OutPacket(ap, ThrottleOutPacketType.Task); + } + + public void SendAvatarClassifiedReply(UUID targetID, Dictionary classifieds) + { + AvatarClassifiedReplyPacket ac = + (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( + PacketType.AvatarClassifiedReply); + + ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); + ac.AgentData.AgentID = AgentId; + ac.AgentData.TargetID = targetID; + + ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifieds.Count]; + + int i = 0; + foreach (KeyValuePair classified in classifieds) + { + ac.Data[i] = new AvatarClassifiedReplyPacket.DataBlock(); + ac.Data[i].ClassifiedID = classified.Key; + ac.Data[i].Name = Utils.StringToBytes(classified.Value); + i++; + } + + OutPacket(ac, ThrottleOutPacketType.Task); + } + + public void SendParcelDwellReply(int localID, UUID parcelID, float dwell) + { + ParcelDwellReplyPacket pd = + (ParcelDwellReplyPacket)PacketPool.Instance.GetPacket( + PacketType.ParcelDwellReply); + + pd.AgentData = new ParcelDwellReplyPacket.AgentDataBlock(); + pd.AgentData.AgentID = AgentId; + + pd.Data = new ParcelDwellReplyPacket.DataBlock(); + pd.Data.LocalID = localID; + pd.Data.ParcelID = parcelID; + pd.Data.Dwell = dwell; + + OutPacket(pd, ThrottleOutPacketType.Land); + } + + public void SendUserInfoReply(bool imViaEmail, bool visible, string email) + { + UserInfoReplyPacket ur = + (UserInfoReplyPacket)PacketPool.Instance.GetPacket( + PacketType.UserInfoReply); + + string Visible = "hidden"; + if (visible) + Visible = "default"; + + ur.AgentData = new UserInfoReplyPacket.AgentDataBlock(); + ur.AgentData.AgentID = AgentId; + + ur.UserData = new UserInfoReplyPacket.UserDataBlock(); + ur.UserData.IMViaEMail = imViaEmail; + ur.UserData.DirectoryVisibility = Utils.StringToBytes(Visible); + ur.UserData.EMail = Utils.StringToBytes(email); + + OutPacket(ur, ThrottleOutPacketType.Task); + } + + public void SendCreateGroupReply(UUID groupID, bool success, string message) + { + CreateGroupReplyPacket createGroupReply = (CreateGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.CreateGroupReply); + + createGroupReply.AgentData = + new CreateGroupReplyPacket.AgentDataBlock(); + createGroupReply.ReplyData = + new CreateGroupReplyPacket.ReplyDataBlock(); + + createGroupReply.AgentData.AgentID = AgentId; + createGroupReply.ReplyData.GroupID = groupID; + + createGroupReply.ReplyData.Success = success; + createGroupReply.ReplyData.Message = Utils.StringToBytes(message); + OutPacket(createGroupReply, ThrottleOutPacketType.Task); + } + + public void SendUseCachedMuteList() + { + UseCachedMuteListPacket useCachedMuteList = (UseCachedMuteListPacket)PacketPool.Instance.GetPacket(PacketType.UseCachedMuteList); + + useCachedMuteList.AgentData = new UseCachedMuteListPacket.AgentDataBlock(); + useCachedMuteList.AgentData.AgentID = AgentId; + + OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); + } + + public void SendMuteListUpdate(string filename) + { + MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); + + muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock(); + muteListUpdate.MuteData.AgentID = AgentId; + muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename); + + OutPacket(muteListUpdate, ThrottleOutPacketType.Task); + } + + public void SendPickInfoReply(UUID pickID, UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) + { + PickInfoReplyPacket pickInfoReply = (PickInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.PickInfoReply); + + pickInfoReply.AgentData = new PickInfoReplyPacket.AgentDataBlock(); + pickInfoReply.AgentData.AgentID = AgentId; + + pickInfoReply.Data = new PickInfoReplyPacket.DataBlock(); + pickInfoReply.Data.PickID = pickID; + pickInfoReply.Data.CreatorID = creatorID; + pickInfoReply.Data.TopPick = topPick; + pickInfoReply.Data.ParcelID = parcelID; + pickInfoReply.Data.Name = Utils.StringToBytes(name); + pickInfoReply.Data.Desc = Utils.StringToBytes(desc); + pickInfoReply.Data.SnapshotID = snapshotID; + pickInfoReply.Data.User = Utils.StringToBytes(user); + pickInfoReply.Data.OriginalName = Utils.StringToBytes(originalName); + pickInfoReply.Data.SimName = Utils.StringToBytes(simName); + pickInfoReply.Data.PosGlobal = new Vector3d(posGlobal); + pickInfoReply.Data.SortOrder = sortOrder; + pickInfoReply.Data.Enabled = enabled; + + OutPacket(pickInfoReply, ThrottleOutPacketType.Task); + } + + #endregion Scene/Avatar to Client // Gesture @@ -3064,7 +3488,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP objectData.FullID = objectID; objectData.OwnerID = ownerID; - objectData.Text = LLUtil.StringToPacketBytes(text); + objectData.Text = Util.StringToBytes256(text); objectData.TextColor[0] = color[0]; objectData.TextColor[1] = color[1]; objectData.TextColor[2] = color[2]; @@ -3201,7 +3625,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } outPacket.Header.Zerocoded = true; - OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); + OutPacket(outPacket, ThrottleOutPacketType.Task); if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) lock (m_primFullUpdateTimer) @@ -3291,7 +3715,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP outPacket.Header.Reliable = false; outPacket.Header.Zerocoded = true; - OutPacket(outPacket, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); + OutPacket(outPacket, ThrottleOutPacketType.Task); if (m_primTerseUpdates.Count == 0) lock (m_primTerseUpdateTimer) @@ -3442,8 +3866,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP objPropDB.SalePrice = SalePrice; objPropDB.Category = Category; objPropDB.LastOwnerID = LastOwnerID; - objPropDB.Name = LLUtil.StringToPacketBytes(ObjectName); - objPropDB.Description = LLUtil.StringToPacketBytes(Description); + objPropDB.Name = Util.StringToBytes256(ObjectName); + objPropDB.Description = Util.StringToBytes256(Description); objPropFamilyPack.ObjectData = objPropDB; objPropFamilyPack.Header.Zerocoded = true; OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task); @@ -3477,11 +3901,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP proper.ObjectData[0].OwnerID = UUID.Zero; else proper.ObjectData[0].OwnerID = OwnerUUID; - proper.ObjectData[0].TouchName = LLUtil.StringToPacketBytes(TouchTitle); + proper.ObjectData[0].TouchName = Util.StringToBytes256(TouchTitle); proper.ObjectData[0].TextureID = TextureID; - proper.ObjectData[0].SitName = LLUtil.StringToPacketBytes(SitTitle); - proper.ObjectData[0].Name = LLUtil.StringToPacketBytes(ItemName); - proper.ObjectData[0].Description = LLUtil.StringToPacketBytes(ItemDescription); + proper.ObjectData[0].SitName = Util.StringToBytes256(SitTitle); + proper.ObjectData[0].Name = Util.StringToBytes256(ItemName); + proper.ObjectData[0].Description = Util.StringToBytes256(ItemDescription); proper.ObjectData[0].OwnerMask = OwnerMask; proper.ObjectData[0].NextOwnerMask = NextOwnerMask; proper.ObjectData[0].GroupMask = GroupMask; @@ -3722,11 +4146,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP updatePacket.ParcelData.MediaAutoScale = landData.MediaAutoScale; updatePacket.ParcelData.MediaID = landData.MediaID; - updatePacket.ParcelData.MediaURL = LLUtil.StringToPacketBytes(landData.MediaURL); - updatePacket.ParcelData.MusicURL = LLUtil.StringToPacketBytes(landData.MusicURL); - updatePacket.ParcelData.Name = Utils.StringToBytes(landData.Name); + updatePacket.ParcelData.MediaURL = Util.StringToBytes256(landData.MediaURL); + updatePacket.ParcelData.MusicURL = Util.StringToBytes256(landData.MusicURL); + updatePacket.ParcelData.Name = Util.StringToBytes256(landData.Name); updatePacket.ParcelData.OtherCleanTime = landData.OtherCleanTime; - updatePacket.ParcelData.OtherCount = 0; //unemplemented + updatePacket.ParcelData.OtherCount = 0; //TODO: Unimplemented updatePacket.ParcelData.OtherPrims = landData.OtherPrims; updatePacket.ParcelData.OwnerID = landData.OwnerID; updatePacket.ParcelData.OwnerPrims = landData.OwnerPrims; @@ -3734,22 +4158,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP updatePacket.ParcelData.ParcelPrimBonus = simObjectBonusFactor; updatePacket.ParcelData.PassHours = landData.PassHours; updatePacket.ParcelData.PassPrice = landData.PassPrice; - updatePacket.ParcelData.PublicCount = 0; //unemplemented + updatePacket.ParcelData.PublicCount = 0; //TODO: Unimplemented - updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint)RegionFlags.DenyAnonymous) > - 0); - updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint)RegionFlags.DenyIdentified) > - 0); - updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint)RegionFlags.DenyTransacted) > - 0); - updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint)RegionFlags.RestrictPushObject) > - 0); + updatePacket.ParcelData.RegionDenyAnonymous = (regionFlags & (uint)RegionFlags.DenyAnonymous) > 0; + updatePacket.ParcelData.RegionDenyIdentified = (regionFlags & (uint)RegionFlags.DenyIdentified) > 0; + updatePacket.ParcelData.RegionDenyTransacted = (regionFlags & (uint)RegionFlags.DenyTransacted) > 0; + updatePacket.ParcelData.RegionPushOverride = (regionFlags & (uint)RegionFlags.RestrictPushObject) > 0; updatePacket.ParcelData.RentPrice = 0; updatePacket.ParcelData.RequestResult = request_result; updatePacket.ParcelData.SalePrice = landData.SalePrice; updatePacket.ParcelData.SelectedPrims = landData.SelectedPrims; - updatePacket.ParcelData.SelfCount = 0; //unemplemented + updatePacket.ParcelData.SelfCount = 0; //TODO: Unimplemented updatePacket.ParcelData.SequenceID = sequence_id; if (landData.SimwideArea > 0) { @@ -4242,6 +4662,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(packet, ThrottleOutPacketType.Task); } + public ulong GetGroupPowers(UUID groupID) + { + if (groupID == m_activeGroupID) + return m_activeGroupPowers; + + if (m_groupPowers.ContainsKey(groupID)) + return m_groupPowers[groupID]; + + return 0; + } + + /// + /// This is a utility method used by single states to not duplicate kicks and blue card of death messages. + /// + public bool ChildAgentStatus() + { + return m_scene.PresenceChildStatus(AgentId); + } + #endregion /// @@ -4260,6 +4699,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); } + #region Packet Handlers + private bool HandleMoneyTransferRequest(IClientAPI sender, Packet Pack) { MoneyTransferRequestPacket money = (MoneyTransferRequestPacket) Pack; @@ -4267,7 +4708,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (money.MoneyData.SourceID == sender.AgentId && money.AgentData.AgentID == sender.AgentId && money.AgentData.SessionID == sender.SessionId) { - handlerMoneyTransferRequest = OnMoneyTransferRequest; + MoneyTransferRequest handlerMoneyTransferRequest = OnMoneyTransferRequest; if (handlerMoneyTransferRequest != null) { handlerMoneyTransferRequest(money.MoneyData.SourceID, money.MoneyData.DestID, @@ -4286,7 +4727,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelBuyPacket parcel = (ParcelBuyPacket) Pack; if (parcel.AgentData.AgentID == AgentId && parcel.AgentData.SessionID == SessionId) { - handlerParcelBuy = OnParcelBuy; + ParcelBuy handlerParcelBuy = OnParcelBuy; if (handlerParcelBuy != null) { handlerParcelBuy(parcel.AgentData.AgentID, parcel.Data.GroupID, parcel.Data.Final, @@ -4307,7 +4748,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < upack.UUIDNameBlock.Length; i++) { - handlerUUIDGroupNameRequest = OnUUIDGroupNameRequest; + UUIDNameRequest handlerUUIDGroupNameRequest = OnUUIDGroupNameRequest; if (handlerUUIDGroupNameRequest != null) { handlerUUIDGroupNameRequest(upack.UUIDNameBlock[i].ID, this); @@ -4323,7 +4764,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_genericPacketHandlers.Count == 0) return false; if (gmpack.AgentData.SessionID != SessionId) return false; - handlerGenericMessage = null; + GenericMessage handlerGenericMessage = null; string method = Util.FieldToString(gmpack.MethodData.Method).ToLower().Trim(); @@ -4364,7 +4805,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectGroupPacket ogpack = (ObjectGroupPacket)Pack; if (ogpack.AgentData.SessionID != SessionId) return false; - handlerObjectGroupRequest = OnObjectGroupRequest; + RequestObjectPropertiesFamily handlerObjectGroupRequest = OnObjectGroupRequest; if (handlerObjectGroupRequest != null) { for (int i = 0; i < ogpack.ObjectData.Length; i++) @@ -4379,7 +4820,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { ViewerEffectPacket viewer = (ViewerEffectPacket)Pack; if (viewer.AgentData.SessionID != SessionId) return false; - handlerViewerEffect = OnViewerEffect; + ViewerEffectEventHandler handlerViewerEffect = OnViewerEffect; if (handlerViewerEffect != null) { int length = viewer.Effect.Length; @@ -4403,6 +4844,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } + #endregion Packet Handlers + public void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question) { ScriptQuestionPacket scriptQuestion = (ScriptQuestionPacket)PacketPool.Instance.GetPacket(PacketType.ScriptQuestion); @@ -4468,7 +4911,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.InfoFormat("[CLIENT]: Got a logout request for {0} in {1}", Name, Scene.RegionInfo.RegionName); - handlerLogout = OnLogout; + Action handlerLogout = OnLogout; if (handlerLogout != null) { @@ -4550,7 +4993,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 1: Vector3 pos1 = new Vector3(block.Data, 0); - handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; + UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; if (handlerUpdatePrimSinglePosition != null) { // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); @@ -4560,7 +5003,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 2: Quaternion rot1 = new Quaternion(block.Data, 0, true); - handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; + UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; if (handlerUpdatePrimSingleRotation != null) { // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W); @@ -4571,7 +5014,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Vector3 rotPos = new Vector3(block.Data, 0); Quaternion rot2 = new Quaternion(block.Data, 12, true); - handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; + UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; if (handlerUpdatePrimSingleRotationPosition != null) { // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z); @@ -4583,7 +5026,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 20: Vector3 scale4 = new Vector3(block.Data, 0); - handlerUpdatePrimScale = OnUpdatePrimScale; + UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; if (handlerUpdatePrimScale != null) { // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z); @@ -4611,7 +5054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 9: Vector3 pos2 = new Vector3(block.Data, 0); - handlerUpdateVector = OnUpdatePrimGroupPosition; + UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; if (handlerUpdateVector != null) { @@ -4622,7 +5065,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 10: Quaternion rot3 = new Quaternion(block.Data, 0, true); - handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; + UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; if (handlerUpdatePrimRotation != null) { // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W); @@ -4645,7 +5088,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case 28: Vector3 scale7 = new Vector3(block.Data, 0); - handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; + UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; if (handlerUpdatePrimGroupScale != null) { // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z); @@ -4765,45 +5208,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP } /// - /// returns a byte array of the client set throttles Gets multiplied by the multiplier - /// - /// - /// non 1 multiplier for subdividing the throttles between individual regions - /// - public byte[] GetThrottlesPacked(float multiplier) - { - return m_PacketHandler.PacketQueue.GetThrottlesPacked(multiplier); - } - /// - /// sets the throttles from values supplied by the client + /// Sets the throttles from values supplied by the client /// /// public void SetChildAgentThrottle(byte[] throttles) { - m_PacketHandler.PacketQueue.SetThrottleFromClient(throttles); + m_udpClient.SetThrottles(throttles); } /// - /// Method gets called when a new packet has arrived from the UDP - /// server. This happens after it's been decoded into a libsl object. + /// Get the current throttles for this client as a packed byte array + /// + /// Unused + /// + public byte[] GetThrottlesPacked(float multiplier) + { + return m_udpClient.GetThrottlesPacked(); + } + + /// + /// Cruft? /// - /// object containing the packet. public virtual void InPacket(object NewPack) { - // Cast NewPack to Packet. - m_PacketHandler.InPacket((Packet) NewPack); + throw new NotImplementedException(); } /// - /// This is the starting point for sending a simulator packet out to the client. - /// - /// Please do not call this from outside the LindenUDP client stack. + /// This is the starting point for sending a simulator packet out to the client /// - /// - /// Corresponds to the type of data that is going out. Enum - public void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType) + /// Packet to send + /// Throttling category for the packet + private void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) { - m_PacketHandler.OutPacket(NewPack, throttlePacketType); + m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); } public bool AddMoney(int debit) @@ -4847,7 +5285,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; } - handlerAutoPilotGo = OnAutoPilotGo; + UpdateVector handlerAutoPilotGo = OnAutoPilotGo; if (handlerAutoPilotGo != null) { handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this); @@ -4899,7 +5337,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRequestAvatarProperties = OnRequestAvatarProperties; + RequestAvatarProperties handlerRequestAvatarProperties = OnRequestAvatarProperties; if (handlerRequestAvatarProperties != null) { handlerRequestAvatarProperties(this, avatarProperties.AgentData.AvatarID); @@ -4940,7 +5378,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP args.Sender = this; args.SenderUUID = this.AgentId; - handlerChatFromClient = OnChatFromClient; + ChatMessage handlerChatFromClient = OnChatFromClient; if (handlerChatFromClient != null) handlerChatFromClient(this, args); } @@ -4958,7 +5396,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdateAvatarProperties = OnUpdateAvatarProperties; + UpdateAvatarProperties handlerUpdateAvatarProperties = OnUpdateAvatarProperties; if (handlerUpdateAvatarProperties != null) { AvatarPropertiesUpdatePacket.PropertiesDataBlock Properties = avatarProps.PropertiesData; @@ -4998,7 +5436,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP args.Position = new Vector3(); args.Scene = Scene; args.Sender = this; - handlerChatFromClient2 = OnChatFromClient; + ChatMessage handlerChatFromClient2 = OnChatFromClient; if (handlerChatFromClient2 != null) handlerChatFromClient2(this, args); } @@ -5019,7 +5457,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName); string IMmessage = Utils.BytesToString(msgpack.MessageBlock.Message); - handlerInstantMessage = OnInstantMessage; + ImprovedInstantMessage handlerInstantMessage = OnInstantMessage; if (handlerInstantMessage != null) { @@ -5062,7 +5500,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP callingCardFolders.Add(afriendpack.FolderData[fi].FolderID); } - handlerApproveFriendRequest = OnApproveFriendRequest; + FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest; if (handlerApproveFriendRequest != null) { handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders); @@ -5105,7 +5543,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID listOwnerAgentID = tfriendpack.AgentData.AgentID; UUID exFriendID = tfriendpack.ExBlock.OtherID; - handlerTerminateFriendship = OnTerminateFriendship; + FriendshipTermination handlerTerminateFriendship = OnTerminateFriendship; if (handlerTerminateFriendship != null) { handlerTerminateFriendship(this, listOwnerAgentID, exFriendID); @@ -5124,7 +5562,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRezObject = OnRezObject; + RezObject handlerRezObject = OnRezObject; if (handlerRezObject != null) { handlerRezObject(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd, @@ -5147,7 +5585,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDeRezObject = OnDeRezObject; + DeRezObject handlerDeRezObject = OnDeRezObject; if (handlerDeRezObject != null) { List deRezIDs = new List(); @@ -5186,7 +5624,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { for (int i = 0; i < modify.ParcelData.Length; i++) { - handlerModifyTerrain = OnModifyTerrain; + ModifyTerrain handlerModifyTerrain = OnModifyTerrain; if (handlerModifyTerrain != null) { handlerModifyTerrain(AgentId, modify.ModifyBlock.Height, modify.ModifyBlock.Seconds, @@ -5203,7 +5641,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RegionHandshakeReply: - handlerRegionHandShakeReply = OnRegionHandShakeReply; + Action handlerRegionHandShakeReply = OnRegionHandShakeReply; if (handlerRegionHandShakeReply != null) { handlerRegionHandShakeReply(this); @@ -5212,14 +5650,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.AgentWearablesRequest: - handlerRequestWearables = OnRequestWearables; + GenericCall2 handlerRequestWearables = OnRequestWearables; if (handlerRequestWearables != null) { handlerRequestWearables(); } - handlerRequestAvatarsData = OnRequestAvatarsData; + Action handlerRequestAvatarsData = OnRequestAvatarsData; if (handlerRequestAvatarsData != null) { @@ -5240,7 +5678,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSetAppearance = OnSetAppearance; + SetAppearance handlerSetAppearance = OnSetAppearance; if (handlerSetAppearance != null) { // Temporarily protect ourselves from the mantis #951 failure. @@ -5291,7 +5729,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP wearingArgs.NowWearing.Add(wearable); } - handlerAvatarNowWearing = OnAvatarNowWearing; + AvatarNowWearing handlerAvatarNowWearing = OnAvatarNowWearing; if (handlerAvatarNowWearing != null) { handlerAvatarNowWearing(this, wearingArgs); @@ -5300,7 +5738,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.RezSingleAttachmentFromInv: - handlerRezSingleAttachment = OnRezSingleAttachmentFromInv; + RezSingleAttachmentFromInv handlerRezSingleAttachment = OnRezSingleAttachmentFromInv; if (handlerRezSingleAttachment != null) { RezSingleAttachmentFromInvPacket rez = (RezSingleAttachmentFromInvPacket)Pack; @@ -5321,7 +5759,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.RezMultipleAttachmentsFromInv: - handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv; + RezMultipleAttachmentsFromInv handlerRezMultipleAttachments = OnRezMultipleAttachmentsFromInv; if (handlerRezMultipleAttachments != null) { RezMultipleAttachmentsFromInvPacket rez = (RezMultipleAttachmentsFromInvPacket)Pack; @@ -5332,7 +5770,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.DetachAttachmentIntoInv: - handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv; + UUIDNameRequest handlerDetachAttachmentIntoInv = OnDetachAttachmentIntoInv; if (handlerDetachAttachmentIntoInv != null) { DetachAttachmentIntoInvPacket detachtoInv = (DetachAttachmentIntoInvPacket)Pack; @@ -5362,7 +5800,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectAttach = OnObjectAttach; + ObjectAttach handlerObjectAttach = OnObjectAttach; if (handlerObjectAttach != null) { @@ -5389,7 +5827,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int j = 0; j < dett.ObjectData.Length; j++) { uint obj = dett.ObjectData[j].ObjectLocalID; - handlerObjectDetach = OnObjectDetach; + ObjectDeselect handlerObjectDetach = OnObjectDetach; if (handlerObjectDetach != null) { handlerObjectDetach(obj, this); @@ -5413,7 +5851,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int j = 0; j < dropp.ObjectData.Length; j++) { uint obj = dropp.ObjectData[j].ObjectLocalID; - handlerObjectDrop = OnObjectDrop; + ObjectDrop handlerObjectDrop = OnObjectDrop; if (handlerObjectDrop != null) { handlerObjectDrop(obj, this); @@ -5433,14 +5871,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSetAlwaysRun = OnSetAlwaysRun; + SetAlwaysRun handlerSetAlwaysRun = OnSetAlwaysRun; if (handlerSetAlwaysRun != null) handlerSetAlwaysRun(this, run.AgentData.AlwaysRun); break; case PacketType.CompleteAgentMovement: - handlerCompleteMovementToRegion = OnCompleteMovementToRegion; + GenericCall2 handlerCompleteMovementToRegion = OnCompleteMovementToRegion; if (handlerCompleteMovementToRegion != null) { handlerCompleteMovementToRegion(); @@ -5509,7 +5947,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP arg.HeadRotation = x.HeadRotation; arg.SessionID = x.SessionID; arg.State = x.State; - handlerAgentUpdate = OnAgentUpdate; + UpdateAgent handlerAgentUpdate = OnAgentUpdate; lastarg = arg; // save this set of arguments for nexttime if (handlerAgentUpdate != null) OnAgentUpdate(this, arg); @@ -5532,8 +5970,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerStartAnim = null; - handlerStopAnim = null; + StartAnim handlerStartAnim = null; + StopAnim handlerStopAnim = null; for (int i = 0; i < AgentAni.AnimationList.Length; i++) { @@ -5570,7 +6008,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerAgentRequestSit = OnAgentRequestSit; + AgentRequestSit handlerAgentRequestSit = OnAgentRequestSit; if (handlerAgentRequestSit != null) handlerAgentRequestSit(this, agentRequestSit.AgentData.AgentID, agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset); @@ -5591,7 +6029,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerAgentSit = OnAgentSit; + AgentSit handlerAgentSit = OnAgentSit; if (handlerAgentSit != null) { OnAgentSit(this, agentSit.AgentData.AgentID); @@ -5609,7 +6047,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSoundTrigger = OnSoundTrigger; + SoundTrigger handlerSoundTrigger = OnSoundTrigger; if (handlerSoundTrigger != null) { handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, soundTriggerPacket.SoundData.OwnerID, @@ -5636,7 +6074,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AvatarPickerRequestPacket.DataBlock querydata = avRequestQuery.Data; //m_log.Debug("Agent Sends:" + Utils.BytesToString(querydata.Name)); - handlerAvatarPickerRequest = OnAvatarPickerRequest; + AvatarPickerRequest handlerAvatarPickerRequest = OnAvatarPickerRequest; if (handlerAvatarPickerRequest != null) { handlerAvatarPickerRequest(this, Requestdata.AgentID, Requestdata.QueryID, @@ -5656,7 +6094,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerAgentDataUpdateRequest = OnAgentDataUpdateRequest; + FetchInventory handlerAgentDataUpdateRequest = OnAgentDataUpdateRequest; if (handlerAgentDataUpdateRequest != null) { @@ -5666,7 +6104,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.UserInfoRequest: - handlerUserInfoRequest = OnUserInfoRequest; + UserInfoRequest handlerUserInfoRequest = OnUserInfoRequest; if (handlerUserInfoRequest != null) { handlerUserInfoRequest(this); @@ -5689,7 +6127,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdateUserInfo = OnUpdateUserInfo; + UpdateUserInfo handlerUpdateUserInfo = OnUpdateUserInfo; if (handlerUpdateUserInfo != null) { bool visible = true; @@ -5718,7 +6156,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (avSetStartLocationRequestPacket.AgentData.AgentID == AgentId && avSetStartLocationRequestPacket.AgentData.SessionID == SessionId) { - handlerSetStartLocationRequest = OnSetStartLocationRequest; + TeleportLocationRequest handlerSetStartLocationRequest = OnSetStartLocationRequest; if (handlerSetStartLocationRequest != null) { handlerSetStartLocationRequest(this, 0, avSetStartLocationRequestPacket.StartLocationData.LocationPos, @@ -5740,23 +6178,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - m_PacketHandler.PacketQueue.SetThrottleFromClient(atpack.Throttle.Throttles); + m_udpClient.SetThrottles(atpack.Throttle.Throttles); break; case PacketType.AgentPause: - m_probesWithNoIngressPackets = 0; - m_clientBlocked = true; + m_udpClient.IsPaused = true; break; case PacketType.AgentResume: - m_probesWithNoIngressPackets = 0; - m_clientBlocked = false; - SendStartPingCheck(0); + m_udpClient.IsPaused = false; + SendStartPingCheck(m_udpClient.CurrentPingSequence++); break; case PacketType.ForceScriptControlRelease: - handlerForceReleaseControls = OnForceReleaseControls; + ForceReleaseControls handlerForceReleaseControls = OnForceReleaseControls; if (handlerForceReleaseControls != null) { handlerForceReleaseControls(this, AgentId); @@ -5790,7 +6226,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP childrenprims.Add(link.ObjectData[i].ObjectLocalID); } } - handlerLinkObjects = OnLinkObjects; + LinkObjects handlerLinkObjects = OnLinkObjects; if (handlerLinkObjects != null) { handlerLinkObjects(this, parentprimid, childrenprims); @@ -5818,7 +6254,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { prims.Add(delink.ObjectData[i].ObjectLocalID); } - handlerDelinkObjects = OnDelinkObjects; + DelinkObjects handlerDelinkObjects = OnDelinkObjects; if (handlerDelinkObjects != null) { handlerDelinkObjects(prims); @@ -5850,7 +6286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //Check to see if adding the prim is allowed; useful for any module wanting to restrict the //object from rezing initially - handlerAddPrim = OnAddPrim; + AddNewPrim handlerAddPrim = OnAddPrim; if (handlerAddPrim != null) handlerAddPrim(AgentId, ActiveGroupId, addPacket.ObjectData.RayEnd, addPacket.ObjectData.Rotation, shape, addPacket.ObjectData.BypassRaycast, addPacket.ObjectData.RayStart, addPacket.ObjectData.RayTargetID, addPacket.ObjectData.RayEndIsIntersection); } @@ -5868,7 +6304,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdatePrimShape = null; + UpdateShape handlerUpdatePrimShape = null; for (int i = 0; i < shapePacket.ObjectData.Length; i++) { handlerUpdatePrimShape = OnUpdatePrimShape; @@ -5913,7 +6349,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdateExtraParams = OnUpdateExtraParams; + ObjectExtraParams handlerUpdateExtraParams = OnUpdateExtraParams; if (handlerUpdateExtraParams != null) { for (int i = 0 ; i < extraPar.ObjectData.Length ; i++) @@ -5938,7 +6374,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectDuplicatePacket.AgentDataBlock AgentandGroupData = dupe.AgentData; - handlerObjectDuplicate = null; + ObjectDuplicate handlerObjectDuplicate = null; for (int i = 0; i < dupe.ObjectData.Length; i++) { @@ -5965,7 +6401,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectRequest = null; + ObjectRequest handlerObjectRequest = null; for (int i = 0; i < incomingRequest.ObjectData.Length; i++) { @@ -5988,7 +6424,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectSelect = null; + ObjectSelect handlerObjectSelect = null; for (int i = 0; i < incomingselect.ObjectData.Length; i++) { @@ -6011,7 +6447,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectDeselect = null; + ObjectDeselect handlerObjectDeselect = null; for (int i = 0; i < incomingdeselect.ObjectData.Length; i++) { @@ -6038,7 +6474,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < position.ObjectData.Length; i++) { - handlerUpdateVector = OnUpdatePrimGroupPosition; + UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; if (handlerUpdateVector != null) handlerUpdateVector(position.ObjectData[i].ObjectLocalID, position.ObjectData[i].Position, this); } @@ -6059,7 +6495,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < scale.ObjectData.Length; i++) { - handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; + UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; if (handlerUpdatePrimGroupScale != null) handlerUpdatePrimGroupScale(scale.ObjectData[i].ObjectLocalID, scale.ObjectData[i].Scale, this); } @@ -6080,7 +6516,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < rotation.ObjectData.Length; i++) { - handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; + UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; if (handlerUpdatePrimRotation != null) handlerUpdatePrimRotation(rotation.ObjectData[i].ObjectLocalID, rotation.ObjectData[i].Rotation, this); } @@ -6098,7 +6534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdatePrimFlags = OnUpdatePrimFlags; + UpdatePrimFlags handlerUpdatePrimFlags = OnUpdatePrimFlags; if (handlerUpdatePrimFlags != null) { @@ -6115,7 +6551,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ObjectImage: ObjectImagePacket imagePack = (ObjectImagePacket)Pack; - handlerUpdatePrimTexture = null; + UpdatePrimTexture handlerUpdatePrimTexture = null; for (int i = 0; i < imagePack.ObjectData.Length; i++) { handlerUpdatePrimTexture = OnUpdatePrimTexture; @@ -6138,7 +6574,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerGrabObject = OnGrabObject; + GrabObject handlerGrabObject = OnGrabObject; if (handlerGrabObject != null) { @@ -6172,7 +6608,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerGrabUpdate = OnGrabUpdate; + MoveObject handlerGrabUpdate = OnGrabUpdate; if (handlerGrabUpdate != null) { @@ -6207,7 +6643,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDeGrabObject = OnDeGrabObject; + DeGrabObject handlerDeGrabObject = OnDeGrabObject; if (handlerDeGrabObject != null) { List touchArgs = new List(); @@ -6241,7 +6677,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSpinStart = OnSpinStart; + SpinStart handlerSpinStart = OnSpinStart; if (handlerSpinStart != null) { handlerSpinStart(spinStart.ObjectData.ObjectID, this); @@ -6265,7 +6701,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP spinUpdate.ObjectData.Rotation.GetAxisAngle(out axis, out angle); //m_log.Warn("[CLIENT]: ObjectSpinUpdate packet rot axis:" + axis + " angle:" + angle); - handlerSpinUpdate = OnSpinUpdate; + SpinObject handlerSpinUpdate = OnSpinUpdate; if (handlerSpinUpdate != null) { handlerSpinUpdate(spinUpdate.ObjectData.ObjectID, spinUpdate.ObjectData.Rotation, this); @@ -6284,7 +6720,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSpinStop = OnSpinStop; + SpinStop handlerSpinStop = OnSpinStop; if (handlerSpinStop != null) { handlerSpinStop(spinStop.ObjectData.ObjectID, this); @@ -6303,7 +6739,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectDescription = null; + GenericCall7 handlerObjectDescription = null; for (int i = 0; i < objDes.ObjectData.Length; i++) { @@ -6327,7 +6763,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectName = null; + GenericCall7 handlerObjectName = null; for (int i = 0; i < objName.ObjectData.Length; i++) { handlerObjectName = OnObjectName; @@ -6355,7 +6791,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UUID AgentID = newobjPerms.AgentData.AgentID; UUID SessionID = newobjPerms.AgentData.SessionID; - handlerObjectPermissions = null; + ObjectPermissions handlerObjectPermissions = null; for (int i = 0; i < newobjPerms.ObjectData.Length; i++) { @@ -6404,7 +6840,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < undoitem.ObjectData.Length; i++) { UUID objiD = undoitem.ObjectData[i].ObjectID; - handlerOnUndo = OnUndo; + AgentSit handlerOnUndo = OnUndo; if (handlerOnUndo != null) { handlerOnUndo(this, objiD); @@ -6425,8 +6861,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectDuplicateOnRay = null; - + ObjectDuplicateOnRay handlerObjectDuplicateOnRay = null; for (int i = 0; i < dupeOnRay.ObjectData.Length; i++) { @@ -6456,7 +6891,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP RequestObjectPropertiesFamilyPacket.ObjectDataBlock packObjBlock = packToolTip.ObjectData; - handlerRequestObjectPropertiesFamily = OnRequestObjectPropertiesFamily; + RequestObjectPropertiesFamily handlerRequestObjectPropertiesFamily = OnRequestObjectPropertiesFamily; if (handlerRequestObjectPropertiesFamily != null) { @@ -6468,7 +6903,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ObjectIncludeInSearch: //This lets us set objects to appear in search (stuff like DataSnapshot, etc) ObjectIncludeInSearchPacket packInSearch = (ObjectIncludeInSearchPacket)Pack; - handlerObjectIncludeInSearch = null; + ObjectIncludeInSearch handlerObjectIncludeInSearch = null; #region Packet Session and User Check if (m_checkPackets) @@ -6505,7 +6940,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerScriptAnswer = OnScriptAnswer; + ScriptAnswer handlerScriptAnswer = OnScriptAnswer; if (handlerScriptAnswer != null) { handlerScriptAnswer(this, scriptAnswer.Data.TaskID, scriptAnswer.Data.ItemID, scriptAnswer.Data.Questions); @@ -6524,7 +6959,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectClickAction = OnObjectClickAction; + GenericCall7 handlerObjectClickAction = OnObjectClickAction; if (handlerObjectClickAction != null) { foreach (ObjectClickActionPacket.ObjectDataBlock odata in ocpacket.ObjectData) @@ -6548,7 +6983,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectMaterial = OnObjectMaterial; + GenericCall7 handlerObjectMaterial = OnObjectMaterial; if (handlerObjectMaterial != null) { foreach (ObjectMaterialPacket.ObjectDataBlock odata in ompacket.ObjectData) @@ -6702,7 +7137,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // m_log.Debug("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionId).ToString()); UUID temp = UUID.Combine(request.AssetBlock.TransactionID, SecureSessionId); - handlerAssetUploadRequest = OnAssetUploadRequest; + UDPAssetUploadRequest handlerAssetUploadRequest = OnAssetUploadRequest; if (handlerAssetUploadRequest != null) { @@ -6715,7 +7150,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RequestXfer: RequestXferPacket xferReq = (RequestXferPacket)Pack; - handlerRequestXfer = OnRequestXfer; + RequestXfer handlerRequestXfer = OnRequestXfer; if (handlerRequestXfer != null) { @@ -6725,7 +7160,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.SendXferPacket: SendXferPacketPacket xferRec = (SendXferPacketPacket)Pack; - handlerXferReceive = OnXferReceive; + XferReceive handlerXferReceive = OnXferReceive; if (handlerXferReceive != null) { handlerXferReceive(this, xferRec.XferID.ID, xferRec.XferID.Packet, xferRec.DataPacket.Data); @@ -6734,7 +7169,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.ConfirmXferPacket: ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket)Pack; - handlerConfirmXfer = OnConfirmXfer; + ConfirmXfer handlerConfirmXfer = OnConfirmXfer; if (handlerConfirmXfer != null) { handlerConfirmXfer(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet); @@ -6742,7 +7177,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; case PacketType.AbortXfer: AbortXferPacket abortXfer = (AbortXferPacket)Pack; - handlerAbortXfer = OnAbortXfer; + AbortXfer handlerAbortXfer = OnAbortXfer; if (handlerAbortXfer != null) { handlerAbortXfer(this, abortXfer.XferID.ID); @@ -6761,7 +7196,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerCreateInventoryFolder = OnCreateNewInventoryFolder; + CreateInventoryFolder handlerCreateInventoryFolder = OnCreateNewInventoryFolder; if (handlerCreateInventoryFolder != null) { handlerCreateInventoryFolder(this, invFolder.FolderData.FolderID, @@ -6784,7 +7219,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerUpdateInventoryFolder = null; + UpdateInventoryFolder handlerUpdateInventoryFolder = null; for (int i = 0; i < invFolderx.FolderData.Length; i++) { @@ -6813,7 +7248,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerMoveInventoryFolder = null; + MoveInventoryFolder handlerMoveInventoryFolder = null; for (int i = 0; i < invFoldery.InventoryData.Length; i++) { @@ -6838,7 +7273,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerCreateNewInventoryItem = OnCreateNewInventoryItem; + CreateNewInventoryItem handlerCreateNewInventoryItem = OnCreateNewInventoryItem; if (handlerCreateNewInventoryItem != null) { handlerCreateNewInventoryItem(this, createItem.InventoryBlock.TransactionID, @@ -6867,7 +7302,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerFetchInventory = null; + FetchInventory handlerFetchInventory = null; for (int i = 0; i < FetchInventoryx.InventoryData.Length; i++) { @@ -6893,7 +7328,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerFetchInventoryDescendents = OnFetchInventoryDescendents; + FetchInventoryDescendents handlerFetchInventoryDescendents = OnFetchInventoryDescendents; if (handlerFetchInventoryDescendents != null) { handlerFetchInventoryDescendents(this, Fetch.InventoryData.FolderID, Fetch.InventoryData.OwnerID, @@ -6913,7 +7348,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerPurgeInventoryDescendents = OnPurgeInventoryDescendents; + PurgeInventoryDescendents handlerPurgeInventoryDescendents = OnPurgeInventoryDescendents; if (handlerPurgeInventoryDescendents != null) { handlerPurgeInventoryDescendents(this, Purge.InventoryData.FolderID); @@ -6933,7 +7368,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnUpdateInventoryItem != null) { - handlerUpdateInventoryItem = null; + UpdateInventoryItem handlerUpdateInventoryItem = null; for (int i = 0; i < inventoryItemUpdate.InventoryData.Length; i++) { handlerUpdateInventoryItem = OnUpdateInventoryItem; @@ -6955,49 +7390,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP itemUpd.SalePrice = inventoryItemUpdate.InventoryData[i].SalePrice; itemUpd.SaleType = inventoryItemUpdate.InventoryData[i].SaleType; itemUpd.Flags = inventoryItemUpdate.InventoryData[i].Flags; - /* - OnUpdateInventoryItem(this, inventoryItemUpdate.InventoryData[i].TransactionID, - inventoryItemUpdate.InventoryData[i].ItemID, - Util.FieldToString(inventoryItemUpdate.InventoryData[i].Name), - Util.FieldToString(inventoryItemUpdate.InventoryData[i].Description), - inventoryItemUpdate.InventoryData[i].NextOwnerMask); - */ + OnUpdateInventoryItem(this, inventoryItemUpdate.InventoryData[i].TransactionID, inventoryItemUpdate.InventoryData[i].ItemID, itemUpd); } } } - //m_log.Debug(Pack.ToString()); - /*for (int i = 0; i < inventoryItemUpdate.InventoryData.Length; i++) - { - if (inventoryItemUpdate.InventoryData[i].TransactionID != UUID.Zero) - { - AssetBase asset = m_assetCache.GetAsset(inventoryItemUpdate.InventoryData[i].TransactionID.Combine(this.SecureSessionId)); - if (asset != null) - { - // m_log.Debug("updating inventory item, found asset" + asset.FullID.ToString() + " already in cache"); - m_inventoryCache.UpdateInventoryItemAsset(this, inventoryItemUpdate.InventoryData[i].ItemID, asset); - } - else - { - asset = this.UploadAssets.AddUploadToAssetCache(inventoryItemUpdate.InventoryData[i].TransactionID); - if (asset != null) - { - //m_log.Debug("updating inventory item, adding asset" + asset.FullID.ToString() + " to cache"); - m_inventoryCache.UpdateInventoryItemAsset(this, inventoryItemUpdate.InventoryData[i].ItemID, asset); - } - else - { - //m_log.Debug("trying to update inventory item, but asset is null"); - } - } - } - else - { - m_inventoryCache.UpdateInventoryItemDetails(this, inventoryItemUpdate.InventoryData[i].ItemID, inventoryItemUpdate.InventoryData[i]); ; - } - }*/ break; case PacketType.CopyInventoryItem: CopyInventoryItemPacket copyitem = (CopyInventoryItemPacket)Pack; @@ -7011,7 +7410,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerCopyInventoryItem = null; + CopyInventoryItem handlerCopyInventoryItem = null; if (OnCopyInventoryItem != null) { foreach (CopyInventoryItemPacket.InventoryDataBlock datablock in copyitem.InventoryData) @@ -7040,7 +7439,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnMoveInventoryItem != null) { - handlerMoveInventoryItem = null; + MoveInventoryItem handlerMoveInventoryItem = null; InventoryItemBase itm = null; List items = new List(); foreach (MoveInventoryItemPacket.InventoryDataBlock datablock in moveitem.InventoryData) @@ -7073,7 +7472,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryItem != null) { - handlerRemoveInventoryItem = null; + RemoveInventoryItem handlerRemoveInventoryItem = null; List uuids = new List(); foreach (RemoveInventoryItemPacket.InventoryDataBlock datablock in removeItem.InventoryData) { @@ -7101,7 +7500,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryFolder != null) { - handlerRemoveInventoryFolder = null; + RemoveInventoryFolder handlerRemoveInventoryFolder = null; List uuids = new List(); foreach (RemoveInventoryFolderPacket.FolderDataBlock datablock in removeFolder.FolderData) { @@ -7126,7 +7525,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion if (OnRemoveInventoryFolder != null) { - handlerRemoveInventoryFolder = null; + RemoveInventoryFolder handlerRemoveInventoryFolder = null; List uuids = new List(); foreach (RemoveInventoryObjectsPacket.FolderDataBlock datablock in removeObject.FolderData) { @@ -7141,7 +7540,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnRemoveInventoryItem != null) { - handlerRemoveInventoryItem = null; + RemoveInventoryItem handlerRemoveInventoryItem = null; List uuids = new List(); foreach (RemoveInventoryObjectsPacket.ItemDataBlock datablock in removeObject.ItemData) { @@ -7166,7 +7565,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRequestTaskInventory = OnRequestTaskInventory; + RequestTaskInventory handlerRequestTaskInventory = OnRequestTaskInventory; if (handlerRequestTaskInventory != null) { handlerRequestTaskInventory(this, requesttask.InventoryData.LocalID); @@ -7188,7 +7587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (updatetask.UpdateData.Key == 0) { - handlerUpdateTaskInventory = OnUpdateTaskInventory; + UpdateTaskInventory handlerUpdateTaskInventory = OnUpdateTaskInventory; if (handlerUpdateTaskInventory != null) { TaskInventoryItem newTaskItem = new TaskInventoryItem(); @@ -7232,7 +7631,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRemoveTaskItem = OnRemoveTaskItem; + RemoveTaskInventory handlerRemoveTaskItem = OnRemoveTaskItem; if (handlerRemoveTaskItem != null) { @@ -7254,7 +7653,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerMoveTaskItem = OnMoveTaskItem; + MoveTaskInventory handlerMoveTaskItem = OnMoveTaskItem; if (handlerMoveTaskItem != null) { @@ -7279,7 +7678,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRezScript = OnRezScript; + RezScript handlerRezScript = OnRezScript; InventoryItemBase item = new InventoryItemBase(); item.ID = rezScriptx.InventoryBlock.ItemID; item.Folder = rezScriptx.InventoryBlock.FolderID; @@ -7322,7 +7721,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRequestMapBlocks = OnRequestMapBlocks; + RequestMapBlocks handlerRequestMapBlocks = OnRequestMapBlocks; if (handlerRequestMapBlocks != null) { handlerRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, @@ -7343,7 +7742,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP string mapName = Util.UTF8.GetString(map.NameData.Name, 0, map.NameData.Name.Length - 1); - handlerMapNameRequest = OnMapNameRequest; + RequestMapName handlerMapNameRequest = OnMapNameRequest; if (handlerMapNameRequest != null) { handlerMapNameRequest(this, mapName); @@ -7394,7 +7793,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { // Teleport home request - handlerTeleportHomeRequest = OnTeleportHomeRequest; + UUIDNameRequest handlerTeleportHomeRequest = OnTeleportHomeRequest; if (handlerTeleportHomeRequest != null) { handlerTeleportHomeRequest(AgentId, this); @@ -7402,7 +7801,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP break; } - handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; + TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest; if (handlerTeleportLandmarkRequest != null) { handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position); @@ -7433,7 +7832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerTeleportLocationRequest = OnTeleportLocationRequest; + TeleportLocationRequest handlerTeleportLocationRequest = OnTeleportLocationRequest; if (handlerTeleportLocationRequest != null) { handlerTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position, @@ -7456,7 +7855,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock) { - handlerNameRequest = OnNameFromUUIDRequest; + UUIDNameRequest handlerNameRequest = OnNameFromUUIDRequest; if (handlerNameRequest != null) { handlerNameRequest(UUIDBlock.ID, this); @@ -7469,7 +7868,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RegionHandleRequest: RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; - handlerRegionHandleRequest = OnRegionHandleRequest; + RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; if (handlerRegionHandleRequest != null) { handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); @@ -7488,7 +7887,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelInfoRequest = OnParcelInfoRequest; + ParcelInfoRequest handlerParcelInfoRequest = OnParcelInfoRequest; if (handlerParcelInfoRequest != null) { handlerParcelInfoRequest(this, pirPack.Data.ParcelID); @@ -7507,7 +7906,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelAccessListRequest = OnParcelAccessListRequest; + ParcelAccessListRequest handlerParcelAccessListRequest = OnParcelAccessListRequest; if (handlerParcelAccessListRequest != null) { @@ -7539,7 +7938,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP entries.Add(entry); } - handlerParcelAccessListUpdateRequest = OnParcelAccessListUpdateRequest; + ParcelAccessListUpdateRequest handlerParcelAccessListUpdateRequest = OnParcelAccessListUpdateRequest; if (handlerParcelAccessListUpdateRequest != null) { handlerParcelAccessListUpdateRequest(updatePacket.AgentData.AgentID, @@ -7560,7 +7959,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelPropertiesRequest = OnParcelPropertiesRequest; + ParcelPropertiesRequest handlerParcelPropertiesRequest = OnParcelPropertiesRequest; if (handlerParcelPropertiesRequest != null) { handlerParcelPropertiesRequest((int)Math.Round(propertiesRequest.ParcelData.West), @@ -7583,7 +7982,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelDivideRequest = OnParcelDivideRequest; + ParcelDivideRequest handlerParcelDivideRequest = OnParcelDivideRequest; if (handlerParcelDivideRequest != null) { handlerParcelDivideRequest((int)Math.Round(landDivide.ParcelData.West), @@ -7604,7 +8003,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelJoinRequest = OnParcelJoinRequest; + ParcelJoinRequest handlerParcelJoinRequest = OnParcelJoinRequest; if (handlerParcelJoinRequest != null) { @@ -7626,7 +8025,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelPropertiesUpdateRequest = OnParcelPropertiesUpdateRequest; + ParcelPropertiesUpdateRequest handlerParcelPropertiesUpdateRequest = OnParcelPropertiesUpdateRequest; if (handlerParcelPropertiesUpdateRequest != null) { @@ -7672,7 +8071,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP returnIDs.Add(rb.ReturnID); } - handlerParcelSelectObjects = OnParcelSelectObjects; + ParcelSelectObjects handlerParcelSelectObjects = OnParcelSelectObjects; if (handlerParcelSelectObjects != null) { @@ -7693,7 +8092,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelObjectOwnerRequest = OnParcelObjectOwnerRequest; + ParcelObjectOwnerRequest handlerParcelObjectOwnerRequest = OnParcelObjectOwnerRequest; if (handlerParcelObjectOwnerRequest != null) { @@ -7712,7 +8111,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelGodForceOwner = OnParcelGodForceOwner; + ParcelGodForceOwner handlerParcelGodForceOwner = OnParcelGodForceOwner; if (handlerParcelGodForceOwner != null) { handlerParcelGodForceOwner(godForceOwnerPacket.Data.LocalID, godForceOwnerPacket.Data.OwnerID, this); @@ -7730,7 +8129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelAbandonRequest = OnParcelAbandonRequest; + ParcelAbandonRequest handlerParcelAbandonRequest = OnParcelAbandonRequest; if (handlerParcelAbandonRequest != null) { handlerParcelAbandonRequest(releasePacket.Data.LocalID, this); @@ -7748,7 +8147,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelReclaim = OnParcelReclaim; + ParcelReclaim handlerParcelReclaim = OnParcelReclaim; if (handlerParcelReclaim != null) { handlerParcelReclaim(reclaimPacket.Data.LocalID, this); @@ -7777,7 +8176,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int parceliterator = 0; parceliterator < parcelReturnObjects.TaskIDs.Length; parceliterator++) puserselectedTaskIDs[parceliterator] = parcelReturnObjects.TaskIDs[parceliterator].TaskID; - handlerParcelReturnObjectsRequest = OnParcelReturnObjectsRequest; + ParcelReturnObjectsRequest handlerParcelReturnObjectsRequest = OnParcelReturnObjectsRequest; if (handlerParcelReturnObjectsRequest != null) { handlerParcelReturnObjectsRequest(parcelReturnObjects.ParcelData.LocalID, parcelReturnObjects.ParcelData.ReturnType, puserselectedOwnerIDs, puserselectedTaskIDs, this); @@ -7797,7 +8196,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelSetOtherCleanTime = OnParcelSetOtherCleanTime; + ParcelSetOtherCleanTime handlerParcelSetOtherCleanTime = OnParcelSetOtherCleanTime; if (handlerParcelSetOtherCleanTime != null) { handlerParcelSetOtherCleanTime(this, @@ -7818,7 +8217,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerLandStatRequest = OnLandStatRequest; + GodLandStatRequest handlerLandStatRequest = OnLandStatRequest; if (handlerLandStatRequest != null) { handlerLandStatRequest(lsrp.RequestData.ParcelLocalID, lsrp.RequestData.ReportType, lsrp.RequestData.RequestFlags, Utils.BytesToString(lsrp.RequestData.Filter), this); @@ -7838,7 +8237,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerParcelDwellRequest = OnParcelDwellRequest; + ParcelDwellRequest handlerParcelDwellRequest = OnParcelDwellRequest; if (handlerParcelDwellRequest != null) { handlerParcelDwellRequest(dwellrq.Data.LocalID, this); @@ -8082,7 +8481,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (Utils.BytesToString(messagePacket.ParamList[0].Parameter) == "bake") { - handlerBakeTerrain = OnBakeTerrain; + BakeTerrain handlerBakeTerrain = OnBakeTerrain; if (handlerBakeTerrain != null) { handlerBakeTerrain(this); @@ -8092,7 +8491,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (messagePacket.ParamList.Length > 1) { - handlerRequestTerrain = OnRequestTerrain; + RequestTerrain handlerRequestTerrain = OnRequestTerrain; if (handlerRequestTerrain != null) { handlerRequestTerrain(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter)); @@ -8103,7 +8502,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (messagePacket.ParamList.Length > 1) { - handlerUploadTerrain = OnUploadTerrain; + RequestTerrain handlerUploadTerrain = OnUploadTerrain; if (handlerUploadTerrain != null) { handlerUploadTerrain(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter)); @@ -8125,7 +8524,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP UInt32 param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter)); UInt32 param2 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[2].Parameter)); - handlerEstateChangeInfo = OnEstateChangeInfo; + EstateChangeInfo handlerEstateChangeInfo = OnEstateChangeInfo; if (handlerEstateChangeInfo != null) { handlerEstateChangeInfo(this, invoice, SenderID, param1, param2); @@ -8159,7 +8558,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRegionInfoRequest = OnRegionInfoRequest; + RegionInfoRequest handlerRegionInfoRequest = OnRegionInfoRequest; if (handlerRegionInfoRequest != null) { handlerRegionInfoRequest(this); @@ -8170,7 +8569,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //EstateCovenantRequestPacket.AgentDataBlock epack = // ((EstateCovenantRequestPacket)Pack).AgentData; - handlerEstateCovenantRequest = OnEstateCovenantRequest; + EstateCovenantRequest handlerEstateCovenantRequest = OnEstateCovenantRequest; if (handlerEstateCovenantRequest != null) { handlerEstateCovenantRequest(this); @@ -8188,7 +8587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP RequestGodlikePowersPacket.AgentDataBlock ablock = rglpPack.AgentData; - handlerReqGodlikePowers = OnRequestGodlikePowers; + RequestGodlikePowers handlerReqGodlikePowers = OnRequestGodlikePowers; if (handlerReqGodlikePowers != null) { @@ -8201,7 +8600,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (gkupack.UserInfo.GodSessionID == SessionId && AgentId == gkupack.UserInfo.GodID) { - handlerGodKickUser = OnGodKickUser; + GodKickUser handlerGodKickUser = OnGodKickUser; if (handlerGodKickUser != null) { handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID, @@ -8241,7 +8640,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerMoneyBalanceRequest = OnMoneyBalanceRequest; + MoneyBalanceRequest handlerMoneyBalanceRequest = OnMoneyBalanceRequest; if (handlerMoneyBalanceRequest != null) { @@ -8252,7 +8651,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.EconomyDataRequest: - handlerEconomoyDataRequest = OnEconomyDataRequest; + EconomyDataRequest handlerEconomoyDataRequest = OnEconomyDataRequest; if (handlerEconomoyDataRequest != null) { handlerEconomoyDataRequest(AgentId); @@ -8261,7 +8660,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.RequestPayPrice: RequestPayPricePacket requestPayPricePacket = (RequestPayPricePacket)Pack; - handlerRequestPayPrice = OnRequestPayPrice; + RequestPayPrice handlerRequestPayPrice = OnRequestPayPrice; if (handlerRequestPayPrice != null) { handlerRequestPayPrice(this, requestPayPricePacket.ObjectData.ObjectID); @@ -8280,7 +8679,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectSaleInfo = OnObjectSaleInfo; + ObjectSaleInfo handlerObjectSaleInfo = OnObjectSaleInfo; if (handlerObjectSaleInfo != null) { foreach (ObjectSaleInfoPacket.ObjectDataBlock d @@ -8308,7 +8707,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerObjectBuy = OnObjectBuy; + ObjectBuy handlerObjectBuy = OnObjectBuy; if (handlerObjectBuy != null) { @@ -8334,7 +8733,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP case PacketType.GetScriptRunning: GetScriptRunningPacket scriptRunning = (GetScriptRunningPacket)Pack; - handlerGetScriptRunning = OnGetScriptRunning; + GetScriptRunning handlerGetScriptRunning = OnGetScriptRunning; if (handlerGetScriptRunning != null) { handlerGetScriptRunning(this, scriptRunning.Script.ObjectID, scriptRunning.Script.ItemID); @@ -8353,7 +8752,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerSetScriptRunning = OnSetScriptRunning; + SetScriptRunning handlerSetScriptRunning = OnSetScriptRunning; if (handlerSetScriptRunning != null) { handlerSetScriptRunning(this, setScriptRunning.Script.ObjectID, setScriptRunning.Script.ItemID, setScriptRunning.Script.Running); @@ -8372,7 +8771,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerScriptReset = OnScriptReset; + ScriptReset handlerScriptReset = OnScriptReset; if (handlerScriptReset != null) { handlerScriptReset(this, scriptResetPacket.Script.ObjectID, scriptResetPacket.Script.ItemID); @@ -8395,7 +8794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerActivateGesture = OnActivateGesture; + ActivateGesture handlerActivateGesture = OnActivateGesture; if (handlerActivateGesture != null) { handlerActivateGesture(this, @@ -8418,7 +8817,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDeactivateGesture = OnDeactivateGesture; + DeactivateGesture handlerDeactivateGesture = OnDeactivateGesture; if (handlerDeactivateGesture != null) { handlerDeactivateGesture(this, deactivateGesturePacket.Data[0].ItemID); @@ -8441,7 +8840,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP foreach (ObjectOwnerPacket.ObjectDataBlock d in objectOwnerPacket.ObjectData) localIDs.Add(d.ObjectLocalID); - handlerObjectOwner = OnObjectOwner; + ObjectOwner handlerObjectOwner = OnObjectOwner; if (handlerObjectOwner != null) { handlerObjectOwner(this, objectOwnerPacket.HeaderData.OwnerID, objectOwnerPacket.HeaderData.GroupID, localIDs); @@ -8454,14 +8853,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region unimplemented handlers case PacketType.StartPingCheck: - // Send the client the ping response back - // Pass the same PingID in the matching packet - // Handled In the packet processing - //m_log.Debug("[CLIENT]: possibly unhandled StartPingCheck packet"); + StartPingCheckPacket pingStart = (StartPingCheckPacket)Pack; + CompletePingCheckPacket pingComplete = new CompletePingCheckPacket(); + pingComplete.PingID.PingID = pingStart.PingID.PingID; + m_udpServer.SendPacket(m_udpClient, pingComplete, ThrottleOutPacketType.Unknown, false); break; + case PacketType.CompletePingCheck: - // TODO: Perhaps this should be processed on the Sim to determine whether or not to drop a dead client - //m_log.Warn("[CLIENT]: unhandled CompletePingCheck packet"); + // TODO: Do stats tracking or something with these? break; case PacketType.ViewerStats: @@ -8482,7 +8881,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion //m_log.Debug(mirpk.ToString()); - handlerMapItemRequest = OnMapItemRequest; + MapItemRequest handlerMapItemRequest = OnMapItemRequest; if (handlerMapItemRequest != null) { handlerMapItemRequest(this,mirpk.AgentData.Flags, mirpk.AgentData.EstateID, @@ -8509,7 +8908,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerMuteListRequest = OnMuteListRequest; + MuteListRequest handlerMuteListRequest = OnMuteListRequest; if (handlerMuteListRequest != null) { handlerMuteListRequest(this, muteListRequest.MuteData.MuteCRC); @@ -8546,7 +8945,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirPlacesQuery = OnDirPlacesQuery; + DirPlacesQuery handlerDirPlacesQuery = OnDirPlacesQuery; if (handlerDirPlacesQuery != null) { handlerDirPlacesQuery(this, @@ -8572,7 +8971,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirFindQuery = OnDirFindQuery; + DirFindQuery handlerDirFindQuery = OnDirFindQuery; if (handlerDirFindQuery != null) { handlerDirFindQuery(this, @@ -8595,7 +8994,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirLandQuery = OnDirLandQuery; + DirLandQuery handlerDirLandQuery = OnDirLandQuery; if (handlerDirLandQuery != null) { handlerDirLandQuery(this, @@ -8619,7 +9018,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirPopularQuery = OnDirPopularQuery; + DirPopularQuery handlerDirPopularQuery = OnDirPopularQuery; if (handlerDirPopularQuery != null) { handlerDirPopularQuery(this, @@ -8639,7 +9038,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerDirClassifiedQuery = OnDirClassifiedQuery; + DirClassifiedQuery handlerDirClassifiedQuery = OnDirClassifiedQuery; if (handlerDirClassifiedQuery != null) { handlerDirClassifiedQuery(this, @@ -9155,7 +9554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelDeedToGroupPacket parcelDeedToGroup = (ParcelDeedToGroupPacket)Pack; if (m_GroupsModule != null) { - handlerParcelDeedToGroup = OnParcelDeedToGroup; + ParcelDeedToGroup handlerParcelDeedToGroup = OnParcelDeedToGroup; if (handlerParcelDeedToGroup != null) { handlerParcelDeedToGroup(parcelDeedToGroup.Data.LocalID, parcelDeedToGroup.Data.GroupID,this); @@ -9399,7 +9798,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerStartLure = OnStartLure; + StartLure handlerStartLure = OnStartLure; if (handlerStartLure != null) handlerStartLure(startLureRequest.Info.LureType, Utils.BytesToString( @@ -9421,7 +9820,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerTeleportLureRequest = OnTeleportLureRequest; + TeleportLureRequest handlerTeleportLureRequest = OnTeleportLureRequest; if (handlerTeleportLureRequest != null) handlerTeleportLureRequest( teleportLureRequest.Info.LureID, @@ -9442,7 +9841,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerClassifiedInfoRequest = OnClassifiedInfoRequest; + ClassifiedInfoRequest handlerClassifiedInfoRequest = OnClassifiedInfoRequest; if (handlerClassifiedInfoRequest != null) handlerClassifiedInfoRequest( classifiedInfoRequest.Data.ClassifiedID, @@ -9462,7 +9861,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerClassifiedInfoUpdate = OnClassifiedInfoUpdate; + ClassifiedInfoUpdate handlerClassifiedInfoUpdate = OnClassifiedInfoUpdate; if (handlerClassifiedInfoUpdate != null) handlerClassifiedInfoUpdate( classifiedInfoUpdate.Data.ClassifiedID, @@ -9494,7 +9893,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerClassifiedDelete = OnClassifiedDelete; + ClassifiedDelete handlerClassifiedDelete = OnClassifiedDelete; if (handlerClassifiedDelete != null) handlerClassifiedDelete( classifiedDelete.Data.ClassifiedID, @@ -9514,7 +9913,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerClassifiedGodDelete = OnClassifiedGodDelete; + ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; if (handlerClassifiedGodDelete != null) handlerClassifiedGodDelete( classifiedGodDelete.Data.ClassifiedID, @@ -9534,7 +9933,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerEventGodDelete = OnEventGodDelete; + EventGodDelete handlerEventGodDelete = OnEventGodDelete; if (handlerEventGodDelete != null) handlerEventGodDelete( eventGodDelete.EventData.EventID, @@ -9559,7 +9958,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerEventNotificationAddRequest = OnEventNotificationAddRequest; + EventNotificationAddRequest handlerEventNotificationAddRequest = OnEventNotificationAddRequest; if (handlerEventNotificationAddRequest != null) handlerEventNotificationAddRequest( eventNotificationAdd.EventData.EventID, this); @@ -9578,7 +9977,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerEventNotificationRemoveRequest = OnEventNotificationRemoveRequest; + EventNotificationRemoveRequest handlerEventNotificationRemoveRequest = OnEventNotificationRemoveRequest; if (handlerEventNotificationRemoveRequest != null) handlerEventNotificationRemoveRequest( eventNotificationRemove.EventData.EventID, this); @@ -9596,7 +9995,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerRetrieveInstantMessages = OnRetrieveInstantMessages; + RetrieveInstantMessages handlerRetrieveInstantMessages = OnRetrieveInstantMessages; if (handlerRetrieveInstantMessages != null) handlerRetrieveInstantMessages(this); break; @@ -9614,7 +10013,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerPickDelete = OnPickDelete; + PickDelete handlerPickDelete = OnPickDelete; if (handlerPickDelete != null) handlerPickDelete(this, pickDelete.Data.PickID); break; @@ -9631,7 +10030,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerPickGodDelete = OnPickGodDelete; + PickGodDelete handlerPickGodDelete = OnPickGodDelete; if (handlerPickGodDelete != null) handlerPickGodDelete(this, pickGodDelete.AgentData.AgentID, @@ -9651,7 +10050,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerPickInfoUpdate = OnPickInfoUpdate; + PickInfoUpdate handlerPickInfoUpdate = OnPickInfoUpdate; if (handlerPickInfoUpdate != null) handlerPickInfoUpdate(this, pickInfoUpdate.Data.PickID, @@ -9676,7 +10075,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - handlerAvatarNotesUpdate = OnAvatarNotesUpdate; + AvatarNotesUpdate handlerAvatarNotesUpdate = OnAvatarNotesUpdate; if (handlerAvatarNotesUpdate != null) handlerAvatarNotesUpdate(this, avatarNotesUpdate.Data.TargetID, @@ -9693,7 +10092,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP PlacesQueryPacket placesQueryPacket = (PlacesQueryPacket)Pack; - handlerPlacesQuery = OnPlacesQuery; + PlacesQuery handlerPlacesQuery = OnPlacesQuery; if (handlerPlacesQuery != null) handlerPlacesQuery(placesQueryPacket.AgentData.QueryID, @@ -9747,306 +10146,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP //shape.Textures = ntex; return shape; } - - /// - /// Send the client an Estate message blue box pop-down with a single OK button - /// - /// - /// - /// - /// - public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message) - { - if (!ChildAgentStatus()) - SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3())); - - //SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch()); - } - - public void SendLogoutPacket() - { - // I know this is a bit of a hack, however there are times when you don't - // want to send this, but still need to do the rest of the shutdown process - // this method gets called from the packet server.. which makes it practically - // impossible to do any other way. - - if (m_SendLogoutPacketWhenClosing) - { - LogoutReplyPacket logReply = (LogoutReplyPacket)PacketPool.Instance.GetPacket(PacketType.LogoutReply); - // TODO: don't create new blocks if recycling an old packet - logReply.AgentData.AgentID = AgentId; - logReply.AgentData.SessionID = SessionId; - logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; - logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); - logReply.InventoryData[0].ItemID = UUID.Zero; - - OutPacket(logReply, ThrottleOutPacketType.Task); - } - } - - public void SendHealth(float health) - { - HealthMessagePacket healthpacket = (HealthMessagePacket)PacketPool.Instance.GetPacket(PacketType.HealthMessage); - healthpacket.HealthData.Health = health; - OutPacket(healthpacket, ThrottleOutPacketType.Task); - } - - public void SendAgentOnline(UUID[] agentIDs) - { - OnlineNotificationPacket onp = new OnlineNotificationPacket(); - OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length]; - for (int i = 0; i < agentIDs.Length; i++) - { - OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); - onpbl.AgentID = agentIDs[i]; - onpb[i] = onpbl; - } - onp.AgentBlock = onpb; - onp.Header.Reliable = true; - OutPacket(onp, ThrottleOutPacketType.Task); - } - - public void SendAgentOffline(UUID[] agentIDs) - { - OfflineNotificationPacket offp = new OfflineNotificationPacket(); - OfflineNotificationPacket.AgentBlockBlock[] offpb = new OfflineNotificationPacket.AgentBlockBlock[agentIDs.Length]; - for (int i = 0; i < agentIDs.Length; i++) - { - OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); - onpbl.AgentID = agentIDs[i]; - offpb[i] = onpbl; - } - offp.AgentBlock = offpb; - offp.Header.Reliable = true; - OutPacket(offp, ThrottleOutPacketType.Task); - } - - public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, - Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook) - { - AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket(); - avatarSitResponse.SitObject.ID = TargetID; - if (CameraAtOffset != Vector3.Zero) - { - avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset; - avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset; - } - avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook; - avatarSitResponse.SitTransform.AutoPilot = autopilot; - avatarSitResponse.SitTransform.SitPosition = OffsetPos; - avatarSitResponse.SitTransform.SitRotation = SitOrientation; - - OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); - } - - public void SendAdminResponse(UUID Token, uint AdminLevel) - { - GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket(); - GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock(); - GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock(); - - adb.AgentID = AgentId; - adb.SessionID = SessionId; // More security - gdb.GodLevel = (byte)AdminLevel; - gdb.Token = Token; - //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock; - respondPacket.GrantData = gdb; - respondPacket.AgentData = adb; - OutPacket(respondPacket, ThrottleOutPacketType.Task); - } - - public void SendGroupMembership(GroupMembershipData[] GroupMembership) - { - m_groupPowers.Clear(); - - AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket(); - AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[GroupMembership.Length]; - for (int i = 0; i < GroupMembership.Length; i++) - { - m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; - - AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock(); - Group.AcceptNotices = GroupMembership[i].AcceptNotices; - Group.Contribution = GroupMembership[i].Contribution; - Group.GroupID = GroupMembership[i].GroupID; - Group.GroupInsigniaID = GroupMembership[i].GroupPicture; - Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); - Group.GroupPowers = GroupMembership[i].GroupPowers; - Groups[i] = Group; - - - } - Groupupdate.GroupData = Groups; - Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock(); - Groupupdate.AgentData.AgentID = AgentId; - OutPacket(Groupupdate, ThrottleOutPacketType.Task); - - try - { - IEventQueue eq = Scene.RequestModuleInterface(); - if (eq != null) - { - eq.GroupMembership(Groupupdate, this.AgentId); - } - } - catch (Exception ex) - { - m_log.Error("Unable to send group membership data via eventqueue - exception: " + ex.ToString()); - m_log.Warn("sending group membership data via UDP"); - OutPacket(Groupupdate, ThrottleOutPacketType.Task); - } - } - - - public void SendGroupNameReply(UUID groupLLUID, string GroupName) - { - UUIDGroupNameReplyPacket pack = new UUIDGroupNameReplyPacket(); - UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; - UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); - uidnamebloc.ID = groupLLUID; - uidnamebloc.GroupName = Utils.StringToBytes(GroupName); - uidnameblock[0] = uidnamebloc; - pack.UUIDNameBlock = uidnameblock; - OutPacket(pack, ThrottleOutPacketType.Task); - } - - public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia) - { - LandStatReplyPacket lsrp = new LandStatReplyPacket(); - // LandStatReplyPacket.RequestDataBlock lsreqdpb = new LandStatReplyPacket.RequestDataBlock(); - LandStatReplyPacket.ReportDataBlock[] lsrepdba = new LandStatReplyPacket.ReportDataBlock[lsrpia.Length]; - //LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); - // lsrepdb. - lsrp.RequestData.ReportType = reportType; - lsrp.RequestData.RequestFlags = requestFlags; - lsrp.RequestData.TotalObjectCount = resultCount; - for (int i = 0; i < lsrpia.Length; i++) - { - LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock(); - lsrepdb.LocationX = lsrpia[i].LocationX; - lsrepdb.LocationY = lsrpia[i].LocationY; - lsrepdb.LocationZ = lsrpia[i].LocationZ; - lsrepdb.Score = lsrpia[i].Score; - lsrepdb.TaskID = lsrpia[i].TaskID; - lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; - lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); - lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); - lsrepdba[i] = lsrepdb; - } - lsrp.ReportData = lsrepdba; - OutPacket(lsrp, ThrottleOutPacketType.Task); - } - - public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running) - { - ScriptRunningReplyPacket scriptRunningReply = new ScriptRunningReplyPacket(); - scriptRunningReply.Script.ObjectID = objectID; - scriptRunningReply.Script.ItemID = itemID; - scriptRunningReply.Script.Running = running; - - OutPacket(scriptRunningReply, ThrottleOutPacketType.Task); - } - - public void SendAsset(AssetRequestToClient req) - { - //m_log.Debug("sending asset " + req.RequestAssetID); - TransferInfoPacket Transfer = new TransferInfoPacket(); - Transfer.TransferInfo.ChannelType = 2; - Transfer.TransferInfo.Status = 0; - Transfer.TransferInfo.TargetType = 0; - if (req.AssetRequestSource == 2) - { - Transfer.TransferInfo.Params = new byte[20]; - Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - int assType = req.AssetInf.Type; - Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); - } - else if (req.AssetRequestSource == 3) - { - Transfer.TransferInfo.Params = req.Params; - // Transfer.TransferInfo.Params = new byte[100]; - //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); - //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); - } - Transfer.TransferInfo.Size = req.AssetInf.Data.Length; - Transfer.TransferInfo.TransferID = req.TransferRequestID; - Transfer.Header.Zerocoded = true; - OutPacket(Transfer, ThrottleOutPacketType.Asset); - - if (req.NumPackets == 1) - { - TransferPacketPacket TransferPacket = new TransferPacketPacket(); - TransferPacket.TransferData.Packet = 0; - TransferPacket.TransferData.ChannelType = 2; - TransferPacket.TransferData.TransferID = req.TransferRequestID; - TransferPacket.TransferData.Data = req.AssetInf.Data; - TransferPacket.TransferData.Status = 1; - TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, ThrottleOutPacketType.Asset); - } - else - { - int processedLength = 0; - int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; - int packetNumber = 0; - - while (processedLength < req.AssetInf.Data.Length) - { - TransferPacketPacket TransferPacket = new TransferPacketPacket(); - TransferPacket.TransferData.Packet = packetNumber; - TransferPacket.TransferData.ChannelType = 2; - TransferPacket.TransferData.TransferID = req.TransferRequestID; - - int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); - byte[] chunk = new byte[chunkSize]; - Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); - - TransferPacket.TransferData.Data = chunk; - - // 0 indicates more packets to come, 1 indicates last packet - if (req.AssetInf.Data.Length - processedLength > maxChunkSize) - { - TransferPacket.TransferData.Status = 0; - } - else - { - TransferPacket.TransferData.Status = 1; - } - TransferPacket.Header.Zerocoded = true; - OutPacket(TransferPacket, ThrottleOutPacketType.Asset); - - processedLength += chunkSize; - packetNumber++; - } - } - } - - public void SendTexture(AssetBase TextureAsset) - { - - } - + public ClientInfo GetClientInfo() { - ClientInfo info = m_PacketHandler.GetClientInfo(); + ClientInfo info = m_udpClient.GetClientInfo(); info.userEP = m_userEndPoint; - info.proxyEP = m_proxyEndPoint; + info.proxyEP = null; info.agentcircuit = new sAgentCircuitData(RequestClientInfo()); return info; } + public void SetClientInfo(ClientInfo info) + { + m_udpClient.SetClientInfo(info); + } + public EndPoint GetClientEP() { return m_userEndPoint; } - public void SetClientInfo(ClientInfo info) - { - m_PacketHandler.SetClientInfo(info); - } - #region Media Parcel Members public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time) @@ -10079,7 +10200,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion - #region Camera public void SendSetFollowCamProperties (UUID objectID, SortedDictionary parameters) @@ -10109,70 +10229,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion - public void SendRegionHandle(UUID regionID, ulong handle) { - RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply); - reply.ReplyBlock.RegionID = regionID; - reply.ReplyBlock.RegionHandle = handle; - OutPacket(reply, ThrottleOutPacketType.Land); - } - - public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) - { - ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); - reply.AgentData.AgentID = m_agentId; - reply.Data.ParcelID = parcelID; - reply.Data.OwnerID = land.OwnerID; - reply.Data.Name = Utils.StringToBytes(land.Name); - reply.Data.Desc = Utils.StringToBytes(land.Description); - reply.Data.ActualArea = land.Area; - reply.Data.BillableArea = land.Area; // TODO: what is this? - - // Bit 0: Mature, bit 7: on sale, other bits: no idea - reply.Data.Flags = (byte)( - ((land.Flags & (uint)ParcelFlags.MaturePublish) != 0 ? (1 << 0) : 0) + - ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0)); - - Vector3 pos = land.UserLocation; - if (pos.Equals(Vector3.Zero)) - { - pos = (land.AABBMax + land.AABBMin) * 0.5f; - } - reply.Data.GlobalX = info.RegionLocX * Constants.RegionSize + x; - reply.Data.GlobalY = info.RegionLocY * Constants.RegionSize + y; - reply.Data.GlobalZ = pos.Z; - reply.Data.SimName = Utils.StringToBytes(info.RegionName); - reply.Data.SnapshotID = land.SnapshotID; - reply.Data.Dwell = land.Dwell; - reply.Data.SalePrice = land.SalePrice; - reply.Data.AuctionID = (int)land.AuctionID; - - OutPacket(reply, ThrottleOutPacketType.Land); - } - - public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt) - { - ScriptTeleportRequestPacket packet = (ScriptTeleportRequestPacket)PacketPool.Instance.GetPacket(PacketType.ScriptTeleportRequest); - - packet.Data.ObjectName = Utils.StringToBytes(objName); - packet.Data.SimName = Utils.StringToBytes(simName); - packet.Data.SimPosition = pos; - packet.Data.LookAt = lookAt; - - OutPacket(packet, ThrottleOutPacketType.Task); - } - public void SetClientOption(string option, string value) { switch (option) { - case "ReliableIsImportant": - bool val; - - if (bool.TryParse(value, out val)) - m_PacketHandler.ReliableIsImportant = val; - break; - default: - break; + default: + break; } } @@ -10180,571 +10242,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP { switch (option) { - case "ReliableIsImportant": - return m_PacketHandler.ReliableIsImportant.ToString(); - default: break; } return string.Empty; } - public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data) - { - DirPlacesReplyPacket packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply); - - packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock(); - - packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; - packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); - - packet.QueryReplies = - new DirPlacesReplyPacket.QueryRepliesBlock[data.Length]; - - packet.StatusData = new DirPlacesReplyPacket.StatusDataBlock[ - data.Length]; - - packet.AgentData.AgentID = AgentId; - - packet.QueryData[0].QueryID = queryID; - - int i = 0; - foreach (DirPlacesReplyData d in data) - { - packet.QueryReplies[i] = - new DirPlacesReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirPlacesReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = Utils.StringToBytes(d.name); - packet.QueryReplies[i].ForSale = d.forSale; - packet.QueryReplies[i].Auction = d.auction; - packet.QueryReplies[i].Dwell = d.dwell; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data) - { - DirPeopleReplyPacket packet = (DirPeopleReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPeopleReply); - - packet.AgentData = new DirPeopleReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirPeopleReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirPeopleReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirPeopleReplyData d in data) - { - packet.QueryReplies[i] = new DirPeopleReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].AgentID = d.agentID; - packet.QueryReplies[i].FirstName = - Utils.StringToBytes(d.firstName); - packet.QueryReplies[i].LastName = - Utils.StringToBytes(d.lastName); - packet.QueryReplies[i].Group = - Utils.StringToBytes(d.group); - packet.QueryReplies[i].Online = d.online; - packet.QueryReplies[i].Reputation = d.reputation; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data) - { - DirEventsReplyPacket packet = (DirEventsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirEventsReply); - - packet.AgentData = new DirEventsReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirEventsReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirEventsReplyPacket.QueryRepliesBlock[ - data.Length]; - - packet.StatusData = new DirEventsReplyPacket.StatusDataBlock[ - data.Length]; - - int i = 0; - foreach (DirEventsReplyData d in data) - { - packet.QueryReplies[i] = new DirEventsReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirEventsReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].OwnerID = d.ownerID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].EventID = d.eventID; - packet.QueryReplies[i].Date = - Utils.StringToBytes(d.date); - packet.QueryReplies[i].UnixTime = d.unixTime; - packet.QueryReplies[i].EventFlags = d.eventFlags; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data) - { - DirGroupsReplyPacket packet = (DirGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirGroupsReply); - - packet.AgentData = new DirGroupsReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirGroupsReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirGroupsReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirGroupsReplyData d in data) - { - packet.QueryReplies[i] = new DirGroupsReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].GroupID = d.groupID; - packet.QueryReplies[i].GroupName = - Utils.StringToBytes(d.groupName); - packet.QueryReplies[i].Members = d.members; - packet.QueryReplies[i].SearchOrder = d.searchOrder; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data) - { - DirClassifiedReplyPacket packet = (DirClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirClassifiedReply); - - packet.AgentData = new DirClassifiedReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirClassifiedReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirClassifiedReplyPacket.QueryRepliesBlock[ - data.Length]; - packet.StatusData = new DirClassifiedReplyPacket.StatusDataBlock[ - data.Length]; - - int i = 0; - foreach (DirClassifiedReplyData d in data) - { - packet.QueryReplies[i] = new DirClassifiedReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirClassifiedReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].ClassifiedID = d.classifiedID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].ClassifiedFlags = d.classifiedFlags; - packet.QueryReplies[i].CreationDate = d.creationDate; - packet.QueryReplies[i].ExpirationDate = d.expirationDate; - packet.QueryReplies[i].PriceForListing = d.price; - packet.StatusData[i].Status = d.Status; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirLandReply(UUID queryID, DirLandReplyData[] data) - { - DirLandReplyPacket packet = (DirLandReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirLandReply); - - packet.AgentData = new DirLandReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirLandReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirLandReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirLandReplyData d in data) - { - packet.QueryReplies[i] = new DirLandReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].Auction = d.auction; - packet.QueryReplies[i].ForSale = d.forSale; - packet.QueryReplies[i].SalePrice = d.salePrice; - packet.QueryReplies[i].ActualArea = d.actualArea; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data) - { - DirPopularReplyPacket packet = (DirPopularReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPopularReply); - - packet.AgentData = new DirPopularReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.QueryData = new DirPopularReplyPacket.QueryDataBlock(); - packet.QueryData.QueryID = queryID; - - packet.QueryReplies = new DirPopularReplyPacket.QueryRepliesBlock[ - data.Length]; - - int i = 0; - foreach (DirPopularReplyData d in data) - { - packet.QueryReplies[i] = new DirPopularReplyPacket.QueryRepliesBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = - Utils.StringToBytes(d.name); - packet.QueryReplies[i].Dwell = d.dwell; - i++; - } - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendEventInfoReply(EventData data) - { - EventInfoReplyPacket packet = (EventInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.EventInfoReply); - - packet.AgentData = new EventInfoReplyPacket.AgentDataBlock(); - packet.AgentData.AgentID = AgentId; - - packet.EventData = new EventInfoReplyPacket.EventDataBlock(); - packet.EventData.EventID = data.eventID; - packet.EventData.Creator = Utils.StringToBytes(data.creator); - packet.EventData.Name = Utils.StringToBytes(data.name); - packet.EventData.Category = Utils.StringToBytes(data.category); - packet.EventData.Desc = Utils.StringToBytes(data.description); - packet.EventData.Date = Utils.StringToBytes(data.date); - packet.EventData.DateUTC = data.dateUTC; - packet.EventData.Duration = data.duration; - packet.EventData.Cover = data.cover; - packet.EventData.Amount = data.amount; - packet.EventData.SimName = Utils.StringToBytes(data.simName); - packet.EventData.GlobalPos = new Vector3d(data.globalPos); - packet.EventData.EventFlags = data.eventFlags; - - OutPacket(packet, ThrottleOutPacketType.Task); - } - - public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags) - { - MapItemReplyPacket mirplk = new MapItemReplyPacket(); - mirplk.AgentData.AgentID = AgentId; - mirplk.RequestData.ItemType = mapitemtype; - mirplk.Data = new MapItemReplyPacket.DataBlock[replies.Length]; - for (int i = 0; i < replies.Length; i++) - { - MapItemReplyPacket.DataBlock mrdata = new MapItemReplyPacket.DataBlock(); - mrdata.X = replies[i].x; - mrdata.Y = replies[i].y; - mrdata.ID = replies[i].id; - mrdata.Extra = replies[i].Extra; - mrdata.Extra2 = replies[i].Extra2; - mrdata.Name = Utils.StringToBytes(replies[i].name); - mirplk.Data[i] = mrdata; - } - //m_log.Debug(mirplk.ToString()); - OutPacket(mirplk, ThrottleOutPacketType.Task); - - } - - public void SendOfferCallingCard(UUID srcID, UUID transactionID) - { - // a bit special, as this uses AgentID to store the source instead - // of the destination. The destination (the receiver) goes into destID - OfferCallingCardPacket p = (OfferCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.OfferCallingCard); - p.AgentData.AgentID = srcID; - p.AgentData.SessionID = UUID.Zero; - p.AgentBlock.DestID = AgentId; - p.AgentBlock.TransactionID = transactionID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAcceptCallingCard(UUID transactionID) - { - AcceptCallingCardPacket p = (AcceptCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.AcceptCallingCard); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = UUID.Zero; - p.FolderData = new AcceptCallingCardPacket.FolderDataBlock[1]; - p.FolderData[0] = new AcceptCallingCardPacket.FolderDataBlock(); - p.FolderData[0].FolderID = UUID.Zero; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendDeclineCallingCard(UUID transactionID) - { - DeclineCallingCardPacket p = (DeclineCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.DeclineCallingCard); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = UUID.Zero; - p.TransactionBlock.TransactionID = transactionID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendTerminateFriend(UUID exFriendID) - { - TerminateFriendshipPacket p = (TerminateFriendshipPacket)PacketPool.Instance.GetPacket(PacketType.TerminateFriendship); - p.AgentData.AgentID = AgentId; - p.AgentData.SessionID = SessionId; - p.ExBlock.OtherID = exFriendID; - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data) - { - AvatarGroupsReplyPacket p = (AvatarGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarGroupsReply); - - p.AgentData = new AvatarGroupsReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - p.AgentData.AvatarID = avatarID; - - p.GroupData = new AvatarGroupsReplyPacket.GroupDataBlock[data.Length]; - int i = 0; - foreach (GroupMembershipData m in data) - { - p.GroupData[i] = new AvatarGroupsReplyPacket.GroupDataBlock(); - p.GroupData[i].GroupPowers = m.GroupPowers; - p.GroupData[i].AcceptNotices = m.AcceptNotices; - p.GroupData[i].GroupTitle = Utils.StringToBytes(m.GroupTitle); - p.GroupData[i].GroupID = m.GroupID; - p.GroupData[i].GroupName = Utils.StringToBytes(m.GroupName); - p.GroupData[i].GroupInsigniaID = m.GroupPicture; - i++; - } - - p.NewGroupData = new AvatarGroupsReplyPacket.NewGroupDataBlock(); - p.NewGroupData.ListInProfile = true; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendJoinGroupReply(UUID groupID, bool success) - { - JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply); - - p.AgentData = new JoinGroupReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - - p.GroupData = new JoinGroupReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - p.GroupData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success) - { - EjectGroupMemberReplyPacket p = (EjectGroupMemberReplyPacket)PacketPool.Instance.GetPacket(PacketType.EjectGroupMemberReply); - - p.AgentData = new EjectGroupMemberReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = agentID; - - p.GroupData = new EjectGroupMemberReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - - p.EjectData = new EjectGroupMemberReplyPacket.EjectDataBlock(); - p.EjectData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendLeaveGroupReply(UUID groupID, bool success) - { - LeaveGroupReplyPacket p = (LeaveGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.LeaveGroupReply); - - p.AgentData = new LeaveGroupReplyPacket.AgentDataBlock(); - p.AgentData.AgentID = AgentId; - - p.GroupData = new LeaveGroupReplyPacket.GroupDataBlock(); - p.GroupData.GroupID = groupID; - p.GroupData.Success = success; - - OutPacket(p, ThrottleOutPacketType.Task); - } - - public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name) - { - if (classifiedID.Length != name.Length) - return; - - AvatarClassifiedReplyPacket ac = - (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarClassifiedReply); - - ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); - ac.AgentData.AgentID = AgentId; - ac.AgentData.TargetID = targetID; - - ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifiedID.Length]; - int i; - for (i = 0 ; i < classifiedID.Length ; i++) - { - ac.Data[i].ClassifiedID = classifiedID[i]; - ac.Data[i].Name = Utils.StringToBytes(name[i]); - } - - OutPacket(ac, ThrottleOutPacketType.Task); - } - - public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price) - { - ClassifiedInfoReplyPacket cr = - (ClassifiedInfoReplyPacket)PacketPool.Instance.GetPacket( - PacketType.ClassifiedInfoReply); - - cr.AgentData = new ClassifiedInfoReplyPacket.AgentDataBlock(); - cr.AgentData.AgentID = AgentId; - - cr.Data = new ClassifiedInfoReplyPacket.DataBlock(); - cr.Data.ClassifiedID = classifiedID; - cr.Data.CreatorID = creatorID; - cr.Data.CreationDate = creationDate; - cr.Data.ExpirationDate = expirationDate; - cr.Data.Category = category; - cr.Data.Name = Utils.StringToBytes(name); - cr.Data.Desc = Utils.StringToBytes(description); - cr.Data.ParcelID = parcelID; - cr.Data.ParentEstate = parentEstate; - cr.Data.SnapshotID = snapshotID; - cr.Data.SimName = Utils.StringToBytes(simName); - cr.Data.PosGlobal = new Vector3d(globalPos); - cr.Data.ParcelName = Utils.StringToBytes(parcelName); - cr.Data.ClassifiedFlags = classifiedFlags; - cr.Data.PriceForListing = price; - - OutPacket(cr, ThrottleOutPacketType.Task); - } - - public void SendAgentDropGroup(UUID groupID) - { - AgentDropGroupPacket dg = - (AgentDropGroupPacket)PacketPool.Instance.GetPacket( - PacketType.AgentDropGroup); - - dg.AgentData = new AgentDropGroupPacket.AgentDataBlock(); - dg.AgentData.AgentID = AgentId; - dg.AgentData.GroupID = groupID; - - OutPacket(dg, ThrottleOutPacketType.Task); - } - - public void SendAvatarNotesReply(UUID targetID, string text) - { - AvatarNotesReplyPacket an = - (AvatarNotesReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarNotesReply); - - an.AgentData = new AvatarNotesReplyPacket.AgentDataBlock(); - an.AgentData.AgentID = AgentId; - - an.Data = new AvatarNotesReplyPacket.DataBlock(); - an.Data.TargetID = targetID; - an.Data.Notes = Utils.StringToBytes(text); - - OutPacket(an, ThrottleOutPacketType.Task); - } - - public void SendAvatarPicksReply(UUID targetID, Dictionary picks) - { - AvatarPicksReplyPacket ap = - (AvatarPicksReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarPicksReply); - - ap.AgentData = new AvatarPicksReplyPacket.AgentDataBlock(); - ap.AgentData.AgentID = AgentId; - ap.AgentData.TargetID = targetID; - - ap.Data = new AvatarPicksReplyPacket.DataBlock[picks.Count]; - - int i = 0; - foreach (KeyValuePair pick in picks) - { - ap.Data[i] = new AvatarPicksReplyPacket.DataBlock(); - ap.Data[i].PickID = pick.Key; - ap.Data[i].PickName = Utils.StringToBytes(pick.Value); - i++; - } - - OutPacket(ap, ThrottleOutPacketType.Task); - } - - public void SendAvatarClassifiedReply(UUID targetID, Dictionary classifieds) - { - AvatarClassifiedReplyPacket ac = - (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket( - PacketType.AvatarClassifiedReply); - - ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock(); - ac.AgentData.AgentID = AgentId; - ac.AgentData.TargetID = targetID; - - ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifieds.Count]; - - int i = 0; - foreach (KeyValuePair classified in classifieds) - { - ac.Data[i] = new AvatarClassifiedReplyPacket.DataBlock(); - ac.Data[i].ClassifiedID = classified.Key; - ac.Data[i].Name = Utils.StringToBytes(classified.Value); - i++; - } - - OutPacket(ac, ThrottleOutPacketType.Task); - } - - public void SendParcelDwellReply(int localID, UUID parcelID, float dwell) - { - ParcelDwellReplyPacket pd = - (ParcelDwellReplyPacket)PacketPool.Instance.GetPacket( - PacketType.ParcelDwellReply); - - pd.AgentData = new ParcelDwellReplyPacket.AgentDataBlock(); - pd.AgentData.AgentID = AgentId; - - pd.Data = new ParcelDwellReplyPacket.DataBlock(); - pd.Data.LocalID = localID; - pd.Data.ParcelID = parcelID; - pd.Data.Dwell = dwell; - - OutPacket(pd, ThrottleOutPacketType.Land); - } - - public void SendUserInfoReply(bool imViaEmail, bool visible, string email) - { - UserInfoReplyPacket ur = - (UserInfoReplyPacket)PacketPool.Instance.GetPacket( - PacketType.UserInfoReply); - - string Visible = "hidden"; - if (visible) - Visible = "default"; - - ur.AgentData = new UserInfoReplyPacket.AgentDataBlock(); - ur.AgentData.AgentID = AgentId; - - ur.UserData = new UserInfoReplyPacket.UserDataBlock(); - ur.UserData.IMViaEMail = imViaEmail; - ur.UserData.DirectoryVisibility = Utils.StringToBytes(Visible); - ur.UserData.EMail = Utils.StringToBytes(email); - - OutPacket(ur, ThrottleOutPacketType.Task); - } - public void KillEndDone() { - KillPacket kp = new KillPacket(); - OutPacket(kp, ThrottleOutPacketType.Task | ThrottleOutPacketType.LowPriority); + m_udpClient.Shutdown(); } #region IClientCore @@ -10767,13 +10273,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - protected virtual void RegisterInterfaces() - { - RegisterInterface(this); - RegisterInterface(this); - RegisterInterface(this); - } - public bool TryGet(out T iface) { if (m_clientInterfaces.ContainsKey(typeof(T))) @@ -10821,78 +10320,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public void SendCreateGroupReply(UUID groupID, bool success, string message) - { - CreateGroupReplyPacket createGroupReply = (CreateGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.CreateGroupReply); - - createGroupReply.AgentData = - new CreateGroupReplyPacket.AgentDataBlock(); - createGroupReply.ReplyData = - new CreateGroupReplyPacket.ReplyDataBlock(); - - createGroupReply.AgentData.AgentID = AgentId; - createGroupReply.ReplyData.GroupID = groupID; - - createGroupReply.ReplyData.Success = success; - createGroupReply.ReplyData.Message = Utils.StringToBytes(message); - OutPacket(createGroupReply, ThrottleOutPacketType.Task); - } - - public void SendUseCachedMuteList() - { - UseCachedMuteListPacket useCachedMuteList = (UseCachedMuteListPacket)PacketPool.Instance.GetPacket(PacketType.UseCachedMuteList); - - useCachedMuteList.AgentData = new UseCachedMuteListPacket.AgentDataBlock(); - useCachedMuteList.AgentData.AgentID = AgentId; - - OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); - } - - public void SendMuteListUpdate(string filename) - { - MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); - - muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock(); - muteListUpdate.MuteData.AgentID = AgentId; - muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename); - - OutPacket(muteListUpdate, ThrottleOutPacketType.Task); - } - - public void SendPickInfoReply(UUID pickID,UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled) - { - PickInfoReplyPacket pickInfoReply = (PickInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.PickInfoReply); - - pickInfoReply.AgentData = new PickInfoReplyPacket.AgentDataBlock(); - pickInfoReply.AgentData.AgentID = AgentId; - - pickInfoReply.Data = new PickInfoReplyPacket.DataBlock(); - pickInfoReply.Data.PickID = pickID; - pickInfoReply.Data.CreatorID = creatorID; - pickInfoReply.Data.TopPick = topPick; - pickInfoReply.Data.ParcelID = parcelID; - pickInfoReply.Data.Name = Utils.StringToBytes(name); - pickInfoReply.Data.Desc = Utils.StringToBytes(desc); - pickInfoReply.Data.SnapshotID = snapshotID; - pickInfoReply.Data.User = Utils.StringToBytes(user); - pickInfoReply.Data.OriginalName = Utils.StringToBytes(originalName); - pickInfoReply.Data.SimName = Utils.StringToBytes(simName); - pickInfoReply.Data.PosGlobal = new Vector3d(posGlobal); - pickInfoReply.Data.SortOrder = sortOrder; - pickInfoReply.Data.Enabled = enabled; - - OutPacket(pickInfoReply, ThrottleOutPacketType.Task); - } - public string Report() { - LLPacketHandler handler = (LLPacketHandler) m_PacketHandler; - return handler.PacketQueue.GetStats(); + return m_udpClient.GetStats(); } public string XReport(string uptime, string version) { - return ""; + return String.Empty; } public void MakeAssetRequest(TransferRequestPacket transferRequest) @@ -10981,7 +10416,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return numPackets; } - #region IClientIPEndpoint Members public IPAddress EndPoint From 8c255b374a73d03be922cef32b06b7b83d5e09bb Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 6 Oct 2009 21:32:15 -0700 Subject: [PATCH 24/36] Uncommented log message on CAPs FetchInventoryDescendants --- OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index e561efbff0..f6d8eace88 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -477,9 +477,9 @@ namespace OpenSim.Region.Framework.Scenes public InventoryCollection HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder, out int version) { -// m_log.DebugFormat( -// "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", -// fetchFolders, fetchItems, folderID, agentID); + m_log.DebugFormat( + "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", + fetchFolders, fetchItems, folderID, agentID); // FIXME MAYBE: We're not handling sortOrder! From d344ca932df5ca75f4739c693627bb1a24d9bbdf Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 6 Oct 2009 22:19:20 -0700 Subject: [PATCH 25/36] A small change in FetchInventoryDescendantsCAPS. --- OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index f6d8eace88..4ae4dc3054 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -497,10 +497,11 @@ namespace OpenSim.Region.Framework.Scenes return ret; } - InventoryCollection contents = InventoryService.GetFolderContent(agentID, folderID); + InventoryCollection contents = new InventoryCollection(); if (folderID != UUID.Zero) { + contents = InventoryService.GetFolderContent(agentID, folderID); InventoryFolderBase containingFolder = new InventoryFolderBase(); containingFolder.ID = folderID; containingFolder.Owner = agentID; From 78e4501bef27c04f317153dcec45346a7f3987ab Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 7 Oct 2009 08:42:33 -0700 Subject: [PATCH 26/36] Improved fault handling in HelloNeighbour. --- .../Neighbour/NeighbourServiceConnector.cs | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs index 145f212590..0a982f8d57 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs @@ -76,10 +76,12 @@ namespace OpenSim.Services.Connectors // Don't remote-call this instance; that's a startup hickup !((regInfo.ExternalHostName == thisRegion.ExternalHostName) && (regInfo.HttpPort == thisRegion.HttpPort))) { - DoHelloNeighbourCall(regInfo, thisRegion); + if (!DoHelloNeighbourCall(regInfo, thisRegion)) + return null; } - //else - // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + else + return null; + return regInfo; } @@ -102,6 +104,7 @@ namespace OpenSim.Services.Connectors catch (Exception e) { m_log.Debug("[REST COMMS]: PackRegionInfoData failed with exception: " + e.Message); + return false; } // Add the regionhandle of the destination region args["destination_handle"] = OSD.FromString(region.RegionHandle.ToString()); @@ -118,7 +121,7 @@ namespace OpenSim.Services.Connectors catch (Exception e) { m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of HelloNeighbour: {0}", e.Message); - // ignore. buffer will be empty, caller should check. + return false; } Stream os = null; @@ -127,20 +130,23 @@ namespace OpenSim.Services.Connectors HelloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send os = HelloNeighbourRequest.GetRequestStream(); os.Write(buffer, 0, strBuffer.Length); //Send it - os.Close(); //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri); } - //catch (WebException ex) - catch + catch (Exception ex) { - //m_log.InfoFormat("[REST COMMS]: Bad send on HelloNeighbour {0}", ex.Message); - + m_log.InfoFormat("[REST COMMS]: Unable to send HelloNeighbour to {0}: {1}", region.RegionName, ex.Message); return false; } + finally + { + if (os != null) + os.Close(); + } // Let's wait for the response //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall"); + StreamReader sr = null; try { WebResponse webResponse = HelloNeighbourRequest.GetResponse(); @@ -149,17 +155,21 @@ namespace OpenSim.Services.Connectors m_log.Info("[REST COMMS]: Null reply on DoHelloNeighbourCall post"); } - StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + sr = new StreamReader(webResponse.GetResponseStream()); //reply = sr.ReadToEnd().Trim(); sr.ReadToEnd().Trim(); - sr.Close(); //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); } - catch (WebException ex) + catch (Exception ex) { m_log.InfoFormat("[REST COMMS]: exception on reply of DoHelloNeighbourCall {0}", ex.Message); - // ignore, really + return false; + } + finally + { + if (sr != null) + sr.Close(); } return true; From 596f2307bfdbb82ed1ee272408ea8363d968c919 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 7 Oct 2009 18:34:59 +0100 Subject: [PATCH 27/36] Add owner_uuid. Not sure this works. Worth a test --- OpenSim/Services/Interfaces/IGridService.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index 2290530a34..14560b1356 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -140,6 +140,14 @@ namespace OpenSim.Services.Interfaces } protected int m_regionLocY; + protected UUID m_estateOwner; + + public UUID EstateOwner + { + get { return m_estateOwner; } + set { m_estateOwner = value; } + } + public UUID RegionID = UUID.Zero; public UUID ScopeID = UUID.Zero; @@ -191,6 +199,7 @@ namespace OpenSim.Services.Interfaces Access = ConvertFrom.AccessLevel; Maturity = ConvertFrom.RegionSettings.Maturity; RegionSecret = ConvertFrom.regionSecret; + EstateOwner = ConvertFrom.EstateSettings.EstateOwner; } public GridRegion(GridRegion ConvertFrom) @@ -207,6 +216,7 @@ namespace OpenSim.Services.Interfaces Access = ConvertFrom.Access; Maturity = ConvertFrom.Maturity; RegionSecret = ConvertFrom.RegionSecret; + EstateOwner = ConvertFrom.EstateOwner; } /// @@ -291,6 +301,7 @@ namespace OpenSim.Services.Interfaces kvp["regionMapTexture"] = TerrainImage.ToString(); kvp["access"] = Access.ToString(); kvp["regionSecret"] = RegionSecret; + kvp["owner_uuid"] = EstateOwner.ToString(); // Maturity doesn't seem to exist in the DB return kvp; } @@ -345,6 +356,9 @@ namespace OpenSim.Services.Interfaces if (kvp.ContainsKey("regionSecret")) RegionSecret =(string)kvp["regionSecret"]; + if (kvp.ContainsKey("owner_uuid")) + EstateOwner = new UUID(kvp["owner_uuid"].ToString()); + } } From a0b6cc38610fb1d6beb3895f01ab1d06af37dd61 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 7 Oct 2009 19:10:18 +0100 Subject: [PATCH 28/36] Enable debugging of the region connector's query string --- OpenSim/Services/Connectors/Grid/GridServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs index acdf5587de..30f5ed01d6 100644 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs @@ -99,7 +99,7 @@ namespace OpenSim.Services.Connectors sendData["METHOD"] = "register"; string reqString = ServerUtils.BuildQueryString(sendData); - //m_log.DebugFormat("[GRID CONNECTOR]: queryString = {0}", reqString); + m_log.DebugFormat("[GRID CONNECTOR]: queryString = {0}", reqString); try { string reply = SynchronousRestFormsRequester.MakeRequest("POST", From 48826fcdf7145a6113d8d61e50c2a76d51a79c86 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 7 Oct 2009 19:22:27 +0100 Subject: [PATCH 29/36] Remove debug again --- OpenSim/Services/Connectors/Grid/GridServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs index 30f5ed01d6..02f2b79cfb 100644 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs @@ -99,7 +99,7 @@ namespace OpenSim.Services.Connectors sendData["METHOD"] = "register"; string reqString = ServerUtils.BuildQueryString(sendData); - m_log.DebugFormat("[GRID CONNECTOR]: queryString = {0}", reqString); + // m_log.DebugFormat("[GRID CONNECTOR]: queryString = {0}", reqString); try { string reply = SynchronousRestFormsRequester.MakeRequest("POST", From d9f15fbf40f7eca81ff2ca6f3792820c6cabc605 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 7 Oct 2009 19:37:18 +0100 Subject: [PATCH 30/36] store owner_uuid in the region table --- OpenSim/Services/GridService/GridService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index a2e4771d4b..86815e53e5 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -200,6 +200,7 @@ namespace OpenSim.Services.GridService rdata.RegionName = rinfo.RegionName; rdata.Data = rinfo.ToKeyValuePairs(); rdata.Data["regionHandle"] = Utils.UIntsToLong((uint)rdata.posX, (uint)rdata.posY); + rdata.Data["owner_uuid"] = rinfo.EstateOwner.ToString(); return rdata; } From ab3bfca54631d55ff951ce02b3f99e64e2ea7367 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 7 Oct 2009 17:29:21 -0700 Subject: [PATCH 31/36] Printout one more field in show threads, but this won't buy us much. --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 8e58980b6e..4179dd38b3 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -246,7 +246,8 @@ namespace OpenSim.Framework.Servers foreach (ProcessThread t in threads) { sb.Append("ID: " + t.Id + ", TotalProcessorTime: " + t.TotalProcessorTime + ", TimeRunning: " + - (DateTime.Now - t.StartTime) + ", Pri: " + t.CurrentPriority + ", State: " + t.ThreadState + Environment.NewLine); + (DateTime.Now - t.StartTime) + ", Pri: " + t.CurrentPriority + ", State: " + t.ThreadState + + ", WaitReason: " + t.WaitReason + Environment.NewLine); } } int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; From c71b3e730d8027b31eb3300c747d011a6e38030e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 7 Oct 2009 18:54:08 -0700 Subject: [PATCH 32/36] Changed the locking mechanism, because the existing one is causing deadlocks to occur. --- .../LindenUDP/LLUDPClientCollection.cs | 125 ++++++++++++++---- 1 file changed, 100 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs index 7d2da68d2d..9be94809e0 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs @@ -41,6 +41,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Dictionary Dictionary2; LLUDPClient[] Array; ReaderWriterLockImpl rwLock = new ReaderWriterLockImpl(); + object m_sync = new object(); public UDPClientCollection() { @@ -58,9 +59,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void Add(UUID key1, IPEndPoint key2, LLUDPClient value) { - rwLock.EnterWriteLock(); + //rwLock.EnterWriteLock(); - try + //try + //{ + // if (Dictionary1.ContainsKey(key1)) + // { + // if (!Dictionary2.ContainsKey(key2)) + // throw new ArgumentException("key1 exists in the dictionary but not key2"); + // } + // else if (Dictionary2.ContainsKey(key2)) + // { + // if (!Dictionary1.ContainsKey(key1)) + // throw new ArgumentException("key2 exists in the dictionary but not key1"); + // } + + // Dictionary1[key1] = value; + // Dictionary2[key2] = value; + + // LLUDPClient[] oldArray = Array; + // int oldLength = oldArray.Length; + + // LLUDPClient[] newArray = new LLUDPClient[oldLength + 1]; + // for (int i = 0; i < oldLength; i++) + // newArray[i] = oldArray[i]; + // newArray[oldLength] = value; + + // Array = newArray; + //} + //finally { rwLock.ExitWriteLock(); } + + lock (m_sync) { if (Dictionary1.ContainsKey(key1)) { @@ -86,14 +115,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP Array = newArray; } - finally { rwLock.ExitWriteLock(); } + } public bool Remove(UUID key1, IPEndPoint key2) { - rwLock.EnterWriteLock(); + //rwLock.EnterWriteLock(); - try + //try + //{ + // LLUDPClient value; + // if (Dictionary1.TryGetValue(key1, out value)) + // { + // Dictionary1.Remove(key1); + // Dictionary2.Remove(key2); + + // LLUDPClient[] oldArray = Array; + // int oldLength = oldArray.Length; + + // LLUDPClient[] newArray = new LLUDPClient[oldLength - 1]; + // int j = 0; + // for (int i = 0; i < oldLength; i++) + // { + // if (oldArray[i] != value) + // newArray[j++] = oldArray[i]; + // } + + // Array = newArray; + // return true; + // } + //} + //finally { rwLock.ExitWriteLock(); } + + //return false; + + lock (m_sync) { LLUDPClient value; if (Dictionary1.TryGetValue(key1, out value)) @@ -116,22 +172,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } } - finally { rwLock.ExitWriteLock(); } return false; + } public void Clear() { - rwLock.EnterWriteLock(); + //rwLock.EnterWriteLock(); - try + //try + //{ + // Dictionary1.Clear(); + // Dictionary2.Clear(); + // Array = new LLUDPClient[0]; + //} + //finally { rwLock.ExitWriteLock(); } + + lock (m_sync) { Dictionary1.Clear(); Dictionary2.Clear(); Array = new LLUDPClient[0]; } - finally { rwLock.ExitWriteLock(); } + } public int Count @@ -151,35 +215,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP public bool TryGetValue(UUID key, out LLUDPClient value) { - bool success; - bool doLock = !rwLock.IsUpgradeableReadLockHeld; - if (doLock) rwLock.EnterReadLock(); + //bool success; + //bool doLock = !rwLock.IsUpgradeableReadLockHeld; + //if (doLock) rwLock.EnterReadLock(); - try { success = Dictionary1.TryGetValue(key, out value); } - finally { if (doLock) rwLock.ExitReadLock(); } + //try { success = Dictionary1.TryGetValue(key, out value); } + //finally { if (doLock) rwLock.ExitReadLock(); } + + //return success; + + lock (m_sync) + return Dictionary1.TryGetValue(key, out value); - return success; } public bool TryGetValue(IPEndPoint key, out LLUDPClient value) { - bool success; - bool doLock = !rwLock.IsUpgradeableReadLockHeld; - if (doLock) rwLock.EnterReadLock(); + //bool success; + //bool doLock = !rwLock.IsUpgradeableReadLockHeld; + //if (doLock) rwLock.EnterReadLock(); - try { success = Dictionary2.TryGetValue(key, out value); } - finally { if (doLock) rwLock.ExitReadLock(); } + //try { success = Dictionary2.TryGetValue(key, out value); } + //finally { if (doLock) rwLock.ExitReadLock(); } - return success; + //return success; + + lock (m_sync) + return Dictionary2.TryGetValue(key, out value); } public void ForEach(Action action) { - bool doLock = !rwLock.IsUpgradeableReadLockHeld; - if (doLock) rwLock.EnterUpgradeableReadLock(); + //bool doLock = !rwLock.IsUpgradeableReadLockHeld; + //if (doLock) rwLock.EnterUpgradeableReadLock(); + + //try { Parallel.ForEach(Array, action); } + //finally { if (doLock) rwLock.ExitUpgradeableReadLock(); } + + lock (m_sync) + Parallel.ForEach(Array, action); - try { Parallel.ForEach(Array, action); } - finally { if (doLock) rwLock.ExitUpgradeableReadLock(); } } } } From 29f03d95f3648dff881a2d91444a71c770390ec9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 7 Oct 2009 19:20:34 -0700 Subject: [PATCH 33/36] Bug fix. --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 4179dd38b3..845a9fe3e2 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -246,8 +246,12 @@ namespace OpenSim.Framework.Servers foreach (ProcessThread t in threads) { sb.Append("ID: " + t.Id + ", TotalProcessorTime: " + t.TotalProcessorTime + ", TimeRunning: " + - (DateTime.Now - t.StartTime) + ", Pri: " + t.CurrentPriority + ", State: " + t.ThreadState + - ", WaitReason: " + t.WaitReason + Environment.NewLine); + (DateTime.Now - t.StartTime) + ", Pri: " + t.CurrentPriority + ", State: " + t.ThreadState ); + if (t.ThreadState == System.Diagnostics.ThreadState.Wait) + sb.Append(", Reason: " + t.WaitReason + Environment.NewLine); + else + sb.Append(Environment.NewLine); + } } int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; From dd80380df5e47c0d67466f7d509898a71e19abd0 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 7 Oct 2009 19:45:57 -0700 Subject: [PATCH 34/36] Another go at the deadlock: not locking TryGetValue, and just catch/ignore exceptions. --- .../LindenUDP/LLUDPClientCollection.cs | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs index 9be94809e0..36e1f497af 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs @@ -215,33 +215,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP public bool TryGetValue(UUID key, out LLUDPClient value) { - //bool success; - //bool doLock = !rwLock.IsUpgradeableReadLockHeld; - //if (doLock) rwLock.EnterReadLock(); + ////bool success; + ////bool doLock = !rwLock.IsUpgradeableReadLockHeld; + ////if (doLock) rwLock.EnterReadLock(); - //try { success = Dictionary1.TryGetValue(key, out value); } - //finally { if (doLock) rwLock.ExitReadLock(); } + ////try { success = Dictionary1.TryGetValue(key, out value); } + ////finally { if (doLock) rwLock.ExitReadLock(); } - //return success; + ////return success; - lock (m_sync) - return Dictionary1.TryGetValue(key, out value); + //lock (m_sync) + // return Dictionary1.TryGetValue(key, out value); + try + { + return Dictionary1.TryGetValue(key, out value); + } + catch { } + value = null; + return false; } public bool TryGetValue(IPEndPoint key, out LLUDPClient value) { - //bool success; - //bool doLock = !rwLock.IsUpgradeableReadLockHeld; - //if (doLock) rwLock.EnterReadLock(); + ////bool success; + ////bool doLock = !rwLock.IsUpgradeableReadLockHeld; + ////if (doLock) rwLock.EnterReadLock(); - //try { success = Dictionary2.TryGetValue(key, out value); } - //finally { if (doLock) rwLock.ExitReadLock(); } + ////try { success = Dictionary2.TryGetValue(key, out value); } + ////finally { if (doLock) rwLock.ExitReadLock(); } - //return success; + ////return success; - lock (m_sync) + //lock (m_sync) + // return Dictionary2.TryGetValue(key, out value); + + try + { return Dictionary2.TryGetValue(key, out value); + } + catch { } + value = null; + return false; + } public void ForEach(Action action) From 68961ec0923fb613eae72f0f83ad3349e608cc05 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 7 Oct 2009 20:36:24 -0700 Subject: [PATCH 35/36] One last attempt at tunning the locking/no locking behaviour. The previous one was too lax and made the important login packets fail. --- .../LindenUDP/LLUDPClientCollection.cs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs index 36e1f497af..f6ccf01bc0 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs @@ -247,16 +247,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP ////return success; - //lock (m_sync) - // return Dictionary2.TryGetValue(key, out value); - - try - { + lock (m_sync) return Dictionary2.TryGetValue(key, out value); - } - catch { } - value = null; - return false; + + //try + //{ + // return Dictionary2.TryGetValue(key, out value); + //} + //catch { } + //value = null; + //return false; } @@ -268,8 +268,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP //try { Parallel.ForEach(Array, action); } //finally { if (doLock) rwLock.ExitUpgradeableReadLock(); } + LLUDPClient[] localArray = null; lock (m_sync) - Parallel.ForEach(Array, action); + { + localArray = new LLUDPClient[Array.Length]; + Array.CopyTo(localArray, 0); + } + + Parallel.ForEach(localArray, action); } } From 1eb390beda0764191680ff2bddfc70b360f930cf Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 8 Oct 2009 08:32:34 +0100 Subject: [PATCH 36/36] Remove ThreadTrackerTest. It's no longer relevant because the thread tracker now uses the system thread list --- OpenSim/Framework/Tests/ThreadTrackerTests.cs | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 OpenSim/Framework/Tests/ThreadTrackerTests.cs diff --git a/OpenSim/Framework/Tests/ThreadTrackerTests.cs b/OpenSim/Framework/Tests/ThreadTrackerTests.cs deleted file mode 100644 index 7eb83e6421..0000000000 --- a/OpenSim/Framework/Tests/ThreadTrackerTests.cs +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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; -using NUnit.Framework; -using System.Threading; -using System.Collections.Generic; - -namespace OpenSim.Framework.Tests -{ - [TestFixture] - public class ThreadTrackerTests - { - private bool running = true; - private bool running2 = true; - - [Test] - public void DefaultThreadTrackerTest() - { - System.Diagnostics.ProcessThreadCollection lThread = ThreadTracker.GetThreads(); - - /* - foreach (Thread t in lThread) - { - System.Console.WriteLine(t.Name); - } - */ - - Assert.That(lThread.Count > 0); - } - } -}