diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index b557ffe5f2..0271738aee 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs @@ -57,39 +57,36 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } /// - /// Return a xfer uploader if one does not already exist. + /// Return the xfer uploader for the given transaction. /// + /// + /// If an uploader does not already exist for this transaction then it is created, otherwise the existing + /// uploader is returned. + /// /// - /// - /// We must transfer the new asset ID into the uploader on creation, otherwise - /// we can see race conditions with other threads which can retrieve an item before it is updated with the new - /// asset id. - /// - /// - /// The xfer uploader requested. Null if one is already in existence. - /// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple - /// transfers are made. Needs to be corrected. - /// - public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID) + /// The asset xfer uploader + public AssetXferUploader RequestXferUploader(UUID transactionID) { + AssetXferUploader uploader; + lock (XferUploaders) { if (!XferUploaders.ContainsKey(transactionID)) { - AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile); + uploader = new AssetXferUploader(this, m_Scene, transactionID, m_dumpAssetsToFile); // m_log.DebugFormat( // "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID); XferUploaders.Add(transactionID, uploader); - - return uploader; + } + else + { + uploader = XferUploaders[transactionID]; } } - m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID); - - return null; + return uploader; } public void HandleXfer(ulong xferID, uint packetID, byte[] data) @@ -151,115 +148,28 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) { - AssetXferUploader uploader = null; + AssetXferUploader uploader = RequestXferUploader(transactionID); - lock (XferUploaders) - { - if (XferUploaders.ContainsKey(transactionID)) - uploader = XferUploaders[transactionID]; - } - - if (uploader != null) - uploader.RequestCreateInventoryItem( - remoteClient, transactionID, folderID, - callbackID, description, name, invType, type, - wearableType, nextOwnerMask); - else - m_log.ErrorFormat( - "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}", - transactionID, name, remoteClient.Name); - } - - /// - /// Get an uploaded asset. If the data is successfully retrieved, - /// the transaction will be removed. - /// - /// - /// The asset if the upload has completed, null if it has not. - private AssetBase GetTransactionAsset(UUID transactionID) - { - lock (XferUploaders) - { - if (XferUploaders.ContainsKey(transactionID)) - { - AssetXferUploader uploader = XferUploaders[transactionID]; - AssetBase asset = uploader.GetAssetData(); - RemoveXferUploader(transactionID); - - return asset; - } - } - - return null; + uploader.RequestCreateInventoryItem( + remoteClient, folderID, callbackID, + description, name, invType, type, wearableType, nextOwnerMask); } public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) { - AssetXferUploader uploader = null; + AssetXferUploader uploader = RequestXferUploader(transactionID); - lock (XferUploaders) - { - if (XferUploaders.ContainsKey(transactionID)) - uploader = XferUploaders[transactionID]; - } - - if (uploader != null) - { - AssetBase asset = GetTransactionAsset(transactionID); - - // Only legacy viewers use this, and they prefer CAPS, which - // we have, so this really never runs. - // Allow it, but only for "safe" types. - if ((InventoryType)item.InvType != InventoryType.Notecard && - (InventoryType)item.InvType != InventoryType.LSL) - return; - - if (asset != null) - { -// m_log.DebugFormat( -// "[AGENT ASSETS TRANSACTIONS]: Updating item {0} in {1} for transaction {2}", -// item.Name, part.Name, transactionID); - - asset.FullID = UUID.Random(); - asset.Name = item.Name; - asset.Description = item.Description; - asset.Type = (sbyte)item.Type; - item.AssetID = asset.FullID; - - m_Scene.AssetService.Store(asset); - } - } - else - { - m_log.ErrorFormat( - "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}", - transactionID, item.Name, part.Name); - } + uploader.RequestUpdateTaskInventoryItem(remoteClient, item); } public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) { - AssetXferUploader uploader = null; + AssetXferUploader uploader = RequestXferUploader(transactionID); - lock (XferUploaders) - { - if (XferUploaders.ContainsKey(transactionID)) - uploader = XferUploaders[transactionID]; - } - - if (uploader != null) - { - uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item); - } - else - { - m_log.ErrorFormat( - "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}", - transactionID, item.Name, remoteClient.Name); - } + uploader.RequestUpdateInventoryItem(remoteClient, item); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 708198923a..73d1f72b2a 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -215,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) { m_log.DebugFormat( - "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", + "[ASSET TRANSACTION MODULE] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); AgentAssetTransactions transactions = @@ -274,13 +274,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); - AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID); - - if (uploader != null) - { - uploader.Initialise(remoteClient, assetID, transaction, type, - data, storeLocal, tempFile); - } + AssetXferUploader uploader = transactions.RequestXferUploader(transaction); + uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); } /// diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index ec4dfd0bbb..8add4bb073 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs @@ -40,39 +40,75 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Upload state. + /// + /// + /// New -> Uploading -> Complete + /// + private enum UploadState + { + New, + Uploading, + Complete + } + /// /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we /// are performing a delayed update. /// AgentAssetTransactions m_transactions; + private UploadState m_uploadState = UploadState.New; + private AssetBase m_asset; private UUID InventFolder = UUID.Zero; private sbyte invType = 0; - private bool m_createItem = false; - private uint m_createItemCallback = 0; - private bool m_updateItem = false; + private bool m_createItem; + private uint m_createItemCallback; + + private bool m_updateItem; private InventoryItemBase m_updateItemData; + private bool m_updateTaskItem; + private TaskInventoryItem m_updateTaskItemData; + private string m_description = String.Empty; private bool m_dumpAssetToFile; - private bool m_finished = false; private string m_name = String.Empty; - private bool m_storeLocal; +// private bool m_storeLocal; private uint nextPerm = 0; private IClientAPI ourClient; - private UUID TransactionID = UUID.Zero; + + private UUID m_transactionID; + private sbyte type = 0; private byte wearableType = 0; public ulong XferID; private Scene m_Scene; - public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) + /// + /// AssetXferUploader constructor + /// + /// /param> + /// + /// + /// + /// If true then when the asset is uploaded it is dumped to a file with the format + /// String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", + /// now.Year, now.Month, now.Day, now.Hour, now.Minute, + /// now.Second, m_asset.Name, m_asset.Type); + /// for debugging purposes. + /// + public AssetXferUploader( + AgentAssetTransactions transactions, Scene scene, UUID transactionID, bool dumpAssetToFile) { + m_asset = new AssetBase(); + m_transactions = transactions; + m_transactionID = transactionID; m_Scene = scene; - m_asset = new AssetBase() { FullID = assetID }; m_dumpAssetToFile = dumpAssetToFile; } @@ -118,30 +154,50 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } /// - /// Initialise asset transfer from the client + /// Start asset transfer from the client /// - /// - /// - /// - public void Initialise(IClientAPI remoteClient, UUID assetID, - UUID transaction, sbyte type, byte[] data, bool storeLocal, - bool tempFile) + /// + /// + /// + /// + /// + /// Optional data. If present then the asset is created immediately with this data + /// rather than requesting an upload from the client. The data must be longer than 2 bytes. + /// + /// + /// + public void StartUpload( + IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal, + bool tempFile) { // m_log.DebugFormat( // "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", // remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); + lock (this) + { + if (m_uploadState != UploadState.New) + { + m_log.WarnFormat( + "[ASSET XFER UPLOADER]: Tried to start upload of asset {0}, transaction {1} for {2} but this is already in state {3}. Aborting.", + assetID, transaction, remoteClient.Name, m_uploadState); + + return; + } + + m_uploadState = UploadState.Uploading; + } + ourClient = remoteClient; - m_asset.Name = "blank"; - m_asset.Description = "empty"; + + m_asset.FullID = assetID; m_asset.Type = type; m_asset.CreatorID = remoteClient.AgentId.ToString(); m_asset.Data = data; m_asset.Local = storeLocal; m_asset.Temporary = tempFile; - TransactionID = transaction; - m_storeLocal = storeLocal; +// m_storeLocal = storeLocal; if (m_asset.Data.Length > 2) { @@ -166,36 +222,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction protected void SendCompleteMessage() { - ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, - m_asset.FullID); - // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create // message from other client UDP. lock (this) { - m_finished = true; + m_uploadState = UploadState.Complete; + + ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); + if (m_createItem) { - DoCreateItem(m_createItemCallback); + CompleteCreateItem(m_createItemCallback); } else if (m_updateItem) { - StoreAssetForItemUpdate(m_updateItemData); - - // Remove ourselves from the list of transactions if completion was delayed until the transaction - // was complete. - // TODO: Should probably do the same for create item. - m_transactions.RemoveXferUploader(TransactionID); + CompleteItemUpdate(m_updateItemData); } - else if (m_storeLocal) + else if (m_updateTaskItem) { - m_Scene.AssetService.Store(m_asset); + CompleteTaskItemUpdate(m_updateTaskItemData); } +// else if (m_storeLocal) +// { +// m_Scene.AssetService.Store(m_asset); +// } } m_log.DebugFormat( "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", - m_asset.FullID, TransactionID); + m_asset.FullID, m_transactionID); if (m_dumpAssetToFile) { @@ -223,40 +278,37 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } public void RequestCreateInventoryItem(IClientAPI remoteClient, - UUID transactionID, UUID folderID, uint callbackID, + UUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) { - if (TransactionID == transactionID) - { - InventFolder = folderID; - m_name = name; - m_description = description; - this.type = type; - this.invType = invType; - this.wearableType = wearableType; - nextPerm = nextOwnerMask; - m_asset.Name = name; - m_asset.Description = description; - m_asset.Type = type; + InventFolder = folderID; + m_name = name; + m_description = description; + this.type = type; + this.invType = invType; + this.wearableType = wearableType; + nextPerm = nextOwnerMask; + m_asset.Name = name; + m_asset.Description = description; + m_asset.Type = type; - // We must lock to avoid a race with a separate thread uploading the asset. - lock (this) + // We must lock to avoid a race with a separate thread uploading the asset. + lock (this) + { + if (m_uploadState == UploadState.Complete) { - if (m_finished) - { - DoCreateItem(callbackID); - } - else - { - m_createItem = true; //set flag so the inventory item is created when upload is complete - m_createItemCallback = callbackID; - } + CompleteCreateItem(callbackID); + } + else + { + m_createItem = true; //set flag so the inventory item is created when upload is complete + m_createItemCallback = callbackID; } } } - public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) + public void RequestUpdateInventoryItem(IClientAPI remoteClient, InventoryItemBase item) { // We must lock to avoid a race with a separate thread uploading the asset. lock (this) @@ -271,9 +323,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction item.AssetID = m_asset.FullID; m_Scene.InventoryService.UpdateItem(item); - if (m_finished) + if (m_uploadState == UploadState.Complete) { - StoreAssetForItemUpdate(item); + CompleteItemUpdate(item); } else { @@ -287,20 +339,59 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } } + public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, TaskInventoryItem taskItem) + { + // We must lock to avoid a race with a separate thread uploading the asset. + lock (this) + { + m_asset.Name = taskItem.Name; + m_asset.Description = taskItem.Description; + m_asset.Type = (sbyte)taskItem.Type; + taskItem.AssetID = m_asset.FullID; + + if (m_uploadState == UploadState.Complete) + { + CompleteTaskItemUpdate(taskItem); + } + else + { + m_updateTaskItem = true; + m_updateTaskItemData = taskItem; + } + } + } + /// - /// Store the asset for the given item. + /// Store the asset for the given item when it has been uploaded. /// /// - private void StoreAssetForItemUpdate(InventoryItemBase item) + private void CompleteItemUpdate(InventoryItemBase item) { // m_log.DebugFormat( // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", // m_asset.FullID, item.Name, ourClient.Name); m_Scene.AssetService.Store(m_asset); + + m_transactions.RemoveXferUploader(m_transactionID); } - private void DoCreateItem(uint callbackID) + /// + /// Store the asset for the given task item when it has been uploaded. + /// + /// + private void CompleteTaskItemUpdate(TaskInventoryItem taskItem) + { +// m_log.DebugFormat( +// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}", +// m_asset.FullID, taskItem.Name, ourClient.Name); + + m_Scene.AssetService.Store(m_asset); + + m_transactions.RemoveXferUploader(m_transactionID); + } + + private void CompleteCreateItem(uint callbackID) { m_Scene.AssetService.Store(m_asset); @@ -326,20 +417,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction ourClient.SendInventoryItemCreateUpdate(item, callbackID); else ourClient.SendAlertMessage("Unable to create inventory item"); - } - /// - /// Get the asset data uploaded in this transfer. - /// - /// null if the asset has not finished uploading - public AssetBase GetAssetData() - { - if (m_finished) - { - return m_asset; - } - - return null; + m_transactions.RemoveXferUploader(m_transactionID); } } -} +} \ No newline at end of file diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index a602dcc60b..22b39ce834 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -1,19 +1,23 @@ -;; 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) +;; 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. +;; 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 " = ". For example, save_crashes = false -;; in the [Startup] section below. +;; The settings in this file are in the form " = ". 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 +;; 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. +;; 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 THE FORMAT OF THIS FILE @@ -26,13 +30,16 @@ ;; 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 (NOTE: generation is not yet implemented) +;; 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. -;; Any options added to OpenSim.ini.example should be initially commented out. +;; Any options added to OpenSim.ini.example should be initially commented +;; out. [Startup] @@ -47,9 +54,12 @@ ;# {save_crashes} {} {Save crashes to disk?} {true false} false ;; Set this to true if you want to log crashes to disk ;; this can be useful when submitting bug reports. - ;; However, this will only log crashes within OpenSimulator that cause the entire program to exit - ;; It will not log crashes caused by virtual machine failures, which includes mono and ODE failures. - ;; You will need to capture these native stack traces by recording the session log itself. + ;; However, this will only log crashes within OpenSimulator that cause the + ;; entire program to exit + ;; It will not log crashes caused by virtual machine failures, which + ;; includes mono and ODE failures. + ;; You will need to capture these native stack traces by recording the + ;; session log itself. ; save_crashes = false ;# {crash_dir} {save_crashes:true} {Directory to save crashes to?} {} crashes @@ -88,35 +98,46 @@ ; allow_regionless = false ;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.001 - ;; Minimum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonPhysicalPrimMin!). + ;; Minimum size for non-physical prims. Affects resizing of existing + ;; prims. This can be overriden in the region config file (as + ;; NonPhysicalPrimMin!). ; NonPhysicalPrimMin = 0.001 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256 - ;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonPhysicalPrimMax!). + ;; Maximum size for non-physical prims. Affects resizing of existing + ;; prims. This can be overriden in the region config file (as + ;; NonPhysicalPrimMax!). ; NonPhysicalPrimMax = 256 ;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10 - ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file. + ;; Maximum size where a prim can be physical. Affects resizing of + ;; existing prims. This can be overriden in the region config file. ; PhysicalPrimMin = 0.01 ;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10 - ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file. + ;; Maximum size where a prim can be physical. Affects resizing of + ;; existing prims. This can be overriden in the region config file. ; PhysicalPrimMax = 10 ;# {ClampPrimSize} {} {Clamp viewer rezzed prims to max sizes?} {true false} false - ;; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum + ;; If a viewer attempts to rez a prim larger than the non-physical or + ;; physical prim max, clamp the dimensions to the appropriate maximum ;; This can be overriden in the region config file. ; ClampPrimSize = false ;# {LinksetPrims} {} {Max prims an object will hold?} {} 0 - ;; Maximum number of prims allowable in a linkset. Affects creating new linksets. Ignored if less than or equal to zero. + ;; Maximum number of prims allowable in a linkset. Affects creating new + ;; linksets. Ignored if less than or equal to zero. ;; This can be overriden in the region config file. ; LinksetPrims = 0 ;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} true - ;; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region. - ;; This only applies when crossing to a region running in a different simulator. - ;; For crossings where the regions are on the same simulator the script is always kept running. + ;; Allow scripts to keep running when they cross region boundaries, rather + ;; than being restarted. State is reloaded on the destination region. + ;; This only applies when crossing to a region running in a different + ;; simulator. + ;; For crossings where the regions are on the same simulator the script is + ;; always kept running. ; AllowScriptCrossing = true ;# {TrustBinaries} {AllowScriptCrossing:true} {Accept compiled binary script code? (DANGEROUS!)} {true false} false @@ -186,7 +207,8 @@ ;# {physics} {} {Select physics engine} {OpenDynamicsEngine BulletSim basicphysics POS} OpenDynamicsEngine ;; OpenDynamicsEngine is by some distance the most developed physics engine ;; BulletSim is incomplete and experimental but in active development - ;; basicphysics effectively does not model physics at all, making all objects phantom + ;; basicphysics effectively does not model physics at all, making all + ;; objects phantom ;; Default is OpenDynamicsEngine ; physics = OpenDynamicsEngine ; physics = BulletSim @@ -229,8 +251,9 @@ ;# {simple_build_permissions} {} {Allow building in parcel by access list (no groups)} {true false} false ;; More control over permissions ;; This is definitely not SL! - ;; Provides a simple control for land owners to give build rights to specific avatars - ;; in publicly accessible parcels that disallow object creation in general. + ;; Provides a simple control for land owners to give build rights to + ;; specific avatars in publicly accessible parcels that disallow object + ;; creation in general. ;; Owners specific avatars by adding them to the Access List of the parcel ;; without having to use the Groups feature ; simple_build_permissions = false @@ -266,11 +289,14 @@ ; DrawPrimOnMapTile = true ;# {HttpProxy} {} {Proxy URL for llHTTPRequest and dynamic texture loading} {} http://proxy.com:8080 - ;; Http proxy setting for llHTTPRequest and dynamic texture loading, if required + ;; Http proxy setting for llHTTPRequest and dynamic texture loading, if + ;; required ; HttpProxy = "http://proxy.com:8080" ;# {HttpProxyExceptions} {HttpProxy} {Set of regular expressions defining URL that should not be proxied} {} - ;; If you're using HttpProxy, then you can set HttpProxyExceptions to a list of regular expressions for URLs that you don't want to go through the proxy + ;; If you're using HttpProxy, then you can set HttpProxyExceptions to a + ;; list of regular expressions for URLs that you don't want to go through + ;; the proxy. ;; For example, servers inside your firewall. ;; Separate patterns with a ';' ; HttpProxyExceptions = ".mydomain.com;localhost" @@ -289,13 +315,15 @@ ; SpawnPointRouting = closest ;# {TelehubAllowLandmark} {} {Allow users with landmarks to override telehub routing} {true false} false - ;; TelehubAllowLandmark allows users with landmarks to override telehub routing and land at the landmark coordinates when set to true + ;; TelehubAllowLandmark allows users with landmarks to override telehub + ;; routing and land at the landmark coordinates when set to true ;; default is false ; TelehubAllowLandmark = false ;# {AllowedClients} {} {Bar (|) separated list of allowed clients} {} ;; Bar (|) separated list of viewers which may gain access to the regions. - ;; One can use a substring of the viewer name to enable only certain versions + ;; One can use a substring of the viewer name to enable only certain + ;; versions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" ;; - "Imprudence" has access ;; - "Imprudence 1.3" has access @@ -304,7 +332,8 @@ ;# {BannedClients} {} {Bar (|) separated list of banned clients} {} ;# Bar (|) separated list of viewers which may not gain access to the regions. - ;; One can use a Substring of the viewer name to disable only certain versions + ;; One can use a Substring of the viewer name to disable only certain + ;; versions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" ;; - "Imprudence" has no access ;; - "Imprudence 1.3" has no access @@ -450,7 +479,8 @@ [SimulatorFeatures] ;# {MapImageServerURI} {} {URL for the map server} {} - ; Experimental new information sent in SimulatorFeatures cap for Kokua viewers + ; Experimental new information sent in SimulatorFeatures cap for Kokua + ; viewers ; meant to override the MapImage and search server url given at login, and varying ; on a sim-basis. ; Viewers that don't understand it, will ignore it