Prim inventory script saving phase 1. Create necessary CAPS structures for correctly accepting prim inventory script updates.

No user functionality yet.
Refactoring to follow.
afrisby
Justin Clarke Casey 2007-12-24 22:35:01 +00:00
parent fa2495ae6b
commit 280a5cba8b
7 changed files with 343 additions and 11 deletions

View File

@ -42,21 +42,29 @@ namespace OpenSim.Region.Capabilities
string inventoryType, string assetType);
public delegate LLUUID UpdateItem(LLUUID itemID, byte[] data);
public delegate LLUUID UpdateTaskScript(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data);
public delegate void NewInventoryItem(LLUUID userID, InventoryItemBase item);
public delegate LLUUID ItemUpdatedCallback(LLUUID userID, LLUUID itemID, byte[] data);
public delegate LLUUID TaskScriptUpdatedCallback(LLUUID userID, LLUUID itemID, LLUUID primID,
bool isScriptRunning, byte[] data);
public class Caps
{
private string m_httpListenerHostName;
private uint m_httpListenPort;
private string m_capsObjectPath = "00001-";
private string m_requestPath = "0000/";
private string m_mapLayerPath = "0001/";
private string m_newInventory = "0002/";
//private string m_requestTexture = "0003/";
private string m_notecardUpdatePath = "0004/";
private string m_notecardTaskUpdatePath = "0005/";
//private string eventQueue = "0100/";
private BaseHttpServer m_httpListener;
private LLUUID m_agentID;
@ -65,8 +73,11 @@ namespace OpenSim.Region.Capabilities
private Queue<string> m_capsEventQueue = new Queue<string>();
private bool m_dumpAssetsToFile;
// These are callbacks which will be setup by the scene so that we can update scene data when we
// receive capability calls
public NewInventoryItem AddNewInventoryItem = null;
public ItemUpdatedCallback ItemUpdatedCall = null;
public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
LLUUID agent, bool dumpAssetsToFile)
@ -100,9 +111,11 @@ namespace OpenSim.Region.Capabilities
AddLegacyCapsHandler(m_httpListener, m_requestPath, CapsRequest);
//AddLegacyCapsHandler(m_httpListener, m_requestTexture , RequestTexture);
AddLegacyCapsHandler(m_httpListener, m_notecardUpdatePath, NoteCardAgentInventory);
AddLegacyCapsHandler(m_httpListener, m_notecardTaskUpdatePath, ScriptTaskInventory);
}
catch
catch (Exception e)
{
MainLog.Instance.Error("CAPS", e.ToString());
}
}
@ -117,7 +130,7 @@ namespace OpenSim.Region.Capabilities
}
/// <summary>
///
/// Construct a client response detailing all the capabilities this server can provide.
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
@ -131,7 +144,7 @@ namespace OpenSim.Region.Capabilities
}
/// <summary>
///
/// Return an LLSDCapsDetails listing all the capabilities this server can provide
/// </summary>
/// <returns></returns>
protected LLSDCapsDetails GetCapabilities()
@ -144,7 +157,7 @@ namespace OpenSim.Region.Capabilities
caps.NewFileAgentInventory = capsBaseUrl + m_newInventory;
caps.UpdateNotecardAgentInventory = capsBaseUrl + m_notecardUpdatePath;
caps.UpdateScriptAgentInventory = capsBaseUrl + m_notecardUpdatePath;
// caps.UpdateScriptTaskInventory = capsBaseUrl + m_requestTexture;
caps.UpdateScriptTaskInventory = capsBaseUrl + m_notecardTaskUpdatePath;
return caps;
}
@ -249,9 +262,65 @@ namespace OpenSim.Region.Capabilities
}
#endregion
/// <summary>
/// Callback for a client request for an upload url for a script task
/// inventory update
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string ScriptTaskInventory(string request, string path, string param)
{
try
{
// MainLog.Instance.Debug("CAPS", "request: {0}, path: {1}, param: {2}", request, path, param);
Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Helpers.StringToField(request));
LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
LLSDHelpers.DeserialiseLLSDMap(hash, llsdUpdateRequest);
string capsBase = "/CAPS/" + m_capsObjectPath;
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
TaskInventoryScriptUpdater uploader =
new TaskInventoryScriptUpdater(
llsdUpdateRequest.item_id,
llsdUpdateRequest.task_id,
llsdUpdateRequest.is_script_running,
capsBase + uploaderPath,
m_httpListener,
m_dumpAssetsToFile);
uploader.OnUpLoad += TaskScriptUpdated;
m_httpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
uploaderPath;
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
uploadResponse.uploader = uploaderURL;
uploadResponse.state = "upload";
// MainLog.Instance.Verbose(
// "CAPS",
// "ScriptTaskInventory response: {0}",
// LLSDHelpers.SerialiseLLSDReply(uploadResponse));
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
}
catch (Exception e)
{
MainLog.Instance.Error("CAPS", e.ToString());
}
return null;
}
/// <summary>
///
/// Callback for a client request for an upload url for a notecard (or script)
/// agent inventory update
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
@ -265,11 +334,10 @@ namespace OpenSim.Region.Capabilities
LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest);
string capsBase = "/CAPS/" + m_capsObjectPath;
LLUUID newInvItem = llsdRequest.item_id;
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
ItemUpdater uploader =
new ItemUpdater(newInvItem, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile);
new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile);
uploader.OnUpLoad += ItemUpdated;
m_httpListener.AddStreamHandler(
@ -281,6 +349,8 @@ namespace OpenSim.Region.Capabilities
uploadResponse.uploader = uploaderURL;
uploadResponse.state = "upload";
MainLog.Instance.Verbose("CAPS", "NoteCardAgentInventory response: {0}", LLSDHelpers.SerialiseLLSDReply(uploadResponse));
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
}
@ -368,12 +438,36 @@ namespace OpenSim.Region.Capabilities
}
}
/// <summary>
/// Called when new asset data for an agent inventory item update has been uploaded.
/// </summary>
/// <param name="itemID">Item to update</param>
/// <param name="data">New asset data</param>
/// <returns></returns>
public LLUUID ItemUpdated(LLUUID itemID, byte[] data)
{
if (ItemUpdatedCall != null)
{
return ItemUpdatedCall(m_agentID, itemID, data);
}
return LLUUID.Zero;
}
/// <summary>
/// Called when new asset data for an agent inventory item update has been uploaded.
/// </summary>
/// <param name="itemID">Item to update</param>
/// <param name="primID">Prim containing item to update</param>
/// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
/// <param name="data">New asset data</param>
public LLUUID TaskScriptUpdated(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data)
{
if (TaskScriptUpdatedCall != null)
{
return TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data);
}
return LLUUID.Zero;
}
@ -452,6 +546,10 @@ namespace OpenSim.Region.Capabilities
}
}
/// <summary>
/// This class is a callback invoked when a client sends asset data to
/// an agent inventory notecard update url
/// </summary>
public class ItemUpdater
{
public event UpdateItem OnUpLoad;
@ -514,5 +612,96 @@ namespace OpenSim.Region.Capabilities
fs.Close();
}
}
/// <summary>
/// This class is a callback invoked when a client sends asset data to
/// a task inventory script update url
/// </summary>
public class TaskInventoryScriptUpdater
{
public event UpdateTaskScript OnUpLoad;
private string uploaderPath = "";
private LLUUID inventoryItemID;
private LLUUID primID;
private bool isScriptRunning;
private BaseHttpServer httpListener;
private bool m_dumpAssetToFile;
public TaskInventoryScriptUpdater(LLUUID inventoryItemID, LLUUID primID, int isScriptRunning,
string path, BaseHttpServer httpServer, bool dumpAssetToFile)
{
m_dumpAssetToFile = dumpAssetToFile;
this.inventoryItemID = inventoryItemID;
this.primID = primID;
// This comes in over the packet as an integer, but actually appears to be treated as a bool
this.isScriptRunning = (0 == isScriptRunning ? false : true);
uploaderPath = path;
httpListener = httpServer;
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string uploaderCaps(byte[] data, string path, string param)
{
try
{
// MainLog.Instance.Verbose(
// "CAPS",
// "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}",
// data, path, param);
string res = "";
LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete();
LLUUID assetID = LLUUID.Zero;
if (OnUpLoad != null)
{
assetID = OnUpLoad(inventoryItemID, primID, isScriptRunning, data);
}
uploadComplete.item_id = inventoryItemID;
uploadComplete.task_id = primID;
uploadComplete.state = "complete";
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
if (m_dumpAssetToFile)
{
SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data);
}
// MainLog.Instance.Verbose("CAPS", "TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
return res;
}
catch (Exception e)
{
MainLog.Instance.Error("CAPS", e.ToString());
}
// XXX Maybe this should be some meaningful error packet
return null;
}
private void SaveAssetToFile(string filename, byte[] data)
{
FileStream fs = File.Create(filename);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(data);
bw.Close();
fs.Close();
}
}
}
}

