Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

connector_plugin
Diva Canto 2012-09-25 20:04:10 -07:00
commit 7d2cd0d935
4 changed files with 248 additions and 234 deletions

View File

@ -57,39 +57,36 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
} }
/// <summary> /// <summary>
/// Return a xfer uploader if one does not already exist. /// Return the xfer uploader for the given transaction.
/// </summary> /// </summary>
/// <remarks>
/// If an uploader does not already exist for this transaction then it is created, otherwise the existing
/// uploader is returned.
/// </remarks>
/// <param name="transactionID"></param> /// <param name="transactionID"></param>
/// <param name="assetID"> /// <returns>The asset xfer uploader</returns>
/// We must transfer the new asset ID into the uploader on creation, otherwise public AssetXferUploader RequestXferUploader(UUID transactionID)
/// we can see race conditions with other threads which can retrieve an item before it is updated with the new
/// asset id.
/// </param>
/// <returns>
/// 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.
/// </returns>
public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID)
{ {
AssetXferUploader uploader;
lock (XferUploaders) lock (XferUploaders)
{ {
if (!XferUploaders.ContainsKey(transactionID)) 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( // m_log.DebugFormat(
// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID); // "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID);
XferUploaders.Add(transactionID, uploader); 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 uploader;
return null;
} }
public void HandleXfer(ulong xferID, uint packetID, byte[] data) 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, string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask) sbyte type, byte wearableType, uint nextOwnerMask)
{ {
AssetXferUploader uploader = null; AssetXferUploader uploader = RequestXferUploader(transactionID);
lock (XferUploaders) uploader.RequestCreateInventoryItem(
{ remoteClient, folderID, callbackID,
if (XferUploaders.ContainsKey(transactionID)) description, name, invType, type, wearableType, nextOwnerMask);
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);
}
/// <summary>
/// Get an uploaded asset. If the data is successfully retrieved,
/// the transaction will be removed.
/// </summary>
/// <param name="transactionID"></param>
/// <returns>The asset if the upload has completed, null if it has not.</returns>
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;
} }
public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
SceneObjectPart part, UUID transactionID, SceneObjectPart part, UUID transactionID,
TaskInventoryItem item) TaskInventoryItem item)
{ {
AssetXferUploader uploader = null; AssetXferUploader uploader = RequestXferUploader(transactionID);
lock (XferUploaders) uploader.RequestUpdateTaskInventoryItem(remoteClient, item);
{
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);
}
} }
public void RequestUpdateInventoryItem(IClientAPI remoteClient, public void RequestUpdateInventoryItem(IClientAPI remoteClient,
UUID transactionID, InventoryItemBase item) UUID transactionID, InventoryItemBase item)
{ {
AssetXferUploader uploader = null; AssetXferUploader uploader = RequestXferUploader(transactionID);
lock (XferUploaders) uploader.RequestUpdateInventoryItem(remoteClient, item);
{
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);
}
} }
} }
} }

View File

@ -215,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
{ {
m_log.DebugFormat( 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); item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
AgentAssetTransactions transactions = AgentAssetTransactions transactions =
@ -274,13 +274,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
} }
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID); AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile);
if (uploader != null)
{
uploader.Initialise(remoteClient, assetID, transaction, type,
data, storeLocal, tempFile);
}
} }
/// <summary> /// <summary>

View File

