/* * Copyright (c) 2006-2008, openmetaverse.org * All rights reserved. * * - 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. * - Neither the name of the openmetaverse.org 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Collections.Generic; using OpenMetaverse.Packets; namespace OpenMetaverse { /// /// Class for controlling various system settings. /// /// Some values are readonly because they affect things that /// happen when the GridClient object is initialized, so changing them at /// runtime won't do any good. Non-readonly values may affect things that /// happen at login or dynamically public class Settings { #region Login/Networking Settings /// Main grid login server public const string AGNI_LOGIN_SERVER = "https://login.agni.lindenlab.com/cgi-bin/login.cgi"; /// Beta grid login server public const string ADITI_LOGIN_SERVER = "https://login.aditi.lindenlab.com/cgi-bin/login.cgi"; /// The relative directory where external resources are kept public static string RESOURCE_DIR = "openmetaverse_data"; /// Login server to connect to public string LOGIN_SERVER = AGNI_LOGIN_SERVER; /// IP Address the client will bind to public static System.Net.IPAddress BIND_ADDR = System.Net.IPAddress.Any; #endregion #region Inventory /// /// InventoryManager requests inventory information on login, /// GridClient initializes an Inventory store for main inventory. /// public const bool ENABLE_INVENTORY_STORE = true; /// /// InventoryManager requests library information on login, /// GridClient initializes an Inventory store for the library. /// public const bool ENABLE_LIBRARY_STORE = true; #endregion #region Timeouts and Intervals /// Number of milliseconds before an asset transfer will time /// out public const int TRANSFER_TIMEOUT = 30 * 1000; /// Number of milliseconds before a teleport attempt will time /// out public int TELEPORT_TIMEOUT = 40 * 1000; /// Number of milliseconds before NetworkManager.Logout() will /// time out public int LOGOUT_TIMEOUT = 5 * 1000; /// Number of milliseconds before a CAPS call will time out /// and try again /// Setting this too low will cause web requests to repeatedly /// time out and retry public int CAPS_TIMEOUT = 60 * 1000; /// Number of milliseconds for xml-rpc to timeout public int LOGIN_TIMEOUT = 60 * 1000; /// Milliseconds before a packet is assumed lost and resent public int RESEND_TIMEOUT = 4000; /// Milliseconds without receiving a packet before the /// connection to a simulator is assumed lost public int SIMULATOR_TIMEOUT = 30 * 1000; /// Milliseconds to wait for a simulator info request through /// the grid interface public int MAP_REQUEST_TIMEOUT = 5 * 1000; /// Number of milliseconds between sending pings to each sim public const int PING_INTERVAL = 2200; /// Number of milliseconds between sending camera updates public const int DEFAULT_AGENT_UPDATE_INTERVAL = 500; /// Number of milliseconds between updating the current /// positions of moving, non-accelerating and non-colliding objects public const int INTERPOLATION_INTERVAL = 250; /// Millisecond interval between ticks, where all ACKs are /// sent out and the age of unACKed packets is checked public const int NETWORK_TICK_INTERVAL = 500; #endregion #region Sizes private int max_pending_acks = 10; /// The initial size of the packet inbox, where packets are /// stored before processing public const int PACKET_INBOX_SIZE = 100; /// Maximum size of packet that we want to send over the wire public const int MAX_PACKET_SIZE = 1200; /// The maximum value of a packet sequence number before it /// rolls over back to one public const int MAX_SEQUENCE = 0xFFFFFF; /// The maximum size of the sequence number archive, used to /// check for resent and/or duplicate packets public const int PACKET_ARCHIVE_SIZE = 200; /// Maximum number of queued ACKs to be sent before SendAcks() /// is forced public int MAX_PENDING_ACKS { get { return max_pending_acks; } set { // We can't safely fit more than 375 ACKs in 1500 bytes if (value > 375) throw new ArgumentOutOfRangeException("Too many ACKs to fit in a single packet"); else if (value < 1) throw new ArgumentOutOfRangeException("Cannot send a non-positive number of ACKs"); max_pending_acks = value; } } /// Maximum number of ACKs to append to a packet public int MAX_APPENDED_ACKS = 10; /// Network stats queue length (seconds) public int STATS_QUEUE_SIZE = 5; #endregion #region Configuration options (mostly booleans) /// Enable to process packets synchronously, where all of the /// callbacks for each packet must return before the next packet is /// processed /// This is an experimental feature and is not completely /// reliable yet. Ideally it would reduce context switches and thread /// overhead, but several calls currently block for a long time and /// would need to be rewritten as asynchronous code before this is /// feasible public bool SYNC_PACKETCALLBACKS = false; /// Enable/disable storing terrain heightmaps in the /// TerrainManager public bool STORE_LAND_PATCHES = false; /// Enable/disable sending periodic camera updates public bool SEND_AGENT_UPDATES = true; /// Enable/disable automatically setting the bandwidth throttle /// after connecting to each simulator /// The default throttle uses the equivalent of the maximum /// bandwidth setting in the official client. If you do not set a /// throttle your connection will by default be throttled well below /// the minimum values and you may experience connection problems public bool SEND_AGENT_THROTTLE = true; /// Enable/disable the sending of pings to monitor lag and /// packet loss public bool SEND_PINGS = true; /// Should we connect to multiple sims? This will allow /// viewing in to neighboring simulators and sim crossings /// (Experimental) public bool MULTIPLE_SIMS = true; /// If true, all object update packets will be decoded in to /// native objects. If false, only updates for our own agent will be /// decoded. Registering an event handler will force objects for that /// type to always be decoded. If this is disabled the object tracking /// will have missing or partial prim and avatar information public bool ALWAYS_DECODE_OBJECTS = true; /// If true, when a cached object check is received from the /// server the full object info will automatically be requested public bool ALWAYS_REQUEST_OBJECTS = true; /// Whether to establish connections to HTTP capabilities /// servers for simulators public bool ENABLE_CAPS = true; /// Whether to decode sim stats public bool ENABLE_SIMSTATS = true; /// The capabilities servers are currently designed to /// periodically return a 502 error which signals for the client to /// re-establish a connection. Set this to true to log those 502 errors public bool LOG_ALL_CAPS_ERRORS = false; /// If true, any reference received for a folder or item /// the library is not aware of will automatically be fetched public bool FETCH_MISSING_INVENTORY = true; /// If true, and SEND_AGENT_UPDATES is true, /// AgentUpdate packets will continuously be sent out to give the bot /// smoother movement and autopiloting public bool DISABLE_AGENT_UPDATE_DUPLICATE_CHECK = true; /// If true, currently visible avatars will be stored /// in dictionaries inside Simulator.ObjectAvatars. /// If false, a new Avatar or Primitive object will be created /// each time an object update packet is received public bool AVATAR_TRACKING = true; /// If true, currently visible avatars will be stored /// in dictionaries inside Simulator.ObjectPrimitives. /// If false, a new Avatar or Primitive object will be created /// each time an object update packet is received public bool OBJECT_TRACKING = true; #endregion #region Parcel Tracking /// If true, parcel details will be stored in the /// Simulator.Parcels dictionary as they are received public bool PARCEL_TRACKING = true; /// /// If true, an incoming parcel properties reply will automatically send /// a request for the parcel access list /// public bool ALWAYS_REQUEST_PARCEL_ACL = true; /// /// if true, an incoming parcel properties reply will automatically send /// a request for the traffic count. /// public bool ALWAYS_REQUEST_PARCEL_DWELL = true; #endregion #region Texture Cache /// /// If true, images downloaded from the server will be cached /// in a local directory /// public bool USE_TEXTURE_CACHE = false; /// Path to store cached texture data public string TEXTURE_CACHE_DIR = RESOURCE_DIR + "/cache"; /// Maximum size cached files are allowed to take on disk (bytes) public long TEXTURE_CACHE_MAX_SIZE = 1024 * 1024 * 1024; // 1GB #endregion #region Misc /// Default color used for viewer particle effects public Color4 DEFAULT_EFFECT_COLOR = new Color4(255, 0, 0, 255); /// Cost of uploading an asset /// Read-only since this value is dynamically fetched at login public int UPLOAD_COST { get { return priceUpload; } } /// Maximum number of times to resend a failed packet public int MAX_RESEND_COUNT = 3; /// Throttle outgoing packet rate public bool THROTTLE_OUTGOING_PACKETS = true; #endregion #region Logging Configuration /// /// Get or set the minimum log level to output to the console by default /// /// If the library is not compiled with DEBUG defined and this level is set to DEBUG /// You will get no output on the console. This behavior can be overriden by creating /// a logger configuration file for log4net /// public static Helpers.LogLevel LOG_LEVEL = Helpers.LogLevel.Debug; /// Attach avatar names to log messages public bool LOG_NAMES = true; /// Log packet retransmission info public bool LOG_RESENDS = true; #endregion #region Private Fields private GridClient Client; private int priceUpload = 0; /// Constructor /// Reference to a GridClient object public Settings(GridClient client) { Client = client; Client.Network.RegisterCallback(Packets.PacketType.EconomyData, new NetworkManager.PacketCallback(EconomyDataHandler)); } #endregion #region Packet Callbacks /// /// Gets the cost of uploading an asset to the grid /// /// /// private void EconomyDataHandler(Packet packet, Simulator simulator) { EconomyDataPacket econ = (EconomyDataPacket)packet; priceUpload = econ.Info.PriceUpload; } #endregion } }