View File

@ -38,7 +38,7 @@ namespace OpenSim.Region.Capabilities
// public string ChatSessionRequest = "";
public string UpdateNotecardAgentInventory = "";
public string UpdateScriptAgentInventory = "";
// public string UpdateScriptTaskInventory = "";
public string UpdateScriptTaskInventory = "";
// public string ParcelVoiceInfoRequest = "";
public LLSDCapsDetails()

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using libsecondlife;
namespace OpenSim.Region.Capabilities
{
[LLSDMap]
public class LLSDTaskInventoryUploadComplete
{
/// <summary>
/// The task inventory item that was updated
/// </summary>
public LLUUID item_id;
/// <summary>
/// The task that was updated
/// </summary>
public LLUUID task_id;
/// <summary>
/// State of the upload. So far have only even seen this set to "complete"
/// </summary>
public string state;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using libsecondlife;
namespace OpenSim.Region.Capabilities
{
[LLSDMap]
public class LLSDTaskScriptUpdate
{
/// <summary>
/// The item containing the script to update
/// </summary>
public LLUUID item_id;
/// <summary>
/// The task containing the script
/// </summary>
public LLUUID task_id;
/// <summary>
/// Signals whether the script is currently active
/// </summary>
public int is_script_running;
}
}

View File

@ -260,7 +260,7 @@ namespace OpenSim.Framework.UserManagement
/// <param name="request">The users loginrequest</param>
public void CreateAgent(UserProfileData profile, XmlRpcRequest request)
{
Hashtable requestData = (Hashtable) request.Params[0];
//Hashtable requestData = (Hashtable) request.Params[0];
UserAgentData agent = new UserAgentData();

View File

@ -74,6 +74,13 @@ namespace OpenSim.Region.Environment.Scenes
return LLUUID.Zero;
}
/// <summary>
/// Capability originating call to update the asset of an item in an agent's inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="data"></param>
/// <returns></returns>
public LLUUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, LLUUID itemID, byte[] data)
{
CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
@ -106,6 +113,39 @@ namespace OpenSim.Region.Environment.Scenes
}
return LLUUID.Zero;
}
/// <summary>
/// Capability originating call to update the asset of a script in a prim's (task's) inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="primID">The prim which contains the item to update</param>
/// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
/// <param name="data"></param>
/// <returns>Asset LLUID created</returns>
public LLUUID CapsUpdateTaskInventoryScriptAsset(LLUUID avatarID, LLUUID itemID,
LLUUID primID, bool isScriptRunning, byte[] data)
{
// TODO Not currently doing anything with the isScriptRunning bool
MainLog.Instance.Verbose(
"PRIMINVENTORY",
"Prim inventory script save functionality not yet implemented."
+ " remoteClient: {0}, itemID: {1}, primID: {2}, isScriptRunning: {3}",
avatarID, itemID, primID, isScriptRunning);
// TODO
// Retrieve client LLUID
// Retrieve sog containing primID
// Retrieve item
// Create new asset and add to cache
// Update item with new asset
// Trigger SOG update (see RezScript)
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
// return new asset id
return null;
}
/// <summary>
/// Update an item which is either already in the client's inventory or is within
@ -470,7 +510,6 @@ namespace OpenSim.Region.Environment.Scenes
if (rezAsset != null)
{
string script = Util.FieldToString(rezAsset.Data);
//Console.WriteLine("rez script "+script);
EventManager.TriggerRezScript(localID, copyID, script);
rezzed = true;
}

View File

@ -1350,10 +1350,13 @@ namespace OpenSim.Region.Environment.Scenes
agent.CapsPath, agent.AgentID, m_dumpAssetsToFile);
Util.SetCapsURL(agent.AgentID, "http://" + m_regInfo.ExternalHostName + ":" + httpListener.Port.ToString() +
"/CAPS/" + agent.CapsPath + "0000/");
"/CAPS/" + agent.CapsPath + "0000/");
cap.RegisterHandlers();
cap.AddNewInventoryItem = AddInventoryItem;
cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset;
cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset;
if (m_capsHandlers.ContainsKey(agent.AgentID))
{
//MainLog.Instance.Warn("client", "Adding duplicate CAPS entry for user " +