Merge branch 'master' into careminster-presence-refactor
						commit
						42b96a8be0
					
				| 
						 | 
				
			
			@ -66,8 +66,8 @@ namespace OpenSim.Client.MXP.ClientStack
 | 
			
		|||
        private readonly IScene m_scene;
 | 
			
		||||
        private readonly string m_firstName;
 | 
			
		||||
        private readonly string m_lastName;
 | 
			
		||||
        private int m_objectsToSynchronize = 0;
 | 
			
		||||
        private int m_objectsSynchronized = -1;
 | 
			
		||||
//        private int m_objectsToSynchronize = 0;
 | 
			
		||||
//        private int m_objectsSynchronized = -1;
 | 
			
		||||
 | 
			
		||||
        private Vector3 m_startPosition=new Vector3(128f, 128f, 128f);
 | 
			
		||||
        #endregion
 | 
			
		||||
| 
						 | 
				
			
			@ -462,8 +462,8 @@ namespace OpenSim.Client.MXP.ClientStack
 | 
			
		|||
 | 
			
		||||
        public void MXPSendSynchronizationBegin(int objectCount)
 | 
			
		||||
        {
 | 
			
		||||
            m_objectsToSynchronize = objectCount;
 | 
			
		||||
            m_objectsSynchronized = 0;
 | 
			
		||||
//            m_objectsToSynchronize = objectCount;
 | 
			
		||||
//            m_objectsSynchronized = 0;
 | 
			
		||||
            SynchronizationBeginEventMessage synchronizationBeginEventMessage = new SynchronizationBeginEventMessage();
 | 
			
		||||
            synchronizationBeginEventMessage.ObjectCount = (uint)objectCount;
 | 
			
		||||
            Session.Send(synchronizationBeginEventMessage);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,8 @@ namespace OpenSim.Data.MySQL
 | 
			
		|||
{
 | 
			
		||||
    public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new()
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        
 | 
			
		||||
        protected Dictionary<string, FieldInfo> m_Fields =
 | 
			
		||||
                new Dictionary<string, FieldInfo>();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +219,6 @@ namespace OpenSim.Data.MySQL
 | 
			
		|||
        {
 | 
			
		||||
            using (MySqlCommand cmd = new MySqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                string query = "";
 | 
			
		||||
                List<String> names = new List<String>();
 | 
			
		||||
                List<String> values = new List<String>();
 | 
			
		||||
| 
						 | 
				
			
			@ -226,6 +227,16 @@ namespace OpenSim.Data.MySQL
 | 
			
		|||
                {
 | 
			
		||||
                    names.Add(fi.Name);
 | 
			
		||||
                    values.Add("?" + fi.Name);
 | 
			
		||||
                    
 | 
			
		||||
                    // Temporarily return more information about what field is unexpectedly null for
 | 
			
		||||
                    // http://opensimulator.org/mantis/view.php?id=5403.  This might be due to a bug in the 
 | 
			
		||||
                    // InventoryTransferModule or we may be required to substitute a DBNull here.
 | 
			
		||||
                    if (fi.GetValue(row) == null)
 | 
			
		||||
                        throw new NullReferenceException(
 | 
			
		||||
                            string.Format(
 | 
			
		||||
                                "[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null", 
 | 
			
		||||
                                fi.Name, row));
 | 
			
		||||
                    
 | 
			
		||||
                    cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -268,4 +279,4 @@ namespace OpenSim.Data.MySQL
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -341,10 +341,15 @@ namespace OpenSim
 | 
			
		|||
 | 
			
		||||
            m_console.Commands.AddCommand("region", false, "config get",
 | 
			
		||||
                                          "config get [<section>] [<key>]",
 | 
			
		||||
                                          "Show a config option", 
 | 
			
		||||
                                          "Synonym for config show",
 | 
			
		||||
                                          HandleConfig);
 | 
			
		||||
            
 | 
			
		||||
            m_console.Commands.AddCommand("region", false, "config show",
 | 
			
		||||
                                          "config show [<section>] [<key>]",
 | 
			
		||||
                                          "Show config information", 
 | 
			
		||||
                                          "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
 | 
			
		||||
                                          + "If a section is given but not a field, then all fields in that section are printed.",
 | 
			
		||||
                                          HandleConfig);
 | 
			
		||||
                                          HandleConfig);            
 | 
			
		||||
 | 
			
		||||
            m_console.Commands.AddCommand("region", false, "config save",
 | 
			
		||||
                                          "config save <path>",
 | 
			
		||||
| 
						 | 
				
			
			@ -593,7 +598,9 @@ namespace OpenSim
 | 
			
		|||
 | 
			
		||||
            if (cmdparams.Length > 0)
 | 
			
		||||
            {
 | 
			
		||||
                switch (cmdparams[0].ToLower())
 | 
			
		||||
                string firstParam = cmdparams[0].ToLower();
 | 
			
		||||
                
 | 
			
		||||
                switch (firstParam)
 | 
			
		||||
                {
 | 
			
		||||
                    case "set":
 | 
			
		||||
                        if (cmdparams.Length < 4)
 | 
			
		||||
| 
						 | 
				
			
			@ -618,6 +625,7 @@ namespace OpenSim
 | 
			
		|||
                        break;
 | 
			
		||||
 | 
			
		||||
                    case "get":
 | 
			
		||||
                    case "show":
 | 
			
		||||
                        if (cmdparams.Length == 1)
 | 
			
		||||
                        {
 | 
			
		||||
                            foreach (IConfig config in m_config.Source.Configs)
 | 
			
		||||
| 
						 | 
				
			
			@ -654,8 +662,8 @@ namespace OpenSim
 | 
			
		|||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            Notice("Syntax: config get [<section>] [<key>]");
 | 
			
		||||
                            Notice("Example: config get ScriptEngine.DotNetEngine NumberOfScriptThreads");
 | 
			
		||||
                            Notice("Syntax: config {0} [<section>] [<key>]", firstParam);
 | 
			
		||||
                            Notice("Example: config {0} ScriptEngine.DotNetEngine NumberOfScriptThreads", firstParam);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,8 @@ using Timer = System.Timers.Timer;
 | 
			
		|||
using AssetLandmark = OpenSim.Framework.AssetLandmark;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		||||
{
 | 
			
		||||
    public delegate bool PacketMethod(IClientAPI simClient, Packet packet);
 | 
			
		||||
| 
						 | 
				
			
			@ -299,6 +301,77 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
        /// <summary>Used to adjust Sun Orbit values so Linden based viewers properly position sun</summary>
 | 
			
		||||
        private const float m_sunPainDaHalfOrbitalCutoff = 4.712388980384689858f;
 | 
			
		||||
 | 
			
		||||
                        // First log file or time has expired, start writing to a new log file
 | 
			
		||||
//<MIC>
 | 
			
		||||
// -----------------------------------------------------------------
 | 
			
		||||
// -----------------------------------------------------------------
 | 
			
		||||
// THIS IS DEBUGGING CODE & SHOULD BE REMOVED
 | 
			
		||||
// -----------------------------------------------------------------
 | 
			
		||||
// -----------------------------------------------------------------
 | 
			
		||||
        public class QueueLogger
 | 
			
		||||
        {
 | 
			
		||||
            public Int32 start = 0;
 | 
			
		||||
            public StreamWriter Log = null;
 | 
			
		||||
            private Dictionary<UUID,int> m_idMap = new Dictionary<UUID,int>();
 | 
			
		||||
 | 
			
		||||
            public QueueLogger()
 | 
			
		||||
            {
 | 
			
		||||
                DateTime now = DateTime.Now;
 | 
			
		||||
                String fname = String.Format("queue-{0}.log", now.ToString("yyyyMMddHHmmss"));
 | 
			
		||||
                Log = new StreamWriter(fname);
 | 
			
		||||
 | 
			
		||||
                start = Util.EnvironmentTickCount();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public int LookupID(UUID uuid)
 | 
			
		||||
            {
 | 
			
		||||
                int localid;
 | 
			
		||||
                if (! m_idMap.TryGetValue(uuid,out localid))
 | 
			
		||||
                {
 | 
			
		||||
                    localid = m_idMap.Count + 1;
 | 
			
		||||
                    m_idMap[uuid] = localid;
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                return localid;                
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static QueueLogger QueueLog = null;
 | 
			
		||||
 | 
			
		||||
        // -----------------------------------------------------------------
 | 
			
		||||
        public void LogAvatarUpdateEvent(UUID client, UUID avatar, Int32 timeinqueue)
 | 
			
		||||
        {
 | 
			
		||||
            if (QueueLog == null)
 | 
			
		||||
                QueueLog = new QueueLogger();
 | 
			
		||||
 | 
			
		||||
            Int32 ticks = Util.EnvironmentTickCountSubtract(QueueLog.start);
 | 
			
		||||
            lock(QueueLog)
 | 
			
		||||
            {
 | 
			
		||||
                int cid = QueueLog.LookupID(client);
 | 
			
		||||
                int aid = QueueLog.LookupID(avatar);
 | 
			
		||||
                QueueLog.Log.WriteLine("{0},AU,AV{1:D4},AV{2:D4},{3}",ticks,cid,aid,timeinqueue);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // -----------------------------------------------------------------
 | 
			
		||||
        public void LogQueueProcessEvent(UUID client, PriorityQueue queue, uint maxup)
 | 
			
		||||
        {
 | 
			
		||||
            if (QueueLog == null)
 | 
			
		||||
                QueueLog = new QueueLogger();
 | 
			
		||||
 | 
			
		||||
            Int32 ticks = Util.EnvironmentTickCountSubtract(QueueLog.start);
 | 
			
		||||
            lock(QueueLog)
 | 
			
		||||
            {
 | 
			
		||||
                int cid = QueueLog.LookupID(client);
 | 
			
		||||
                QueueLog.Log.WriteLine("{0},PQ,AV{1:D4},{2},{3}",ticks,cid,maxup,queue.ToString());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
// -----------------------------------------------------------------
 | 
			
		||||
// -----------------------------------------------------------------
 | 
			
		||||
// -----------------------------------------------------------------
 | 
			
		||||
// -----------------------------------------------------------------
 | 
			
		||||
//</MIC>
 | 
			
		||||
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3575,6 +3648,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
 | 
			
		||||
        #region Primitive Packet/Data Sending Methods
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Generate one of the object update packets based on PrimUpdateFlags
 | 
			
		||||
        /// and broadcast the packet to clients
 | 
			
		||||
| 
						 | 
				
			
			@ -3590,12 +3664,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
                        return; // Don't send updates for other people's HUDs
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            double priority = m_prioritizer.GetUpdatePriority(this, entity);
 | 
			
		||||
            uint priority = m_prioritizer.GetUpdatePriority(this, entity);
 | 
			
		||||
 | 
			
		||||
            lock (m_entityUpdates.SyncRoot)
 | 
			
		||||
                m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation), entity.LocalId);
 | 
			
		||||
                m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Int32 m_LastQueueFill = 0;
 | 
			
		||||
        private uint m_maxUpdates = 0;
 | 
			
		||||
 | 
			
		||||
        private void ProcessEntityUpdates(int maxUpdates)
 | 
			
		||||
        {
 | 
			
		||||
            OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
 | 
			
		||||
| 
						 | 
				
			
			@ -3603,195 +3680,232 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
            OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
 | 
			
		||||
            OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
 | 
			
		||||
 | 
			
		||||
            if (maxUpdates <= 0) maxUpdates = Int32.MaxValue;
 | 
			
		||||
            int updatesThisCall = 0;
 | 
			
		||||
 | 
			
		||||
            float avgTimeDilation = 0;
 | 
			
		||||
 | 
			
		||||
            EntityUpdate update;
 | 
			
		||||
            while (updatesThisCall < maxUpdates)
 | 
			
		||||
            if (maxUpdates <= 0)
 | 
			
		||||
            {
 | 
			
		||||
                lock (m_entityUpdates.SyncRoot)
 | 
			
		||||
                    if (!m_entityUpdates.TryDequeue(out update))
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                avgTimeDilation += update.TimeDilation;
 | 
			
		||||
                avgTimeDilation *= 0.5f;
 | 
			
		||||
 | 
			
		||||
                if (update.Entity is SceneObjectPart)
 | 
			
		||||
                m_maxUpdates = Int32.MaxValue;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (m_maxUpdates == 0 || m_LastQueueFill == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    SceneObjectPart part = (SceneObjectPart)update.Entity;
 | 
			
		||||
 | 
			
		||||
                    // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
 | 
			
		||||
                    // will never receive an update after a prim kill.  Even then, keeping the kill record may be a good
 | 
			
		||||
                    // safety measure.
 | 
			
		||||
                    //
 | 
			
		||||
                    // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
 | 
			
		||||
                    // after a kill, it will keep displaying the deleted object until relog.  OpenSim currently performs
 | 
			
		||||
                    // updates and kills on different threads with different scheduling strategies, hence this protection.
 | 
			
		||||
                    // 
 | 
			
		||||
                    // This doesn't appear to apply to child prims - a client will happily ignore these updates
 | 
			
		||||
                    // after the root prim has been deleted.
 | 
			
		||||
                    lock (m_killRecord)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (m_killRecord.Contains(part.LocalId))
 | 
			
		||||
                            continue;
 | 
			
		||||
                        if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
 | 
			
		||||
                            continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (part.ParentGroup.IsDeleted)
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    if (part.ParentGroup.IsAttachment)
 | 
			
		||||
                    {   // Someone else's HUD, why are we getting these?
 | 
			
		||||
                        if (part.ParentGroup.OwnerID != AgentId &&
 | 
			
		||||
                            part.ParentGroup.RootPart.Shape.State >= 30)
 | 
			
		||||
                            continue;
 | 
			
		||||
                        ScenePresence sp;
 | 
			
		||||
                        // Owner is not in the sim, don't update it to
 | 
			
		||||
                        // anyone
 | 
			
		||||
                        if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
 | 
			
		||||
                            continue;
 | 
			
		||||
 | 
			
		||||
                        List<SceneObjectGroup> atts = sp.Attachments;
 | 
			
		||||
                        bool found = false;
 | 
			
		||||
                        foreach (SceneObjectGroup att in atts)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (att == part.ParentGroup)
 | 
			
		||||
                            {
 | 
			
		||||
                                found = true;
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // It's an attachment of a valid avatar, but
 | 
			
		||||
                        // doesn't seem to be attached, skip
 | 
			
		||||
                        if (!found)
 | 
			
		||||
                            continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (part.ParentGroup.IsAttachment && m_disableFacelights)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
 | 
			
		||||
                            part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
 | 
			
		||||
                        {
 | 
			
		||||
                            part.Shape.LightEntry = false;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ++updatesThisCall;
 | 
			
		||||
 | 
			
		||||
                #region UpdateFlags to packet type conversion
 | 
			
		||||
 | 
			
		||||
                PrimUpdateFlags updateFlags = update.Flags;
 | 
			
		||||
 | 
			
		||||
                bool canUseCompressed = true;
 | 
			
		||||
                bool canUseImproved = true;
 | 
			
		||||
 | 
			
		||||
                // Compressed object updates only make sense for LL primitives
 | 
			
		||||
                if (!(update.Entity is SceneObjectPart))
 | 
			
		||||
                {
 | 
			
		||||
                    canUseCompressed = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
 | 
			
		||||
                {
 | 
			
		||||
                    canUseCompressed = false;
 | 
			
		||||
                    canUseImproved = false;
 | 
			
		||||
                    m_maxUpdates = (uint)maxUpdates;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.Joint))
 | 
			
		||||
                    if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200)
 | 
			
		||||
                        m_maxUpdates += 5;
 | 
			
		||||
                    else
 | 
			
		||||
                        m_maxUpdates = m_maxUpdates >> 1;
 | 
			
		||||
                }
 | 
			
		||||
                m_maxUpdates = Util.Clamp<uint>(m_maxUpdates,10,500);
 | 
			
		||||
            }
 | 
			
		||||
            m_LastQueueFill = Util.EnvironmentTickCount();
 | 
			
		||||
            
 | 
			
		||||
            int updatesThisCall = 0;
 | 
			
		||||
 | 
			
		||||
//<MIC>
 | 
			
		||||
// DEBUGGING CODE... REMOVE
 | 
			
		||||
//            LogQueueProcessEvent(this.m_agentId,m_entityUpdates,m_maxUpdates);
 | 
			
		||||
//</MIC>            
 | 
			
		||||
            // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
 | 
			
		||||
            // condition where a kill can be processed before an out-of-date update for the same object.                        
 | 
			
		||||
            float avgTimeDilation = 1.0f;
 | 
			
		||||
 | 
			
		||||
            lock (m_killRecord)
 | 
			
		||||
            {
 | 
			
		||||
                EntityUpdate update;
 | 
			
		||||
                Int32 timeinqueue; // this is just debugging code & can be dropped later
 | 
			
		||||
                
 | 
			
		||||
                while (updatesThisCall < m_maxUpdates)
 | 
			
		||||
                {
 | 
			
		||||
                    lock (m_entityUpdates.SyncRoot)
 | 
			
		||||
                        if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
 | 
			
		||||
                            break;
 | 
			
		||||
                    avgTimeDilation += update.TimeDilation;
 | 
			
		||||
                    avgTimeDilation *= 0.5f;
 | 
			
		||||
 | 
			
		||||
                    if (update.Entity is SceneObjectPart)
 | 
			
		||||
                    {
 | 
			
		||||
                        SceneObjectPart part = (SceneObjectPart)update.Entity;
 | 
			
		||||
 | 
			
		||||
                        // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
 | 
			
		||||
                        // will never receive an update after a prim kill.  Even then, keeping the kill record may be a good
 | 
			
		||||
                        // safety measure.
 | 
			
		||||
                        //
 | 
			
		||||
                        // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
 | 
			
		||||
                        // after a kill, it will keep displaying the deleted object until relog.  OpenSim currently performs
 | 
			
		||||
                        // updates and kills on different threads with different scheduling strategies, hence this protection.
 | 
			
		||||
                        // 
 | 
			
		||||
                        // This doesn't appear to apply to child prims - a client will happily ignore these updates
 | 
			
		||||
                        // after the root prim has been deleted.
 | 
			
		||||
                        lock (m_killRecord)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (m_killRecord.Contains(part.LocalId))
 | 
			
		||||
                                continue;
 | 
			
		||||
                            if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
 | 
			
		||||
                                continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (part.ParentGroup.IsDeleted)
 | 
			
		||||
                            continue;
 | 
			
		||||
 | 
			
		||||
                        if (part.ParentGroup.IsAttachment)
 | 
			
		||||
                        {   // Someone else's HUD, why are we getting these?
 | 
			
		||||
                            if (part.ParentGroup.OwnerID != AgentId &&
 | 
			
		||||
                                part.ParentGroup.RootPart.Shape.State >= 30)
 | 
			
		||||
                                continue;
 | 
			
		||||
                            ScenePresence sp;
 | 
			
		||||
                            // Owner is not in the sim, don't update it to
 | 
			
		||||
                            // anyone
 | 
			
		||||
                            if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
 | 
			
		||||
                                continue;
 | 
			
		||||
 | 
			
		||||
                            List<SceneObjectGroup> atts = sp.Attachments;
 | 
			
		||||
                            bool found = false;
 | 
			
		||||
                            foreach (SceneObjectGroup att in atts)
 | 
			
		||||
                            {
 | 
			
		||||
                                if (att == part.ParentGroup)
 | 
			
		||||
                                {
 | 
			
		||||
                                    found = true;
 | 
			
		||||
                                    break;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // It's an attachment of a valid avatar, but
 | 
			
		||||
                            // doesn't seem to be attached, skip
 | 
			
		||||
                            if (!found)
 | 
			
		||||
                                continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (part.ParentGroup.IsAttachment && m_disableFacelights)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
 | 
			
		||||
                                part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
 | 
			
		||||
                            {
 | 
			
		||||
                                part.Shape.LightEntry = false;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    ++updatesThisCall;
 | 
			
		||||
 | 
			
		||||
                    #region UpdateFlags to packet type conversion
 | 
			
		||||
 | 
			
		||||
                    PrimUpdateFlags updateFlags = update.Flags;
 | 
			
		||||
 | 
			
		||||
                    bool canUseCompressed = true;
 | 
			
		||||
                    bool canUseImproved = true;
 | 
			
		||||
 | 
			
		||||
                    // Compressed object updates only make sense for LL primitives
 | 
			
		||||
                    if (!(update.Entity is SceneObjectPart))
 | 
			
		||||
                    {
 | 
			
		||||
                        canUseCompressed = false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.Text) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.Material) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
 | 
			
		||||
                        updateFlags.HasFlag(PrimUpdateFlags.Joint))
 | 
			
		||||
                    if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
 | 
			
		||||
                    {
 | 
			
		||||
                        canUseCompressed = false;
 | 
			
		||||
                        canUseImproved = false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #endregion UpdateFlags to packet type conversion
 | 
			
		||||
 | 
			
		||||
                #region Block Construction
 | 
			
		||||
 | 
			
		||||
                // TODO: Remove this once we can build compressed updates
 | 
			
		||||
                canUseCompressed = false;
 | 
			
		||||
 | 
			
		||||
                if (!canUseImproved && !canUseCompressed)
 | 
			
		||||
                {
 | 
			
		||||
                    if (update.Entity is ScenePresence)
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
 | 
			
		||||
                        if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.Joint))
 | 
			
		||||
                        {
 | 
			
		||||
                            if (update.Entity is ScenePresence)
 | 
			
		||||
                            {
 | 
			
		||||
                                objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.Text) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.Material) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
 | 
			
		||||
                            updateFlags.HasFlag(PrimUpdateFlags.Joint))
 | 
			
		||||
                        {
 | 
			
		||||
                            canUseImproved = false;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    #endregion UpdateFlags to packet type conversion
 | 
			
		||||
 | 
			
		||||
                    #region Block Construction
 | 
			
		||||
 | 
			
		||||
                    // TODO: Remove this once we can build compressed updates
 | 
			
		||||
                    canUseCompressed = false;
 | 
			
		||||
 | 
			
		||||
                    if (!canUseImproved && !canUseCompressed)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (update.Entity is ScenePresence)
 | 
			
		||||
                        {
 | 
			
		||||
                            objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
    //                            if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment)
 | 
			
		||||
    //                            {
 | 
			
		||||
    //                                SceneObjectPart sop = (SceneObjectPart)update.Entity;
 | 
			
		||||
    //                                string text = sop.Text;
 | 
			
		||||
    //                                if (text.IndexOf("\n") >= 0)
 | 
			
		||||
    //                                    text = text.Remove(text.IndexOf("\n"));
 | 
			
		||||
    //
 | 
			
		||||
    //                                if (m_attachmentsSent.Contains(sop.ParentID))
 | 
			
		||||
    //                                {
 | 
			
		||||
    ////                                    m_log.DebugFormat(
 | 
			
		||||
    ////                                        "[CLIENT]: Sending full info about attached prim {0} text {1}",
 | 
			
		||||
    ////                                        sop.LocalId, text);
 | 
			
		||||
    //
 | 
			
		||||
    //                                    objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock(sop, this.m_agentId));
 | 
			
		||||
    //
 | 
			
		||||
    //                                    m_attachmentsSent.Add(sop.LocalId);
 | 
			
		||||
    //                                }
 | 
			
		||||
    //                                else
 | 
			
		||||
    //                                {
 | 
			
		||||
    //                                    m_log.DebugFormat(
 | 
			
		||||
    //                                        "[CLIENT]: Requeueing full update of prim {0} text {1} since we haven't sent its parent {2} yet",
 | 
			
		||||
    //                                        sop.LocalId, text, sop.ParentID);
 | 
			
		||||
    //
 | 
			
		||||
    //                                    m_entityUpdates.Enqueue(double.MaxValue, update, sop.LocalId);
 | 
			
		||||
    //                                }
 | 
			
		||||
    //                            }
 | 
			
		||||
    //                            else
 | 
			
		||||
    //                            {
 | 
			
		||||
                                objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
 | 
			
		||||
    //                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (!canUseImproved)
 | 
			
		||||
                    {
 | 
			
		||||
                        compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
//                            if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment)
 | 
			
		||||
//                            {
 | 
			
		||||
//                                SceneObjectPart sop = (SceneObjectPart)update.Entity;
 | 
			
		||||
//                                string text = sop.Text;
 | 
			
		||||
//                                if (text.IndexOf("\n") >= 0)
 | 
			
		||||
//                                    text = text.Remove(text.IndexOf("\n"));
 | 
			
		||||
//
 | 
			
		||||
//                                if (m_attachmentsSent.Contains(sop.ParentID))
 | 
			
		||||
//                                {
 | 
			
		||||
////                                    m_log.DebugFormat(
 | 
			
		||||
////                                        "[CLIENT]: Sending full info about attached prim {0} text {1}",
 | 
			
		||||
////                                        sop.LocalId, text);
 | 
			
		||||
//
 | 
			
		||||
//                                    objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock(sop, this.m_agentId));
 | 
			
		||||
//
 | 
			
		||||
//                                    m_attachmentsSent.Add(sop.LocalId);
 | 
			
		||||
//                                }
 | 
			
		||||
//                                else
 | 
			
		||||
//                                {
 | 
			
		||||
//                                    m_log.DebugFormat(
 | 
			
		||||
//                                        "[CLIENT]: Requeueing full update of prim {0} text {1} since we haven't sent its parent {2} yet",
 | 
			
		||||
//                                        sop.LocalId, text, sop.ParentID);
 | 
			
		||||
//
 | 
			
		||||
//                                    m_entityUpdates.Enqueue(double.MaxValue, update, sop.LocalId);
 | 
			
		||||
//                                }
 | 
			
		||||
//                            }
 | 
			
		||||
//                            else
 | 
			
		||||
//                            {
 | 
			
		||||
                            objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
 | 
			
		||||
//                            }
 | 
			
		||||
                        if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
 | 
			
		||||
                            // Self updates go into a special list
 | 
			
		||||
                            terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
 | 
			
		||||
                        else
 | 
			
		||||
                            // Everything else goes here
 | 
			
		||||
                            terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (!canUseImproved)
 | 
			
		||||
                {
 | 
			
		||||
                    compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
 | 
			
		||||
                        // Self updates go into a special list
 | 
			
		||||
                        terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
 | 
			
		||||
                    else
 | 
			
		||||
                        // Everything else goes here
 | 
			
		||||
                        terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #endregion Block Construction
 | 
			
		||||
                    #endregion Block Construction
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #region Packet Sending
 | 
			
		||||
| 
						 | 
				
			
			@ -3864,26 +3978,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
 | 
			
		||||
        public void ReprioritizeUpdates()
 | 
			
		||||
        {
 | 
			
		||||
            //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName);
 | 
			
		||||
 | 
			
		||||
            lock (m_entityUpdates.SyncRoot)
 | 
			
		||||
                m_entityUpdates.Reprioritize(UpdatePriorityHandler);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool UpdatePriorityHandler(ref double priority, uint localID)
 | 
			
		||||
        private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity)
 | 
			
		||||
        {
 | 
			
		||||
            EntityBase entity;
 | 
			
		||||
            if (m_scene.Entities.TryGetValue(localID, out entity))
 | 
			
		||||
            if (entity != null)
 | 
			
		||||
            {
 | 
			
		||||
                priority = m_prioritizer.GetUpdatePriority(this, entity);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return priority != double.NaN;
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void FlushPrimUpdates()
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
 | 
			
		||||
            m_log.WarnFormat("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
 | 
			
		||||
 | 
			
		||||
            while (m_entityUpdates.Count > 0)
 | 
			
		||||
                ProcessEntityUpdates(-1);
 | 
			
		||||
| 
						 | 
				
			
			@ -11831,171 +11943,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
            OutPacket(pack, ThrottleOutPacketType.Task);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #region PriorityQueue
 | 
			
		||||
        public class PriorityQueue
 | 
			
		||||
        {
 | 
			
		||||
            internal delegate bool UpdatePriorityHandler(ref double priority, uint local_id);
 | 
			
		||||
 | 
			
		||||
            private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[1];
 | 
			
		||||
            private Dictionary<uint, LookupItem> m_lookupTable;
 | 
			
		||||
            private Comparison<double> m_comparison;
 | 
			
		||||
            private object m_syncRoot = new object();
 | 
			
		||||
 | 
			
		||||
            internal PriorityQueue() :
 | 
			
		||||
                this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<double>.Default) { }
 | 
			
		||||
            internal PriorityQueue(int capacity) :
 | 
			
		||||
                this(capacity, Comparer<double>.Default) { }
 | 
			
		||||
            internal PriorityQueue(IComparer<double> comparer) :
 | 
			
		||||
                this(new Comparison<double>(comparer.Compare)) { }
 | 
			
		||||
            internal PriorityQueue(Comparison<double> comparison) :
 | 
			
		||||
                this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, comparison) { }
 | 
			
		||||
            internal PriorityQueue(int capacity, IComparer<double> comparer) :
 | 
			
		||||
                this(capacity, new Comparison<double>(comparer.Compare)) { }
 | 
			
		||||
            internal PriorityQueue(int capacity, Comparison<double> comparison)
 | 
			
		||||
            {
 | 
			
		||||
                m_lookupTable = new Dictionary<uint, LookupItem>(capacity);
 | 
			
		||||
 | 
			
		||||
                for (int i = 0; i < m_heaps.Length; ++i)
 | 
			
		||||
                    m_heaps[i] = new MinHeap<MinHeapItem>(capacity);
 | 
			
		||||
                this.m_comparison = comparison;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public object SyncRoot { get { return this.m_syncRoot; } }
 | 
			
		||||
            internal int Count
 | 
			
		||||
            {
 | 
			
		||||
                get
 | 
			
		||||
                {
 | 
			
		||||
                    int count = 0;
 | 
			
		||||
                    for (int i = 0; i < m_heaps.Length; ++i)
 | 
			
		||||
                        count = m_heaps[i].Count;
 | 
			
		||||
                    return count;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public bool Enqueue(double priority, EntityUpdate value, uint local_id)
 | 
			
		||||
            {
 | 
			
		||||
                LookupItem item;
 | 
			
		||||
 | 
			
		||||
                if (m_lookupTable.TryGetValue(local_id, out item))
 | 
			
		||||
                {
 | 
			
		||||
                    // Combine flags
 | 
			
		||||
                    value.Flags |= item.Heap[item.Handle].Value.Flags;
 | 
			
		||||
 | 
			
		||||
                    item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.m_comparison);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    item.Heap = m_heaps[0];
 | 
			
		||||
                    item.Heap.Add(new MinHeapItem(priority, value, local_id, this.m_comparison), ref item.Handle);
 | 
			
		||||
                    m_lookupTable.Add(local_id, item);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            internal EntityUpdate Peek()
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < m_heaps.Length; ++i)
 | 
			
		||||
                    if (m_heaps[i].Count > 0)
 | 
			
		||||
                        return m_heaps[i].Min().Value;
 | 
			
		||||
                throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            internal bool TryDequeue(out EntityUpdate value)
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < m_heaps.Length; ++i)
 | 
			
		||||
                {
 | 
			
		||||
                    if (m_heaps[i].Count > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        MinHeapItem item = m_heaps[i].RemoveMin();
 | 
			
		||||
                        m_lookupTable.Remove(item.LocalID);
 | 
			
		||||
                        value = item.Value;
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                value = default(EntityUpdate);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            internal void Reprioritize(UpdatePriorityHandler handler)
 | 
			
		||||
            {
 | 
			
		||||
                MinHeapItem item;
 | 
			
		||||
                double priority;
 | 
			
		||||
 | 
			
		||||
                foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values))
 | 
			
		||||
                {
 | 
			
		||||
                    if (lookup.Heap.TryGetValue(lookup.Handle, out item))
 | 
			
		||||
                    {
 | 
			
		||||
                        priority = item.Priority;
 | 
			
		||||
                        if (handler(ref priority, item.LocalID))
 | 
			
		||||
                        {
 | 
			
		||||
                            if (lookup.Heap.ContainsHandle(lookup.Handle))
 | 
			
		||||
                                lookup.Heap[lookup.Handle] =
 | 
			
		||||
                                    new MinHeapItem(priority, item.Value, item.LocalID, this.m_comparison);
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update");
 | 
			
		||||
                            lookup.Heap.Remove(lookup.Handle);
 | 
			
		||||
                            this.m_lookupTable.Remove(item.LocalID);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #region MinHeapItem
 | 
			
		||||
            private struct MinHeapItem : IComparable<MinHeapItem>
 | 
			
		||||
            {
 | 
			
		||||
                private double priority;
 | 
			
		||||
                private EntityUpdate value;
 | 
			
		||||
                private uint local_id;
 | 
			
		||||
                private Comparison<double> comparison;
 | 
			
		||||
 | 
			
		||||
                internal MinHeapItem(double priority, EntityUpdate value, uint local_id) :
 | 
			
		||||
                    this(priority, value, local_id, Comparer<double>.Default) { }
 | 
			
		||||
                internal MinHeapItem(double priority, EntityUpdate value, uint local_id, IComparer<double> comparer) :
 | 
			
		||||
                    this(priority, value, local_id, new Comparison<double>(comparer.Compare)) { }
 | 
			
		||||
                internal MinHeapItem(double priority, EntityUpdate value, uint local_id, Comparison<double> comparison)
 | 
			
		||||
                {
 | 
			
		||||
                    this.priority = priority;
 | 
			
		||||
                    this.value = value;
 | 
			
		||||
                    this.local_id = local_id;
 | 
			
		||||
                    this.comparison = comparison;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                internal double Priority { get { return this.priority; } }
 | 
			
		||||
                internal EntityUpdate Value { get { return this.value; } }
 | 
			
		||||
                internal uint LocalID { get { return this.local_id; } }
 | 
			
		||||
 | 
			
		||||
                public override string ToString()
 | 
			
		||||
                {
 | 
			
		||||
                    StringBuilder sb = new StringBuilder();
 | 
			
		||||
                    sb.Append("[");
 | 
			
		||||
                    sb.Append(this.priority.ToString());
 | 
			
		||||
                    sb.Append(",");
 | 
			
		||||
                    if (this.value != null)
 | 
			
		||||
                        sb.Append(this.value.ToString());
 | 
			
		||||
                    sb.Append("]");
 | 
			
		||||
                    return sb.ToString();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                public int CompareTo(MinHeapItem other)
 | 
			
		||||
                {
 | 
			
		||||
                    return this.comparison(this.priority, other.priority);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region LookupItem
 | 
			
		||||
            private struct LookupItem
 | 
			
		||||
            {
 | 
			
		||||
                internal MinHeap<MinHeapItem> Heap;
 | 
			
		||||
                internal IHandle Handle;
 | 
			
		||||
            }
 | 
			
		||||
            #endregion
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public struct PacketProcessor
 | 
			
		||||
        {
 | 
			
		||||
            public PacketMethod method;
 | 
			
		||||
| 
						 | 
				
			
			@ -12016,8 +11963,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        public static OSD BuildEvent(string eventName, OSD eventBody)
 | 
			
		||||
        {
 | 
			
		||||
            OSDMap osdEvent = new OSDMap(2);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
        /// <summary>Caches packed throttle information</summary>
 | 
			
		||||
        private byte[] m_packedThrottles;
 | 
			
		||||
 | 
			
		||||
        private int m_defaultRTO = 3000;
 | 
			
		||||
        private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
 | 
			
		||||
        private int m_maxRTO = 60000;
 | 
			
		||||
        public bool m_deliverPackets = true;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -567,7 +567,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		|||
            int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR));
 | 
			
		||||
 | 
			
		||||
            // Clamp the retransmission timeout to manageable values
 | 
			
		||||
            rto = Utils.Clamp(RTO, m_defaultRTO, m_maxRTO);
 | 
			
		||||
            rto = Utils.Clamp(rto, m_defaultRTO, m_maxRTO);
 | 
			
		||||
 | 
			
		||||
            RTO = rto;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,245 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Client;
 | 
			
		||||
using log4net;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.ClientStack.LindenUDP
 | 
			
		||||
{
 | 
			
		||||
    public class PriorityQueue
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        internal delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity);
 | 
			
		||||
 | 
			
		||||
        // Heap[0] for self updates
 | 
			
		||||
        // Heap[1..12] for entity updates
 | 
			
		||||
 | 
			
		||||
        internal const uint m_numberOfQueues = 12;
 | 
			
		||||
 | 
			
		||||
        private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[m_numberOfQueues];
 | 
			
		||||
        private Dictionary<uint, LookupItem> m_lookupTable;
 | 
			
		||||
        private uint m_nextQueue = 0;
 | 
			
		||||
        private UInt64 m_nextRequest = 0;
 | 
			
		||||
 | 
			
		||||
        private object m_syncRoot = new object();
 | 
			
		||||
        public object SyncRoot {
 | 
			
		||||
            get { return this.m_syncRoot; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { }
 | 
			
		||||
 | 
			
		||||
        internal PriorityQueue(int capacity)
 | 
			
		||||
        {
 | 
			
		||||
            m_lookupTable = new Dictionary<uint, LookupItem>(capacity);
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < m_heaps.Length; ++i)
 | 
			
		||||
                m_heaps[i] = new MinHeap<MinHeapItem>(capacity);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal int Count
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                int count = 0;
 | 
			
		||||
                for (int i = 0; i < m_heaps.Length; ++i)
 | 
			
		||||
                    count += m_heaps[i].Count;
 | 
			
		||||
                return count;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Enqueue(uint pqueue, EntityUpdate value)
 | 
			
		||||
        {
 | 
			
		||||
            LookupItem lookup;
 | 
			
		||||
 | 
			
		||||
            uint localid = value.Entity.LocalId;
 | 
			
		||||
            UInt64 entry = m_nextRequest++;
 | 
			
		||||
            if (m_lookupTable.TryGetValue(localid, out lookup))
 | 
			
		||||
            {
 | 
			
		||||
                entry = lookup.Heap[lookup.Handle].EntryOrder;
 | 
			
		||||
                value.Flags |=  lookup.Heap[lookup.Handle].Value.Flags;
 | 
			
		||||
                lookup.Heap.Remove(lookup.Handle);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            pqueue = Util.Clamp<uint>(pqueue, 0, m_numberOfQueues - 1);
 | 
			
		||||
            lookup.Heap = m_heaps[pqueue];
 | 
			
		||||
            lookup.Heap.Add(new MinHeapItem(pqueue, entry, value), ref lookup.Handle);
 | 
			
		||||
            m_lookupTable[localid] = lookup;
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal bool TryDequeue(out EntityUpdate value, out Int32 timeinqueue)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < m_numberOfQueues; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                // To get the fair queing, we cycle through each of the
 | 
			
		||||
                // queues when finding an element to dequeue, this code
 | 
			
		||||
                // assumes that the distribution of updates in the queues
 | 
			
		||||
                // is polynomial, probably quadractic (eg distance of PI * R^2)
 | 
			
		||||
                uint h = (uint)((m_nextQueue + i) % m_numberOfQueues);
 | 
			
		||||
                if (m_heaps[h].Count > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    m_nextQueue = (uint)((h + 1) % m_numberOfQueues);
 | 
			
		||||
 | 
			
		||||
                    MinHeapItem item = m_heaps[h].RemoveMin();
 | 
			
		||||
                    m_lookupTable.Remove(item.Value.Entity.LocalId);
 | 
			
		||||
                    timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
 | 
			
		||||
                    value = item.Value;
 | 
			
		||||
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            timeinqueue = 0;
 | 
			
		||||
            value = default(EntityUpdate);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal void Reprioritize(UpdatePriorityHandler handler)
 | 
			
		||||
        {
 | 
			
		||||
            MinHeapItem item;
 | 
			
		||||
            foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values))
 | 
			
		||||
            {
 | 
			
		||||
                if (lookup.Heap.TryGetValue(lookup.Handle, out item))
 | 
			
		||||
                {
 | 
			
		||||
                    uint pqueue = item.PriorityQueue;
 | 
			
		||||
                    uint localid = item.Value.Entity.LocalId;
 | 
			
		||||
 | 
			
		||||
                    if (handler(ref pqueue, item.Value.Entity))
 | 
			
		||||
                    {
 | 
			
		||||
                        // unless the priority queue has changed, there is no need to modify
 | 
			
		||||
                        // the entry
 | 
			
		||||
                        pqueue = Util.Clamp<uint>(pqueue, 0, m_numberOfQueues - 1);
 | 
			
		||||
                        if (pqueue != item.PriorityQueue)
 | 
			
		||||
                        {
 | 
			
		||||
                            lookup.Heap.Remove(lookup.Handle);
 | 
			
		||||
 | 
			
		||||
                            LookupItem litem = lookup;
 | 
			
		||||
                            litem.Heap = m_heaps[pqueue];
 | 
			
		||||
                            litem.Heap.Add(new MinHeapItem(pqueue, item), ref litem.Handle);
 | 
			
		||||
                            m_lookupTable[localid] = litem;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        // m_log.WarnFormat("[PQUEUE]: UpdatePriorityHandler returned false for {0}",item.Value.Entity.UUID);
 | 
			
		||||
                        lookup.Heap.Remove(lookup.Handle);
 | 
			
		||||
                        this.m_lookupTable.Remove(localid);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            string s = "";
 | 
			
		||||
            for (int i = 0; i < m_numberOfQueues; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (s != "") s += ",";
 | 
			
		||||
                s += m_heaps[i].Count.ToString();
 | 
			
		||||
            }
 | 
			
		||||
            return s;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#region MinHeapItem
 | 
			
		||||
        private struct MinHeapItem : IComparable<MinHeapItem>
 | 
			
		||||
        {
 | 
			
		||||
            private EntityUpdate value;
 | 
			
		||||
            internal EntityUpdate Value {
 | 
			
		||||
                get {
 | 
			
		||||
                    return this.value;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private uint pqueue;
 | 
			
		||||
            internal uint PriorityQueue {
 | 
			
		||||
                get {
 | 
			
		||||
                    return this.pqueue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private Int32 entrytime;
 | 
			
		||||
            internal Int32 EntryTime {
 | 
			
		||||
                get {
 | 
			
		||||
                    return this.entrytime;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private UInt64 entryorder;
 | 
			
		||||
            internal UInt64 EntryOrder
 | 
			
		||||
            {
 | 
			
		||||
                get {
 | 
			
		||||
                    return this.entryorder;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            internal MinHeapItem(uint pqueue, MinHeapItem other)
 | 
			
		||||
            {
 | 
			
		||||
                this.entrytime = other.entrytime;
 | 
			
		||||
                this.entryorder = other.entryorder;
 | 
			
		||||
                this.value = other.value;
 | 
			
		||||
                this.pqueue = pqueue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            internal MinHeapItem(uint pqueue, UInt64 entryorder, EntityUpdate value)
 | 
			
		||||
            {
 | 
			
		||||
                this.entrytime = Util.EnvironmentTickCount();
 | 
			
		||||
                this.entryorder = entryorder;
 | 
			
		||||
                this.value = value;
 | 
			
		||||
                this.pqueue = pqueue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override string ToString()
 | 
			
		||||
            {
 | 
			
		||||
                return String.Format("[{0},{1},{2}]",pqueue,entryorder,value.Entity.LocalId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public int CompareTo(MinHeapItem other)
 | 
			
		||||
            {
 | 
			
		||||
                // I'm assuming that the root part of an SOG is added to the update queue
 | 
			
		||||
                // before the component parts
 | 
			
		||||
                return Comparer<UInt64>.Default.Compare(this.EntryOrder, other.EntryOrder);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
#region LookupItem
 | 
			
		||||
        private struct LookupItem
 | 
			
		||||
        {
 | 
			
		||||
            internal MinHeap<MinHeapItem> Heap;
 | 
			
		||||
            internal IHandle Handle;
 | 
			
		||||
        }
 | 
			
		||||
#endregion
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -29,8 +29,10 @@ using System;
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Security;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Security.Cryptography.X509Certificates;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
| 
						 | 
				
			
			@ -100,8 +102,24 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 | 
			
		|||
 | 
			
		||||
        public HttpRequestModule()
 | 
			
		||||
        {
 | 
			
		||||
            ServicePointManager.ServerCertificateValidationCallback +=ValidateServerCertificate;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool ValidateServerCertificate(
 | 
			
		||||
            object sender,
 | 
			
		||||
            X509Certificate  certificate,
 | 
			
		||||
            X509Chain  chain,
 | 
			
		||||
            SslPolicyErrors  sslPolicyErrors)
 | 
			
		||||
        {
 | 
			
		||||
            HttpWebRequest Request = (HttpWebRequest)sender;
 | 
			
		||||
 | 
			
		||||
            if (Request.Headers.Get("NoVerifyCert") != null)
 | 
			
		||||
            {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return chain.Build(new X509Certificate2(certificate));
 | 
			
		||||
        }
 | 
			
		||||
        #region IHttpRequestModule Members
 | 
			
		||||
 | 
			
		||||
        public UUID MakeHttpRequest(string url, string parameters, string body)
 | 
			
		||||
| 
						 | 
				
			
			@ -141,8 +159,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 | 
			
		|||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case (int)HttpRequestConstants.HTTP_VERIFY_CERT:
 | 
			
		||||
 | 
			
		||||
                            // TODO implement me
 | 
			
		||||
                            htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0);
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -189,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 | 
			
		|||
        * Not sure how important ordering is is here - the next first
 | 
			
		||||
        * one completed in the list is returned, based soley on its list
 | 
			
		||||
        * position, not the order in which the request was started or
 | 
			
		||||
        * finsihed.  I thought about setting up a queue for this, but
 | 
			
		||||
        * finished.  I thought about setting up a queue for this, but
 | 
			
		||||
        * it will need some refactoring and this works 'enough' right now
 | 
			
		||||
        */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,8 +254,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 | 
			
		|||
 | 
			
		||||
            m_scene.RegisterModuleInterface<IHttpRequestModule>(this);
 | 
			
		||||
 | 
			
		||||
        m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
 | 
			
		||||
        m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
 | 
			
		||||
            m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
 | 
			
		||||
            m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
 | 
			
		||||
 | 
			
		||||
            m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -282,7 +299,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 | 
			
		|||
        public string HttpMethod  = "GET";
 | 
			
		||||
        public string HttpMIMEType = "text/plain;charset=utf-8";
 | 
			
		||||
        public int HttpTimeout;
 | 
			
		||||
        // public bool HttpVerifyCert = true; // not implemented
 | 
			
		||||
        public bool HttpVerifyCert = true;
 | 
			
		||||
        private Thread httpThread;
 | 
			
		||||
 | 
			
		||||
        // Request info
 | 
			
		||||
| 
						 | 
				
			
			@ -348,6 +365,17 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 | 
			
		|||
                Request.Method = HttpMethod;
 | 
			
		||||
                Request.ContentType = HttpMIMEType;
 | 
			
		||||
 | 
			
		||||
                if(!HttpVerifyCert)
 | 
			
		||||
                {
 | 
			
		||||
                    // We could hijack Connection Group Name to identify
 | 
			
		||||
                    // a desired security exception.  But at the moment we'll use a dummy header instead.
 | 
			
		||||
//                    Request.ConnectionGroupName = "NoVerify";
 | 
			
		||||
                    Request.Headers.Add("NoVerifyCert", "true");
 | 
			
		||||
                }
 | 
			
		||||
//                else
 | 
			
		||||
//                {
 | 
			
		||||
//                    Request.ConnectionGroupName="Verify";
 | 
			
		||||
//                }
 | 
			
		||||
                if (proxyurl != null && proxyurl.Length > 0) 
 | 
			
		||||
                {
 | 
			
		||||
                    if (proxyexcepts != null && proxyexcepts.Length > 0) 
 | 
			
		||||
| 
						 | 
				
			
			@ -450,4 +478,4 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -223,7 +223,8 @@ namespace OpenSim.Region.Framework
 | 
			
		|||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.ErrorFormat(
 | 
			
		||||
                        "[MODULES]: Could not load types for [{0}].  Exception {1}", pluginAssembly.FullName, e);
 | 
			
		||||
                        "[MODULES]: Could not load types for plugin DLL {0}.  Exception {1} {2}", 
 | 
			
		||||
                        pluginAssembly.FullName, e.Message, e.StackTrace);
 | 
			
		||||
                    
 | 
			
		||||
                    // justincc: Right now this is fatal to really get the user's attention
 | 
			
		||||
                    // TomMeta: WTF? No, how about we /don't/ throw a fatal exception when there's no need to?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,17 +58,8 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
 | 
			
		||||
    public class Prioritizer
 | 
			
		||||
    {
 | 
			
		||||
//        private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This is added to the priority of all child prims, to make sure that the root prim update is sent to the
 | 
			
		||||
        /// viewer before child prim updates.
 | 
			
		||||
        /// The adjustment is added to child prims and subtracted from root prims, so the gap ends up
 | 
			
		||||
        /// being double.  We do it both ways so that there is a still a priority delta even if the priority is already
 | 
			
		||||
        /// double.MinValue or double.MaxValue.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private double m_childPrimAdjustmentFactor = 0.05;
 | 
			
		||||
 | 
			
		||||
        private Scene m_scene;
 | 
			
		||||
 | 
			
		||||
        public Prioritizer(Scene scene)
 | 
			
		||||
| 
						 | 
				
			
			@ -76,17 +67,35 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
            m_scene = scene;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public double GetUpdatePriority(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns the priority queue into which the update should be placed. Updates within a
 | 
			
		||||
        /// queue will be processed in arrival order. There are currently 12 priority queues
 | 
			
		||||
        /// implemented in PriorityQueue class in LLClientView. Queue 0 is generally retained
 | 
			
		||||
        /// for avatar updates. The fair queuing discipline for processing the priority queues
 | 
			
		||||
        /// assumes that the number of entities in each priority queues increases exponentially.
 | 
			
		||||
        /// So for example... if queue 1 contains all updates within 10m of the avatar or camera
 | 
			
		||||
        /// then queue 2 at 20m is about 3X bigger in space & about 3X bigger in total number
 | 
			
		||||
        /// of updates.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public uint GetUpdatePriority(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        {
 | 
			
		||||
            double priority = 0;
 | 
			
		||||
 | 
			
		||||
            // If entity is null we have a serious problem
 | 
			
		||||
            if (entity == null)
 | 
			
		||||
                return 100000;
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[PRIORITIZER] attempt to prioritize null entity");
 | 
			
		||||
                throw new InvalidOperationException("Prioritization entity not defined");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // If this is an update for our own avatar give it the highest priority
 | 
			
		||||
            if (client.AgentId == entity.UUID)
 | 
			
		||||
                return 0;
 | 
			
		||||
 | 
			
		||||
            uint priority;
 | 
			
		||||
            
 | 
			
		||||
            switch (m_scene.UpdatePrioritizationScheme)
 | 
			
		||||
            {
 | 
			
		||||
                case UpdatePrioritizationSchemes.Time:
 | 
			
		||||
                    priority = GetPriorityByTime();
 | 
			
		||||
                    priority = GetPriorityByTime(client, entity);
 | 
			
		||||
                    break;
 | 
			
		||||
                case UpdatePrioritizationSchemes.Distance:
 | 
			
		||||
                    priority = GetPriorityByDistance(client, entity);
 | 
			
		||||
| 
						 | 
				
			
			@ -104,182 +113,119 @@ namespace OpenSim.Region.Framework.Scenes
 | 
			
		|||
                    throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            // Adjust priority so that root prims are sent to the viewer first.  This is especially important for 
 | 
			
		||||
            // attachments acting as huds, since current viewers fail to display hud child prims if their updates
 | 
			
		||||
            // arrive before the root one.
 | 
			
		||||
            if (entity is SceneObjectPart)
 | 
			
		||||
            {
 | 
			
		||||
                SceneObjectPart sop = ((SceneObjectPart)entity);
 | 
			
		||||
                
 | 
			
		||||
                if (sop.IsRoot)
 | 
			
		||||
                {
 | 
			
		||||
                    if (priority >= double.MinValue + m_childPrimAdjustmentFactor)
 | 
			
		||||
                        priority -= m_childPrimAdjustmentFactor;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (priority <= double.MaxValue - m_childPrimAdjustmentFactor)
 | 
			
		||||
                        priority += m_childPrimAdjustmentFactor;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return priority;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private double GetPriorityByTime()
 | 
			
		||||
 | 
			
		||||
        private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        {
 | 
			
		||||
            return DateTime.UtcNow.ToOADate();
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private double GetPriorityByDistance(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        private uint GetPriorityByDistance(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        {
 | 
			
		||||
            return ComputeDistancePriority(client,entity,false);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        {
 | 
			
		||||
            return ComputeDistancePriority(client,entity,true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        {
 | 
			
		||||
            if (entity == null) return 0;
 | 
			
		||||
 | 
			
		||||
            uint pqueue = ComputeDistancePriority(client,entity,true);
 | 
			
		||||
 | 
			
		||||
            ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
 | 
			
		||||
            if (presence != null)
 | 
			
		||||
            {
 | 
			
		||||
                // If this is an update for our own avatar give it the highest priority
 | 
			
		||||
                if (presence == entity)
 | 
			
		||||
                    return 0.0;
 | 
			
		||||
 | 
			
		||||
                // Use the camera position for local agents and avatar position for remote agents
 | 
			
		||||
                Vector3 presencePos = (presence.IsChildAgent) ?
 | 
			
		||||
                    presence.AbsolutePosition :
 | 
			
		||||
                    presence.CameraPosition;
 | 
			
		||||
 | 
			
		||||
                // Use group position for child prims
 | 
			
		||||
                Vector3 entityPos;
 | 
			
		||||
                if (entity is SceneObjectPart)
 | 
			
		||||
                {
 | 
			
		||||
                    // Can't use Scene.GetGroupByPrim() here, since the entity may have been delete from the scene
 | 
			
		||||
                    // before its scheduled update was triggered
 | 
			
		||||
                    //entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
 | 
			
		||||
                    entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    entityPos = entity.AbsolutePosition;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return Vector3.DistanceSquared(presencePos, entityPos);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return double.NaN;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private double GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        {
 | 
			
		||||
            if (entity == null) return double.NaN;
 | 
			
		||||
            ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
 | 
			
		||||
            if (presence != null)
 | 
			
		||||
            {
 | 
			
		||||
                // If this is an update for our own avatar give it the highest priority
 | 
			
		||||
                if (presence == entity)
 | 
			
		||||
                    return 0.0;
 | 
			
		||||
 | 
			
		||||
                // Use group position for child prims
 | 
			
		||||
                Vector3 entityPos = entity.AbsolutePosition;
 | 
			
		||||
                if (entity is SceneObjectPart)
 | 
			
		||||
                {
 | 
			
		||||
                    // Can't use Scene.GetGroupByPrim() here, since the entity may have been delete from the scene
 | 
			
		||||
                    // before its scheduled update was triggered
 | 
			
		||||
                    //entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
 | 
			
		||||
                    entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    entityPos = entity.AbsolutePosition;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!presence.IsChildAgent)
 | 
			
		||||
                {
 | 
			
		||||
                    // Root agent. Use distance from camera and a priority decrease for objects behind us
 | 
			
		||||
                    Vector3 camPosition = presence.CameraPosition;
 | 
			
		||||
                    Vector3 camAtAxis = presence.CameraAtAxis;
 | 
			
		||||
                    if (entity is SceneObjectPart)
 | 
			
		||||
                    {
 | 
			
		||||
                        // Non physical prims are lower priority than physical prims
 | 
			
		||||
                        PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
 | 
			
		||||
                        if (physActor == null || !physActor.IsPhysical)
 | 
			
		||||
                            pqueue++;
 | 
			
		||||
 | 
			
		||||
                    // Distance
 | 
			
		||||
                    double priority = Vector3.DistanceSquared(camPosition, entityPos);
 | 
			
		||||
 | 
			
		||||
                    // Plane equation
 | 
			
		||||
                    float d = -Vector3.Dot(camPosition, camAtAxis);
 | 
			
		||||
                    float p = Vector3.Dot(camAtAxis, entityPos) + d;
 | 
			
		||||
                    if (p < 0.0f) priority *= 2.0;
 | 
			
		||||
 | 
			
		||||
                    return priority;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // Child agent. Use the normal distance method
 | 
			
		||||
                    Vector3 presencePos = presence.AbsolutePosition;
 | 
			
		||||
 | 
			
		||||
                    return Vector3.DistanceSquared(presencePos, entityPos);
 | 
			
		||||
                        // Attachments are high priority, 
 | 
			
		||||
                        // MIC: shouldn't these already be in the highest priority queue already
 | 
			
		||||
                        // since their root position is same as the avatars?
 | 
			
		||||
                        if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
 | 
			
		||||
                            pqueue = 1;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return double.NaN;
 | 
			
		||||
            return pqueue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private double GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity)
 | 
			
		||||
        private uint ComputeDistancePriority(IClientAPI client, ISceneEntity entity, bool useFrontBack)
 | 
			
		||||
        {
 | 
			
		||||
            // If this is an update for our own avatar give it the highest priority
 | 
			
		||||
            if (client.AgentId == entity.UUID)
 | 
			
		||||
                return 0.0;
 | 
			
		||||
                return 0;
 | 
			
		||||
            if (entity == null)
 | 
			
		||||
                return double.NaN;
 | 
			
		||||
                return 0;
 | 
			
		||||
 | 
			
		||||
            // Get this agent's position
 | 
			
		||||
            ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
 | 
			
		||||
            if (presence != null)
 | 
			
		||||
            if (presence == null)
 | 
			
		||||
            {
 | 
			
		||||
                // Use group position for child prims
 | 
			
		||||
                Vector3 entityPos;
 | 
			
		||||
                if (entity is SceneObjectPart)
 | 
			
		||||
                    entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition;
 | 
			
		||||
                else
 | 
			
		||||
                    entityPos = entity.AbsolutePosition;
 | 
			
		||||
 | 
			
		||||
                if (!presence.IsChildAgent)
 | 
			
		||||
                {
 | 
			
		||||
                    if (entity is ScenePresence)
 | 
			
		||||
                        return 1.0;
 | 
			
		||||
 | 
			
		||||
                    // Root agent. Use distance from camera and a priority decrease for objects behind us
 | 
			
		||||
                    Vector3 camPosition = presence.CameraPosition;
 | 
			
		||||
                    Vector3 camAtAxis = presence.CameraAtAxis;
 | 
			
		||||
 | 
			
		||||
                    // Distance
 | 
			
		||||
                    double priority = Vector3.DistanceSquared(camPosition, entityPos);
 | 
			
		||||
 | 
			
		||||
                    // Plane equation
 | 
			
		||||
                    float d = -Vector3.Dot(camPosition, camAtAxis);
 | 
			
		||||
                    float p = Vector3.Dot(camAtAxis, entityPos) + d;
 | 
			
		||||
                    if (p < 0.0f) priority *= 2.0;
 | 
			
		||||
 | 
			
		||||
                    if (entity is SceneObjectPart)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
 | 
			
		||||
                        {
 | 
			
		||||
                            priority = 1.0;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
 | 
			
		||||
                            if (physActor == null || !physActor.IsPhysical)
 | 
			
		||||
                                priority += 100;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (((SceneObjectPart)entity).ParentGroup.RootPart != (SceneObjectPart)entity)
 | 
			
		||||
                            priority +=1;
 | 
			
		||||
                    }
 | 
			
		||||
                    return priority;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // Child agent. Use the normal distance method
 | 
			
		||||
                    Vector3 presencePos = presence.AbsolutePosition;
 | 
			
		||||
 | 
			
		||||
                    return Vector3.DistanceSquared(presencePos, entityPos);
 | 
			
		||||
                }
 | 
			
		||||
                m_log.WarnFormat("[PRIORITIZER] attempt to use agent {0} not in the scene",client.AgentId);
 | 
			
		||||
                // throw new InvalidOperationException("Prioritization agent not defined");
 | 
			
		||||
                return Int32.MaxValue;
 | 
			
		||||
            }
 | 
			
		||||
                
 | 
			
		||||
            // Use group position for child prims, since we are putting child prims in
 | 
			
		||||
            // the same queue with the root of the group, the root prim (which goes into
 | 
			
		||||
            // the queue first) should always be sent first, no need to adjust child prim
 | 
			
		||||
            // priorities
 | 
			
		||||
            Vector3 entityPos = entity.AbsolutePosition;
 | 
			
		||||
            if (entity is SceneObjectPart)
 | 
			
		||||
            {
 | 
			
		||||
                SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup;
 | 
			
		||||
                if (group != null)
 | 
			
		||||
                    entityPos = group.AbsolutePosition;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return double.NaN;
 | 
			
		||||
            // Use the camera position for local agents and avatar position for remote agents
 | 
			
		||||
            Vector3 presencePos = (presence.IsChildAgent) ?
 | 
			
		||||
                presence.AbsolutePosition :
 | 
			
		||||
                presence.CameraPosition;
 | 
			
		||||
 | 
			
		||||
            // Compute the distance... 
 | 
			
		||||
            double distance = Vector3.Distance(presencePos, entityPos);
 | 
			
		||||
 | 
			
		||||
            // And convert the distance to a priority queue, this computation gives queues
 | 
			
		||||
            // at 10, 20, 40, 80, 160, 320, 640, and 1280m
 | 
			
		||||
            uint pqueue = 1;
 | 
			
		||||
            for (int i = 0; i < 8; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (distance < 10 * Math.Pow(2.0,i))
 | 
			
		||||
                    break;
 | 
			
		||||
                pqueue++;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            // If this is a root agent, then determine front & back
 | 
			
		||||
            // Bump up the priority queue (drop the priority) for any objects behind the avatar
 | 
			
		||||
            if (useFrontBack && ! presence.IsChildAgent)
 | 
			
		||||
            {
 | 
			
		||||
                // Root agent, decrease priority for objects behind us
 | 
			
		||||
                Vector3 camPosition = presence.CameraPosition;
 | 
			
		||||
                Vector3 camAtAxis = presence.CameraAtAxis;
 | 
			
		||||
 | 
			
		||||
                // Plane equation
 | 
			
		||||
                float d = -Vector3.Dot(camPosition, camAtAxis);
 | 
			
		||||
                float p = Vector3.Dot(camAtAxis, entityPos) + d;
 | 
			
		||||
                if (p < 0.0f) 
 | 
			
		||||
                    pqueue++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return pqueue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10930,12 +10930,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 | 
			
		|||
        {
 | 
			
		||||
            UUID rq = UUID.Random();
 | 
			
		||||
 | 
			
		||||
            UUID tid = AsyncCommands.
 | 
			
		||||
                DataserverPlugin.RegisterRequest(m_localID,
 | 
			
		||||
                                             m_itemID, rq.ToString());
 | 
			
		||||
            AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString());
 | 
			
		||||
 | 
			
		||||
            AsyncCommands.
 | 
			
		||||
                DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id)));
 | 
			
		||||
            AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id)));
 | 
			
		||||
 | 
			
		||||
            return rq.ToString();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -10949,12 +10946,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 | 
			
		|||
        {
 | 
			
		||||
            UUID rq = UUID.Random();
 | 
			
		||||
 | 
			
		||||
            UUID tid = AsyncCommands.
 | 
			
		||||
                DataserverPlugin.RegisterRequest(m_localID,
 | 
			
		||||
                                             m_itemID, rq.ToString());
 | 
			
		||||
            AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString());
 | 
			
		||||
 | 
			
		||||
            AsyncCommands.
 | 
			
		||||
                DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id));
 | 
			
		||||
            AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id));
 | 
			
		||||
 | 
			
		||||
            return rq.ToString();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -169,7 +169,7 @@ namespace OpenSim.Services.Interfaces
 | 
			
		|||
        /// Get an item, given by its UUID
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        /// <returns>null if no item was found, otherwise the found item</returns>
 | 
			
		||||
        InventoryItemBase GetItem(InventoryItemBase item);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,22 @@
 | 
			
		|||
;; A note on the format of this file
 | 
			
		||||
;; This is the main configuration file for OpenSimulator.  If it's named OpenSim.ini
 | 
			
		||||
;; then it will be loaded by OpenSimulator.  If it's named OpenSim.ini.example then
 | 
			
		||||
;; you will need to copy it to OpenSim.ini first (if that file does not already exist)
 | 
			
		||||
;;
 | 
			
		||||
;; If you are copying, then once you have copied OpenSim.ini.example to OpenSim.ini you will
 | 
			
		||||
;; need to pick an architecture in the [Architecture] section at the end of this file.
 | 
			
		||||
;;
 | 
			
		||||
;; The settings in this file are in the form "<key> = <value>".  For example, save_crashes = false
 | 
			
		||||
;; in the [Startup] section below.
 | 
			
		||||
;;
 | 
			
		||||
;; All settings are initially commented out and the default value used, as found in
 | 
			
		||||
;; OpenSimDefaults.ini.  To change a setting, first uncomment it by deleting the initial semicolon (;)
 | 
			
		||||
;; and then change the value.  This will override the value in OpenSimDefaults.ini
 | 
			
		||||
;; 
 | 
			
		||||
;; If you want to find out what configuration OpenSimulator has finished with once all the configuration
 | 
			
		||||
;; files are loaded then type "config show" on the region console command line.
 | 
			
		||||
;;
 | 
			
		||||
;; 
 | 
			
		||||
;; NOTES FOR DEVELOPERS REGARDING FORMAT OF TIHS FILE
 | 
			
		||||
;;
 | 
			
		||||
;; All leading white space is ignored, but preserved.
 | 
			
		||||
;;
 | 
			
		||||
| 
						 | 
				
			
			@ -8,15 +26,14 @@
 | 
			
		|||
;;    formatted as:
 | 
			
		||||
;;    {option} {depends on} {question to ask} {choices} default value
 | 
			
		||||
;;    Any text comments following the declaration, up to the next blank line.
 | 
			
		||||
;;    will be copied to the generated file.
 | 
			
		||||
;;    A * in the choices list will allow an empty entry.\
 | 
			
		||||
;;    will be copied to the generated file (NOTE: generation is not yet implemented)
 | 
			
		||||
;;    A * in the choices list will allow an empty entry.
 | 
			
		||||
;;    An empty question will set the default if the dependencies are
 | 
			
		||||
;;    satisfied.
 | 
			
		||||
;;
 | 
			
		||||
;; ;  denotes a commented out option. Uncomment it to actvate it
 | 
			
		||||
;;    and change it to the desired value
 | 
			
		||||
;;    Any options added to OpenSim.ini.exmaple must be commented out,
 | 
			
		||||
;;    and their value must represent the default.
 | 
			
		||||
;; ;  denotes a commented out option.
 | 
			
		||||
;;    Any options added to OpenSim.ini.example should be initially commented out.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Startup]
 | 
			
		||||
    ;# {save_crashes} {} {Save crashes to disk?} {true false} false
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +52,7 @@
 | 
			
		|||
 | 
			
		||||
    ;; Determine where OpenSimulator looks for the files which tell it
 | 
			
		||||
    ;; which regions to server
 | 
			
		||||
    ;; Defaults to "filesystem" if this setting isn't present
 | 
			
		||||
    ;; Default is "filesystem"
 | 
			
		||||
    ; region_info_source = "filesystem"
 | 
			
		||||
    ; region_info_source = "web"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +148,7 @@
 | 
			
		|||
    ;; ZeroMesher is faster but leaves the physics engine to model the mesh
 | 
			
		||||
    ;; using the basic shapes that it supports.
 | 
			
		||||
    ;; Usually this is only a box.
 | 
			
		||||
    ;; Default is Meshmerizer
 | 
			
		||||
    ; meshing = Meshmerizer
 | 
			
		||||
    ; meshing = ZeroMesher
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +156,7 @@
 | 
			
		|||
    ;; OpenDynamicsEngine is by some distance the most developed physics engine
 | 
			
		||||
    ;; basicphysics effectively does not model physics at all, making all
 | 
			
		||||
    ;; objects phantom
 | 
			
		||||
    ;; Default is OpenDynamicsEngine
 | 
			
		||||
    ; physics = OpenDynamicsEngine
 | 
			
		||||
    ; physics = basicphysics
 | 
			
		||||
    ; physics = POS
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +173,6 @@
 | 
			
		|||
    ;; permission checks (allowing anybody to copy
 | 
			
		||||
    ;; any item, etc.  This may not yet be implemented uniformally.
 | 
			
		||||
    ;; If set to true, then all permissions checks are carried out
 | 
			
		||||
    ;; Default is false
 | 
			
		||||
    ; serverside_object_permissions = false
 | 
			
		||||
 | 
			
		||||
    ;; This allows users with a UserLevel of 200 or more to assume god
 | 
			
		||||
| 
						 | 
				
			
			@ -188,6 +206,7 @@
 | 
			
		|||
    ;; server to send mail through.
 | 
			
		||||
    ; emailmodule = DefaultEmailModule
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[SMTP]
 | 
			
		||||
    ;; The SMTP server enabled the email module to send email to external
 | 
			
		||||
    ;; destinations.
 | 
			
		||||
| 
						 | 
				
			
			@ -214,6 +233,7 @@
 | 
			
		|||
    ;# {SMTP_SERVER_PASSWORD} {[Startup]emailmodule:DefaultEmailModule enabled:true} {SMTP server password} {}
 | 
			
		||||
    ; SMTP_SERVER_PASSWORD = ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Network]
 | 
			
		||||
    ;; Configure the remote console user here. This will not actually be used
 | 
			
		||||
    ;; unless you use -console=rest at startup.
 | 
			
		||||
| 
						 | 
				
			
			@ -247,6 +267,7 @@
 | 
			
		|||
    ;; " (Mozilla Compatible)" to the text where there are problems with a web server
 | 
			
		||||
    ; user_agent = "OpenSim LSL (Mozilla Compatible)"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[ClientStack.LindenUDP]
 | 
			
		||||
    ;; See OpensSimDefaults.ini for the throttle options. You can copy the
 | 
			
		||||
    ;; relevant sections and override them here.
 | 
			
		||||
| 
						 | 
				
			
			@ -263,17 +284,18 @@
 | 
			
		|||
    ;; building's lights to possibly not be rendered.
 | 
			
		||||
    ; DisableFacelights = "false"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Chat]
 | 
			
		||||
    ;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10
 | 
			
		||||
    ;; Distance in meters that whispers should travel.  Default is 10m
 | 
			
		||||
    ;; Distance in meters that whispers should travel.
 | 
			
		||||
    ; whisper_distance = 10
 | 
			
		||||
 | 
			
		||||
    ;# {say_distance} {} {Distance at which normal chat is heard, in meters? (SL uses 20 here)} {} 30
 | 
			
		||||
    ;; Distance in meters that ordinary chat should travel.  Default is 30m
 | 
			
		||||
    ;; Distance in meters that ordinary chat should travel.
 | 
			
		||||
    ; say_distance = 30
 | 
			
		||||
 | 
			
		||||
    ;# {shout_distance} {Distance at which a shout is heard, in meters?} {} 100
 | 
			
		||||
    ;; Distance in meters that shouts should travel.  Default is 100m
 | 
			
		||||
    ;; Distance in meters that shouts should travel.
 | 
			
		||||
    ; shout_distance = 100
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -337,13 +359,13 @@
 | 
			
		|||
    ;# {create_region_enable_voice} {enabled:true} {Enable voice for newly created regions?} {true false} false
 | 
			
		||||
    ;; set this variable to true if you want the create_region XmlRpc
 | 
			
		||||
    ;; call to unconditionally enable voice on all parcels for a newly
 | 
			
		||||
    ;; created region [default: false]
 | 
			
		||||
    ;; created region
 | 
			
		||||
    ; create_region_enable_voice = false
 | 
			
		||||
 | 
			
		||||
    ;# {create_region_public} {enabled:true} {Make newly created regions public?} {true false} false
 | 
			
		||||
    ;; set this variable to false if you want the create_region XmlRpc
 | 
			
		||||
    ;; call to create all regions as private per default (can be
 | 
			
		||||
    ;; overridden in the XmlRpc call) [default: true]
 | 
			
		||||
    ;; overridden in the XmlRpc call)
 | 
			
		||||
    ; create_region_public = false
 | 
			
		||||
 | 
			
		||||
    ;# {enabled_methods} {enabled:true} {List of methods to allow, separated by |} {} all
 | 
			
		||||
| 
						 | 
				
			
			@ -372,15 +394,16 @@
 | 
			
		|||
    ;; default avatars
 | 
			
		||||
    ; default_appearance = default_appearance.xml
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Wind]
 | 
			
		||||
    ;# {enabled} {} {Enable wind module?} {true false} true
 | 
			
		||||
    ;; Enables the wind module.  Default is true
 | 
			
		||||
    ;enabled = true
 | 
			
		||||
    ;; Enables the wind module.
 | 
			
		||||
    ; enabled = true
 | 
			
		||||
 | 
			
		||||
    ;# {wind_update_rate} {enabled:true} {Wind update rate in frames?} {} 150
 | 
			
		||||
    ;; How often should wind be updated, as a function of world frames.
 | 
			
		||||
    ;; Approximately 50 frames a second
 | 
			
		||||
    wind_update_rate = 150
 | 
			
		||||
    ; wind_update_rate = 150
 | 
			
		||||
 | 
			
		||||
    ;; The Default Wind Plugin to load
 | 
			
		||||
    ; wind_plugin = SimpleRandomWind
 | 
			
		||||
| 
						 | 
				
			
			@ -396,9 +419,10 @@
 | 
			
		|||
 | 
			
		||||
    ;# {strength} {enabled:true wind_plugin:SimpleRandomWind} {Wind strength?} {} 1.0
 | 
			
		||||
    ;; This setting is specific to the SimpleRandomWind plugin
 | 
			
		||||
    ;; Adjusts wind strength. 0.0 = no wind, 1.0 = normal wind.  Default is 1.0
 | 
			
		||||
    ;; Adjusts wind strength. 0.0 = no wind, 1.0 = normal wind.
 | 
			
		||||
    ; strength = 1.0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[LightShare]
 | 
			
		||||
    ;# {enable_windlight} {} {Enable LightShare technology?} {true false} false
 | 
			
		||||
    ;; This enables the transmission of Windlight scenes to supporting clients,
 | 
			
		||||
| 
						 | 
				
			
			@ -406,7 +430,8 @@
 | 
			
		|||
    ;; It has no ill effect on viewers which do not support server-side
 | 
			
		||||
    ;; windlight settings.
 | 
			
		||||
    ;; Currently we only have support for MySQL databases.
 | 
			
		||||
    ; enable_windlight = false;
 | 
			
		||||
    ; enable_windlight = false
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[DataSnapshot]
 | 
			
		||||
    ;# {index_sims} {} {Enable data snapshotting (search)?} {true false} false
 | 
			
		||||
| 
						 | 
				
			
			@ -417,7 +442,6 @@
 | 
			
		|||
    ;; and you can ignore the rest of these search-related configs.
 | 
			
		||||
    ; index_sims = false
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ;# {data_exposure} {index_sims:true} {How much data should be exposed?} {minimum all} minimum
 | 
			
		||||
    ;; The variable data_exposure controls what the regions expose:
 | 
			
		||||
    ;;    minimum: exposes only things explicitly marked for search
 | 
			
		||||
| 
						 | 
				
			
			@ -462,6 +486,7 @@
 | 
			
		|||
    ;; Money Unit fee to create groups
 | 
			
		||||
    ; PriceGroupCreate = 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[XEngine]
 | 
			
		||||
    ;# {Enabled} {} {Enable the XEngine scripting engine?} {true false} true
 | 
			
		||||
    ;; Enable this engine in this OpenSim instance
 | 
			
		||||
| 
						 | 
				
			
			@ -556,9 +581,9 @@
 | 
			
		|||
    ;; Default is ./bin/ScriptEngines
 | 
			
		||||
    ; ScriptEnginesPath = "ScriptEngines"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[MRM]
 | 
			
		||||
    ;; Enables the Mini Region Modules Script Engine.
 | 
			
		||||
    ;; default is false
 | 
			
		||||
    ; Enabled = false
 | 
			
		||||
 | 
			
		||||
    ;; Runs MRM in a Security Sandbox
 | 
			
		||||
| 
						 | 
				
			
			@ -580,6 +605,7 @@
 | 
			
		|||
    ;; May represent a security risk if you disable this.
 | 
			
		||||
    ; OwnerOnly = true
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[FreeSwitchVoice]
 | 
			
		||||
    ;; In order for this to work you need a functioning FreeSWITCH PBX set up.
 | 
			
		||||
    ;; Configuration details at http://opensimulator.org/wiki/Freeswitch_Module
 | 
			
		||||
| 
						 | 
				
			
			@ -593,6 +619,7 @@
 | 
			
		|||
    ;; If using a remote module, specify the server URL
 | 
			
		||||
    ; FreeswitchServiceURL = http://my.grid.server:8003/fsapi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[FreeswitchService]
 | 
			
		||||
    ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!
 | 
			
		||||
    ;; !!!!!!STANDALONE ONLY!!!!!!
 | 
			
		||||
| 
						 | 
				
			
			@ -611,6 +638,7 @@
 | 
			
		|||
    ; UserName = "freeswitch"
 | 
			
		||||
    ; Password = "password"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Groups]
 | 
			
		||||
    ;# {Enabled} {} {Enable groups?} {true false} false
 | 
			
		||||
    ;; Enables the groups module
 | 
			
		||||
| 
						 | 
				
			
			@ -634,7 +662,7 @@
 | 
			
		|||
    ;# {ServicesConnectorModule} {Module:GroupsModule} {Service connector to use for groups} {XmlRpcGroupsServicesConnector SimianGroupsServicesConnector} XmlRpcGroupsServicesConnector
 | 
			
		||||
    ;; Service connectors to the Groups Service as used in the GroupsModule.  Select one depending on
 | 
			
		||||
    ;; whether you're using a Flotsam XmlRpc backend or a SimianGrid backend
 | 
			
		||||
    ; ServicesConnectorModule = SimianGroupsServicesConnector
 | 
			
		||||
    ; ServicesConnectorModule = XmlRpcGroupsServicesConnector
 | 
			
		||||
 | 
			
		||||
    ;# {GroupsServerURI} {Module:GroupsModule} {Groups Server URI} {}
 | 
			
		||||
    ;; URI for the groups services
 | 
			
		||||
| 
						 | 
				
			
			@ -654,6 +682,7 @@
 | 
			
		|||
    ; XmlRpcServiceReadKey    = 1234
 | 
			
		||||
    ; XmlRpcServiceWriteKey   = 1234
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[InterestManagement]
 | 
			
		||||
     ;# {UpdatePrioritizationScheme} {} {Update prioritization scheme?} {BestAvatarResponsiveness Time Distance SimpleAngularDistance FrontBack} BestAvatarResponsiveness
 | 
			
		||||
     ;; This section controls how state updates are prioritized for each client
 | 
			
		||||
| 
						 | 
				
			
			@ -661,24 +690,28 @@
 | 
			
		|||
     ;; SimpleAngularDistance, FrontBack
 | 
			
		||||
     ; UpdatePrioritizationScheme = BestAvatarResponsiveness
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[MediaOnAPrim]
 | 
			
		||||
    ;# {Enabled} {} {Enable Media-on-a-Prim (MOAP)} {true false} true
 | 
			
		||||
    ;; Enable media on a prim facilities
 | 
			
		||||
    ; Enabled = true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Architecture]
 | 
			
		||||
    ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini
 | 
			
		||||
    ;; Choose one of these architecture includes:
 | 
			
		||||
    ;; Include-Architecture = "config-include/Standalone.ini"
 | 
			
		||||
    ;; Include-Architecture = "config-include/StandaloneHypergrid.ini"
 | 
			
		||||
    ;; Include-Architecture = "config-include/Grid.ini"
 | 
			
		||||
    ;; Include-Architecture = "config-include/GridHypergrid.ini"
 | 
			
		||||
    ;; Include-Architecture = "config-include/SimianGrid.ini"
 | 
			
		||||
    ;; Include-Architecture = "config-include/HyperSimianGrid.ini"
 | 
			
		||||
    ;; Uncomment one of the following includes as required.  For instance, to create a standalone OpenSim,
 | 
			
		||||
    ;; uncomment Include-Architecture = "config-include/Standalone.ini"
 | 
			
		||||
    ;; 
 | 
			
		||||
    ;; Then you will need to copy and edit the corresponding *Common.example file in config-include/
 | 
			
		||||
    ;; that the referenced .ini file goes on to include.
 | 
			
		||||
    ;;
 | 
			
		||||
    ;; For instance, if you chose "config-include/Standalone.ini" then you will need to copy 
 | 
			
		||||
    ;; "config-include/StandaloneCommon.ini.example" to "config-include/StandaloneCommon.ini" before
 | 
			
		||||
    ;; editing it to set the database and backend services that OpenSim will use.
 | 
			
		||||
    ;;
 | 
			
		||||
    ; Include-Architecture = "config-include/Standalone.ini"
 | 
			
		||||
 | 
			
		||||
    ;; Then choose
 | 
			
		||||
    ;; config-include/StandaloneCommon.ini.example (if you're in standlone) OR
 | 
			
		||||
    ;; config-include/GridCommon.ini.example (if you're connected to a grid)
 | 
			
		||||
    ;; Copy to your own .ini there (without .example extension) and edit it
 | 
			
		||||
    ;; to customize your data
 | 
			
		||||
    ; Include-Architecture = "config-include/StandaloneHypergrid.ini"
 | 
			
		||||
    ; Include-Architecture = "config-include/Grid.ini"
 | 
			
		||||
    ; Include-Architecture = "config-include/GridHypergrid.ini"
 | 
			
		||||
    ; Include-Architecture = "config-include/SimianGrid.ini"
 | 
			
		||||
    ; Include-Architecture = "config-include/HyperSimianGrid.ini"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,7 @@
 | 
			
		|||
; This file contains defaults for various settings in OpenSimulator.  These can be overriden
 | 
			
		||||
; by changing the same setting in OpenSim.ini (once OpenSim.ini.example has been copied to OpenSim.ini).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Startup]
 | 
			
		||||
    ; Set this to true if you want to log crashes to disk
 | 
			
		||||
    ; this can be useful when submitting bug reports.
 | 
			
		||||
| 
						 | 
				
			
			@ -287,6 +291,7 @@
 | 
			
		|||
    ;SMTP_SERVER_LOGIN=foo
 | 
			
		||||
    ;SMTP_SERVER_PASSWORD=bar
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Network]
 | 
			
		||||
    ConsoleUser = "Test"
 | 
			
		||||
    ConsolePass = "secret"
 | 
			
		||||
| 
						 | 
				
			
			@ -317,6 +322,7 @@
 | 
			
		|||
    ; " (Mozilla Compatible)" to the text where there are problems with a web server
 | 
			
		||||
    ;user_agent = "OpenSim LSL (Mozilla Compatible)"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[XMLRPC]
 | 
			
		||||
    ; ##
 | 
			
		||||
    ; ## Scripting XMLRPC mapper
 | 
			
		||||
| 
						 | 
				
			
			@ -330,6 +336,7 @@
 | 
			
		|||
    ;XmlRpcRouterModule = "XmlRpcRouterModule"
 | 
			
		||||
    ;XmlRpcPort = 20800
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[ClientStack.LindenUDP]
 | 
			
		||||
    ; Set this to true to process incoming packets asynchronously. Networking is
 | 
			
		||||
    ; already separated from packet handling with a queue, so this will only
 | 
			
		||||
| 
						 | 
				
			
			@ -422,6 +429,7 @@
 | 
			
		|||
    ;
 | 
			
		||||
    ;DisableFacelights = "false"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Chat]
 | 
			
		||||
    ; Controls whether the chat module is enabled.  Default is true.
 | 
			
		||||
    enabled = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -680,6 +688,7 @@
 | 
			
		|||
    ; path to default appearance XML file that specifies the look of the default avatars
 | 
			
		||||
    ;default_appearance = default_appearance.xml 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[RestPlugins]
 | 
			
		||||
    ; Change this to true to enable REST Plugins. This must be true if you wish to use
 | 
			
		||||
    ; REST Region or REST Asset and Inventory Plugins
 | 
			
		||||
| 
						 | 
				
			
			@ -706,11 +715,10 @@
 | 
			
		|||
    flush-on-error = true
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; Uncomment the following for IRC bridge
 | 
			
		||||
; experimental, so if it breaks... keep both parts... yada yada
 | 
			
		||||
; IRC bridge is experimental, so if it breaks... keep both parts... yada yada
 | 
			
		||||
; also, not good error detection when it fails
 | 
			
		||||
;[IRC]
 | 
			
		||||
    ;enabled = true ; you need to set this otherwise it won't connect
 | 
			
		||||
[IRC]
 | 
			
		||||
    enabled = false; you need to set this to true otherwise it won't connect
 | 
			
		||||
    ;server  = name.of.irc.server.on.the.net
 | 
			
		||||
    ;; user password - only use this if the server requires one
 | 
			
		||||
    ;password = mypass
 | 
			
		||||
| 
						 | 
				
			
			@ -767,14 +775,14 @@
 | 
			
		|||
    ;exclude_list=User 1,User 2,User 3
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;[CMS]
 | 
			
		||||
    ;enabled = true
 | 
			
		||||
[CMS]
 | 
			
		||||
    enabled = false
 | 
			
		||||
    ;channel = 345
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
; Uncomment the following to control the progression of daytime
 | 
			
		||||
; in the Sim.  The defaults are what is shown below
 | 
			
		||||
;[Sun]
 | 
			
		||||
; The following settings control the progression of daytime
 | 
			
		||||
; in the Sim.  The defaults are the same as the commented out settings
 | 
			
		||||
[Sun]
 | 
			
		||||
    ; number of wall clock hours for an opensim day.  24.0 would mean realtime
 | 
			
		||||
    ;day_length = 4
 | 
			
		||||
    ; Year length in days
 | 
			
		||||
| 
						 | 
				
			
			@ -821,12 +829,13 @@
 | 
			
		|||
    ; default is 1000
 | 
			
		||||
    cloud_update_rate = 1000
 | 
			
		||||
 | 
			
		||||
[LightShare]
 | 
			
		||||
 | 
			
		||||
[LightShare]
 | 
			
		||||
    ; This enables the transmission of Windlight scenes to supporting clients, such as the Meta7 viewer.
 | 
			
		||||
    ; It has no ill effect on viewers which do not support server-side windlight settings.
 | 
			
		||||
    ; Currently we only have support for MySQL databases.
 | 
			
		||||
    enable_windlight = false;
 | 
			
		||||
    enable_windlight = false
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Trees]
 | 
			
		||||
    ; Enable this to allow the tree module to manage your sim trees, including growing, reproducing and dying
 | 
			
		||||
| 
						 | 
				
			
			@ -838,7 +847,6 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
[VectorRender]
 | 
			
		||||
 | 
			
		||||
    ; the font to use for rendering text (default: Arial)
 | 
			
		||||
    ; font_name = "Arial"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1032,6 +1040,7 @@
 | 
			
		|||
    ;; Path to script assemblies 
 | 
			
		||||
    ; ScriptEnginesPath = "ScriptEngines"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[OpenGridProtocol]
 | 
			
		||||
    ;These are the settings for the Open Grid Protocol..  the Agent Domain, Region Domain,   you know..
 | 
			
		||||
    ;On/true or Off/false
 | 
			
		||||
| 
						 | 
				
			
			@ -1240,11 +1249,11 @@
 | 
			
		|||
     ChildReprioritizationDistance = 20.0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[WebStats]
 | 
			
		||||
; View region statistics via a web page
 | 
			
		||||
; See http://opensimulator.org/wiki/FAQ#Region_Statistics_on_a_Web_Page
 | 
			
		||||
; Use a web browser and type in the "Login URI" + "/SStats/"
 | 
			
		||||
; For example- http://127.0.0.1:9000/SStats/
 | 
			
		||||
[WebStats]
 | 
			
		||||
; enabled=false
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										
											BIN
										
									
								
								bin/libode.dylib
								
								
								
								
							
							
						
						
									
										
											BIN
										
									
								
								bin/libode.dylib
								
								
								
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue