From 05a2feba5d780c57c252891a20071800fd9f2e3e Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 4 Aug 2014 19:57:47 +0100 Subject: start sending terrain in scenePresence after well defined avatar. Minor change on significante AgentUpdate check. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 28 +- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 34 +- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- OpenSim/Region/Framework/Scenes/SceneBase.cs | 1160 ++++++++++---------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 19 +- 5 files changed, 629 insertions(+), 616 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 34a2797..7d61577 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -577,7 +577,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Fire the callback for this connection closing if (OnConnectionClosed != null) + { OnConnectionClosed(this); + } + // Flush all of the packets out of the UDP server for this client if (m_udpServer != null) @@ -5518,8 +5521,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); -// AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false); - AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, true); + AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false); AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance); @@ -5732,10 +5734,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Scene/Avatar // Threshold for body rotation to be a significant agent update - private const float QDELTA = 0.000001f; + // private const float QDELTA = 0.000001f; + // QDELTA is now relative to abs of cos of angle between orientations + + private const float QDELTABODY = 1 - 0.0001f; + private const float QDELTAHEAD = 1 - 0.0001f; + // Threshold for camera rotation to be a significant agent update private const float VDELTA = 0.01f; - + /// /// This checks the update significance against the last update made. /// @@ -5755,13 +5762,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) { - float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2); + // float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2); //qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2); + // now using abs of cos + float qdelta1 = (float)Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation)); + float qdelta2 = (float)Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation)); bool movementSignificant = - (qdelta1 > QDELTA) // significant if body rotation above threshold - // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack +// (qdelta1 > QDELTA) // significant if body rotation above threshold + (qdelta1 < QDELTABODY) // higher angle lower cos +// Ignoring head rotation altogether, because it's not being used for anything interesting up the stack // || (qdelta2 > QDELTA * 10) // significant if head rotation above threshold + || (qdelta2 < QDELTAHEAD) // using cos above || (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands || (x.Far != m_thisAgentUpdateArgs.Far) // significant if far distance changed @@ -6476,7 +6488,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Action handlerRegionHandShakeReply = OnRegionHandShakeReply; if (handlerRegionHandShakeReply != null) { - Thread.Sleep(500); +// Thread.Sleep(500); handlerRegionHandShakeReply(this); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index b7c8594..a3fdae1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1750,25 +1750,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP endPoint, sessionInfo); - // Send ack straight away to let the viewer know that the connection is active. - // The client will be null if it already exists (e.g. if on a region crossing the client sends a use - // circuit code to the existing child agent. This is not particularly obvious. - SendAckImmediate(endPoint, uccp.Header.Sequence); - - // We only want to send initial data to new clients, not ones which are being converted from child to root. - if (client != null) - { - AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); - bool tp = (aCircuit.teleportFlags > 0); - // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from - if (!tp) - client.SceneAgent.SendInitialDataToMe(); - } - // Now we know we can handle more data - Thread.Sleep(200); +// Thread.Sleep(200); - // Obtain the queue and remove it from the cache + // Obtain the pending queue and remove it from the cache Queue queue = null; lock (m_pendingCache) @@ -1790,6 +1775,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP PacketReceived(buf); } queue = null; + + // Send ack straight away to let the viewer know that the connection is active. + // The client will be null if it already exists (e.g. if on a region crossing the client sends a use + // circuit code to the existing child agent. This is not particularly obvious. + SendAckImmediate(endPoint, uccp.Header.Sequence); + + // We only want to send initial data to new clients, not ones which are being converted from child to root. + if (client != null) + { + AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); + bool tp = (aCircuit.teleportFlags > 0); + // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from + if (!tp) + client.SceneAgent.SendInitialDataToMe(); + } } else { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0266faf..ec54e15 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3179,7 +3179,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientTerrainEvents(IClientAPI client) { - client.OnRegionHandShakeReply += SendLayerData; +// client.OnRegionHandShakeReply += SendLayerData; } public virtual void SubscribeToClientPrimEvents(IClientAPI client) @@ -3307,7 +3307,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client) { - client.OnRegionHandShakeReply -= SendLayerData; +// client.OnRegionHandShakeReply -= SendLayerData; } public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 08e26c5..6adccca 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -1,581 +1,581 @@ -/* - * 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 OpenMetaverse; -using log4net; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Console; - -using OpenSim.Region.Framework.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; - -namespace OpenSim.Region.Framework.Scenes -{ - public abstract class SceneBase : IScene - { +/* + * 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 OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; + +using OpenSim.Region.Framework.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.Framework.Scenes +{ + public abstract class SceneBase : IScene + { protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static readonly string LogHeader = "[SCENE]"; - - #region Events - - public event restart OnRestart; - - #endregion - - #region Fields - - public string Name { get { return RegionInfo.RegionName; } } - - public IConfigSource Config - { - get { return GetConfig(); } - } - - protected virtual IConfigSource GetConfig() - { - return null; - } - - /// - /// All the region modules attached to this scene. - /// - public Dictionary RegionModules - { - get { return m_regionModules; } - } - private Dictionary m_regionModules = new Dictionary(); - - /// - /// The module interfaces available from this scene. - /// - protected Dictionary> ModuleInterfaces = new Dictionary>(); - - protected Dictionary ModuleAPIMethods = new Dictionary(); - - /// - /// The module commanders available from this scene - /// - protected Dictionary m_moduleCommanders = new Dictionary(); - - /// - /// Registered classes that are capable of creating entities. - /// - protected Dictionary m_entityCreators = new Dictionary(); - - /// - /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is - /// dispensed. - /// - protected uint m_lastAllocatedLocalId = 720000; - - private readonly Mutex _primAllocateMutex = new Mutex(false); - - protected readonly ClientManager m_clientManager = new ClientManager(); - - public bool LoginsEnabled - { - get - { - return m_loginsEnabled; - } - - set - { - if (m_loginsEnabled != value) - { - m_loginsEnabled = value; - EventManager.TriggerRegionLoginsStatusChange(this); - } - } - } - private bool m_loginsEnabled; - - public bool Ready - { - get - { - return m_ready; - } - - set - { - if (m_ready != value) - { - m_ready = value; - EventManager.TriggerRegionReadyStatusChange(this); - } - } - } - private bool m_ready; - - public float TimeDilation - { - get { return 1.0f; } - } - - protected ulong m_regionHandle; - protected string m_regionName; - - public ITerrainChannel Heightmap; - - /// - /// Allows retrieval of land information for this scene. - /// - public ILandChannel LandChannel; - - /// - /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules - /// to subscribe to scene events. - /// - public EventManager EventManager - { - get { return m_eventManager; } - } - protected EventManager m_eventManager; - - protected ScenePermissions m_permissions; - public ScenePermissions Permissions - { - get { return m_permissions; } - } - - protected string m_datastore; - - /* Used by the loadbalancer plugin on GForge */ - protected RegionStatus m_regStatus; - public RegionStatus RegionStatus - { - get { return m_regStatus; } - set { m_regStatus = value; } - } - - #endregion - - public SceneBase(RegionInfo regInfo) - { - RegionInfo = regInfo; - } - - #region Update Methods - - /// - /// Called to update the scene loop by a number of frames and until shutdown. - /// - /// - /// Number of frames to update. Exits on shutdown even if there are frames remaining. - /// If -1 then updates until shutdown. - /// - public abstract void Update(int frames); - - #endregion - - #region Terrain Methods - - /// - /// Loads the World heightmap - /// - public abstract void LoadWorldMap(); - - /// - /// Send the region heightmap to the client - /// - /// Client to send to - public virtual void SendLayerData(IClientAPI RemoteClient) - { - RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); - } - - #endregion - - #region Add/Remove Agent/Avatar - - public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type); - - public abstract bool CloseAgent(UUID agentID, bool force); - - public bool TryGetScenePresence(UUID agentID, out object scenePresence) - { - scenePresence = null; - ScenePresence sp = null; - if (TryGetScenePresence(agentID, out sp)) - { - scenePresence = sp; - return true; - } - - return false; - } - - /// - /// Try to get a scene presence from the scene - /// - /// - /// null if there is no scene presence with the given agent id - /// true if there was a scene presence with the given id, false otherwise. - public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); - - #endregion - - /// - /// - /// - /// - public virtual RegionInfo RegionInfo { get; private set; } - - #region admin stuff - - public abstract void OtherRegionUp(GridRegion otherRegion); - - public virtual string GetSimulatorVersion() - { - return "OpenSimulator Server"; - } - - #endregion - - #region Shutdown - - /// - /// Tidy before shutdown - /// - public virtual void Close() - { - try - { - EventManager.TriggerShutdown(); - } - catch (Exception e) - { - m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); - } - } - - #endregion - - /// - /// Returns a new unallocated local ID - /// - /// A brand new local ID - public uint AllocateLocalId() - { - uint myID; - - _primAllocateMutex.WaitOne(); - myID = ++m_lastAllocatedLocalId; - _primAllocateMutex.ReleaseMutex(); - - return myID; - } - - #region Module Methods - - /// - /// Add a region-module to this scene. TODO: This will replace AddModule in the future. - /// - /// - /// - public void AddRegionModule(string name, IRegionModuleBase module) - { - if (!RegionModules.ContainsKey(name)) - { - RegionModules.Add(name, module); - } - } - - public void RemoveRegionModule(string name) - { - RegionModules.Remove(name); - } - - /// - /// Register a module commander. - /// - /// - public void RegisterModuleCommander(ICommander commander) - { - lock (m_moduleCommanders) - { - m_moduleCommanders.Add(commander.Name, commander); - } - } - - /// - /// Unregister a module commander and all its commands - /// - /// - public void UnregisterModuleCommander(string name) - { - lock (m_moduleCommanders) - { - ICommander commander; - if (m_moduleCommanders.TryGetValue(name, out commander)) - m_moduleCommanders.Remove(name); - } - } - - /// - /// Get a module commander - /// - /// - /// The module commander, null if no module commander with that name was found - public ICommander GetCommander(string name) - { - lock (m_moduleCommanders) - { - if (m_moduleCommanders.ContainsKey(name)) - return m_moduleCommanders[name]; - } - - return null; - } - - public Dictionary GetCommanders() - { - return m_moduleCommanders; - } - - /// - /// Register an interface to a region module. This allows module methods to be called directly as - /// well as via events. If there is already a module registered for this interface, it is not replaced - /// (is this the best behaviour?) - /// - /// - public void RegisterModuleInterface(M mod) - { -// m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); - - List l = null; - if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) - { - l = new List(); - ModuleInterfaces.Add(typeof(M), l); - } - - if (l.Count > 0) - return; - - l.Add(mod); - - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = entityCreator; - } - } - } - - public void UnregisterModuleInterface(M mod) - { - List l; - if (ModuleInterfaces.TryGetValue(typeof(M), out l)) - { - if (l.Remove(mod)) - { - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = null; - } - } - } - } - } - - public void StackModuleInterface(M mod) - { - List l; - if (ModuleInterfaces.ContainsKey(typeof(M))) - l = ModuleInterfaces[typeof(M)]; - else - l = new List(); - - if (l.Contains(mod)) - return; - - l.Add(mod); - - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = entityCreator; - } - } - - ModuleInterfaces[typeof(M)] = l; - } - - /// - /// For the given interface, retrieve the region module which implements it. - /// - /// null if there is no registered module implementing that interface - public T RequestModuleInterface() - { - if (ModuleInterfaces.ContainsKey(typeof(T)) && - (ModuleInterfaces[typeof(T)].Count > 0)) - return (T)ModuleInterfaces[typeof(T)][0]; - else - return default(T); - } - - /// - /// For the given interface, retrieve an array of region modules that implement it. - /// - /// an empty array if there are no registered modules implementing that interface - public T[] RequestModuleInterfaces() - { - if (ModuleInterfaces.ContainsKey(typeof(T))) - { - List ret = new List(); - - foreach (Object o in ModuleInterfaces[typeof(T)]) - ret.Add((T)o); - return ret.ToArray(); - } - else - { - return new T[] {}; - } - } - - #endregion - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// - /// - /// - /// - public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) - { - AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// The use of IRegionModuleBase is a cheap trick to get a different method signature, - /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. - /// - /// - /// Category of the command. This is the section under which it will appear when the user asks for help - /// - /// - /// - /// - /// - public void AddCommand( - string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) - { - AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// - /// - /// - /// - /// - public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) - { - string moduleName = ""; - - if (module != null) - moduleName = module.Name; - - AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// Category of the command. This is the section under which it will appear when the user asks for help - /// - /// - /// - /// - /// - /// - /// - public void AddCommand( - string category, IRegionModuleBase module, string command, - string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) - { - if (MainConsole.Instance == null) - return; - - bool shared = false; - - if (module != null) - shared = module is ISharedRegionModule; - - MainConsole.Instance.Commands.AddCommand( - category, shared, command, shorthelp, longhelp, descriptivehelp, callback); - } - - public virtual ISceneObject DeserializeObject(string representation) - { - return null; - } - - public virtual bool AllowScriptCrossings - { - get { return false; } - } - - public virtual void Start() - { - } - - public void Restart() - { - // This has to be here to fire the event - restart handlerPhysicsCrash = OnRestart; - if (handlerPhysicsCrash != null) - handlerPhysicsCrash(RegionInfo); - } - - public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); - } -} + protected static readonly string LogHeader = "[SCENE]"; + + #region Events + + public event restart OnRestart; + + #endregion + + #region Fields + + public string Name { get { return RegionInfo.RegionName; } } + + public IConfigSource Config + { + get { return GetConfig(); } + } + + protected virtual IConfigSource GetConfig() + { + return null; + } + + /// + /// All the region modules attached to this scene. + /// + public Dictionary RegionModules + { + get { return m_regionModules; } + } + private Dictionary m_regionModules = new Dictionary(); + + /// + /// The module interfaces available from this scene. + /// + protected Dictionary> ModuleInterfaces = new Dictionary>(); + + protected Dictionary ModuleAPIMethods = new Dictionary(); + + /// + /// The module commanders available from this scene + /// + protected Dictionary m_moduleCommanders = new Dictionary(); + + /// + /// Registered classes that are capable of creating entities. + /// + protected Dictionary m_entityCreators = new Dictionary(); + + /// + /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is + /// dispensed. + /// + protected uint m_lastAllocatedLocalId = 720000; + + private readonly Mutex _primAllocateMutex = new Mutex(false); + + protected readonly ClientManager m_clientManager = new ClientManager(); + + public bool LoginsEnabled + { + get + { + return m_loginsEnabled; + } + + set + { + if (m_loginsEnabled != value) + { + m_loginsEnabled = value; + EventManager.TriggerRegionLoginsStatusChange(this); + } + } + } + private bool m_loginsEnabled; + + public bool Ready + { + get + { + return m_ready; + } + + set + { + if (m_ready != value) + { + m_ready = value; + EventManager.TriggerRegionReadyStatusChange(this); + } + } + } + private bool m_ready; + + public float TimeDilation + { + get { return 1.0f; } + } + + protected ulong m_regionHandle; + protected string m_regionName; + + public ITerrainChannel Heightmap; + + /// + /// Allows retrieval of land information for this scene. + /// + public ILandChannel LandChannel; + + /// + /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules + /// to subscribe to scene events. + /// + public EventManager EventManager + { + get { return m_eventManager; } + } + protected EventManager m_eventManager; + + protected ScenePermissions m_permissions; + public ScenePermissions Permissions + { + get { return m_permissions; } + } + + protected string m_datastore; + + /* Used by the loadbalancer plugin on GForge */ + protected RegionStatus m_regStatus; + public RegionStatus RegionStatus + { + get { return m_regStatus; } + set { m_regStatus = value; } + } + + #endregion + + public SceneBase(RegionInfo regInfo) + { + RegionInfo = regInfo; + } + + #region Update Methods + + /// + /// Called to update the scene loop by a number of frames and until shutdown. + /// + /// + /// Number of frames to update. Exits on shutdown even if there are frames remaining. + /// If -1 then updates until shutdown. + /// + public abstract void Update(int frames); + + #endregion + + #region Terrain Methods + + /// + /// Loads the World heightmap + /// + public abstract void LoadWorldMap(); + + /// + /// Send the region heightmap to the client + /// + /// Client to send to + public virtual void SendLayerData(IClientAPI RemoteClient) + { + RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); + } + + #endregion + + #region Add/Remove Agent/Avatar + + public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type); + + public abstract bool CloseAgent(UUID agentID, bool force); + + public bool TryGetScenePresence(UUID agentID, out object scenePresence) + { + scenePresence = null; + ScenePresence sp = null; + if (TryGetScenePresence(agentID, out sp)) + { + scenePresence = sp; + return true; + } + + return false; + } + + /// + /// Try to get a scene presence from the scene + /// + /// + /// null if there is no scene presence with the given agent id + /// true if there was a scene presence with the given id, false otherwise. + public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); + + #endregion + + /// + /// + /// + /// + public virtual RegionInfo RegionInfo { get; private set; } + + #region admin stuff + + public abstract void OtherRegionUp(GridRegion otherRegion); + + public virtual string GetSimulatorVersion() + { + return "OpenSimulator Server"; + } + + #endregion + + #region Shutdown + + /// + /// Tidy before shutdown + /// + public virtual void Close() + { + try + { + EventManager.TriggerShutdown(); + } + catch (Exception e) + { + m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); + } + } + + #endregion + + /// + /// Returns a new unallocated local ID + /// + /// A brand new local ID + public uint AllocateLocalId() + { + uint myID; + + _primAllocateMutex.WaitOne(); + myID = ++m_lastAllocatedLocalId; + _primAllocateMutex.ReleaseMutex(); + + return myID; + } + + #region Module Methods + + /// + /// Add a region-module to this scene. TODO: This will replace AddModule in the future. + /// + /// + /// + public void AddRegionModule(string name, IRegionModuleBase module) + { + if (!RegionModules.ContainsKey(name)) + { + RegionModules.Add(name, module); + } + } + + public void RemoveRegionModule(string name) + { + RegionModules.Remove(name); + } + + /// + /// Register a module commander. + /// + /// + public void RegisterModuleCommander(ICommander commander) + { + lock (m_moduleCommanders) + { + m_moduleCommanders.Add(commander.Name, commander); + } + } + + /// + /// Unregister a module commander and all its commands + /// + /// + public void UnregisterModuleCommander(string name) + { + lock (m_moduleCommanders) + { + ICommander commander; + if (m_moduleCommanders.TryGetValue(name, out commander)) + m_moduleCommanders.Remove(name); + } + } + + /// + /// Get a module commander + /// + /// + /// The module commander, null if no module commander with that name was found + public ICommander GetCommander(string name) + { + lock (m_moduleCommanders) + { + if (m_moduleCommanders.ContainsKey(name)) + return m_moduleCommanders[name]; + } + + return null; + } + + public Dictionary GetCommanders() + { + return m_moduleCommanders; + } + + /// + /// Register an interface to a region module. This allows module methods to be called directly as + /// well as via events. If there is already a module registered for this interface, it is not replaced + /// (is this the best behaviour?) + /// + /// + public void RegisterModuleInterface(M mod) + { +// m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); + + List l = null; + if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) + { + l = new List(); + ModuleInterfaces.Add(typeof(M), l); + } + + if (l.Count > 0) + return; + + l.Add(mod); + + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = entityCreator; + } + } + } + + public void UnregisterModuleInterface(M mod) + { + List l; + if (ModuleInterfaces.TryGetValue(typeof(M), out l)) + { + if (l.Remove(mod)) + { + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = null; + } + } + } + } + } + + public void StackModuleInterface(M mod) + { + List l; + if (ModuleInterfaces.ContainsKey(typeof(M))) + l = ModuleInterfaces[typeof(M)]; + else + l = new List(); + + if (l.Contains(mod)) + return; + + l.Add(mod); + + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = entityCreator; + } + } + + ModuleInterfaces[typeof(M)] = l; + } + + /// + /// For the given interface, retrieve the region module which implements it. + /// + /// null if there is no registered module implementing that interface + public T RequestModuleInterface() + { + if (ModuleInterfaces.ContainsKey(typeof(T)) && + (ModuleInterfaces[typeof(T)].Count > 0)) + return (T)ModuleInterfaces[typeof(T)][0]; + else + return default(T); + } + + /// + /// For the given interface, retrieve an array of region modules that implement it. + /// + /// an empty array if there are no registered modules implementing that interface + public T[] RequestModuleInterfaces() + { + if (ModuleInterfaces.ContainsKey(typeof(T))) + { + List ret = new List(); + + foreach (Object o in ModuleInterfaces[typeof(T)]) + ret.Add((T)o); + return ret.ToArray(); + } + else + { + return new T[] {}; + } + } + + #endregion + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// + /// + /// + /// + public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) + { + AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// The use of IRegionModuleBase is a cheap trick to get a different method signature, + /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. + /// + /// + /// Category of the command. This is the section under which it will appear when the user asks for help + /// + /// + /// + /// + /// + public void AddCommand( + string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) + { + AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// + /// + /// + /// + /// + public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) + { + string moduleName = ""; + + if (module != null) + moduleName = module.Name; + + AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// Category of the command. This is the section under which it will appear when the user asks for help + /// + /// + /// + /// + /// + /// + /// + public void AddCommand( + string category, IRegionModuleBase module, string command, + string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) + { + if (MainConsole.Instance == null) + return; + + bool shared = false; + + if (module != null) + shared = module is ISharedRegionModule; + + MainConsole.Instance.Commands.AddCommand( + category, shared, command, shorthelp, longhelp, descriptivehelp, callback); + } + + public virtual ISceneObject DeserializeObject(string representation) + { + return null; + } + + public virtual bool AllowScriptCrossings + { + get { return false; } + } + + public virtual void Start() + { + } + + public void Restart() + { + // This has to be here to fire the event + restart handlerPhysicsCrash = OnRestart; + if (handlerPhysicsCrash != null) + handlerPhysicsCrash(RegionInfo); + } + + public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); + } +} diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 24a92eb..8088dd3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3473,6 +3473,7 @@ namespace OpenSim.Region.Framework.Scenes landch.sendClientInitialLandInfo(ControllingClient); } } + m_scene.SendLayerData(ControllingClient); SendOtherAgentsAvatarDataToMe(); SendOtherAgentsAppearanceToMe(); @@ -5426,7 +5427,7 @@ namespace OpenSim.Region.Framework.Scenes { if (p.IsChildAgent) continue; - m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname); +// m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname); ControllingClient.SendAvatarDataImmediate(p); p.SendAppearanceToAgent(this); p.SendAttachmentsToClient(ControllingClient); @@ -5454,7 +5455,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendme) { - m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); +// m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); try { ControllingClient.SendKillObject(new List { p.LocalId }); } catch (NullReferenceException) { } } @@ -5499,7 +5500,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendto) { - m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); +// m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); try { p.ControllingClient.SendKillObject(new List { LocalId }); } catch (NullReferenceException) { } } @@ -5509,7 +5510,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendme) { - m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); +// m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); try { ControllingClient.SendKillObject(new List { p.LocalId }); } catch (NullReferenceException) { } } @@ -5519,7 +5520,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in viewsToSendto) { - m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname); +// m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname); p.ControllingClient.SendAvatarDataImmediate(this); SendAppearanceToAgent(p); SendAttachmentsToClient(p.ControllingClient); @@ -5532,9 +5533,9 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in viewsToSendme) { - m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); if (p.IsChildAgent) continue; +// m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); ControllingClient.SendAvatarDataImmediate(p); p.SendAppearanceToAgent(this); p.SendAttachmentsToClient(ControllingClient); @@ -5603,7 +5604,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendme) { - m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); +// m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); try { ControllingClient.SendKillObject(new List { p.LocalId }); } catch (NullReferenceException) { } } @@ -5752,7 +5753,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendto) { - m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); +// m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); try { p.ControllingClient.SendKillObject(new List { LocalId }); } catch (NullReferenceException) { } } @@ -5762,7 +5763,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendme) { - m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); +// m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); try {ControllingClient.SendKillObject(new List { p.LocalId }); } catch (NullReferenceException) { } } -- cgit v1.1 From 3d81f25e34cd7d536ad0e36242703ac1bc56038d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 4 Aug 2014 20:32:11 +0100 Subject: Revert "start sending terrain in scenePresence after well defined avatar. Minor" This reverts commit 05a2feba5d780c57c252891a20071800fd9f2e3e. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 28 +- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 34 +- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- OpenSim/Region/Framework/Scenes/SceneBase.cs | 1160 ++++++++++---------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 19 +- 5 files changed, 616 insertions(+), 629 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7d61577..34a2797 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -577,10 +577,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Fire the callback for this connection closing if (OnConnectionClosed != null) - { OnConnectionClosed(this); - } - // Flush all of the packets out of the UDP server for this client if (m_udpServer != null) @@ -5521,7 +5518,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); - AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false); +// AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false); + AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, true); AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance); @@ -5734,15 +5732,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Scene/Avatar // Threshold for body rotation to be a significant agent update - // private const float QDELTA = 0.000001f; - // QDELTA is now relative to abs of cos of angle between orientations - - private const float QDELTABODY = 1 - 0.0001f; - private const float QDELTAHEAD = 1 - 0.0001f; - + private const float QDELTA = 0.000001f; // Threshold for camera rotation to be a significant agent update private const float VDELTA = 0.01f; - + /// /// This checks the update significance against the last update made. /// @@ -5762,18 +5755,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) { - // float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2); + float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2); //qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2); - // now using abs of cos - float qdelta1 = (float)Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation)); - float qdelta2 = (float)Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation)); bool movementSignificant = -// (qdelta1 > QDELTA) // significant if body rotation above threshold - (qdelta1 < QDELTABODY) // higher angle lower cos -// Ignoring head rotation altogether, because it's not being used for anything interesting up the stack + (qdelta1 > QDELTA) // significant if body rotation above threshold + // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack // || (qdelta2 > QDELTA * 10) // significant if head rotation above threshold - || (qdelta2 < QDELTAHEAD) // using cos above || (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands || (x.Far != m_thisAgentUpdateArgs.Far) // significant if far distance changed @@ -6488,7 +6476,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Action handlerRegionHandShakeReply = OnRegionHandShakeReply; if (handlerRegionHandShakeReply != null) { -// Thread.Sleep(500); + Thread.Sleep(500); handlerRegionHandShakeReply(this); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index a3fdae1..b7c8594 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1750,10 +1750,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP endPoint, sessionInfo); + // Send ack straight away to let the viewer know that the connection is active. + // The client will be null if it already exists (e.g. if on a region crossing the client sends a use + // circuit code to the existing child agent. This is not particularly obvious. + SendAckImmediate(endPoint, uccp.Header.Sequence); + + // We only want to send initial data to new clients, not ones which are being converted from child to root. + if (client != null) + { + AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); + bool tp = (aCircuit.teleportFlags > 0); + // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from + if (!tp) + client.SceneAgent.SendInitialDataToMe(); + } + // Now we know we can handle more data -// Thread.Sleep(200); + Thread.Sleep(200); - // Obtain the pending queue and remove it from the cache + // Obtain the queue and remove it from the cache Queue queue = null; lock (m_pendingCache) @@ -1775,21 +1790,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP PacketReceived(buf); } queue = null; - - // Send ack straight away to let the viewer know that the connection is active. - // The client will be null if it already exists (e.g. if on a region crossing the client sends a use - // circuit code to the existing child agent. This is not particularly obvious. - SendAckImmediate(endPoint, uccp.Header.Sequence); - - // We only want to send initial data to new clients, not ones which are being converted from child to root. - if (client != null) - { - AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); - bool tp = (aCircuit.teleportFlags > 0); - // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from - if (!tp) - client.SceneAgent.SendInitialDataToMe(); - } } else { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ec54e15..0266faf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3179,7 +3179,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void SubscribeToClientTerrainEvents(IClientAPI client) { -// client.OnRegionHandShakeReply += SendLayerData; + client.OnRegionHandShakeReply += SendLayerData; } public virtual void SubscribeToClientPrimEvents(IClientAPI client) @@ -3307,7 +3307,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client) { -// client.OnRegionHandShakeReply -= SendLayerData; + client.OnRegionHandShakeReply -= SendLayerData; } public virtual void UnSubscribeToClientPrimEvents(IClientAPI client) diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 6adccca..08e26c5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -1,581 +1,581 @@ -/* - * 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 OpenMetaverse; -using log4net; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Console; - -using OpenSim.Region.Framework.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; - -namespace OpenSim.Region.Framework.Scenes -{ - public abstract class SceneBase : IScene - { +/* + * 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 OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; + +using OpenSim.Region.Framework.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.Framework.Scenes +{ + public abstract class SceneBase : IScene + { protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static readonly string LogHeader = "[SCENE]"; - - #region Events - - public event restart OnRestart; - - #endregion - - #region Fields - - public string Name { get { return RegionInfo.RegionName; } } - - public IConfigSource Config - { - get { return GetConfig(); } - } - - protected virtual IConfigSource GetConfig() - { - return null; - } - - /// - /// All the region modules attached to this scene. - /// - public Dictionary RegionModules - { - get { return m_regionModules; } - } - private Dictionary m_regionModules = new Dictionary(); - - /// - /// The module interfaces available from this scene. - /// - protected Dictionary> ModuleInterfaces = new Dictionary>(); - - protected Dictionary ModuleAPIMethods = new Dictionary(); - - /// - /// The module commanders available from this scene - /// - protected Dictionary m_moduleCommanders = new Dictionary(); - - /// - /// Registered classes that are capable of creating entities. - /// - protected Dictionary m_entityCreators = new Dictionary(); - - /// - /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is - /// dispensed. - /// - protected uint m_lastAllocatedLocalId = 720000; - - private readonly Mutex _primAllocateMutex = new Mutex(false); - - protected readonly ClientManager m_clientManager = new ClientManager(); - - public bool LoginsEnabled - { - get - { - return m_loginsEnabled; - } - - set - { - if (m_loginsEnabled != value) - { - m_loginsEnabled = value; - EventManager.TriggerRegionLoginsStatusChange(this); - } - } - } - private bool m_loginsEnabled; - - public bool Ready - { - get - { - return m_ready; - } - - set - { - if (m_ready != value) - { - m_ready = value; - EventManager.TriggerRegionReadyStatusChange(this); - } - } - } - private bool m_ready; - - public float TimeDilation - { - get { return 1.0f; } - } - - protected ulong m_regionHandle; - protected string m_regionName; - - public ITerrainChannel Heightmap; - - /// - /// Allows retrieval of land information for this scene. - /// - public ILandChannel LandChannel; - - /// - /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules - /// to subscribe to scene events. - /// - public EventManager EventManager - { - get { return m_eventManager; } - } - protected EventManager m_eventManager; - - protected ScenePermissions m_permissions; - public ScenePermissions Permissions - { - get { return m_permissions; } - } - - protected string m_datastore; - - /* Used by the loadbalancer plugin on GForge */ - protected RegionStatus m_regStatus; - public RegionStatus RegionStatus - { - get { return m_regStatus; } - set { m_regStatus = value; } - } - - #endregion - - public SceneBase(RegionInfo regInfo) - { - RegionInfo = regInfo; - } - - #region Update Methods - - /// - /// Called to update the scene loop by a number of frames and until shutdown. - /// - /// - /// Number of frames to update. Exits on shutdown even if there are frames remaining. - /// If -1 then updates until shutdown. - /// - public abstract void Update(int frames); - - #endregion - - #region Terrain Methods - - /// - /// Loads the World heightmap - /// - public abstract void LoadWorldMap(); - - /// - /// Send the region heightmap to the client - /// - /// Client to send to - public virtual void SendLayerData(IClientAPI RemoteClient) - { - RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); - } - - #endregion - - #region Add/Remove Agent/Avatar - - public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type); - - public abstract bool CloseAgent(UUID agentID, bool force); - - public bool TryGetScenePresence(UUID agentID, out object scenePresence) - { - scenePresence = null; - ScenePresence sp = null; - if (TryGetScenePresence(agentID, out sp)) - { - scenePresence = sp; - return true; - } - - return false; - } - - /// - /// Try to get a scene presence from the scene - /// - /// - /// null if there is no scene presence with the given agent id - /// true if there was a scene presence with the given id, false otherwise. - public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); - - #endregion - - /// - /// - /// - /// - public virtual RegionInfo RegionInfo { get; private set; } - - #region admin stuff - - public abstract void OtherRegionUp(GridRegion otherRegion); - - public virtual string GetSimulatorVersion() - { - return "OpenSimulator Server"; - } - - #endregion - - #region Shutdown - - /// - /// Tidy before shutdown - /// - public virtual void Close() - { - try - { - EventManager.TriggerShutdown(); - } - catch (Exception e) - { - m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); - } - } - - #endregion - - /// - /// Returns a new unallocated local ID - /// - /// A brand new local ID - public uint AllocateLocalId() - { - uint myID; - - _primAllocateMutex.WaitOne(); - myID = ++m_lastAllocatedLocalId; - _primAllocateMutex.ReleaseMutex(); - - return myID; - } - - #region Module Methods - - /// - /// Add a region-module to this scene. TODO: This will replace AddModule in the future. - /// - /// - /// - public void AddRegionModule(string name, IRegionModuleBase module) - { - if (!RegionModules.ContainsKey(name)) - { - RegionModules.Add(name, module); - } - } - - public void RemoveRegionModule(string name) - { - RegionModules.Remove(name); - } - - /// - /// Register a module commander. - /// - /// - public void RegisterModuleCommander(ICommander commander) - { - lock (m_moduleCommanders) - { - m_moduleCommanders.Add(commander.Name, commander); - } - } - - /// - /// Unregister a module commander and all its commands - /// - /// - public void UnregisterModuleCommander(string name) - { - lock (m_moduleCommanders) - { - ICommander commander; - if (m_moduleCommanders.TryGetValue(name, out commander)) - m_moduleCommanders.Remove(name); - } - } - - /// - /// Get a module commander - /// - /// - /// The module commander, null if no module commander with that name was found - public ICommander GetCommander(string name) - { - lock (m_moduleCommanders) - { - if (m_moduleCommanders.ContainsKey(name)) - return m_moduleCommanders[name]; - } - - return null; - } - - public Dictionary GetCommanders() - { - return m_moduleCommanders; - } - - /// - /// Register an interface to a region module. This allows module methods to be called directly as - /// well as via events. If there is already a module registered for this interface, it is not replaced - /// (is this the best behaviour?) - /// - /// - public void RegisterModuleInterface(M mod) - { -// m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); - - List l = null; - if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) - { - l = new List(); - ModuleInterfaces.Add(typeof(M), l); - } - - if (l.Count > 0) - return; - - l.Add(mod); - - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = entityCreator; - } - } - } - - public void UnregisterModuleInterface(M mod) - { - List l; - if (ModuleInterfaces.TryGetValue(typeof(M), out l)) - { - if (l.Remove(mod)) - { - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = null; - } - } - } - } - } - - public void StackModuleInterface(M mod) - { - List l; - if (ModuleInterfaces.ContainsKey(typeof(M))) - l = ModuleInterfaces[typeof(M)]; - else - l = new List(); - - if (l.Contains(mod)) - return; - - l.Add(mod); - - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = entityCreator; - } - } - - ModuleInterfaces[typeof(M)] = l; - } - - /// - /// For the given interface, retrieve the region module which implements it. - /// - /// null if there is no registered module implementing that interface - public T RequestModuleInterface() - { - if (ModuleInterfaces.ContainsKey(typeof(T)) && - (ModuleInterfaces[typeof(T)].Count > 0)) - return (T)ModuleInterfaces[typeof(T)][0]; - else - return default(T); - } - - /// - /// For the given interface, retrieve an array of region modules that implement it. - /// - /// an empty array if there are no registered modules implementing that interface - public T[] RequestModuleInterfaces() - { - if (ModuleInterfaces.ContainsKey(typeof(T))) - { - List ret = new List(); - - foreach (Object o in ModuleInterfaces[typeof(T)]) - ret.Add((T)o); - return ret.ToArray(); - } - else - { - return new T[] {}; - } - } - - #endregion - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// - /// - /// - /// - public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) - { - AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// The use of IRegionModuleBase is a cheap trick to get a different method signature, - /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. - /// - /// - /// Category of the command. This is the section under which it will appear when the user asks for help - /// - /// - /// - /// - /// - public void AddCommand( - string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) - { - AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// - /// - /// - /// - /// - public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) - { - string moduleName = ""; - - if (module != null) - moduleName = module.Name; - - AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// Category of the command. This is the section under which it will appear when the user asks for help - /// - /// - /// - /// - /// - /// - /// - public void AddCommand( - string category, IRegionModuleBase module, string command, - string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) - { - if (MainConsole.Instance == null) - return; - - bool shared = false; - - if (module != null) - shared = module is ISharedRegionModule; - - MainConsole.Instance.Commands.AddCommand( - category, shared, command, shorthelp, longhelp, descriptivehelp, callback); - } - - public virtual ISceneObject DeserializeObject(string representation) - { - return null; - } - - public virtual bool AllowScriptCrossings - { - get { return false; } - } - - public virtual void Start() - { - } - - public void Restart() - { - // This has to be here to fire the event - restart handlerPhysicsCrash = OnRestart; - if (handlerPhysicsCrash != null) - handlerPhysicsCrash(RegionInfo); - } - - public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); - } -} + protected static readonly string LogHeader = "[SCENE]"; + + #region Events + + public event restart OnRestart; + + #endregion + + #region Fields + + public string Name { get { return RegionInfo.RegionName; } } + + public IConfigSource Config + { + get { return GetConfig(); } + } + + protected virtual IConfigSource GetConfig() + { + return null; + } + + /// + /// All the region modules attached to this scene. + /// + public Dictionary RegionModules + { + get { return m_regionModules; } + } + private Dictionary m_regionModules = new Dictionary(); + + /// + /// The module interfaces available from this scene. + /// + protected Dictionary> ModuleInterfaces = new Dictionary>(); + + protected Dictionary ModuleAPIMethods = new Dictionary(); + + /// + /// The module commanders available from this scene + /// + protected Dictionary m_moduleCommanders = new Dictionary(); + + /// + /// Registered classes that are capable of creating entities. + /// + protected Dictionary m_entityCreators = new Dictionary(); + + /// + /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is + /// dispensed. + /// + protected uint m_lastAllocatedLocalId = 720000; + + private readonly Mutex _primAllocateMutex = new Mutex(false); + + protected readonly ClientManager m_clientManager = new ClientManager(); + + public bool LoginsEnabled + { + get + { + return m_loginsEnabled; + } + + set + { + if (m_loginsEnabled != value) + { + m_loginsEnabled = value; + EventManager.TriggerRegionLoginsStatusChange(this); + } + } + } + private bool m_loginsEnabled; + + public bool Ready + { + get + { + return m_ready; + } + + set + { + if (m_ready != value) + { + m_ready = value; + EventManager.TriggerRegionReadyStatusChange(this); + } + } + } + private bool m_ready; + + public float TimeDilation + { + get { return 1.0f; } + } + + protected ulong m_regionHandle; + protected string m_regionName; + + public ITerrainChannel Heightmap; + + /// + /// Allows retrieval of land information for this scene. + /// + public ILandChannel LandChannel; + + /// + /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules + /// to subscribe to scene events. + /// + public EventManager EventManager + { + get { return m_eventManager; } + } + protected EventManager m_eventManager; + + protected ScenePermissions m_permissions; + public ScenePermissions Permissions + { + get { return m_permissions; } + } + + protected string m_datastore; + + /* Used by the loadbalancer plugin on GForge */ + protected RegionStatus m_regStatus; + public RegionStatus RegionStatus + { + get { return m_regStatus; } + set { m_regStatus = value; } + } + + #endregion + + public SceneBase(RegionInfo regInfo) + { + RegionInfo = regInfo; + } + + #region Update Methods + + /// + /// Called to update the scene loop by a number of frames and until shutdown. + /// + /// + /// Number of frames to update. Exits on shutdown even if there are frames remaining. + /// If -1 then updates until shutdown. + /// + public abstract void Update(int frames); + + #endregion + + #region Terrain Methods + + /// + /// Loads the World heightmap + /// + public abstract void LoadWorldMap(); + + /// + /// Send the region heightmap to the client + /// + /// Client to send to + public virtual void SendLayerData(IClientAPI RemoteClient) + { + RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); + } + + #endregion + + #region Add/Remove Agent/Avatar + + public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type); + + public abstract bool CloseAgent(UUID agentID, bool force); + + public bool TryGetScenePresence(UUID agentID, out object scenePresence) + { + scenePresence = null; + ScenePresence sp = null; + if (TryGetScenePresence(agentID, out sp)) + { + scenePresence = sp; + return true; + } + + return false; + } + + /// + /// Try to get a scene presence from the scene + /// + /// + /// null if there is no scene presence with the given agent id + /// true if there was a scene presence with the given id, false otherwise. + public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); + + #endregion + + /// + /// + /// + /// + public virtual RegionInfo RegionInfo { get; private set; } + + #region admin stuff + + public abstract void OtherRegionUp(GridRegion otherRegion); + + public virtual string GetSimulatorVersion() + { + return "OpenSimulator Server"; + } + + #endregion + + #region Shutdown + + /// + /// Tidy before shutdown + /// + public virtual void Close() + { + try + { + EventManager.TriggerShutdown(); + } + catch (Exception e) + { + m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); + } + } + + #endregion + + /// + /// Returns a new unallocated local ID + /// + /// A brand new local ID + public uint AllocateLocalId() + { + uint myID; + + _primAllocateMutex.WaitOne(); + myID = ++m_lastAllocatedLocalId; + _primAllocateMutex.ReleaseMutex(); + + return myID; + } + + #region Module Methods + + /// + /// Add a region-module to this scene. TODO: This will replace AddModule in the future. + /// + /// + /// + public void AddRegionModule(string name, IRegionModuleBase module) + { + if (!RegionModules.ContainsKey(name)) + { + RegionModules.Add(name, module); + } + } + + public void RemoveRegionModule(string name) + { + RegionModules.Remove(name); + } + + /// + /// Register a module commander. + /// + /// + public void RegisterModuleCommander(ICommander commander) + { + lock (m_moduleCommanders) + { + m_moduleCommanders.Add(commander.Name, commander); + } + } + + /// + /// Unregister a module commander and all its commands + /// + /// + public void UnregisterModuleCommander(string name) + { + lock (m_moduleCommanders) + { + ICommander commander; + if (m_moduleCommanders.TryGetValue(name, out commander)) + m_moduleCommanders.Remove(name); + } + } + + /// + /// Get a module commander + /// + /// + /// The module commander, null if no module commander with that name was found + public ICommander GetCommander(string name) + { + lock (m_moduleCommanders) + { + if (m_moduleCommanders.ContainsKey(name)) + return m_moduleCommanders[name]; + } + + return null; + } + + public Dictionary GetCommanders() + { + return m_moduleCommanders; + } + + /// + /// Register an interface to a region module. This allows module methods to be called directly as + /// well as via events. If there is already a module registered for this interface, it is not replaced + /// (is this the best behaviour?) + /// + /// + public void RegisterModuleInterface(M mod) + { +// m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); + + List l = null; + if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) + { + l = new List(); + ModuleInterfaces.Add(typeof(M), l); + } + + if (l.Count > 0) + return; + + l.Add(mod); + + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = entityCreator; + } + } + } + + public void UnregisterModuleInterface(M mod) + { + List l; + if (ModuleInterfaces.TryGetValue(typeof(M), out l)) + { + if (l.Remove(mod)) + { + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = null; + } + } + } + } + } + + public void StackModuleInterface(M mod) + { + List l; + if (ModuleInterfaces.ContainsKey(typeof(M))) + l = ModuleInterfaces[typeof(M)]; + else + l = new List(); + + if (l.Contains(mod)) + return; + + l.Add(mod); + + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = entityCreator; + } + } + + ModuleInterfaces[typeof(M)] = l; + } + + /// + /// For the given interface, retrieve the region module which implements it. + /// + /// null if there is no registered module implementing that interface + public T RequestModuleInterface() + { + if (ModuleInterfaces.ContainsKey(typeof(T)) && + (ModuleInterfaces[typeof(T)].Count > 0)) + return (T)ModuleInterfaces[typeof(T)][0]; + else + return default(T); + } + + /// + /// For the given interface, retrieve an array of region modules that implement it. + /// + /// an empty array if there are no registered modules implementing that interface + public T[] RequestModuleInterfaces() + { + if (ModuleInterfaces.ContainsKey(typeof(T))) + { + List ret = new List(); + + foreach (Object o in ModuleInterfaces[typeof(T)]) + ret.Add((T)o); + return ret.ToArray(); + } + else + { + return new T[] {}; + } + } + + #endregion + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// + /// + /// + /// + public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) + { + AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// The use of IRegionModuleBase is a cheap trick to get a different method signature, + /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. + /// + /// + /// Category of the command. This is the section under which it will appear when the user asks for help + /// + /// + /// + /// + /// + public void AddCommand( + string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) + { + AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// + /// + /// + /// + /// + public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) + { + string moduleName = ""; + + if (module != null) + moduleName = module.Name; + + AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// Category of the command. This is the section under which it will appear when the user asks for help + /// + /// + /// + /// + /// + /// + /// + public void AddCommand( + string category, IRegionModuleBase module, string command, + string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) + { + if (MainConsole.Instance == null) + return; + + bool shared = false; + + if (module != null) + shared = module is ISharedRegionModule; + + MainConsole.Instance.Commands.AddCommand( + category, shared, command, shorthelp, longhelp, descriptivehelp, callback); + } + + public virtual ISceneObject DeserializeObject(string representation) + { + return null; + } + + public virtual bool AllowScriptCrossings + { + get { return false; } + } + + public virtual void Start() + { + } + + public void Restart() + { + // This has to be here to fire the event + restart handlerPhysicsCrash = OnRestart; + if (handlerPhysicsCrash != null) + handlerPhysicsCrash(RegionInfo); + } + + public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); + } +} diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 8088dd3..24a92eb 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3473,7 +3473,6 @@ namespace OpenSim.Region.Framework.Scenes landch.sendClientInitialLandInfo(ControllingClient); } } - m_scene.SendLayerData(ControllingClient); SendOtherAgentsAvatarDataToMe(); SendOtherAgentsAppearanceToMe(); @@ -5427,7 +5426,7 @@ namespace OpenSim.Region.Framework.Scenes { if (p.IsChildAgent) continue; -// m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname); + m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname); ControllingClient.SendAvatarDataImmediate(p); p.SendAppearanceToAgent(this); p.SendAttachmentsToClient(ControllingClient); @@ -5455,7 +5454,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendme) { -// m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); + m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); try { ControllingClient.SendKillObject(new List { p.LocalId }); } catch (NullReferenceException) { } } @@ -5500,7 +5499,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendto) { -// m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); + m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); try { p.ControllingClient.SendKillObject(new List { LocalId }); } catch (NullReferenceException) { } } @@ -5510,7 +5509,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendme) { -// m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); + m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); try { ControllingClient.SendKillObject(new List { p.LocalId }); } catch (NullReferenceException) { } } @@ -5520,7 +5519,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in viewsToSendto) { -// m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname); + m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname); p.ControllingClient.SendAvatarDataImmediate(this); SendAppearanceToAgent(p); SendAttachmentsToClient(p.ControllingClient); @@ -5533,9 +5532,9 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in viewsToSendme) { + m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); if (p.IsChildAgent) continue; -// m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); ControllingClient.SendAvatarDataImmediate(p); p.SendAppearanceToAgent(this); p.SendAttachmentsToClient(ControllingClient); @@ -5604,7 +5603,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendme) { -// m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); + m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); try { ControllingClient.SendKillObject(new List { p.LocalId }); } catch (NullReferenceException) { } } @@ -5753,7 +5752,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendto) { -// m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); + m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname); try { p.ControllingClient.SendKillObject(new List { LocalId }); } catch (NullReferenceException) { } } @@ -5763,7 +5762,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (ScenePresence p in killsToSendme) { -// m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); + m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); try {ControllingClient.SendKillObject(new List { p.LocalId }); } catch (NullReferenceException) { } } -- cgit v1.1 From 3cca5ec6674b413a419d3f1c42467e57fb883f56 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 4 Aug 2014 21:52:29 +0100 Subject: check... --- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 34 +- OpenSim/Region/Framework/Scenes/SceneBase.cs | 1160 ++++++++++---------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +- 3 files changed, 598 insertions(+), 606 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index b7c8594..a3fdae1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1750,25 +1750,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP endPoint, sessionInfo); - // Send ack straight away to let the viewer know that the connection is active. - // The client will be null if it already exists (e.g. if on a region crossing the client sends a use - // circuit code to the existing child agent. This is not particularly obvious. - SendAckImmediate(endPoint, uccp.Header.Sequence); - - // We only want to send initial data to new clients, not ones which are being converted from child to root. - if (client != null) - { - AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); - bool tp = (aCircuit.teleportFlags > 0); - // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from - if (!tp) - client.SceneAgent.SendInitialDataToMe(); - } - // Now we know we can handle more data - Thread.Sleep(200); +// Thread.Sleep(200); - // Obtain the queue and remove it from the cache + // Obtain the pending queue and remove it from the cache Queue queue = null; lock (m_pendingCache) @@ -1790,6 +1775,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP PacketReceived(buf); } queue = null; + + // Send ack straight away to let the viewer know that the connection is active. + // The client will be null if it already exists (e.g. if on a region crossing the client sends a use + // circuit code to the existing child agent. This is not particularly obvious. + SendAckImmediate(endPoint, uccp.Header.Sequence); + + // We only want to send initial data to new clients, not ones which are being converted from child to root. + if (client != null) + { + AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); + bool tp = (aCircuit.teleportFlags > 0); + // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from + if (!tp) + client.SceneAgent.SendInitialDataToMe(); + } } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index 08e26c5..dd0c828 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -1,581 +1,581 @@ -/* - * 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 OpenMetaverse; -using log4net; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Console; - -using OpenSim.Region.Framework.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; - -namespace OpenSim.Region.Framework.Scenes -{ - public abstract class SceneBase : IScene - { +/* + * 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 OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; + +using OpenSim.Region.Framework.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.Framework.Scenes +{ + public abstract class SceneBase : IScene + { protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected static readonly string LogHeader = "[SCENE]"; - - #region Events - - public event restart OnRestart; - - #endregion - - #region Fields - - public string Name { get { return RegionInfo.RegionName; } } - - public IConfigSource Config - { - get { return GetConfig(); } - } - - protected virtual IConfigSource GetConfig() - { - return null; - } - - /// - /// All the region modules attached to this scene. - /// - public Dictionary RegionModules - { - get { return m_regionModules; } - } - private Dictionary m_regionModules = new Dictionary(); - - /// - /// The module interfaces available from this scene. - /// - protected Dictionary> ModuleInterfaces = new Dictionary>(); - - protected Dictionary ModuleAPIMethods = new Dictionary(); - - /// - /// The module commanders available from this scene - /// - protected Dictionary m_moduleCommanders = new Dictionary(); - - /// - /// Registered classes that are capable of creating entities. - /// - protected Dictionary m_entityCreators = new Dictionary(); - - /// - /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is - /// dispensed. - /// - protected uint m_lastAllocatedLocalId = 720000; - - private readonly Mutex _primAllocateMutex = new Mutex(false); - - protected readonly ClientManager m_clientManager = new ClientManager(); - - public bool LoginsEnabled - { - get - { - return m_loginsEnabled; - } - - set - { - if (m_loginsEnabled != value) - { - m_loginsEnabled = value; - EventManager.TriggerRegionLoginsStatusChange(this); - } - } - } - private bool m_loginsEnabled; - - public bool Ready - { - get - { - return m_ready; - } - - set - { - if (m_ready != value) - { - m_ready = value; - EventManager.TriggerRegionReadyStatusChange(this); - } - } - } - private bool m_ready; - - public float TimeDilation - { - get { return 1.0f; } - } - - protected ulong m_regionHandle; - protected string m_regionName; - - public ITerrainChannel Heightmap; - - /// - /// Allows retrieval of land information for this scene. - /// - public ILandChannel LandChannel; - - /// - /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules - /// to subscribe to scene events. - /// - public EventManager EventManager - { - get { return m_eventManager; } - } - protected EventManager m_eventManager; - - protected ScenePermissions m_permissions; - public ScenePermissions Permissions - { - get { return m_permissions; } - } - - protected string m_datastore; - - /* Used by the loadbalancer plugin on GForge */ - protected RegionStatus m_regStatus; - public RegionStatus RegionStatus - { - get { return m_regStatus; } - set { m_regStatus = value; } - } - - #endregion - - public SceneBase(RegionInfo regInfo) - { - RegionInfo = regInfo; - } - - #region Update Methods - - /// - /// Called to update the scene loop by a number of frames and until shutdown. - /// - /// - /// Number of frames to update. Exits on shutdown even if there are frames remaining. - /// If -1 then updates until shutdown. - /// - public abstract void Update(int frames); - - #endregion - - #region Terrain Methods - - /// - /// Loads the World heightmap - /// - public abstract void LoadWorldMap(); - - /// - /// Send the region heightmap to the client - /// - /// Client to send to - public virtual void SendLayerData(IClientAPI RemoteClient) - { - RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); - } - - #endregion - - #region Add/Remove Agent/Avatar - - public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type); - - public abstract bool CloseAgent(UUID agentID, bool force); - - public bool TryGetScenePresence(UUID agentID, out object scenePresence) - { - scenePresence = null; - ScenePresence sp = null; - if (TryGetScenePresence(agentID, out sp)) - { - scenePresence = sp; - return true; - } - - return false; - } - - /// - /// Try to get a scene presence from the scene - /// - /// - /// null if there is no scene presence with the given agent id - /// true if there was a scene presence with the given id, false otherwise. - public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); - - #endregion - - /// - /// - /// - /// - public virtual RegionInfo RegionInfo { get; private set; } - - #region admin stuff - - public abstract void OtherRegionUp(GridRegion otherRegion); - - public virtual string GetSimulatorVersion() - { - return "OpenSimulator Server"; - } - - #endregion - - #region Shutdown - - /// - /// Tidy before shutdown - /// - public virtual void Close() - { - try - { - EventManager.TriggerShutdown(); - } - catch (Exception e) - { - m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); - } - } - - #endregion - - /// - /// Returns a new unallocated local ID - /// - /// A brand new local ID - public uint AllocateLocalId() - { - uint myID; - - _primAllocateMutex.WaitOne(); - myID = ++m_lastAllocatedLocalId; - _primAllocateMutex.ReleaseMutex(); - - return myID; - } - - #region Module Methods - - /// - /// Add a region-module to this scene. TODO: This will replace AddModule in the future. - /// - /// - /// - public void AddRegionModule(string name, IRegionModuleBase module) - { - if (!RegionModules.ContainsKey(name)) - { - RegionModules.Add(name, module); - } - } - - public void RemoveRegionModule(string name) - { - RegionModules.Remove(name); - } - - /// - /// Register a module commander. - /// - /// - public void RegisterModuleCommander(ICommander commander) - { - lock (m_moduleCommanders) - { - m_moduleCommanders.Add(commander.Name, commander); - } - } - - /// - /// Unregister a module commander and all its commands - /// - /// - public void UnregisterModuleCommander(string name) - { - lock (m_moduleCommanders) - { - ICommander commander; - if (m_moduleCommanders.TryGetValue(name, out commander)) - m_moduleCommanders.Remove(name); - } - } - - /// - /// Get a module commander - /// - /// - /// The module commander, null if no module commander with that name was found - public ICommander GetCommander(string name) - { - lock (m_moduleCommanders) - { - if (m_moduleCommanders.ContainsKey(name)) - return m_moduleCommanders[name]; - } - - return null; - } - - public Dictionary GetCommanders() - { - return m_moduleCommanders; - } - - /// - /// Register an interface to a region module. This allows module methods to be called directly as - /// well as via events. If there is already a module registered for this interface, it is not replaced - /// (is this the best behaviour?) - /// - /// - public void RegisterModuleInterface(M mod) - { -// m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); - - List l = null; - if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) - { - l = new List(); - ModuleInterfaces.Add(typeof(M), l); - } - - if (l.Count > 0) - return; - - l.Add(mod); - - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = entityCreator; - } - } - } - - public void UnregisterModuleInterface(M mod) - { - List l; - if (ModuleInterfaces.TryGetValue(typeof(M), out l)) - { - if (l.Remove(mod)) - { - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = null; - } - } - } - } - } - - public void StackModuleInterface(M mod) - { - List l; - if (ModuleInterfaces.ContainsKey(typeof(M))) - l = ModuleInterfaces[typeof(M)]; - else - l = new List(); - - if (l.Contains(mod)) - return; - - l.Add(mod); - - if (mod is IEntityCreator) - { - IEntityCreator entityCreator = (IEntityCreator)mod; - foreach (PCode pcode in entityCreator.CreationCapabilities) - { - m_entityCreators[pcode] = entityCreator; - } - } - - ModuleInterfaces[typeof(M)] = l; - } - - /// - /// For the given interface, retrieve the region module which implements it. - /// - /// null if there is no registered module implementing that interface - public T RequestModuleInterface() - { - if (ModuleInterfaces.ContainsKey(typeof(T)) && - (ModuleInterfaces[typeof(T)].Count > 0)) - return (T)ModuleInterfaces[typeof(T)][0]; - else - return default(T); - } - - /// - /// For the given interface, retrieve an array of region modules that implement it. - /// - /// an empty array if there are no registered modules implementing that interface - public T[] RequestModuleInterfaces() - { - if (ModuleInterfaces.ContainsKey(typeof(T))) - { - List ret = new List(); - - foreach (Object o in ModuleInterfaces[typeof(T)]) - ret.Add((T)o); - return ret.ToArray(); - } - else - { - return new T[] {}; - } - } - - #endregion - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// - /// - /// - /// - public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) - { - AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// The use of IRegionModuleBase is a cheap trick to get a different method signature, - /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. - /// - /// - /// Category of the command. This is the section under which it will appear when the user asks for help - /// - /// - /// - /// - /// - public void AddCommand( - string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) - { - AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// - /// - /// - /// - /// - public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) - { - string moduleName = ""; - - if (module != null) - moduleName = module.Name; - - AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); - } - - /// - /// Call this from a region module to add a command to the OpenSim console. - /// - /// - /// Category of the command. This is the section under which it will appear when the user asks for help - /// - /// - /// - /// - /// - /// - /// - public void AddCommand( - string category, IRegionModuleBase module, string command, - string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) - { - if (MainConsole.Instance == null) - return; - - bool shared = false; - - if (module != null) - shared = module is ISharedRegionModule; - - MainConsole.Instance.Commands.AddCommand( - category, shared, command, shorthelp, longhelp, descriptivehelp, callback); - } - - public virtual ISceneObject DeserializeObject(string representation) - { - return null; - } - - public virtual bool AllowScriptCrossings - { - get { return false; } - } - - public virtual void Start() - { - } - - public void Restart() - { - // This has to be here to fire the event - restart handlerPhysicsCrash = OnRestart; - if (handlerPhysicsCrash != null) - handlerPhysicsCrash(RegionInfo); - } - - public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); - } -} + protected static readonly string LogHeader = "[SCENE]"; + + #region Events + + public event restart OnRestart; + + #endregion + + #region Fields + + public string Name { get { return RegionInfo.RegionName; } } + + public IConfigSource Config + { + get { return GetConfig(); } + } + + protected virtual IConfigSource GetConfig() + { + return null; + } + + /// + /// All the region modules attached to this scene. + /// + public Dictionary RegionModules + { + get { return m_regionModules; } + } + private Dictionary m_regionModules = new Dictionary(); + + /// + /// The module interfaces available from this scene. + /// + protected Dictionary> ModuleInterfaces = new Dictionary>(); + + protected Dictionary ModuleAPIMethods = new Dictionary(); + + /// + /// The module commanders available from this scene + /// + protected Dictionary m_moduleCommanders = new Dictionary(); + + /// + /// Registered classes that are capable of creating entities. + /// + protected Dictionary m_entityCreators = new Dictionary(); + + /// + /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is + /// dispensed. + /// + protected uint m_lastAllocatedLocalId = 720000; + + private readonly Mutex _primAllocateMutex = new Mutex(false); + + protected readonly ClientManager m_clientManager = new ClientManager(); + + public bool LoginsEnabled + { + get + { + return m_loginsEnabled; + } + + set + { + if (m_loginsEnabled != value) + { + m_loginsEnabled = value; + EventManager.TriggerRegionLoginsStatusChange(this); + } + } + } + private bool m_loginsEnabled; + + public bool Ready + { + get + { + return m_ready; + } + + set + { + if (m_ready != value) + { + m_ready = value; + EventManager.TriggerRegionReadyStatusChange(this); + } + } + } + private bool m_ready; + + public float TimeDilation + { + get { return 1.0f; } + } + + protected ulong m_regionHandle; + protected string m_regionName; + + public ITerrainChannel Heightmap; + + /// + /// Allows retrieval of land information for this scene. + /// + public ILandChannel LandChannel; + + /// + /// Manage events that occur in this scene (avatar movement, script rez, etc.). Commonly used by region modules + /// to subscribe to scene events. + /// + public EventManager EventManager + { + get { return m_eventManager; } + } + protected EventManager m_eventManager; + + protected ScenePermissions m_permissions; + public ScenePermissions Permissions + { + get { return m_permissions; } + } + + protected string m_datastore; + + /* Used by the loadbalancer plugin on GForge */ + protected RegionStatus m_regStatus; + public RegionStatus RegionStatus + { + get { return m_regStatus; } + set { m_regStatus = value; } + } + + #endregion + + public SceneBase(RegionInfo regInfo) + { + RegionInfo = regInfo; + } + + #region Update Methods + + /// + /// Called to update the scene loop by a number of frames and until shutdown. + /// + /// + /// Number of frames to update. Exits on shutdown even if there are frames remaining. + /// If -1 then updates until shutdown. + /// + public abstract void Update(int frames); + + #endregion + + #region Terrain Methods + + /// + /// Loads the World heightmap + /// + public abstract void LoadWorldMap(); + + /// + /// Send the region heightmap to the client + /// + /// Client to send to + public virtual void SendLayerData(IClientAPI RemoteClient) + { + RemoteClient.SendLayerData(Heightmap.GetFloatsSerialised()); + } + + #endregion + + #region Add/Remove Agent/Avatar + + public abstract ISceneAgent AddNewAgent(IClientAPI client, PresenceType type); + + public abstract bool CloseAgent(UUID agentID, bool force); + + public bool TryGetScenePresence(UUID agentID, out object scenePresence) + { + scenePresence = null; + ScenePresence sp = null; + if (TryGetScenePresence(agentID, out sp)) + { + scenePresence = sp; + return true; + } + + return false; + } + + /// + /// Try to get a scene presence from the scene + /// + /// + /// null if there is no scene presence with the given agent id + /// true if there was a scene presence with the given id, false otherwise. + public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); + + #endregion + + /// + /// + /// + /// + public virtual RegionInfo RegionInfo { get; private set; } + + #region admin stuff + + public abstract void OtherRegionUp(GridRegion otherRegion); + + public virtual string GetSimulatorVersion() + { + return "OpenSimulator Server"; + } + + #endregion + + #region Shutdown + + /// + /// Tidy before shutdown + /// + public virtual void Close() + { + try + { + EventManager.TriggerShutdown(); + } + catch (Exception e) + { + m_log.Error(string.Format("[SCENE]: SceneBase.cs: Close() - Failed with exception ", e)); + } + } + + #endregion + + /// + /// Returns a new unallocated local ID + /// + /// A brand new local ID + public uint AllocateLocalId() + { + uint myID; + + _primAllocateMutex.WaitOne(); + myID = ++m_lastAllocatedLocalId; + _primAllocateMutex.ReleaseMutex(); + + return myID; + } + + #region Module Methods + + /// + /// Add a region-module to this scene. TODO: This will replace AddModule in the future. + /// + /// + /// + public void AddRegionModule(string name, IRegionModuleBase module) + { + if (!RegionModules.ContainsKey(name)) + { + RegionModules.Add(name, module); + } + } + + public void RemoveRegionModule(string name) + { + RegionModules.Remove(name); + } + + /// + /// Register a module commander. + /// + /// + public void RegisterModuleCommander(ICommander commander) + { + lock (m_moduleCommanders) + { + m_moduleCommanders.Add(commander.Name, commander); + } + } + + /// + /// Unregister a module commander and all its commands + /// + /// + public void UnregisterModuleCommander(string name) + { + lock (m_moduleCommanders) + { + ICommander commander; + if (m_moduleCommanders.TryGetValue(name, out commander)) + m_moduleCommanders.Remove(name); + } + } + + /// + /// Get a module commander + /// + /// + /// The module commander, null if no module commander with that name was found + public ICommander GetCommander(string name) + { + lock (m_moduleCommanders) + { + if (m_moduleCommanders.ContainsKey(name)) + return m_moduleCommanders[name]; + } + + return null; + } + + public Dictionary GetCommanders() + { + return m_moduleCommanders; + } + + /// + /// Register an interface to a region module. This allows module methods to be called directly as + /// well as via events. If there is already a module registered for this interface, it is not replaced + /// (is this the best behaviour?) + /// + /// + public void RegisterModuleInterface(M mod) + { +// m_log.DebugFormat("[SCENE BASE]: Registering interface {0}", typeof(M)); + + List l = null; + if (!ModuleInterfaces.TryGetValue(typeof(M), out l)) + { + l = new List(); + ModuleInterfaces.Add(typeof(M), l); + } + + if (l.Count > 0) + return; + + l.Add(mod); + + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = entityCreator; + } + } + } + + public void UnregisterModuleInterface(M mod) + { + List l; + if (ModuleInterfaces.TryGetValue(typeof(M), out l)) + { + if (l.Remove(mod)) + { + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = null; + } + } + } + } + } + + public void StackModuleInterface(M mod) + { + List l; + if (ModuleInterfaces.ContainsKey(typeof(M))) + l = ModuleInterfaces[typeof(M)]; + else + l = new List(); + + if (l.Contains(mod)) + return; + + l.Add(mod); + + if (mod is IEntityCreator) + { + IEntityCreator entityCreator = (IEntityCreator)mod; + foreach (PCode pcode in entityCreator.CreationCapabilities) + { + m_entityCreators[pcode] = entityCreator; + } + } + + ModuleInterfaces[typeof(M)] = l; + } + + /// + /// For the given interface, retrieve the region module which implements it. + /// + /// null if there is no registered module implementing that interface + public T RequestModuleInterface() + { + if (ModuleInterfaces.ContainsKey(typeof(T)) && + (ModuleInterfaces[typeof(T)].Count > 0)) + return (T)ModuleInterfaces[typeof(T)][0]; + else + return default(T); + } + + /// + /// For the given interface, retrieve an array of region modules that implement it. + /// + /// an empty array if there are no registered modules implementing that interface + public T[] RequestModuleInterfaces() + { + if (ModuleInterfaces.ContainsKey(typeof(T))) + { + List ret = new List(); + + foreach (Object o in ModuleInterfaces[typeof(T)]) + ret.Add((T)o); + return ret.ToArray(); + } + else + { + return new T[] {}; + } + } + + #endregion + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// + /// + /// + /// + public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) + { + AddCommand(module, command, shorthelp, longhelp, string.Empty, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// The use of IRegionModuleBase is a cheap trick to get a different method signature, + /// though all new modules should be using interfaces descended from IRegionModuleBase anyway. + /// + /// + /// Category of the command. This is the section under which it will appear when the user asks for help + /// + /// + /// + /// + /// + public void AddCommand( + string category, IRegionModuleBase module, string command, string shorthelp, string longhelp, CommandDelegate callback) + { + AddCommand(category, module, command, shorthelp, longhelp, string.Empty, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// + /// + /// + /// + /// + public void AddCommand(IRegionModuleBase module, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) + { + string moduleName = ""; + + if (module != null) + moduleName = module.Name; + + AddCommand(moduleName, module, command, shorthelp, longhelp, descriptivehelp, callback); + } + + /// + /// Call this from a region module to add a command to the OpenSim console. + /// + /// + /// Category of the command. This is the section under which it will appear when the user asks for help + /// + /// + /// + /// + /// + /// + /// + public void AddCommand( + string category, IRegionModuleBase module, string command, + string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) + { + if (MainConsole.Instance == null) + return; + + bool shared = false; + + if (module != null) + shared = module is ISharedRegionModule; + + MainConsole.Instance.Commands.AddCommand( + category, shared, command, shorthelp, longhelp, descriptivehelp, callback); + } + + public virtual ISceneObject DeserializeObject(string representation) + { + return null; + } + + public virtual bool AllowScriptCrossings + { + get { return false; } + } + + public virtual void Start() + { + } + + public void Restart() + { + // This has to be here to fire the event + restart handlerPhysicsCrash = OnRestart; + if (handlerPhysicsCrash != null) + handlerPhysicsCrash(RegionInfo); + } + + public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); + } +} diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 24a92eb..596feb1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3369,19 +3369,11 @@ namespace OpenSim.Region.Framework.Scenes public void SendTerseUpdateToAgentClient(ScenePresence p) { - // messy checks because a client doesn't know what presence it belongs too - IClientAPI remoteClient = p.ControllingClient; - if (remoteClient == null) - return; - - if (!remoteClient.IsActive) - return; - + if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID && p.GodLevel < 200) return; - //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); remoteClient.SendEntityUpdate( this, -- cgit v1.1 From 507a29d5819fcbbac4eb22b0e45b11cf3afb5096 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 4 Aug 2014 21:55:58 +0100 Subject: diference fix --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 596feb1..f41a828 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3370,7 +3370,10 @@ namespace OpenSim.Region.Framework.Scenes public void SendTerseUpdateToAgentClient(ScenePresence p) { IClientAPI remoteClient = p.ControllingClient; - + + if (!remoteClient.IsActive) + return; + if (ParcelHideThisAvatar && p.currentParcelUUID != currentParcelUUID && p.GodLevel < 200) return; -- cgit v1.1 From 6eca2475d4babfcf84aa40a885ff1e65e99a9420 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Aug 2014 17:55:30 +0100 Subject: dont assume that all zero folded perms are to ignore ( coerence with old code in avn-current ) --- OpenSim/Framework/PermissionsUtil.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/PermissionsUtil.cs b/OpenSim/Framework/PermissionsUtil.cs index d785a78..5d3186d 100644 --- a/OpenSim/Framework/PermissionsUtil.cs +++ b/OpenSim/Framework/PermissionsUtil.cs @@ -72,8 +72,8 @@ namespace OpenSim.Framework /// The permissions variable to modify. public static void ApplyFoldedPermissions(uint foldedPerms, ref uint mainPerms) { - if ((foldedPerms & 7) == 0) - return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded +// if ((foldedPerms & 7) == 0) +// return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded if ((foldedPerms & ((uint)PermissionMask.Copy >> 13)) == 0) mainPerms &= ~(uint)PermissionMask.Copy; -- cgit v1.1 From c80322f1e69123922d9611b678e91323de97b835 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Aug 2014 19:03:11 +0100 Subject: dont change agentItem.BasePermissions where avination-current didn't change --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 746b703..8634a3a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1234,8 +1234,9 @@ namespace OpenSim.Region.Framework.Scenes { uint perms = taskItem.CurrentPermissions; PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms); - agentItem.BasePermissions = perms | (uint)PermissionMask.Move; - agentItem.CurrentPermissions = agentItem.BasePermissions; +// agentItem.BasePermissions = perms | (uint)PermissionMask.Move; +// agentItem.CurrentPermissions = agentItem.BasePermissions; + agentItem.CurrentPermissions = perms | (uint)PermissionMask.Move; } else { -- cgit v1.1 From 01780d4dc6b3dc266b8fbf22f779ced5bd002743 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Aug 2014 19:59:21 +0100 Subject: put back a check for null foldedperms --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index cf2e037..eb5d784 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -2942,7 +2942,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// private void ApplyNextOwnerPermissions(InventoryItemBase item) { - if (item.InvType == (int)InventoryType.Object) + if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) { uint perms = item.CurrentPermissions; PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms); -- cgit v1.1 From 2c4908578ed40c743d566a3cd1995a4e69ed17c8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Aug 2014 21:55:42 +0100 Subject: revert to old avn-current code, not using ApplyPermissionsOnRez() till its reviewed/fixed --- .../Framework/Scenes/SceneObjectPartInventory.cs | 44 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 257e01e..400a415 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -922,7 +922,7 @@ namespace OpenSim.Region.Framework.Scenes rootPart.Name = item.Name; rootPart.Description = item.Description; } - +/* reverted to old code till part.ApplyPermissionsOnRez is better reviewed/fixed group.SetGroup(m_part.GroupID, null); foreach (SceneObjectPart part in group.Parts) @@ -938,7 +938,49 @@ namespace OpenSim.Region.Framework.Scenes part.ApplyPermissionsOnRez(dest, false, m_part.ParentGroup.Scene); } +*/ +// old code start + SceneObjectPart[] partList = group.Parts; + + group.SetGroup(m_part.GroupID, null); + + // TODO: Remove magic number badness + if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number + { + if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) + { + foreach (SceneObjectPart part in partList) + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) + part.EveryoneMask = item.EveryonePermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) + part.NextOwnerMask = item.NextPermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) + part.GroupMask = item.GroupPermissions; + } + group.ApplyNextOwnerPermissions(); + } + } + + foreach (SceneObjectPart part in partList) + { + // TODO: Remove magic number badness + if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.OwnerID; + part.Inventory.ChangeInventoryOwner(item.OwnerID); + } + + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) + part.EveryoneMask = item.EveryonePermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) + part.NextOwnerMask = item.NextPermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) + part.GroupMask = item.GroupPermissions; + } +// old code end rootPart.TrimPermissions(); } -- cgit v1.1 From 3c321e5bb37d0430085c361632fb668824e9b500 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Aug 2014 22:49:41 +0100 Subject: dont mess with names and descriptions on coalescence objects. Inventory name can change for inventory purposes only. --- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 5 ++++- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index e4f23f9..e8e281e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -1032,10 +1032,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // object itself before we rez. // // Only do these for the first object if we are rezzing a coalescence. - if (i == 0) + // nahh dont mess with coalescence objects, + // the name in inventory can be change for inventory purpuses only + if (i == 0 && objlist.Count == 1) { rootPart.Name = item.Name; rootPart.Description = item.Description; + // this should be done only on first or all ??? if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0) { rootPart.ObjectSaleType = item.SaleType; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 400a415..657d7c1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -917,7 +917,9 @@ namespace OpenSim.Region.Framework.Scenes // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. // Only do these for the first object if we are rezzing a coalescence. - if (i == 0) + // nahh dont mess with coalescence objects, + // the name in inventory can be change for inventory purpuses only + if (i == 0 && objlist.Count == 1) { rootPart.Name = item.Name; rootPart.Description = item.Description; -- cgit v1.1 From e1a5a1f829ad7b82fa8dc5b81248dff45b586f40 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Aug 2014 23:25:08 +0100 Subject: apply objectSlamSale to all roots of coalescence objects. replace the single object condition for renaming --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 14 +++++++------- .../Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index e8e281e..7b13e0b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -1034,16 +1034,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // Only do these for the first object if we are rezzing a coalescence. // nahh dont mess with coalescence objects, // the name in inventory can be change for inventory purpuses only - if (i == 0 && objlist.Count == 1) + if (objlist.Count == 1) { rootPart.Name = item.Name; rootPart.Description = item.Description; - // this should be done only on first or all ??? - if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0) - { - rootPart.ObjectSaleType = item.SaleType; - rootPart.SalePrice = item.SalePrice; - } + } + + if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0) + { + rootPart.ObjectSaleType = item.SaleType; + rootPart.SalePrice = item.SalePrice; } so.FromFolderID = item.Folder; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 657d7c1..a6a963b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -919,7 +919,7 @@ namespace OpenSim.Region.Framework.Scenes // Only do these for the first object if we are rezzing a coalescence. // nahh dont mess with coalescence objects, // the name in inventory can be change for inventory purpuses only - if (i == 0 && objlist.Count == 1) + if (objlist.Count == 1) { rootPart.Name = item.Name; rootPart.Description = item.Description; -- cgit v1.1 From bd3d58dd00ceafab961d684208c10fae20f89dc2 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 6 Aug 2014 04:54:14 +0100 Subject: try to make the baked textures cache work --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 73 ++++++++++++---------- 1 file changed, 40 insertions(+), 33 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 34a2797..7f25f78 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -6535,7 +6535,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length]; for (int i=0; i AvatarWearable.MAX_WEARABLES) maxWearablesLoop = AvatarWearable.MAX_WEARABLES; - if (bakedTextureModule != null && cache != null) +// if (bakedTextureModule != null && cache != null) + if (cache != null) { // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid WearableCacheItem[] cacheItems = null; ScenePresence p = m_scene.GetScenePresence(AgentId); if (p.Appearance != null) - if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty) + { + if (p.Appearance.WearableCacheItems == null) { - try + if (bakedTextureModule != null) { - cacheItems = bakedTextureModule.Get(AgentId); - p.Appearance.WearableCacheItems = cacheItems; - p.Appearance.WearableCacheItemsDirty = false; - } + try + { + if (p.Appearance.WearableCacheItemsDirty) + { + cacheItems = bakedTextureModule.Get(AgentId); + p.Appearance.WearableCacheItems = cacheItems; + p.Appearance.WearableCacheItemsDirty = false; + } + } - /* - * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception! - * - catch (System.Net.Sockets.SocketException) - { - cacheItems = null; - } - catch (WebException) - { - cacheItems = null; - } - catch (InvalidOperationException) - { - cacheItems = null; - } */ - catch (Exception) - { - cacheItems = null; + /* + * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception! + * + catch (System.Net.Sockets.SocketException) + { + cacheItems = null; + } + catch (WebException) + { + cacheItems = null; + } + catch (InvalidOperationException) + { + cacheItems = null; + } */ + catch (Exception) + { + cacheItems = null; + } } - } else if (p.Appearance.WearableCacheItems != null) { cacheItems = p.Appearance.WearableCacheItems; } + } if (cache != null && cacheItems != null) { @@ -12077,8 +12088,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP item.TextureAsset.Temporary = true; cache.Store(item.TextureAsset); } - - } } @@ -12136,13 +12145,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - - if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null) cachedresp.WearableData[i].TextureID = UUID.Zero; //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - else - cachedresp.WearableData[i].TextureID = UUID.Zero; +// else +// cachedresp.WearableData[i].TextureID = UUID.Zero; // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); cachedresp.WearableData[i].HostName = new byte[0]; } -- cgit v1.1 From 66dea8fe05dbf0f9783f520cddf4d3aa700015d6 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 6 Aug 2014 05:17:30 +0100 Subject: some debug to remove later --- OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs | 6 ++++++ OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 47988dd..19afe97 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -268,6 +268,12 @@ namespace OpenSim.Region.ClientStack.Linden } } } + + for (int iter = 0; iter < maxCacheitemsLoop; iter++) + { + m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + + cacheItems[iter].TextureID); + } } public void PostInitialise() diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7f25f78..0e8c7ca 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12041,6 +12041,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (bakedTextureModule != null) { + m_log.Debug("[ HandleAgentTextureCached] bakedTextureModule"); try { if (p.Appearance.WearableCacheItemsDirty) @@ -12072,7 +12073,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } - else if (p.Appearance.WearableCacheItems != null) + + if (p.Appearance.WearableCacheItems != null) { cacheItems = p.Appearance.WearableCacheItems; } -- cgit v1.1 From 552b4e45e8700cc71bbbea18b5bad167998a74e4 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 6 Aug 2014 05:56:10 +0100 Subject: bakemodule didnt like last changes --- .../ClientStack/Linden/Caps/UploadBakedTextureModule.cs | 8 +++----- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 13 +++++-------- 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 19afe97..2da653d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -254,18 +254,16 @@ namespace OpenSim.Region.ClientStack.Linden } } - - p.Appearance.WearableCacheItems = cacheItems; - - - + if (m_BakedTextureModule != null) { m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); p.Appearance.WearableCacheItemsDirty = true; } + else + p.Appearance.WearableCacheItemsDirty = false; } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 0e8c7ca..08b6cb4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12037,19 +12037,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP ScenePresence p = m_scene.GetScenePresence(AgentId); if (p.Appearance != null) { - if (p.Appearance.WearableCacheItems == null) + if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty) { if (bakedTextureModule != null) { m_log.Debug("[ HandleAgentTextureCached] bakedTextureModule"); try { - if (p.Appearance.WearableCacheItemsDirty) - { - cacheItems = bakedTextureModule.Get(AgentId); - p.Appearance.WearableCacheItems = cacheItems; - p.Appearance.WearableCacheItemsDirty = false; - } + cacheItems = bakedTextureModule.Get(AgentId); + p.Appearance.WearableCacheItems = cacheItems; + p.Appearance.WearableCacheItemsDirty = false; } /* @@ -12074,7 +12071,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - if (p.Appearance.WearableCacheItems != null) + else if (p.Appearance.WearableCacheItems != null) { cacheItems = p.Appearance.WearableCacheItems; } -- cgit v1.1 From c3f9c99fb32d15e57b24502b71c79fe028ed3007 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Aug 2014 05:20:45 +0100 Subject: DANGER... changed bakedtextures caching. Assuming grid baking is cache only, reduced number of accesses to it. TESTING --- OpenSim/Framework/WearableCacheItem.cs | 2 +- .../Linden/Caps/UploadBakedTextureModule.cs | 124 +++++---- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 110 ++++---- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 279 +++++++++++++++------ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 5 files changed, 299 insertions(+), 218 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs index 1aecf79..cde2862 100644 --- a/OpenSim/Framework/WearableCacheItem.cs +++ b/OpenSim/Framework/WearableCacheItem.cs @@ -46,7 +46,7 @@ namespace OpenSim.Framework int itemmax = 21; WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; for (uint i=0;i AvatarWearable.MAX_WEARABLES) - { - maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; - m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); - } - - m_BakedTextureModule = m_scene.RequestModuleInterface(); - if (cacheItems.Length > 0) - { - m_log.Debug("[Cacheitems]: " + cacheItems.Length); - for (int iter = 0; iter < maxCacheitemsLoop; iter++) - { - m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + - cacheItems[iter].TextureID); - } - - ScenePresence p = null; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) +/* not in use. work done in AvatarFactoryModule ValidateBakedTextureCache() and UpdateBakedTextureCache() + private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { + // if cacheItems.Length > 0 viewer is giving us current textures information. + // baked ones should had been uploaded and in assets cache as local itens + + + if (cacheItems.Length == 0) + return; // no textures information, nothing to do + + ScenePresence p = null; + if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) + return; // what are we doing if there is no presence to cache for? + + if (p.IsDeleted) + return; // does this really work? + + int maxCacheitemsLoop = cacheItems.Length; + if (maxCacheitemsLoop > 20) + { + maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; + m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); + } + + m_BakedTextureModule = m_scene.RequestModuleInterface(); + + + // some nice debug + m_log.Debug("[Cacheitems]: " + cacheItems.Length); + for (int iter = 0; iter < maxCacheitemsLoop; iter++) + { + m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + + cacheItems[iter].TextureID); + } + + // p.Appearance.WearableCacheItems is in memory primary cashID to textures mapper WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; + if (existingitems == null) { if (m_BakedTextureModule != null) @@ -161,38 +173,22 @@ namespace OpenSim.Region.ClientStack.Linden p.Appearance.WearableCacheItems = savedcache; p.Appearance.WearableCacheItemsDirty = false; } - } - /* - * The following Catch types DO NOT WORK with m_BakedTextureModule.Get - * it jumps to the General Packet Exception Handler if you don't catch Exception! - * - catch (System.Net.Sockets.SocketException) - { - cacheItems = null; - } - catch (WebException) - { - cacheItems = null; - } - catch (InvalidOperationException) - { - cacheItems = null; - } */ + catch (Exception) { - // The service logs a sufficient error message. + // The service logs a sufficient error message. } - + if (savedcache != null) existingitems = savedcache; } } + // Existing items null means it's a fully new appearance if (existingitems == null) { - for (int i = 0; i < maxCacheitemsLoop; i++) { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) @@ -205,7 +201,7 @@ namespace OpenSim.Region.ClientStack.Linden AppearanceManager.DEFAULT_AVATAR_TEXTURE; continue; } - cacheItems[i].TextureID =face.TextureID; + cacheItems[i].TextureID = face.TextureID; if (m_scene.AssetService != null) cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); @@ -214,15 +210,10 @@ namespace OpenSim.Region.ClientStack.Linden { m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } - - } } else - - - { - // for each uploaded baked texture + { for (int i = 0; i < maxCacheitemsLoop; i++) { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) @@ -253,27 +244,24 @@ namespace OpenSim.Region.ClientStack.Linden } } } - p.Appearance.WearableCacheItems = cacheItems; - + if (m_BakedTextureModule != null) { m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); p.Appearance.WearableCacheItemsDirty = true; - + } else p.Appearance.WearableCacheItemsDirty = false; - } - } - - for (int iter = 0; iter < maxCacheitemsLoop; iter++) - { - m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + - cacheItems[iter].TextureID); - } - } + for (int iter = 0; iter < maxCacheitemsLoop; iter++) + { + m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + + cacheItems[iter].TextureID); + } + } + */ public void PostInitialise() { } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 08b6cb4..38a9af3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3684,6 +3684,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP avp.Sender.IsTrial = false; avp.Sender.ID = agentID; avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; + + // this need be use in future + // avp.AppearanceData[0].AppearanceVersion = 0; + // avp.AppearanceData[0].CofVersion = 0; + //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); OutPacket(avp, ThrottleOutPacketType.Task); } @@ -12006,8 +12011,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); if (cachedtex.AgentData.SessionID != SessionId) - return false; - + return false; // TODO: don't create new blocks if recycling an old packet cachedresp.AgentData.AgentID = AgentId; @@ -12022,23 +12026,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP //WearableCacheItem[] items = fac.GetCachedItems(AgentId); IAssetService cache = m_scene.AssetService; - IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface(); //bakedTextureModule = null; int maxWearablesLoop = cachedtex.WearableData.Length; if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) maxWearablesLoop = AvatarWearable.MAX_WEARABLES; -// if (bakedTextureModule != null && cache != null) + int cacheHits = 0; + if (cache != null) { // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid WearableCacheItem[] cacheItems = null; + ScenePresence p = m_scene.GetScenePresence(AgentId); - if (p.Appearance != null) + + if (p!= null && p.Appearance != null) { - if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty) + /* we should only check bakedTextureModule at login or when appearance changes + if (p.Appearance.WearableCacheItems == null) // currently with a caching only bakemodule Appearance.Wearables.dirty as no use { + IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface(); if (bakedTextureModule != null) { m_log.Debug("[ HandleAgentTextureCached] bakedTextureModule"); @@ -12047,23 +12055,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP cacheItems = bakedTextureModule.Get(AgentId); p.Appearance.WearableCacheItems = cacheItems; p.Appearance.WearableCacheItemsDirty = false; - } - /* - * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception! - * - catch (System.Net.Sockets.SocketException) - { - cacheItems = null; - } - catch (WebException) - { - cacheItems = null; + if (cacheItems != null) + { + foreach (WearableCacheItem item in cacheItems) + { + if (item.TextureAsset != null) + { + item.TextureAsset.Temporary = true; + item.TextureAsset.Local = true; + cache.Store(item.TextureAsset); + } + } + } } - catch (InvalidOperationException) - { - cacheItems = null; - } */ + catch (Exception) { cacheItems = null; @@ -12075,36 +12081,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP { cacheItems = p.Appearance.WearableCacheItems; } +*/ + cacheItems = p.Appearance.WearableCacheItems; } - if (cache != null && cacheItems != null) - { - foreach (WearableCacheItem item in cacheItems) - { - - if (cache.GetCached(item.TextureID.ToString()) == null) - { - item.TextureAsset.Temporary = true; - cache.Store(item.TextureAsset); - } - } - } - if (cacheItems != null) { - for (int i = 0; i < maxWearablesLoop; i++) { - WearableCacheItem item = - WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems); + int idx = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].HostName = new byte[0]; - if (item != null && cachedtex.WearableData[i].ID == item.CacheId) + if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId) { - - cachedresp.WearableData[i].TextureID = item.TextureID; + cachedresp.WearableData[i].TextureID = cacheItems[idx].TextureID; + cacheHits++; } else { @@ -12124,36 +12117,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } - else + else // no cache { - if (cache == null) + for (int i = 0; i < maxWearablesLoop; i++) { - for (int i = 0; i < maxWearablesLoop; i++) - { - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - cachedresp.WearableData[i].TextureID = UUID.Zero; - //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - cachedresp.WearableData[i].HostName = new byte[0]; - } - } - else - { - for (int i = 0; i < maxWearablesLoop; i++) - { - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - - if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null) - cachedresp.WearableData[i].TextureID = UUID.Zero; - //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); -// else -// cachedresp.WearableData[i].TextureID = UUID.Zero; - // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - cachedresp.WearableData[i].HostName = new byte[0]; - } + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].TextureID = UUID.Zero; + cachedresp.WearableData[i].HostName = new byte[0]; } } + + m_log.DebugFormat("texture cached: hits {0}", cacheHits); + cachedresp.Header.Zerocoded = true; OutPacket(cachedresp, ThrottleOutPacketType.Task); diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 09cc998..b4aefce 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -188,27 +188,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // Process the visual params, this may change height as well if (visualParams != null) { - // string[] visualParamsStrings = new string[visualParams.Length]; - // for (int i = 0; i < visualParams.Length; i++) - // visualParamsStrings[i] = visualParams[i].ToString(); - // m_log.DebugFormat( - // "[AVFACTORY]: Setting visual params for {0} to {1}", - // client.Name, string.Join(", ", visualParamsStrings)); -/* - float oldHeight = sp.Appearance.AvatarHeight; - changed = sp.Appearance.SetVisualParams(visualParams); - - if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) - ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); - */ -// float oldoff = sp.Appearance.AvatarFeetOffset; -// Vector3 oldbox = sp.Appearance.AvatarBoxSize; changed = sp.Appearance.SetVisualParams(visualParams); -// float off = sp.Appearance.AvatarFeetOffset; -// Vector3 box = sp.Appearance.AvatarBoxSize; -// if(oldoff != off || oldbox != box) -// ((ScenePresence)sp).SetSize(box,off); - } // Process the baked texture array @@ -222,9 +202,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // WriteBakedTexturesReport(sp, m_log.DebugFormat); + // If bake textures are missing and this is not an NPC, request a rebake from client - if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) - RequestRebake(sp, true); + // rebake may messup caching, and should not be needed + + +// if (!UpdateBakedTextureCache(sp,cacheItems) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) +// RequestRebake(sp, true); + + UpdateBakedTextureCache(sp, cacheItems); // This appears to be set only in the final stage of the appearance // update transaction. In theory, we should be able to do an immediate @@ -377,13 +363,138 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } + // called on textures update + public bool UpdateBakedTextureCache(IScenePresence sp, WearableCacheItem[] cacheItems) + { + bool defonly = true; // are we only using default textures + + // uploaded baked textures will be in assets local cache + IAssetService cache = m_scene.AssetService; + + int validDirtyBakes = 0; + int hits = 0; + + // our main cacheIDs mapper is p.Appearance.WearableCacheItems + WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; + + if (wearableCache == null) + { + wearableCache = WearableCacheItem.GetDefaultCacheItem(); + } + + // Process received baked textures + for (int i = 0; i < cacheItems.Length; i++) + { + int idx = (int)cacheItems[i].TextureIndex; + Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; + + // No face + if (face == null) + { + // for some reason viewer is cleaning this + sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); + sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; + continue; + } + else + { + if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) + { + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; + continue; + } + + defonly = false; // found a non-default texture reference + + if(sp.Appearance.Texture.FaceTextures[idx].TextureID == wearableCache[idx].TextureID) + { + if(wearableCache[idx].CacheId != cacheItems[i].CacheId) + { + wearableCache[idx].CacheId = cacheItems[i].CacheId; + validDirtyBakes++; + hits++; + //assuming this can only happen if asset is in cache + } + continue; + } + + + wearableCache[idx].TextureAsset = null; + if (cache != null) + wearableCache[idx].TextureAsset = cache.GetCached(face.TextureID.ToString()); + + if (wearableCache[idx].TextureAsset != null) + { + wearableCache[idx].CacheId = cacheItems[i].CacheId; + wearableCache[idx].TextureID = sp.Appearance.Texture.FaceTextures[idx].TextureID; + validDirtyBakes++; + hits++; + } + else + { + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; + continue; + } + } + } + + sp.Appearance.WearableCacheItems = wearableCache; + + // if we got a full set of baked textures save all in BakedTextureModule + + if (validDirtyBakes == cacheItems.Length) + { + IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface(); + if (m_BakedTextureModule != null) + { + m_log.Debug("[UpdateBakedCache] uploading to bakedModule cache"); + + m_BakedTextureModule.Store(sp.UUID, wearableCache); + } + } + + // debug + for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) + { + int j = AvatarAppearance.BAKE_INDICES[iter]; + m_log.Debug("[UpdateBCache] {" + iter + "/" + + sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + + sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + + sp.Appearance.WearableCacheItems[j].TextureID); + } + + // If we only found default textures, then the appearance is not cached + return (defonly ? false : true); + } + + // called when we get a new root avatar public bool ValidateBakedTextureCache(IScenePresence sp) { bool defonly = true; // are we only using default textures - IImprovedAssetCache cache = m_scene.RequestModuleInterface(); + IAssetService cache = m_scene.AssetService; IBakedTextureModule bakedModule = m_scene.RequestModuleInterface(); WearableCacheItem[] wearableCache = null; + // debug + for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) + { + int j = AvatarAppearance.BAKE_INDICES[iter]; + Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[iter]; + if(face != null) + m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - " + face.TextureID); + else + m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture"); + } + + + int hits = 0; // Cache wearable data for teleport. // Only makes sense if there's a bake module and a cache module if (bakedModule != null && cache != null) @@ -394,41 +505,35 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } catch (Exception) { - + wearableCache = null; } + if (wearableCache != null) { for (int i = 0; i < wearableCache.Length; i++) { - cache.Cache(wearableCache[i].TextureAsset); - } - } - } - /* - IBakedTextureModule bakedModule = m_scene.RequestModuleInterface(); - if (invService.GetRootFolder(userID) != null) - { - WearableCacheItem[] wearableCache = null; - if (bakedModule != null) - { - try - { - wearableCache = bakedModule.Get(userID); - appearance.WearableCacheItems = wearableCache; - appearance.WearableCacheItemsDirty = false; - foreach (WearableCacheItem item in wearableCache) + + m_log.Debug("[ValidateBakedCache] got bakedModule cache"); + + if (wearableCache[i].TextureAsset != null) { - appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID; + wearableCache[i].TextureAsset.Temporary = true; + wearableCache[i].TextureAsset.Local = true; + cache.Store(wearableCache[i].TextureAsset); + } + else + { + wearableCache[i].TextureID = UUID.Zero; + wearableCache[i].CacheId = UUID.Zero; } - } - catch (Exception) - { - } } - */ + } + + if(wearableCache == null) + wearableCache = WearableCacheItem.GetDefaultCacheItem(); - // Process the texture entry + // Process the baked textures for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) { int idx = AvatarAppearance.BAKE_INDICES[i]; @@ -437,61 +542,73 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // No face, so lets check our baked service cache, teleport or login. if (face == null) { - if (wearableCache != null) + sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx); + if (wearableCache[idx].TextureID != UUID.Zero) { - // If we find the an appearance item, set it as the textureentry and the face - WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache); - if (searchitem != null) - { - sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); - sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID; - face = sp.Appearance.Texture.FaceTextures[idx]; - } - else - { - // if there is no texture entry and no baked cache, skip it - continue; - } + sp.Appearance.Texture.FaceTextures[idx].TextureID = wearableCache[idx].TextureID; + face = sp.Appearance.Texture.FaceTextures[idx]; + // let run to end of loop to check cache } else { - //No texture entry face and no cache. Skip this face. + sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; + face = sp.Appearance.Texture.FaceTextures[idx]; + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; continue; } } - - -// m_log.DebugFormat( -// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", -// face.TextureID, idx, client.Name, client.AgentId); + - // if the texture is one of the "defaults" then skip it - // this should probably be more intelligent (skirt texture doesnt matter - // if the avatar isnt wearing a skirt) but if any of the main baked - // textures is default then the rest should be as well if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) + { + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; continue; - + } + defonly = false; // found a non-default texture reference - if (cache != null) + if(wearableCache[idx].TextureID != sp.Appearance.Texture.FaceTextures[idx].TextureID) { - if (!cache.Check(face.TextureID.ToString())) - return false; + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; + continue; } - else + + wearableCache[idx].TextureAsset = null; + if (cache != null) { - if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) - return false; + wearableCache[idx].TextureAsset = m_scene.AssetService.Get(face.TextureID.ToString()); + if (wearableCache[idx].TextureAsset == null) + { + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + } + else + hits++; } } -// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); + sp.Appearance.WearableCacheItems = wearableCache; + + m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1} {2} {3}", sp.Name, sp.UUID, hits, defonly.ToString()); + // debug + for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) + { + int j = AvatarAppearance.BAKE_INDICES[iter]; + m_log.Debug("[ValidateBakedCache] {" + iter + "/" + + sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + + sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + + sp.Appearance.WearableCacheItems[j].TextureID); + } // If we only found default textures, then the appearance is not cached return (defonly ? false : true); } - public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) { int texturesRebaked = 0; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f41a828..965d7c2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3502,7 +3502,7 @@ namespace OpenSim.Region.Framework.Scenes // If we aren't using a cached appearance, then clear out the baked textures if (!cachedappearance) { - Appearance.ResetAppearance(); +// Appearance.ResetAppearance(); // save what ???? // maybe needed so the tryretry repair works? if (m_scene.AvatarFactory != null) -- cgit v1.1 From b7f24bacce523240b73fba7ea0f3403dc59c3596 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Aug 2014 06:09:56 +0100 Subject: bugg --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 54 +++++++++++----------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 2 files changed, 27 insertions(+), 29 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index b4aefce..877231a 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -481,6 +481,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory IAssetService cache = m_scene.AssetService; IBakedTextureModule bakedModule = m_scene.RequestModuleInterface(); WearableCacheItem[] wearableCache = null; + WearableCacheItem[] bakedModuleCache = null; + + wearableCache = WearableCacheItem.GetDefaultCacheItem(); // debug for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) @@ -493,46 +496,47 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture"); } - int hits = 0; // Cache wearable data for teleport. // Only makes sense if there's a bake module and a cache module if (bakedModule != null && cache != null) { + m_log.Debug("[ValidateBakedCache] calling bakedModule"); try { - wearableCache = bakedModule.Get(sp.UUID); + bakedModuleCache = bakedModule.Get(sp.UUID); } catch (Exception) { - wearableCache = null; + bakedModuleCache = null; } - if (wearableCache != null) + if (bakedModuleCache != null) { - for (int i = 0; i < wearableCache.Length; i++) - { + m_log.Debug("[ValidateBakedCache] got bakedModule cache " + wearableCache.Length); - m_log.Debug("[ValidateBakedCache] got bakedModule cache"); + // old store have diferent sizes and index starts at 1 + int offset = 0; + if (bakedModuleCache[0].TextureIndex == 1) + offset = -1; + int j; - if (wearableCache[i].TextureAsset != null) - { - wearableCache[i].TextureAsset.Temporary = true; - wearableCache[i].TextureAsset.Local = true; - cache.Store(wearableCache[i].TextureAsset); - } - else + for (int i = 0; i < bakedModuleCache.Length; i++) + { + j = (int)bakedModuleCache[i].TextureIndex + offset; + + if (bakedModuleCache[i].TextureAsset != null) { - wearableCache[i].TextureID = UUID.Zero; - wearableCache[i].CacheId = UUID.Zero; + wearableCache[j].TextureID = bakedModuleCache[i].TextureID; + wearableCache[j].CacheId = bakedModuleCache[i].TextureID; + bakedModuleCache[i].TextureAsset.Temporary = true; + bakedModuleCache[i].TextureAsset.Local = true; + cache.Store(bakedModuleCache[i].TextureAsset); } } } } - if(wearableCache == null) - wearableCache = WearableCacheItem.GetDefaultCacheItem(); - // Process the baked textures for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) { @@ -540,7 +544,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; // No face, so lets check our baked service cache, teleport or login. - if (face == null) + if (face == null || face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) { sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx); if (wearableCache[idx].TextureID != UUID.Zero) @@ -554,24 +558,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; face = sp.Appearance.Texture.FaceTextures[idx]; wearableCache[idx].CacheId = UUID.Zero; - wearableCache[idx].TextureID = UUID.Zero; wearableCache[idx].TextureAsset = null; continue; } } - if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) { - wearableCache[idx].CacheId = UUID.Zero; - wearableCache[idx].TextureID = UUID.Zero; - wearableCache[idx].TextureAsset = null; + defonly = false; // found a non-default texture reference continue; } - defonly = false; // found a non-default texture reference - - if(wearableCache[idx].TextureID != sp.Appearance.Texture.FaceTextures[idx].TextureID) + if(wearableCache[idx].TextureID != face.TextureID) { wearableCache[idx].CacheId = UUID.Zero; wearableCache[idx].TextureID = UUID.Zero; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 965d7c2..8fae032 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3525,7 +3525,7 @@ namespace OpenSim.Region.Framework.Scenes // send even grays if (cachedappearance) { - m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name); +// m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name); // If the avatars baked textures are all in the cache, then we have a // complete appearance... send it out, if not, then we'll send it when // the avatar finishes updating its appearance -- cgit v1.1 From 12d8ed2dcdc354d0059b63a2139f544c3c7b30b8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Aug 2014 07:08:01 +0100 Subject: only send to bakedmodule the baked textures :) --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 877231a..a19790d 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -422,7 +422,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } continue; } - wearableCache[idx].TextureAsset = null; if (cache != null) @@ -456,7 +455,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { m_log.Debug("[UpdateBakedCache] uploading to bakedModule cache"); - m_BakedTextureModule.Store(sp.UUID, wearableCache); + WearableCacheItem[] toBakedModule = new WearableCacheItem[AvatarAppearance.BAKE_INDICES.Length]; + + for (int i = 0; i < cacheItems.Length; i++) + { + int idx = (int)cacheItems[i].TextureIndex; + cacheItems[i].CacheId = wearableCache[idx].CacheId; + cacheItems[i].TextureID = wearableCache[idx].TextureID; + cacheItems[i].TextureAsset = wearableCache[idx].TextureAsset; + } + m_BakedTextureModule.Store(sp.UUID, cacheItems); } } @@ -513,22 +521,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (bakedModuleCache != null) { - m_log.Debug("[ValidateBakedCache] got bakedModule cache " + wearableCache.Length); - - // old store have diferent sizes and index starts at 1 - int offset = 0; - if (bakedModuleCache[0].TextureIndex == 1) - offset = -1; - int j; + m_log.Debug("[ValidateBakedCache] got bakedModule cache " + bakedModuleCache.Length); for (int i = 0; i < bakedModuleCache.Length; i++) { - j = (int)bakedModuleCache[i].TextureIndex + offset; + int j = (int)bakedModuleCache[i].TextureIndex; if (bakedModuleCache[i].TextureAsset != null) { wearableCache[j].TextureID = bakedModuleCache[i].TextureID; wearableCache[j].CacheId = bakedModuleCache[i].TextureID; + wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset; bakedModuleCache[i].TextureAsset.Temporary = true; bakedModuleCache[i].TextureAsset.Local = true; cache.Store(bakedModuleCache[i].TextureAsset); -- cgit v1.1 From a95afb7fc59db4c88855ba79a97046afa24a8eac Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Aug 2014 07:36:23 +0100 Subject: bug --- OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index a19790d..edf62db 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -530,7 +530,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (bakedModuleCache[i].TextureAsset != null) { wearableCache[j].TextureID = bakedModuleCache[i].TextureID; - wearableCache[j].CacheId = bakedModuleCache[i].TextureID; + wearableCache[j].CacheId = bakedModuleCache[i].CacheId; wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset; bakedModuleCache[i].TextureAsset.Temporary = true; bakedModuleCache[i].TextureAsset.Local = true; -- cgit v1.1 From 1408c9eee7eb8b73b49255f6c7bf81f4a759d01c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Aug 2014 07:55:56 +0100 Subject: reply to cached checks with same serial number --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 38a9af3..def1f8e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12016,8 +12016,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP // TODO: don't create new blocks if recycling an old packet cachedresp.AgentData.AgentID = AgentId; cachedresp.AgentData.SessionID = m_sessionId; - cachedresp.AgentData.SerialNum = m_cachedTextureSerial; - m_cachedTextureSerial++; +// cachedresp.AgentData.SerialNum = m_cachedTextureSerial; +// m_cachedTextureSerial++; + cachedresp.AgentData.SerialNum = cachedtex.AgentData.SerialNum; cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; @@ -12094,7 +12095,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].HostName = new byte[0]; - if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId) + if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId) { cachedresp.WearableData[i].TextureID = cacheItems[idx].TextureID; cacheHits++; -- cgit v1.1 From dfa9ba0937f6e2d30e1d541d64533ede4ecb671e Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Aug 2014 08:47:03 +0100 Subject: minor clean, dont check for cache if we aren't using it.. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 104 +++++---------------- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 28 +----- 2 files changed, 27 insertions(+), 105 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index def1f8e..e9a087b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12011,120 +12011,60 @@ namespace OpenSim.Region.ClientStack.LindenUDP AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); if (cachedtex.AgentData.SessionID != SessionId) - return false; + return false; // TODO: don't create new blocks if recycling an old packet cachedresp.AgentData.AgentID = AgentId; cachedresp.AgentData.SessionID = m_sessionId; -// cachedresp.AgentData.SerialNum = m_cachedTextureSerial; -// m_cachedTextureSerial++; cachedresp.AgentData.SerialNum = cachedtex.AgentData.SerialNum; cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; - //IAvatarFactoryModule fac = m_scene.RequestModuleInterface(); - // var item = fac.GetBakedTextureFaces(AgentId); - //WearableCacheItem[] items = fac.GetCachedItems(AgentId); - - IAssetService cache = m_scene.AssetService; - //bakedTextureModule = null; int maxWearablesLoop = cachedtex.WearableData.Length; if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) maxWearablesLoop = AvatarWearable.MAX_WEARABLES; int cacheHits = 0; - if (cache != null) - { - // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid - - WearableCacheItem[] cacheItems = null; - - ScenePresence p = m_scene.GetScenePresence(AgentId); - - if (p!= null && p.Appearance != null) - { - /* we should only check bakedTextureModule at login or when appearance changes - if (p.Appearance.WearableCacheItems == null) // currently with a caching only bakemodule Appearance.Wearables.dirty as no use - { - IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface(); - if (bakedTextureModule != null) - { - m_log.Debug("[ HandleAgentTextureCached] bakedTextureModule"); - try - { - cacheItems = bakedTextureModule.Get(AgentId); - p.Appearance.WearableCacheItems = cacheItems; - p.Appearance.WearableCacheItemsDirty = false; + // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid - if (cacheItems != null) - { - foreach (WearableCacheItem item in cacheItems) - { - if (item.TextureAsset != null) - { - item.TextureAsset.Temporary = true; - item.TextureAsset.Local = true; - cache.Store(item.TextureAsset); - } - } - } - } + WearableCacheItem[] cacheItems = null; - catch (Exception) - { - cacheItems = null; - } - } - } + ScenePresence p = m_scene.GetScenePresence(AgentId); - else if (p.Appearance.WearableCacheItems != null) - { - cacheItems = p.Appearance.WearableCacheItems; - } -*/ - cacheItems = p.Appearance.WearableCacheItems; - } + if (p != null && p.Appearance != null) + { + cacheItems = p.Appearance.WearableCacheItems; + } - if (cacheItems != null) + if (cacheItems != null) + { + for (int i = 0; i < maxWearablesLoop; i++) { - for (int i = 0; i < maxWearablesLoop; i++) - { - int idx = cachedtex.WearableData[i].TextureIndex; + int idx = cachedtex.WearableData[i].TextureIndex; - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - cachedresp.WearableData[i].HostName = new byte[0]; - if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId) - { - cachedresp.WearableData[i].TextureID = cacheItems[idx].TextureID; - cacheHits++; - } - else - { - cachedresp.WearableData[i].TextureID = UUID.Zero; - } + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].HostName = new byte[0]; + if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId) + { + cachedresp.WearableData[i].TextureID = cacheItems[idx].TextureID; + cacheHits++; } - } - else - { - for (int i = 0; i < maxWearablesLoop; i++) + else { - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].TextureID = UUID.Zero; - //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - cachedresp.WearableData[i].HostName = new byte[0]; } } } - else // no cache + else { for (int i = 0; i < maxWearablesLoop; i++) { cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].TextureID = UUID.Zero; + //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); cachedresp.WearableData[i].HostName = new byte[0]; } } diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index edf62db..2e5c58a 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -493,18 +493,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory wearableCache = WearableCacheItem.GetDefaultCacheItem(); - // debug - for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) - { - int j = AvatarAppearance.BAKE_INDICES[iter]; - Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[iter]; - if(face != null) - m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - " + face.TextureID); - else - m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture"); - } - - int hits = 0; + int hits = 0; // Cache wearable data for teleport. // Only makes sense if there's a bake module and a cache module if (bakedModule != null && cache != null) @@ -546,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory int idx = AvatarAppearance.BAKE_INDICES[i]; Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; - // No face, so lets check our baked service cache, teleport or login. + // No face, so lets check our cache if (face == null || face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) { sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx); @@ -560,8 +549,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; face = sp.Appearance.Texture.FaceTextures[idx]; - wearableCache[idx].CacheId = UUID.Zero; - wearableCache[idx].TextureAsset = null; +// lets try not invalidating the cache entry +// wearableCache[idx].CacheId = UUID.Zero; +// wearableCache[idx].TextureAsset = null; continue; } } @@ -624,14 +614,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (face == null) continue; -// m_log.DebugFormat( -// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", -// face.TextureID, idx, client.Name, client.AgentId); - - // if the texture is one of the "defaults" then skip it - // this should probably be more intelligent (skirt texture doesnt matter - // if the avatar isnt wearing a skirt) but if any of the main baked - // textures is default then the rest should be as well if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) continue; -- cgit v1.1