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

connector_plugin
BlueWall 2012-09-25 18:14:06 -04:00
commit 4dc27aa91f
4 changed files with 364 additions and 191 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,73 @@ 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_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,20 +152,43 @@ 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 = new AssetBase() { FullID = assetID };
m_asset.Name = "blank"; m_asset.Name = "blank";
m_asset.Description = "empty"; m_asset.Description = "empty";
m_asset.Type = type; m_asset.Type = type;
@ -140,8 +197,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
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,14 +222,14 @@ 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); DoCreateItem(m_createItemCallback);
@ -185,17 +241,23 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
// Remove ourselves from the list of transactions if completion was delayed until the transaction // Remove ourselves from the list of transactions if completion was delayed until the transaction
// was complete. // was complete.
// TODO: Should probably do the same for create item. // TODO: Should probably do the same for create item.
m_transactions.RemoveXferUploader(TransactionID); m_transactions.RemoveXferUploader(m_transactionID);
} }
else if (m_storeLocal) else if (m_updateTaskItem)
{ {
m_Scene.AssetService.Store(m_asset); StoreAssetForTaskItemUpdate(m_updateTaskItemData);
m_transactions.RemoveXferUploader(m_transactionID);
} }
// 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 +285,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) DoCreateItem(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,7 +330,7 @@ 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); StoreAssetForItemUpdate(item);
} }
@ -287,8 +346,30 @@ 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)
{
StoreAssetForTaskItemUpdate(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 StoreAssetForItemUpdate(InventoryItemBase item)
@ -300,6 +381,19 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
} }
/// <summary>
/// Store the asset for the given task item when it has been uploaded.
/// </summary>
/// <param name="taskItem"></param>
private void StoreAssetForTaskItemUpdate(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);
}
private void DoCreateItem(uint callbackID) private void DoCreateItem(uint callbackID)
{ {
m_Scene.AssetService.Store(m_asset); m_Scene.AssetService.Store(m_asset);
@ -327,19 +421,5 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
else else
ourClient.SendAlertMessage("Unable to create inventory item"); ourClient.SendAlertMessage("Unable to create inventory item");
} }
/// <summary>
/// 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