@ -40,39 +40,75 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Upload state.
/// </summary>
/// <remarks>
/// New -> Uploading -> Complete
/// </remarks>
private enum UploadState
{
New,
Uploading,
Complete
}
/// <summary> /// <summary>
/// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
/// are performing a delayed update. /// are performing a delayed update.
/// </summary> /// </summary>
AgentAssetTransactions m_transactions; AgentAssetTransactions m_transactions;
private UploadState m_uploadState = UploadState.New;
private AssetBase m_asset; private AssetBase m_asset;
private UUID InventFolder = UUID.Zero; private UUID InventFolder = UUID.Zero;
private sbyte invType = 0; private sbyte invType = 0;
private bool m_createItem = false; private bool m_createItem;
private uint m_createItemCallback = 0; private uint m_createItemCallback;
private bool m_updateItem = false;
private bool m_updateItem;
private InventoryItemBase m_updateItemData; private InventoryItemBase m_updateItemData;
private bool m_updateTaskItem;
private TaskInventoryItem m_updateTaskItemData;
private string m_description = String.Empty; private string m_description = String.Empty;
private bool m_dumpAssetToFile; private bool m_dumpAssetToFile;
private bool m_finished = false;
private string m_name = String.Empty; private string m_name = String.Empty;
private bool m_storeLocal; // private bool m_storeLocal;
private uint nextPerm = 0; private uint nextPerm = 0;
private IClientAPI ourClient; private IClientAPI ourClient;
private UUID TransactionID = UUID.Zero;
private UUID m_transactionID;
private sbyte type = 0; private sbyte type = 0;
private byte wearableType = 0; private byte wearableType = 0;
public ulong XferID; public ulong XferID;
private Scene m_Scene; private Scene m_Scene;
public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) /// <summary>
/// AssetXferUploader constructor
/// </summary>
/// <param name='transactions'>/param>
/// <param name='scene'></param>
/// <param name='transactionID'></param>
/// <param name='dumpAssetToFile'>
/// 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.
/// </param>
public AssetXferUploader(
AgentAssetTransactions transactions, Scene scene, UUID transactionID, bool dumpAssetToFile)
{ {
m_asset = new AssetBase();
m_transactions = transactions; m_transactions = transactions;
m_transactionID = transactionID;
m_Scene = scene; m_Scene = scene;
m_asset = new AssetBase() { FullID = assetID };
m_dumpAssetToFile = dumpAssetToFile; m_dumpAssetToFile = dumpAssetToFile;
} }
@ -118,30 +154,50 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
} }
/// <summary> /// <summary>
/// Initialise asset transfer from the client /// Start asset transfer from the client
/// </summary> /// </summary>
/// <param name="xferID"></param> /// <param name="remoteClient"></param>
/// <param name="packetID"></param> /// <param name="assetID"></param>
/// <param name="data"></param> /// <param name="transaction"></param>
public void Initialise(IClientAPI remoteClient, UUID assetID, /// <param name="type"></param>
UUID transaction, sbyte type, byte[] data, bool storeLocal, /// <param name="data">
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.
/// </param>
/// <param name="storeLocal"></param>
/// <param name="tempFile"></param>
public void StartUpload(
IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal,
bool tempFile)
{ {
// m_log.DebugFormat( // 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}", // "[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); // 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; ourClient = remoteClient;
m_asset.Name = "blank";
m_asset.Description = "empty"; m_asset.FullID = assetID;
m_asset.Type = type; m_asset.Type = type;
m_asset.CreatorID = remoteClient.AgentId.ToString(); m_asset.CreatorID = remoteClient.AgentId.ToString();
m_asset.Data = data; m_asset.Data = data;
m_asset.Local = storeLocal; m_asset.Local = storeLocal;
m_asset.Temporary = tempFile; m_asset.Temporary = tempFile;
TransactionID = transaction; // m_storeLocal = storeLocal;
m_storeLocal = storeLocal;
if (m_asset.Data.Length > 2) if (m_asset.Data.Length > 2)
{ {
@ -166,36 +222,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
protected void SendCompleteMessage() 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 // 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. // message from other client UDP.
lock (this) lock (this)
{ {
m_finished = true; m_uploadState = UploadState.Complete;
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID);
if (m_createItem) if (m_createItem)
{ {
DoCreateItem(m_createItemCallback); CompleteCreateItem(m_createItemCallback);
} }
else if (m_updateItem) else if (m_updateItem)
{ {
StoreAssetForItemUpdate(m_updateItemData); CompleteItemUpdate(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);
} }
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( m_log.DebugFormat(
"[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
m_asset.FullID, TransactionID); m_asset.FullID, m_transactionID);
if (m_dumpAssetToFile) if (m_dumpAssetToFile)
{ {
@ -223,40 +278,37 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
} }
public void RequestCreateInventoryItem(IClientAPI remoteClient, public void RequestCreateInventoryItem(IClientAPI remoteClient,
UUID transactionID, UUID folderID, uint callbackID, UUID folderID, uint callbackID,
string description, string name, sbyte invType, string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask) sbyte type, byte wearableType, uint nextOwnerMask)
{ {
if (TransactionID == transactionID) InventFolder = folderID;
{ m_name = name;
InventFolder = folderID; m_description = description;
m_name = name; this.type = type;
m_description = description; this.invType = invType;
this.type = type; this.wearableType = wearableType;
this.invType = invType; nextPerm = nextOwnerMask;
this.wearableType = wearableType; m_asset.Name = name;
nextPerm = nextOwnerMask; m_asset.Description = description;
m_asset.Name = name; m_asset.Type = type;
m_asset.Description = description;
m_asset.Type = type;
// We must lock to avoid a race with a separate thread uploading the asset. // We must lock to avoid a race with a separate thread uploading the asset.
lock (this) lock (this)
{
if (m_uploadState == UploadState.Complete)
{ {
if (m_finished) CompleteCreateItem(callbackID);
{ }
DoCreateItem(callbackID); else
} {
else m_createItem = true; //set flag so the inventory item is created when upload is complete
{ m_createItemCallback = callbackID;
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. // We must lock to avoid a race with a separate thread uploading the asset.
lock (this) lock (this)
@ -271,9 +323,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
item.AssetID = m_asset.FullID; item.AssetID = m_asset.FullID;
m_Scene.InventoryService.UpdateItem(item); m_Scene.InventoryService.UpdateItem(item);
if (m_finished) if (m_uploadState == UploadState.Complete)
{ {
StoreAssetForItemUpdate(item); CompleteItemUpdate(item);
} }
else 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;
}
}
}
/// <summary> /// <summary>
/// Store the asset for the given item. /// Store the asset for the given item when it has been uploaded.
/// </summary> /// </summary>
/// <param name="item"></param> /// <param name="item"></param>
private void StoreAssetForItemUpdate(InventoryItemBase item) private void CompleteItemUpdate(InventoryItemBase item)
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
// m_asset.FullID, item.Name, ourClient.Name); // m_asset.FullID, item.Name, ourClient.Name);
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
m_transactions.RemoveXferUploader(m_transactionID);
} }
private void DoCreateItem(uint callbackID) /// <summary>
/// Store the asset for the given task item when it has been uploaded.
/// </summary>
/// <param name="taskItem"></param>
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); m_Scene.AssetService.Store(m_asset);
@ -326,20 +417,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
ourClient.SendInventoryItemCreateUpdate(item, callbackID); ourClient.SendInventoryItemCreateUpdate(item, callbackID);
else else
ourClient.SendAlertMessage("Unable to create inventory item"); ourClient.SendAlertMessage("Unable to create inventory item");
}
/// <summary> m_transactions.RemoveXferUploader(m_transactionID);
/// Get the asset data uploaded in this transfer.
/// </summary>
/// <returns>null if the asset has not finished uploading</returns>
public AssetBase GetAssetData()
{
if (m_finished)
{
return m_asset;
}
return null;
} }
} }
} }

View File

@ -1,19 +1,23 @@
;; This is the main configuration file for OpenSimulator. If it's named OpenSim.ini ;; This is the main configuration file for OpenSimulator.
;; then it will be loaded by OpenSimulator. If it's named OpenSim.ini.example then ;; If it's named OpenSim.ini then it will be loaded by OpenSimulator.
;; you will need to copy it to OpenSim.ini first (if that file does not already exist) ;; 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 ;; If you are copying, then once you have copied OpenSim.ini.example to
;; need to pick an architecture in the [Architecture] section at the end of this file. ;; 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 ;; The settings in this file are in the form "<key> = <value>". For example,
;; in the [Startup] section below. ;; save_crashes = false in the [Startup] section below.
;; ;;
;; All settings are initially commented out and the default value used, as found in ;; All settings are initially commented out and the default value used, as
;; OpenSimDefaults.ini. To change a setting, first uncomment it by deleting the initial semicolon (;) ;; found in OpenSimDefaults.ini. To change a setting, first uncomment it by
;; and then change the value. This will override the value in OpenSimDefaults.ini ;; 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 ;; If you want to find out what configuration OpenSimulator has finished with
;; files are loaded then type "config show" on the region console command line. ;; 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 ;; NOTES FOR DEVELOPERS REGARDING THE FORMAT OF THIS FILE
@ -26,13 +30,16 @@
;; formatted as: ;; formatted as:
;; {option} {depends on} {question to ask} {choices} default value ;; {option} {depends on} {question to ask} {choices} default value
;; Any text comments following the declaration, up to the next blank line. ;; 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. ;; A * in the choices list will allow an empty entry.
;; An empty question will set the default if the dependencies are ;; An empty question will set the default if the dependencies are
;; satisfied. ;; satisfied.
;; ;;
;; ; denotes a commented out option. ;; ; 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] [Startup]
@ -47,9 +54,12 @@
;# {save_crashes} {} {Save crashes to disk?} {true false} false ;# {save_crashes} {} {Save crashes to disk?} {true false} false
;; Set this to true if you want to log crashes to disk ;; Set this to true if you want to log crashes to disk
;; this can be useful when submitting bug reports. ;; this can be useful when submitting bug reports.
;; However, this will only log crashes within OpenSimulator that cause the entire program to exit ;; However, this will only log crashes within OpenSimulator that cause the
;; It will not log crashes caused by virtual machine failures, which includes mono and ODE failures. ;; entire program to exit
;; You will need to capture these native stack traces by recording the session log itself. ;; 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 ; save_crashes = false
;# {crash_dir} {save_crashes:true} {Directory to save crashes to?} {} crashes ;# {crash_dir} {save_crashes:true} {Directory to save crashes to?} {} crashes
@ -88,35 +98,46 @@
; allow_regionless = false ; allow_regionless = false
;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.001 ;# {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 ; NonPhysicalPrimMin = 0.001
;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256 ;# {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 ; NonPhysicalPrimMax = 256
;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10 ;# {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 ; PhysicalPrimMin = 0.01
;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10 ;# {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 ; PhysicalPrimMax = 10
;# {ClampPrimSize} {} {Clamp viewer rezzed prims to max sizes?} {true false} false ;# {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. ;; This can be overriden in the region config file.
; ClampPrimSize = false ; ClampPrimSize = false
;# {LinksetPrims} {} {Max prims an object will hold?} {} 0 ;# {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. ;; This can be overriden in the region config file.
; LinksetPrims = 0 ; LinksetPrims = 0
;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} true ;# {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. ;; Allow scripts to keep running when they cross region boundaries, rather
;; This only applies when crossing to a region running in a different simulator. ;; than being restarted. State is reloaded on the destination region.
;; For crossings where the regions are on the same simulator the script is always kept running. ;; 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 ; AllowScriptCrossing = true
;# {TrustBinaries} {AllowScriptCrossing:true} {Accept compiled binary script code? (DANGEROUS!)} {true false} false ;# {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 ;# {physics} {} {Select physics engine} {OpenDynamicsEngine BulletSim basicphysics POS} OpenDynamicsEngine
;; OpenDynamicsEngine is by some distance the most developed physics engine ;; OpenDynamicsEngine is by some distance the most developed physics engine
;; BulletSim is incomplete and experimental but in active development ;; 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 ;; Default is OpenDynamicsEngine
; physics = OpenDynamicsEngine ; physics = OpenDynamicsEngine
; physics = BulletSim ; physics = BulletSim
@ -229,8 +251,9 @@
;# {simple_build_permissions} {} {Allow building in parcel by access list (no groups)} {true false} false ;# {simple_build_permissions} {} {Allow building in parcel by access list (no groups)} {true false} false
;; More control over permissions ;; More control over permissions
;; This is definitely not SL! ;; This is definitely not SL!
;; Provides a simple control for land owners to give build rights to specific avatars ;; Provides a simple control for land owners to give build rights to
;; in publicly accessible parcels that disallow object creation in general. ;; 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 ;; Owners specific avatars by adding them to the Access List of the parcel
;; without having to use the Groups feature ;; without having to use the Groups feature
; simple_build_permissions = false ; simple_build_permissions = false
@ -266,11 +289,14 @@
; DrawPrimOnMapTile = true ; DrawPrimOnMapTile = true
;# {HttpProxy} {} {Proxy URL for llHTTPRequest and dynamic texture loading} {} http://proxy.com:8080 ;# {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" ; HttpProxy = "http://proxy.com:8080"
;# {HttpProxyExceptions} {HttpProxy} {Set of regular expressions defining URL that should not be proxied} {} ;# {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. ;; For example, servers inside your firewall.
;; Separate patterns with a ';' ;; Separate patterns with a ';'
; HttpProxyExceptions = ".mydomain.com;localhost" ; HttpProxyExceptions = ".mydomain.com;localhost"
@ -289,13 +315,15 @@
; SpawnPointRouting = closest ; SpawnPointRouting = closest
;# {TelehubAllowLandmark} {} {Allow users with landmarks to override telehub routing} {true false} false ;# {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 ;; default is false
; TelehubAllowLandmark = false ; TelehubAllowLandmark = false
;# {AllowedClients} {} {Bar (|) separated list of allowed clients} {} ;# {AllowedClients} {} {Bar (|) separated list of allowed clients} {}
;; Bar (|) separated list of viewers which may gain access to the regions. ;; 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" ;; Example: Agent uses the viewer "Imprudence 1.3.2.0"
;; - "Imprudence" has access ;; - "Imprudence" has access
;; - "Imprudence 1.3" has access ;; - "Imprudence 1.3" has access
@ -304,7 +332,8 @@
;# {BannedClients} {} {Bar (|) separated list of banned clients} {} ;# {BannedClients} {} {Bar (|) separated list of banned clients} {}
;# Bar (|) separated list of viewers which may not gain access to the regions. ;# 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" ;; Example: Agent uses the viewer "Imprudence 1.3.2.0"
;; - "Imprudence" has no access ;; - "Imprudence" has no access
;; - "Imprudence 1.3" has no access ;; - "Imprudence 1.3" has no access
@ -450,7 +479,8 @@
[SimulatorFeatures] [SimulatorFeatures]
;# {MapImageServerURI} {} {URL for the map server} {} ;# {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 ; meant to override the MapImage and search server url given at login, and varying
; on a sim-basis. ; on a sim-basis.
; Viewers that don't understand it, will ignore it ; Viewers that don't understand it, will ignore it