@ -345,15 +345,58 @@ namespace OpenSim.Region.Framework.Scenes
public event StopScript OnStopScript; public event StopScript OnStopScript;
public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta); public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta);
/// <summary>
/// Triggered when an object is moved.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerGroupMove"/>
/// in <see cref="SceneObjectGroup.UpdateGroupPosition"/>,
/// <see cref="SceneObjectGroup.GrabMovement"/>
/// </remarks>
public event SceneGroupMoved OnSceneGroupMove; public event SceneGroupMoved OnSceneGroupMove;
public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID); public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID);
/// <summary>
/// Triggered when an object is grabbed.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerGroupGrab"/>
/// in <see cref="SceneObjectGroup.OnGrabGroup"/>
/// via <see cref="SceneObjectGroup.ObjectGrabHandler"/>
/// via <see cref="Scene.ProcessObjectGrab"/>
/// via <see cref="OpenSim.Framework.IClientAPI.OnGrabObject"/>
/// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleObjectGrab"/>
/// </remarks>
public event SceneGroupGrabed OnSceneGroupGrab; public event SceneGroupGrabed OnSceneGroupGrab;
public delegate bool SceneGroupSpinStarted(UUID groupID); public delegate bool SceneGroupSpinStarted(UUID groupID);
/// <summary>
/// Triggered when an object starts to spin.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerGroupSpinStart"/>
/// in <see cref="SceneObjectGroup.SpinStart"/>
/// via <see cref="SceneGraph.SpinStart"/>
/// via <see cref="OpenSim.Framework.IClientAPI.OnSpinStart"/>
/// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleObjectSpinStart"/>
/// </remarks>
public event SceneGroupSpinStarted OnSceneGroupSpinStart; public event SceneGroupSpinStarted OnSceneGroupSpinStart;
public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation); public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation);
/// <summary>
/// Triggered when an object is being spun.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerGroupSpin"/>
/// in <see cref="SceneObjectGroup.SpinMovement"/>
/// via <see cref="SceneGraph.SpinObject"/>
/// via <see cref="OpenSim.Framework.IClientAPI.OnSpinUpdate"/>
/// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleObjectSpinUpdate"/>
/// </remarks>
public event SceneGroupSpun OnSceneGroupSpin; public event SceneGroupSpun OnSceneGroupSpin;
public delegate void LandObjectAdded(ILandObject newParcel); public delegate void LandObjectAdded(ILandObject newParcel);
@ -460,36 +503,170 @@ namespace OpenSim.Region.Framework.Scenes
} }
/// <summary> /// <summary>
/// Triggered when some scene object properties change.
/// </summary>
/// <remarks>
/// ScriptChangedEvent is fired when a scene object property that a script might be interested /// ScriptChangedEvent is fired when a scene object property that a script might be interested
/// in (such as color, scale or inventory) changes. Only enough information sent is for the LSL changed event. /// in (such as color, scale or inventory) changes. Only enough information sent is for the LSL changed event.
/// This is not an indication that the script has changed (see OnUpdateScript for that). /// This is not an indication that the script has changed (see OnUpdateScript for that).
/// This event is sent to a script to tell it that some property changed on /// This event is sent to a script to tell it that some property changed on
/// the object the script is in. See http://lslwiki.net/lslwiki/wakka.php?wakka=changed . /// the object the script is in. See http://lslwiki.net/lslwiki/wakka.php?wakka=changed .
/// </summary> /// Triggered by <see cref="TriggerOnScriptChangedEvent"/>
/// in <see cref="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule.TeleportAgentWithinRegion"/>,
/// <see cref="SceneObjectPart.TriggerScriptChangedEvent"/>
/// </remarks>
public event ScriptChangedEvent OnScriptChangedEvent; public event ScriptChangedEvent OnScriptChangedEvent;
public delegate void ScriptChangedEvent(uint localID, uint change); public delegate void ScriptChangedEvent(uint localID, uint change);
public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed); public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed);
/// <summary>
/// Triggered when a script receives control input from an agent.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerControlEvent"/>
/// in <see cref="ScenePresence.SendControlsToScripts"/>
/// via <see cref="ScenePresence.HandleAgentUpdate"/>
/// via <see cref="OpenSim.Framework.IClientAPI.OnAgentUpdate"/>
/// via <see cref="OpenSim.Region.ClientStack.LindenUDP.LLClientView.HandleAgentUpdate"/>
/// </remarks>
public event ScriptControlEvent OnScriptControlEvent; public event ScriptControlEvent OnScriptControlEvent;
public delegate void ScriptAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 atpos); public delegate void ScriptAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 atpos);
/// <summary>
/// Triggered when an object has arrived within a tolerance distance
/// of a motion target.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerAtTargetEvent"/>
/// in <see cref="SceneObjectGroup.checkAtTargets"/>
/// via <see cref="SceneObjectGroup.ScheduleGroupForFullUpdate"/>,
/// <see cref="Scene.CheckAtTargets"/> via <see cref="Scene.Update"/>
/// </remarks>
public event ScriptAtTargetEvent OnScriptAtTargetEvent; public event ScriptAtTargetEvent OnScriptAtTargetEvent;
public delegate void ScriptNotAtTargetEvent(uint localID); public delegate void ScriptNotAtTargetEvent(uint localID);
/// <summary>
/// Triggered when an object has a motion target but has not arrived
/// within a tolerance distance.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerNotAtTargetEvent"/>
/// in <see cref="SceneObjectGroup.checkAtTargets"/>
/// via <see cref="SceneObjectGroup.ScheduleGroupForFullUpdate"/>,
/// <see cref="Scene.CheckAtTargets"/> via <see cref="Scene.Update"/>
/// </remarks>
public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent; public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent;
public delegate void ScriptAtRotTargetEvent(uint localID, uint handle, Quaternion targetrot, Quaternion atrot); public delegate void ScriptAtRotTargetEvent(uint localID, uint handle, Quaternion targetrot, Quaternion atrot);
/// <summary>
/// Triggered when an object has arrived within a tolerance rotation
/// of a rotation target.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerAtRotTargetEvent"/>
/// in <see cref="SceneObjectGroup.checkAtTargets"/>
/// via <see cref="SceneObjectGroup.ScheduleGroupForFullUpdate"/>,
/// <see cref="Scene.CheckAtTargets"/> via <see cref="Scene.Update"/>
/// </remarks>
public event ScriptAtRotTargetEvent OnScriptAtRotTargetEvent; public event ScriptAtRotTargetEvent OnScriptAtRotTargetEvent;
public delegate void ScriptNotAtRotTargetEvent(uint localID); public delegate void ScriptNotAtRotTargetEvent(uint localID);
/// <summary>
/// Triggered when an object has a rotation target but has not arrived
/// within a tolerance rotation.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerNotAtRotTargetEvent"/>
/// in <see cref="SceneObjectGroup.checkAtTargets"/>
/// via <see cref="SceneObjectGroup.ScheduleGroupForFullUpdate"/>,
/// <see cref="Scene.CheckAtTargets"/> via <see cref="Scene.Update"/>
/// </remarks>
public event ScriptNotAtRotTargetEvent OnScriptNotAtRotTargetEvent; public event ScriptNotAtRotTargetEvent OnScriptNotAtRotTargetEvent;
public delegate void ScriptColliding(uint localID, ColliderArgs colliders); public delegate void ScriptColliding(uint localID, ColliderArgs colliders);
/// <summary>
/// Triggered when a physical collision has started between a prim
/// and something other than the region terrain.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerScriptCollidingStart"/>
/// in <see cref="SceneObjectPart.SendCollisionEvent"/>
/// via <see cref="SceneObjectPart.PhysicsCollision"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
/// </remarks>
public event ScriptColliding OnScriptColliderStart; public event ScriptColliding OnScriptColliderStart;
/// <summary>
/// Triggered when something that previously collided with a prim has
/// not stopped colliding with it.
/// </summary>
/// <remarks>
/// <seealso cref="OnScriptColliderStart"/>
/// Triggered by <see cref="TriggerScriptColliding"/>
/// in <see cref="SceneObjectPart.SendCollisionEvent"/>
/// via <see cref="SceneObjectPart.PhysicsCollision"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
/// </remarks>
public event ScriptColliding OnScriptColliding; public event ScriptColliding OnScriptColliding;
/// <summary>
/// Triggered when something that previously collided with a prim has
/// stopped colliding with it.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerScriptCollidingEnd"/>
/// in <see cref="SceneObjectPart.SendCollisionEvent"/>
/// via <see cref="SceneObjectPart.PhysicsCollision"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
/// </remarks>
public event ScriptColliding OnScriptCollidingEnd; public event ScriptColliding OnScriptCollidingEnd;
/// <summary>
/// Triggered when a physical collision has started between an object
/// and the region terrain.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerScriptLandCollidingStart"/>
/// in <see cref="SceneObjectPart.SendLandCollisionEvent"/>
/// via <see cref="SceneObjectPart.PhysicsCollision"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
/// </remarks>
public event ScriptColliding OnScriptLandColliderStart; public event ScriptColliding OnScriptLandColliderStart;
/// <summary>
/// Triggered when an object that previously collided with the region
/// terrain has not yet stopped colliding with it.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerScriptLandColliding"/>
/// in <see cref="SceneObjectPart.SendLandCollisionEvent"/>
/// via <see cref="SceneObjectPart.PhysicsCollision"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
/// </remarks>
public event ScriptColliding OnScriptLandColliding; public event ScriptColliding OnScriptLandColliding;
/// <summary>
/// Triggered when an object that previously collided with the region
/// terrain has stopped colliding with it.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerScriptLandCollidingEnd"/>
/// in <see cref="SceneObjectPart.SendLandCollisionEvent"/>
/// via <see cref="SceneObjectPart.PhysicsCollision"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.OnCollisionUpdate"/>
/// via <see cref="OpenSim.Region.Physics.Manager.PhysicsActor.SendCollisionUpdate"/>
/// </remarks>
public event ScriptColliding OnScriptLandColliderEnd; public event ScriptColliding OnScriptLandColliderEnd;
public delegate void OnMakeChildAgentDelegate(ScenePresence presence); public delegate void OnMakeChildAgentDelegate(ScenePresence presence);
@ -550,6 +727,13 @@ namespace OpenSim.Region.Framework.Scenes
/* /*
public delegate void ScriptTimerEvent(uint localID, double timerinterval); public delegate void ScriptTimerEvent(uint localID, double timerinterval);
/// <summary>
/// Used to be triggered when the LSL timer event fires.
/// </summary>
/// <remarks>
/// Triggered by <see cref="TriggerTimerEvent"/>
/// via <see cref="SceneObjectPart.handleTimerAccounting"/>
/// </remarks>
public event ScriptTimerEvent OnScriptTimerEvent; public event ScriptTimerEvent OnScriptTimerEvent;
*/ */
@ -2293,7 +2477,11 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
// this lets us keep track of nasty script events like timer, etc. /// <summary>
/// this lets us keep track of nasty script events like timer, etc.
/// </summary>
/// <param name="objLocalID"></param>
/// <param name="Interval"></param>
public void TriggerTimerEvent(uint objLocalID, double Interval) public void TriggerTimerEvent(uint objLocalID, double Interval)
{ {
throw new NotImplementedException("TriggerTimerEvent was thought to be not used anymore and the registration for the event from scene object part has been commented out due to a memory leak"); throw new NotImplementedException("TriggerTimerEvent was thought to be not used anymore and the registration for the event from scene object part has been commented out due to a memory leak");