diff options
author | diva | 2009-06-18 00:48:39 +0000 |
---|---|---|
committer | diva | 2009-06-18 00:48:39 +0000 |
commit | 913bc3bdb380cebebd11b657966486448962ab47 (patch) | |
tree | f41837093cd692b9fe42a21c9cb1473ef81dd0f1 /OpenSim/Framework/Capabilities/Caps.cs | |
parent | Fix an uninitialized data block. Thanks, jhurliman (diff) | |
download | opensim-SC-913bc3bdb380cebebd11b657966486448962ab47.zip opensim-SC-913bc3bdb380cebebd11b657966486448962ab47.tar.gz opensim-SC-913bc3bdb380cebebd11b657966486448962ab47.tar.bz2 opensim-SC-913bc3bdb380cebebd11b657966486448962ab47.tar.xz |
Moved OpenSim/Framework/Communications/Capabilities up to OpenSim/Framework/Capabilities. Didn't change the namespace because VC# is not helping, and this would imply manually changing more than 50 files. So the namespace is still OpenSim.Framework.Communications.Capabilities, to be cleaned up later by someone with more energy.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Capabilities/Caps.cs (renamed from OpenSim/Framework/Communications/Capabilities/Caps.cs) | 2424 |
1 files changed, 1212 insertions, 1212 deletions
diff --git a/OpenSim/Framework/Communications/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index 8c14e1d..bd38b50 100644 --- a/OpenSim/Framework/Communications/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs | |||
@@ -1,1212 +1,1212 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.IO; | 31 | using System.IO; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using log4net; | 33 | using log4net; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenSim.Framework.Servers; | 35 | using OpenSim.Framework.Servers; |
36 | using OpenSim.Framework.Servers.HttpServer; | 36 | using OpenSim.Framework.Servers.HttpServer; |
37 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
38 | 38 | ||
39 | // using OpenSim.Region.Framework.Interfaces; | 39 | // using OpenSim.Region.Framework.Interfaces; |
40 | 40 | ||
41 | namespace OpenSim.Framework.Communications.Capabilities | 41 | namespace OpenSim.Framework.Communications.Capabilities |
42 | { | 42 | { |
43 | public delegate void UpLoadedAsset( | 43 | public delegate void UpLoadedAsset( |
44 | string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, | 44 | string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, |
45 | byte[] data, string inventoryType, string assetType); | 45 | byte[] data, string inventoryType, string assetType); |
46 | 46 | ||
47 | public delegate UUID UpdateItem(UUID itemID, byte[] data); | 47 | public delegate UUID UpdateItem(UUID itemID, byte[] data); |
48 | 48 | ||
49 | public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data); | 49 | public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data); |
50 | 50 | ||
51 | public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); | 51 | public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); |
52 | 52 | ||
53 | public delegate void NewAsset(AssetBase asset); | 53 | public delegate void NewAsset(AssetBase asset); |
54 | 54 | ||
55 | public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data); | 55 | public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data); |
56 | 56 | ||
57 | public delegate void TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, | 57 | public delegate void TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, |
58 | bool isScriptRunning, byte[] data); | 58 | bool isScriptRunning, byte[] data); |
59 | 59 | ||
60 | public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, | 60 | public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, |
61 | bool fetchFolders, bool fetchItems, int sortOrder); | 61 | bool fetchFolders, bool fetchItems, int sortOrder); |
62 | 62 | ||
63 | /// <summary> | 63 | /// <summary> |
64 | /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that | 64 | /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that |
65 | /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want | 65 | /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want |
66 | /// to just pass the whole Scene into CAPS. | 66 | /// to just pass the whole Scene into CAPS. |
67 | /// </summary> | 67 | /// </summary> |
68 | public delegate IClientAPI GetClientDelegate(UUID agentID); | 68 | public delegate IClientAPI GetClientDelegate(UUID agentID); |
69 | 69 | ||
70 | public class Caps | 70 | public class Caps |
71 | { | 71 | { |
72 | private static readonly ILog m_log = | 72 | private static readonly ILog m_log = |
73 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 73 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
74 | 74 | ||
75 | private string m_httpListenerHostName; | 75 | private string m_httpListenerHostName; |
76 | private uint m_httpListenPort; | 76 | private uint m_httpListenPort; |
77 | 77 | ||
78 | /// <summary> | 78 | /// <summary> |
79 | /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester. | 79 | /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester. |
80 | /// </summary> | 80 | /// </summary> |
81 | private string m_capsObjectPath; | 81 | private string m_capsObjectPath; |
82 | public string CapsObjectPath { get { return m_capsObjectPath; } } | 82 | public string CapsObjectPath { get { return m_capsObjectPath; } } |
83 | 83 | ||
84 | private CapsHandlers m_capsHandlers; | 84 | private CapsHandlers m_capsHandlers; |
85 | 85 | ||
86 | private static readonly string m_requestPath = "0000/"; | 86 | private static readonly string m_requestPath = "0000/"; |
87 | // private static readonly string m_mapLayerPath = "0001/"; | 87 | // private static readonly string m_mapLayerPath = "0001/"; |
88 | private static readonly string m_newInventory = "0002/"; | 88 | private static readonly string m_newInventory = "0002/"; |
89 | //private static readonly string m_requestTexture = "0003/"; | 89 | //private static readonly string m_requestTexture = "0003/"; |
90 | private static readonly string m_notecardUpdatePath = "0004/"; | 90 | private static readonly string m_notecardUpdatePath = "0004/"; |
91 | private static readonly string m_notecardTaskUpdatePath = "0005/"; | 91 | private static readonly string m_notecardTaskUpdatePath = "0005/"; |
92 | // private static readonly string m_fetchInventoryPath = "0006/"; | 92 | // private static readonly string m_fetchInventoryPath = "0006/"; |
93 | 93 | ||
94 | // The following entries are in a module, however, they are also here so that we don't re-assign | 94 | // The following entries are in a module, however, they are also here so that we don't re-assign |
95 | // the path to another cap by mistake. | 95 | // the path to another cap by mistake. |
96 | // private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; // This is in a module. | 96 | // private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; // This is in a module. |
97 | // private static readonly string m_provisionVoiceAccountRequestPath = "0008/";// This is in a module. | 97 | // private static readonly string m_provisionVoiceAccountRequestPath = "0008/";// This is in a module. |
98 | 98 | ||
99 | // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. | 99 | // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. |
100 | 100 | ||
101 | //private string eventQueue = "0100/"; | 101 | //private string eventQueue = "0100/"; |
102 | private IHttpServer m_httpListener; | 102 | private IHttpServer m_httpListener; |
103 | private UUID m_agentID; | 103 | private UUID m_agentID; |
104 | private IAssetService m_assetCache; | 104 | private IAssetService m_assetCache; |
105 | private int m_eventQueueCount = 1; | 105 | private int m_eventQueueCount = 1; |
106 | private Queue<string> m_capsEventQueue = new Queue<string>(); | 106 | private Queue<string> m_capsEventQueue = new Queue<string>(); |
107 | private bool m_dumpAssetsToFile; | 107 | private bool m_dumpAssetsToFile; |
108 | private string m_regionName; | 108 | private string m_regionName; |
109 | 109 | ||
110 | public bool SSLCaps | 110 | public bool SSLCaps |
111 | { | 111 | { |
112 | get { return m_httpListener.UseSSL; } | 112 | get { return m_httpListener.UseSSL; } |
113 | } | 113 | } |
114 | public string SSLCommonName | 114 | public string SSLCommonName |
115 | { | 115 | { |
116 | get { return m_httpListener.SSLCommonName; } | 116 | get { return m_httpListener.SSLCommonName; } |
117 | } | 117 | } |
118 | public CapsHandlers CapsHandlers | 118 | public CapsHandlers CapsHandlers |
119 | { | 119 | { |
120 | get { return m_capsHandlers; } | 120 | get { return m_capsHandlers; } |
121 | } | 121 | } |
122 | 122 | ||
123 | // These are callbacks which will be setup by the scene so that we can update scene data when we | 123 | // These are callbacks which will be setup by the scene so that we can update scene data when we |
124 | // receive capability calls | 124 | // receive capability calls |
125 | public NewInventoryItem AddNewInventoryItem = null; | 125 | public NewInventoryItem AddNewInventoryItem = null; |
126 | public NewAsset AddNewAsset = null; | 126 | public NewAsset AddNewAsset = null; |
127 | public ItemUpdatedCallback ItemUpdatedCall = null; | 127 | public ItemUpdatedCallback ItemUpdatedCall = null; |
128 | public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; | 128 | public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null; |
129 | public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; | 129 | public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null; |
130 | public GetClientDelegate GetClient = null; | 130 | public GetClientDelegate GetClient = null; |
131 | 131 | ||
132 | public Caps(IAssetService assetCache, IHttpServer httpServer, string httpListen, uint httpPort, string capsPath, | 132 | public Caps(IAssetService assetCache, IHttpServer httpServer, string httpListen, uint httpPort, string capsPath, |
133 | UUID agent, bool dumpAssetsToFile, string regionName) | 133 | UUID agent, bool dumpAssetsToFile, string regionName) |
134 | { | 134 | { |
135 | m_assetCache = assetCache; | 135 | m_assetCache = assetCache; |
136 | m_capsObjectPath = capsPath; | 136 | m_capsObjectPath = capsPath; |
137 | m_httpListener = httpServer; | 137 | m_httpListener = httpServer; |
138 | m_httpListenerHostName = httpListen; | 138 | m_httpListenerHostName = httpListen; |
139 | 139 | ||
140 | m_httpListenPort = httpPort; | 140 | m_httpListenPort = httpPort; |
141 | 141 | ||
142 | if (httpServer.UseSSL) | 142 | if (httpServer.UseSSL) |
143 | { | 143 | { |
144 | m_httpListenPort = httpServer.SSLPort; | 144 | m_httpListenPort = httpServer.SSLPort; |
145 | httpListen = httpServer.SSLCommonName; | 145 | httpListen = httpServer.SSLCommonName; |
146 | httpPort = httpServer.SSLPort; | 146 | httpPort = httpServer.SSLPort; |
147 | } | 147 | } |
148 | 148 | ||
149 | m_agentID = agent; | 149 | m_agentID = agent; |
150 | m_dumpAssetsToFile = dumpAssetsToFile; | 150 | m_dumpAssetsToFile = dumpAssetsToFile; |
151 | m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, httpServer.UseSSL); | 151 | m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, httpServer.UseSSL); |
152 | m_regionName = regionName; | 152 | m_regionName = regionName; |
153 | } | 153 | } |
154 | 154 | ||
155 | /// <summary> | 155 | /// <summary> |
156 | /// Register all CAPS http service handlers | 156 | /// Register all CAPS http service handlers |
157 | /// </summary> | 157 | /// </summary> |
158 | public void RegisterHandlers() | 158 | public void RegisterHandlers() |
159 | { | 159 | { |
160 | DeregisterHandlers(); | 160 | DeregisterHandlers(); |
161 | 161 | ||
162 | string capsBase = "/CAPS/" + m_capsObjectPath; | 162 | string capsBase = "/CAPS/" + m_capsObjectPath; |
163 | 163 | ||
164 | RegisterRegionServiceHandlers(capsBase); | 164 | RegisterRegionServiceHandlers(capsBase); |
165 | RegisterInventoryServiceHandlers(capsBase); | 165 | RegisterInventoryServiceHandlers(capsBase); |
166 | 166 | ||
167 | } | 167 | } |
168 | 168 | ||
169 | public void RegisterRegionServiceHandlers(string capsBase) | 169 | public void RegisterRegionServiceHandlers(string capsBase) |
170 | { | 170 | { |
171 | try | 171 | try |
172 | { | 172 | { |
173 | // the root of all evil | 173 | // the root of all evil |
174 | m_capsHandlers["SEED"] = new RestStreamHandler("POST", capsBase + m_requestPath, CapsRequest); | 174 | m_capsHandlers["SEED"] = new RestStreamHandler("POST", capsBase + m_requestPath, CapsRequest); |
175 | m_log.DebugFormat( | 175 | m_log.DebugFormat( |
176 | "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_agentID); | 176 | "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_agentID); |
177 | 177 | ||
178 | //m_capsHandlers["MapLayer"] = | 178 | //m_capsHandlers["MapLayer"] = |
179 | // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST", | 179 | // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST", |
180 | // capsBase + m_mapLayerPath, | 180 | // capsBase + m_mapLayerPath, |
181 | // GetMapLayer); | 181 | // GetMapLayer); |
182 | m_capsHandlers["UpdateScriptTaskInventory"] = | 182 | m_capsHandlers["UpdateScriptTaskInventory"] = |
183 | new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); | 183 | new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); |
184 | m_capsHandlers["UpdateScriptTask"] = m_capsHandlers["UpdateScriptTaskInventory"]; | 184 | m_capsHandlers["UpdateScriptTask"] = m_capsHandlers["UpdateScriptTaskInventory"]; |
185 | 185 | ||
186 | } | 186 | } |
187 | catch (Exception e) | 187 | catch (Exception e) |
188 | { | 188 | { |
189 | m_log.Error("[CAPS]: " + e.ToString()); | 189 | m_log.Error("[CAPS]: " + e.ToString()); |
190 | } | 190 | } |
191 | } | 191 | } |
192 | 192 | ||
193 | public void RegisterInventoryServiceHandlers(string capsBase) | 193 | public void RegisterInventoryServiceHandlers(string capsBase) |
194 | { | 194 | { |
195 | try | 195 | try |
196 | { | 196 | { |
197 | // I don't think this one works... | 197 | // I don't think this one works... |
198 | m_capsHandlers["NewFileAgentInventory"] = | 198 | m_capsHandlers["NewFileAgentInventory"] = |
199 | new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST", | 199 | new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST", |
200 | capsBase + m_newInventory, | 200 | capsBase + m_newInventory, |
201 | NewAgentInventoryRequest); | 201 | NewAgentInventoryRequest); |
202 | m_capsHandlers["UpdateNotecardAgentInventory"] = | 202 | m_capsHandlers["UpdateNotecardAgentInventory"] = |
203 | new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); | 203 | new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); |
204 | m_capsHandlers["UpdateScriptAgentInventory"] = m_capsHandlers["UpdateNotecardAgentInventory"]; | 204 | m_capsHandlers["UpdateScriptAgentInventory"] = m_capsHandlers["UpdateNotecardAgentInventory"]; |
205 | m_capsHandlers["UpdateScriptAgent"] = m_capsHandlers["UpdateScriptAgentInventory"]; | 205 | m_capsHandlers["UpdateScriptAgent"] = m_capsHandlers["UpdateScriptAgentInventory"]; |
206 | 206 | ||
207 | // As of RC 1.22.9 of the Linden client this is | 207 | // As of RC 1.22.9 of the Linden client this is |
208 | // supported | 208 | // supported |
209 | 209 | ||
210 | // m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); | 210 | // m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest); |
211 | 211 | ||
212 | // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and | 212 | // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and |
213 | // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires | 213 | // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires |
214 | // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service, | 214 | // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service, |
215 | // but when I went on the Linden grid, the | 215 | // but when I went on the Linden grid, the |
216 | // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead, | 216 | // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead, |
217 | // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP | 217 | // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP |
218 | // | 218 | // |
219 | // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid | 219 | // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid |
220 | // we will be | 220 | // we will be |
221 | // able to get the data we need to implement the necessary part of the protocol to fix the issue above. | 221 | // able to get the data we need to implement the necessary part of the protocol to fix the issue above. |
222 | // m_capsHandlers["FetchInventoryDescendents"] = | 222 | // m_capsHandlers["FetchInventoryDescendents"] = |
223 | // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest); | 223 | // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest); |
224 | 224 | ||
225 | // m_capsHandlers["FetchInventoryDescendents"] = | 225 | // m_capsHandlers["FetchInventoryDescendents"] = |
226 | // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST", | 226 | // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST", |
227 | // capsBase + m_fetchInventory, | 227 | // capsBase + m_fetchInventory, |
228 | // FetchInventory)); | 228 | // FetchInventory)); |
229 | // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST", | 229 | // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST", |
230 | // capsBase + m_requestTexture, | 230 | // capsBase + m_requestTexture, |
231 | // RequestTexture); | 231 | // RequestTexture); |
232 | } | 232 | } |
233 | catch (Exception e) | 233 | catch (Exception e) |
234 | { | 234 | { |
235 | m_log.Error("[CAPS]: " + e.ToString()); | 235 | m_log.Error("[CAPS]: " + e.ToString()); |
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
239 | /// <summary> | 239 | /// <summary> |
240 | /// Register a handler. This allows modules to register handlers. | 240 | /// Register a handler. This allows modules to register handlers. |
241 | /// </summary> | 241 | /// </summary> |
242 | /// <param name="capName"></param> | 242 | /// <param name="capName"></param> |
243 | /// <param name="handler"></param> | 243 | /// <param name="handler"></param> |
244 | public void RegisterHandler(string capName, IRequestHandler handler) | 244 | public void RegisterHandler(string capName, IRequestHandler handler) |
245 | { | 245 | { |
246 | m_capsHandlers[capName] = handler; | 246 | m_capsHandlers[capName] = handler; |
247 | //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path); | 247 | //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path); |
248 | } | 248 | } |
249 | 249 | ||
250 | /// <summary> | 250 | /// <summary> |
251 | /// Remove all CAPS service handlers. | 251 | /// Remove all CAPS service handlers. |
252 | /// | 252 | /// |
253 | /// </summary> | 253 | /// </summary> |
254 | /// <param name="httpListener"></param> | 254 | /// <param name="httpListener"></param> |
255 | /// <param name="path"></param> | 255 | /// <param name="path"></param> |
256 | /// <param name="restMethod"></param> | 256 | /// <param name="restMethod"></param> |
257 | public void DeregisterHandlers() | 257 | public void DeregisterHandlers() |
258 | { | 258 | { |
259 | if (m_capsHandlers != null) | 259 | if (m_capsHandlers != null) |
260 | { | 260 | { |
261 | foreach (string capsName in m_capsHandlers.Caps) | 261 | foreach (string capsName in m_capsHandlers.Caps) |
262 | { | 262 | { |
263 | m_capsHandlers.Remove(capsName); | 263 | m_capsHandlers.Remove(capsName); |
264 | } | 264 | } |
265 | } | 265 | } |
266 | } | 266 | } |
267 | 267 | ||
268 | /// <summary> | 268 | /// <summary> |
269 | /// Construct a client response detailing all the capabilities this server can provide. | 269 | /// Construct a client response detailing all the capabilities this server can provide. |
270 | /// </summary> | 270 | /// </summary> |
271 | /// <param name="request"></param> | 271 | /// <param name="request"></param> |
272 | /// <param name="path"></param> | 272 | /// <param name="path"></param> |
273 | /// <param name="param"></param> | 273 | /// <param name="param"></param> |
274 | /// <param name="httpRequest">HTTP request header object</param> | 274 | /// <param name="httpRequest">HTTP request header object</param> |
275 | /// <param name="httpResponse">HTTP response header object</param> | 275 | /// <param name="httpResponse">HTTP response header object</param> |
276 | /// <returns></returns> | 276 | /// <returns></returns> |
277 | public string CapsRequest(string request, string path, string param, | 277 | public string CapsRequest(string request, string path, string param, |
278 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) | 278 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) |
279 | { | 279 | { |
280 | //m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); | 280 | //m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); |
281 | 281 | ||
282 | string result = LLSDHelpers.SerialiseLLSDReply(m_capsHandlers.CapsDetails); | 282 | string result = LLSDHelpers.SerialiseLLSDReply(m_capsHandlers.CapsDetails); |
283 | 283 | ||
284 | //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); | 284 | //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); |
285 | 285 | ||
286 | return result; | 286 | return result; |
287 | } | 287 | } |
288 | 288 | ||
289 | // FIXME: these all should probably go into the respective region | 289 | // FIXME: these all should probably go into the respective region |
290 | // modules | 290 | // modules |
291 | 291 | ||
292 | /// <summary> | 292 | /// <summary> |
293 | /// Processes a fetch inventory request and sends the reply | 293 | /// Processes a fetch inventory request and sends the reply |
294 | 294 | ||
295 | /// </summary> | 295 | /// </summary> |
296 | /// <param name="request"></param> | 296 | /// <param name="request"></param> |
297 | /// <param name="path"></param> | 297 | /// <param name="path"></param> |
298 | /// <param name="param"></param> | 298 | /// <param name="param"></param> |
299 | /// <returns></returns> | 299 | /// <returns></returns> |
300 | // Request is like: | 300 | // Request is like: |
301 | //<llsd> | 301 | //<llsd> |
302 | // <map><key>folders</key> | 302 | // <map><key>folders</key> |
303 | // <array> | 303 | // <array> |
304 | // <map> | 304 | // <map> |
305 | // <key>fetch-folders</key><boolean>1</boolean><key>fetch-items</key><boolean>1</boolean><key>folder-id</key><uuid>8e1e3a30-b9bf-11dc-95ff-0800200c9a66</uuid><key>owner-id</key><uuid>11111111-1111-0000-0000-000100bba000</uuid><key>sort-order</key><integer>1</integer> | 305 | // <key>fetch-folders</key><boolean>1</boolean><key>fetch-items</key><boolean>1</boolean><key>folder-id</key><uuid>8e1e3a30-b9bf-11dc-95ff-0800200c9a66</uuid><key>owner-id</key><uuid>11111111-1111-0000-0000-000100bba000</uuid><key>sort-order</key><integer>1</integer> |
306 | // </map> | 306 | // </map> |
307 | // </array> | 307 | // </array> |
308 | // </map> | 308 | // </map> |
309 | //</llsd> | 309 | //</llsd> |
310 | // | 310 | // |
311 | // multiple fetch-folder maps are allowed within the larger folders map. | 311 | // multiple fetch-folder maps are allowed within the larger folders map. |
312 | public string FetchInventoryRequest(string request, string path, string param) | 312 | public string FetchInventoryRequest(string request, string path, string param) |
313 | { | 313 | { |
314 | // string unmodifiedRequest = request.ToString(); | 314 | // string unmodifiedRequest = request.ToString(); |
315 | 315 | ||
316 | //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest); | 316 | //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest); |
317 | m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName); | 317 | m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName); |
318 | 318 | ||
319 | Hashtable hash = new Hashtable(); | 319 | Hashtable hash = new Hashtable(); |
320 | try | 320 | try |
321 | { | 321 | { |
322 | hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); | 322 | hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); |
323 | } | 323 | } |
324 | catch (LLSD.LLSDParseException pe) | 324 | catch (LLSD.LLSDParseException pe) |
325 | { | 325 | { |
326 | m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); | 326 | m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); |
327 | m_log.Error("Request: " + request.ToString()); | 327 | m_log.Error("Request: " + request.ToString()); |
328 | } | 328 | } |
329 | 329 | ||
330 | ArrayList foldersrequested = (ArrayList)hash["folders"]; | 330 | ArrayList foldersrequested = (ArrayList)hash["folders"]; |
331 | 331 | ||
332 | string response = ""; | 332 | string response = ""; |
333 | 333 | ||
334 | for (int i = 0; i < foldersrequested.Count; i++) | 334 | for (int i = 0; i < foldersrequested.Count; i++) |
335 | { | 335 | { |
336 | string inventoryitemstr = ""; | 336 | string inventoryitemstr = ""; |
337 | Hashtable inventoryhash = (Hashtable)foldersrequested[i]; | 337 | Hashtable inventoryhash = (Hashtable)foldersrequested[i]; |
338 | 338 | ||
339 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); | 339 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); |
340 | LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); | 340 | LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); |
341 | LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); | 341 | LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); |
342 | 342 | ||
343 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); | 343 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); |
344 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); | 344 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); |
345 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); | 345 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); |
346 | 346 | ||
347 | response += inventoryitemstr; | 347 | response += inventoryitemstr; |
348 | } | 348 | } |
349 | 349 | ||
350 | if (response.Length == 0) | 350 | if (response.Length == 0) |
351 | { | 351 | { |
352 | // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. | 352 | // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. |
353 | // Therefore, I'm concluding that the client only has so many threads available to do requests | 353 | // Therefore, I'm concluding that the client only has so many threads available to do requests |
354 | // and when a thread stalls.. is stays stalled. | 354 | // and when a thread stalls.. is stays stalled. |
355 | // Therefore we need to return something valid | 355 | // Therefore we need to return something valid |
356 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; | 356 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; |
357 | } | 357 | } |
358 | else | 358 | else |
359 | { | 359 | { |
360 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; | 360 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; |
361 | } | 361 | } |
362 | 362 | ||
363 | //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml"); | 363 | //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml"); |
364 | //m_log.Debug(Util.GetFormattedXml(response)); | 364 | //m_log.Debug(Util.GetFormattedXml(response)); |
365 | 365 | ||
366 | return response; | 366 | return response; |
367 | } | 367 | } |
368 | 368 | ||
369 | public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse) | 369 | public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse) |
370 | { | 370 | { |
371 | // m_log.Debug("[CAPS]: FetchInventoryDescendentsRequest in region: " + m_regionName + "request is "+request); | 371 | // m_log.Debug("[CAPS]: FetchInventoryDescendentsRequest in region: " + m_regionName + "request is "+request); |
372 | 372 | ||
373 | // nasty temporary hack here, the linden client falsely identifies the uuid 00000000-0000-0000-0000-000000000000 as a string which breaks us | 373 | // nasty temporary hack here, the linden client falsely identifies the uuid 00000000-0000-0000-0000-000000000000 as a string which breaks us |
374 | // correctly mark it as a uuid | 374 | // correctly mark it as a uuid |
375 | request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>"); | 375 | request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>"); |
376 | 376 | ||
377 | // another hack <integer>1</integer> results in a System.ArgumentException: Object type System.Int32 cannot be converted to target type: System.Boolean | 377 | // another hack <integer>1</integer> results in a System.ArgumentException: Object type System.Int32 cannot be converted to target type: System.Boolean |
378 | request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>"); | 378 | request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>"); |
379 | request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>"); | 379 | request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>"); |
380 | Hashtable hash = new Hashtable(); | 380 | Hashtable hash = new Hashtable(); |
381 | try | 381 | try |
382 | { | 382 | { |
383 | hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); | 383 | hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); |
384 | } | 384 | } |
385 | catch (LLSD.LLSDParseException pe) | 385 | catch (LLSD.LLSDParseException pe) |
386 | { | 386 | { |
387 | m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); | 387 | m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message); |
388 | m_log.Error("Request: " + request.ToString()); | 388 | m_log.Error("Request: " + request.ToString()); |
389 | } | 389 | } |
390 | 390 | ||
391 | ArrayList foldersrequested = (ArrayList)hash["folders"]; | 391 | ArrayList foldersrequested = (ArrayList)hash["folders"]; |
392 | 392 | ||
393 | string response = ""; | 393 | string response = ""; |
394 | for (int i = 0; i < foldersrequested.Count; i++) | 394 | for (int i = 0; i < foldersrequested.Count; i++) |
395 | { | 395 | { |
396 | string inventoryitemstr = ""; | 396 | string inventoryitemstr = ""; |
397 | Hashtable inventoryhash = (Hashtable)foldersrequested[i]; | 397 | Hashtable inventoryhash = (Hashtable)foldersrequested[i]; |
398 | 398 | ||
399 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); | 399 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); |
400 | 400 | ||
401 | try{ | 401 | try{ |
402 | LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); | 402 | LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); |
403 | } | 403 | } |
404 | catch(Exception e) | 404 | catch(Exception e) |
405 | { | 405 | { |
406 | m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); | 406 | m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e); |
407 | } | 407 | } |
408 | LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); | 408 | LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); |
409 | 409 | ||
410 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); | 410 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); |
411 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); | 411 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); |
412 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); | 412 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); |
413 | 413 | ||
414 | response += inventoryitemstr; | 414 | response += inventoryitemstr; |
415 | } | 415 | } |
416 | 416 | ||
417 | 417 | ||
418 | if (response.Length == 0) | 418 | if (response.Length == 0) |
419 | { | 419 | { |
420 | // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. | 420 | // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants. |
421 | // Therefore, I'm concluding that the client only has so many threads available to do requests | 421 | // Therefore, I'm concluding that the client only has so many threads available to do requests |
422 | // and when a thread stalls.. is stays stalled. | 422 | // and when a thread stalls.. is stays stalled. |
423 | // Therefore we need to return something valid | 423 | // Therefore we need to return something valid |
424 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; | 424 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; |
425 | } | 425 | } |
426 | else | 426 | else |
427 | { | 427 | { |
428 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; | 428 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; |
429 | } | 429 | } |
430 | 430 | ||
431 | //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); | 431 | //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml"); |
432 | //m_log.Debug("[CAPS] "+response); | 432 | //m_log.Debug("[CAPS] "+response); |
433 | 433 | ||
434 | return response; | 434 | return response; |
435 | } | 435 | } |
436 | 436 | ||
437 | 437 | ||
438 | 438 | ||
439 | /// <summary> | 439 | /// <summary> |
440 | /// Construct an LLSD reply packet to a CAPS inventory request | 440 | /// Construct an LLSD reply packet to a CAPS inventory request |
441 | /// </summary> | 441 | /// </summary> |
442 | /// <param name="invFetch"></param> | 442 | /// <param name="invFetch"></param> |
443 | /// <returns></returns> | 443 | /// <returns></returns> |
444 | private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) | 444 | private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) |
445 | { | 445 | { |
446 | LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); | 446 | LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); |
447 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); | 447 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); |
448 | contents.agent_id = m_agentID; | 448 | contents.agent_id = m_agentID; |
449 | contents.owner_id = invFetch.owner_id; | 449 | contents.owner_id = invFetch.owner_id; |
450 | contents.folder_id = invFetch.folder_id; | 450 | contents.folder_id = invFetch.folder_id; |
451 | 451 | ||
452 | // The version number being sent back was originally 1. | 452 | // The version number being sent back was originally 1. |
453 | // Unfortunately, on 1.19.1.4, this means that we see a problem where on subsequent logins | 453 | // Unfortunately, on 1.19.1.4, this means that we see a problem where on subsequent logins |
454 | // without clearing client cache, objects in the root folder disappear until the cache is cleared, | 454 | // without clearing client cache, objects in the root folder disappear until the cache is cleared, |
455 | // at which point they reappear. | 455 | // at which point they reappear. |
456 | // | 456 | // |
457 | // Seeing the version to something other than 0 may be the right thing to do, but there is | 457 | // Seeing the version to something other than 0 may be the right thing to do, but there is |
458 | // a greater subtlety of the second life protocol that needs to be understood first. | 458 | // a greater subtlety of the second life protocol that needs to be understood first. |
459 | contents.version = 0; | 459 | contents.version = 0; |
460 | 460 | ||
461 | contents.descendents = 0; | 461 | contents.descendents = 0; |
462 | reply.folders.Array.Add(contents); | 462 | reply.folders.Array.Add(contents); |
463 | List<InventoryItemBase> itemList = null; | 463 | List<InventoryItemBase> itemList = null; |
464 | if (CAPSFetchInventoryDescendents != null) | 464 | if (CAPSFetchInventoryDescendents != null) |
465 | { | 465 | { |
466 | itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order); | 466 | itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order); |
467 | } | 467 | } |
468 | 468 | ||
469 | if (itemList != null) | 469 | if (itemList != null) |
470 | { | 470 | { |
471 | foreach (InventoryItemBase invItem in itemList) | 471 | foreach (InventoryItemBase invItem in itemList) |
472 | { | 472 | { |
473 | contents.items.Array.Add(ConvertInventoryItem(invItem)); | 473 | contents.items.Array.Add(ConvertInventoryItem(invItem)); |
474 | } | 474 | } |
475 | } | 475 | } |
476 | /* The following block is removed as it ALWAYS sends the error to the client because the RC 1.22.9 client tries to | 476 | /* The following block is removed as it ALWAYS sends the error to the client because the RC 1.22.9 client tries to |
477 | find items that have become dissasociated with a paret folder and have parent of 00000000-0000-00000.... | 477 | find items that have become dissasociated with a paret folder and have parent of 00000000-0000-00000.... |
478 | else | 478 | else |
479 | { | 479 | { |
480 | IClientAPI client = GetClient(m_agentID); | 480 | IClientAPI client = GetClient(m_agentID); |
481 | 481 | ||
482 | // We're going to both notify the client of inventory service failure and send back a 'no folder contents' response. | 482 | // We're going to both notify the client of inventory service failure and send back a 'no folder contents' response. |
483 | // If we don't send back the response, | 483 | // If we don't send back the response, |
484 | // the client becomes unhappy (see Teravus' comment in FetchInventoryRequest()) | 484 | // the client becomes unhappy (see Teravus' comment in FetchInventoryRequest()) |
485 | if (client != null) | 485 | if (client != null) |
486 | { | 486 | { |
487 | client.SendAgentAlertMessage( | 487 | client.SendAgentAlertMessage( |
488 | "AGIN0001E: The inventory service has either failed or is not responding. Your inventory will not function properly for the rest of this session. Please clear your cache and relog.", | 488 | "AGIN0001E: The inventory service has either failed or is not responding. Your inventory will not function properly for the rest of this session. Please clear your cache and relog.", |
489 | true); | 489 | true); |
490 | } | 490 | } |
491 | else | 491 | else |
492 | { | 492 | { |
493 | m_log.ErrorFormat( | 493 | m_log.ErrorFormat( |
494 | "[AGENT INVENTORY]: Could not lookup controlling client for {0} in order to notify them of the inventory service failure", | 494 | "[AGENT INVENTORY]: Could not lookup controlling client for {0} in order to notify them of the inventory service failure", |
495 | m_agentID); | 495 | m_agentID); |
496 | } | 496 | } |
497 | }*/ | 497 | }*/ |
498 | 498 | ||
499 | contents.descendents = contents.items.Array.Count; | 499 | contents.descendents = contents.items.Array.Count; |
500 | return reply; | 500 | return reply; |
501 | } | 501 | } |
502 | 502 | ||
503 | /// <summary> | 503 | /// <summary> |
504 | /// Convert an internal inventory item object into an LLSD object. | 504 | /// Convert an internal inventory item object into an LLSD object. |
505 | /// </summary> | 505 | /// </summary> |
506 | /// <param name="invItem"></param> | 506 | /// <param name="invItem"></param> |
507 | /// <returns></returns> | 507 | /// <returns></returns> |
508 | private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) | 508 | private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) |
509 | { | 509 | { |
510 | LLSDInventoryItem llsdItem = new LLSDInventoryItem(); | 510 | LLSDInventoryItem llsdItem = new LLSDInventoryItem(); |
511 | llsdItem.asset_id = invItem.AssetID; | 511 | llsdItem.asset_id = invItem.AssetID; |
512 | llsdItem.created_at = invItem.CreationDate; | 512 | llsdItem.created_at = invItem.CreationDate; |
513 | llsdItem.desc = invItem.Description; | 513 | llsdItem.desc = invItem.Description; |
514 | llsdItem.flags = 0; | 514 | llsdItem.flags = 0; |
515 | llsdItem.item_id = invItem.ID; | 515 | llsdItem.item_id = invItem.ID; |
516 | llsdItem.name = invItem.Name; | 516 | llsdItem.name = invItem.Name; |
517 | llsdItem.parent_id = invItem.Folder; | 517 | llsdItem.parent_id = invItem.Folder; |
518 | try | 518 | try |
519 | { | 519 | { |
520 | // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. | 520 | // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions. |
521 | llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; | 521 | llsdItem.type = TaskInventoryItem.Types[invItem.AssetType]; |
522 | llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType]; | 522 | llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType]; |
523 | } | 523 | } |
524 | catch (Exception e) | 524 | catch (Exception e) |
525 | { | 525 | { |
526 | m_log.Error("[CAPS]: Problem setting asset/inventory type while converting inventory item " + invItem.Name + " to LLSD:", e); | 526 | m_log.Error("[CAPS]: Problem setting asset/inventory type while converting inventory item " + invItem.Name + " to LLSD:", e); |
527 | } | 527 | } |
528 | llsdItem.permissions = new LLSDPermissions(); | 528 | llsdItem.permissions = new LLSDPermissions(); |
529 | llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; | 529 | llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; |
530 | llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; | 530 | llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; |
531 | llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; | 531 | llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; |
532 | llsdItem.permissions.group_id = UUID.Zero; | 532 | llsdItem.permissions.group_id = UUID.Zero; |
533 | llsdItem.permissions.group_mask = 0; | 533 | llsdItem.permissions.group_mask = 0; |
534 | llsdItem.permissions.is_owner_group = false; | 534 | llsdItem.permissions.is_owner_group = false; |
535 | llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; | 535 | llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; |
536 | llsdItem.permissions.owner_id = m_agentID; // FixMe | 536 | llsdItem.permissions.owner_id = m_agentID; // FixMe |
537 | llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; | 537 | llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; |
538 | llsdItem.sale_info = new LLSDSaleInfo(); | 538 | llsdItem.sale_info = new LLSDSaleInfo(); |
539 | llsdItem.sale_info.sale_price = 10; | 539 | llsdItem.sale_info.sale_price = 10; |
540 | llsdItem.sale_info.sale_type = "not"; | 540 | llsdItem.sale_info.sale_type = "not"; |
541 | 541 | ||
542 | return llsdItem; | 542 | return llsdItem; |
543 | } | 543 | } |
544 | 544 | ||
545 | /// <summary> | 545 | /// <summary> |
546 | /// | 546 | /// |
547 | /// </summary> | 547 | /// </summary> |
548 | /// <param name="mapReq"></param> | 548 | /// <param name="mapReq"></param> |
549 | /// <returns></returns> | 549 | /// <returns></returns> |
550 | public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) | 550 | public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) |
551 | { | 551 | { |
552 | m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName); | 552 | m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName); |
553 | LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); | 553 | LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); |
554 | mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); | 554 | mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); |
555 | return mapResponse; | 555 | return mapResponse; |
556 | } | 556 | } |
557 | 557 | ||
558 | /// <summary> | 558 | /// <summary> |
559 | /// | 559 | /// |
560 | /// </summary> | 560 | /// </summary> |
561 | /// <returns></returns> | 561 | /// <returns></returns> |
562 | protected static OSDMapLayer GetOSDMapLayerResponse() | 562 | protected static OSDMapLayer GetOSDMapLayerResponse() |
563 | { | 563 | { |
564 | OSDMapLayer mapLayer = new OSDMapLayer(); | 564 | OSDMapLayer mapLayer = new OSDMapLayer(); |
565 | mapLayer.Right = 5000; | 565 | mapLayer.Right = 5000; |
566 | mapLayer.Top = 5000; | 566 | mapLayer.Top = 5000; |
567 | mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); | 567 | mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); |
568 | 568 | ||
569 | return mapLayer; | 569 | return mapLayer; |
570 | } | 570 | } |
571 | 571 | ||
572 | /// <summary> | 572 | /// <summary> |
573 | /// | 573 | /// |
574 | /// </summary> | 574 | /// </summary> |
575 | /// <param name="request"></param> | 575 | /// <param name="request"></param> |
576 | /// <param name="path"></param> | 576 | /// <param name="path"></param> |
577 | /// <param name="param"></param> | 577 | /// <param name="param"></param> |
578 | /// <returns></returns> | 578 | /// <returns></returns> |
579 | public string RequestTexture(string request, string path, string param) | 579 | public string RequestTexture(string request, string path, string param) |
580 | { | 580 | { |
581 | m_log.Debug("texture request " + request); | 581 | m_log.Debug("texture request " + request); |
582 | // Needs implementing (added to remove compiler warning) | 582 | // Needs implementing (added to remove compiler warning) |
583 | return String.Empty; | 583 | return String.Empty; |
584 | } | 584 | } |
585 | 585 | ||
586 | #region EventQueue (Currently not enabled) | 586 | #region EventQueue (Currently not enabled) |
587 | 587 | ||
588 | /// <summary> | 588 | /// <summary> |
589 | /// | 589 | /// |
590 | /// </summary> | 590 | /// </summary> |
591 | /// <param name="request"></param> | 591 | /// <param name="request"></param> |
592 | /// <param name="path"></param> | 592 | /// <param name="path"></param> |
593 | /// <param name="param"></param> | 593 | /// <param name="param"></param> |
594 | /// <returns></returns> | 594 | /// <returns></returns> |
595 | public string ProcessEventQueue(string request, string path, string param) | 595 | public string ProcessEventQueue(string request, string path, string param) |
596 | { | 596 | { |
597 | string res = String.Empty; | 597 | string res = String.Empty; |
598 | 598 | ||
599 | if (m_capsEventQueue.Count > 0) | 599 | if (m_capsEventQueue.Count > 0) |
600 | { | 600 | { |
601 | lock (m_capsEventQueue) | 601 | lock (m_capsEventQueue) |
602 | { | 602 | { |
603 | string item = m_capsEventQueue.Dequeue(); | 603 | string item = m_capsEventQueue.Dequeue(); |
604 | res = item; | 604 | res = item; |
605 | } | 605 | } |
606 | } | 606 | } |
607 | else | 607 | else |
608 | { | 608 | { |
609 | res = CreateEmptyEventResponse(); | 609 | res = CreateEmptyEventResponse(); |
610 | } | 610 | } |
611 | return res; | 611 | return res; |
612 | } | 612 | } |
613 | 613 | ||
614 | /// <summary> | 614 | /// <summary> |
615 | /// | 615 | /// |
616 | /// </summary> | 616 | /// </summary> |
617 | /// <param name="caps"></param> | 617 | /// <param name="caps"></param> |
618 | /// <param name="ipAddressPort"></param> | 618 | /// <param name="ipAddressPort"></param> |
619 | /// <returns></returns> | 619 | /// <returns></returns> |
620 | public string CreateEstablishAgentComms(string caps, string ipAddressPort) | 620 | public string CreateEstablishAgentComms(string caps, string ipAddressPort) |
621 | { | 621 | { |
622 | LLSDCapEvent eventItem = new LLSDCapEvent(); | 622 | LLSDCapEvent eventItem = new LLSDCapEvent(); |
623 | eventItem.id = m_eventQueueCount; | 623 | eventItem.id = m_eventQueueCount; |
624 | //should be creating a EstablishAgentComms item, but there isn't a class for it yet | 624 | //should be creating a EstablishAgentComms item, but there isn't a class for it yet |
625 | eventItem.events.Array.Add(new LLSDEmpty()); | 625 | eventItem.events.Array.Add(new LLSDEmpty()); |
626 | string res = LLSDHelpers.SerialiseLLSDReply(eventItem); | 626 | string res = LLSDHelpers.SerialiseLLSDReply(eventItem); |
627 | m_eventQueueCount++; | 627 | m_eventQueueCount++; |
628 | 628 | ||
629 | m_capsEventQueue.Enqueue(res); | 629 | m_capsEventQueue.Enqueue(res); |
630 | return res; | 630 | return res; |
631 | } | 631 | } |
632 | 632 | ||
633 | /// <summary> | 633 | /// <summary> |
634 | /// | 634 | /// |
635 | /// </summary> | 635 | /// </summary> |
636 | /// <returns></returns> | 636 | /// <returns></returns> |
637 | public string CreateEmptyEventResponse() | 637 | public string CreateEmptyEventResponse() |
638 | { | 638 | { |
639 | LLSDCapEvent eventItem = new LLSDCapEvent(); | 639 | LLSDCapEvent eventItem = new LLSDCapEvent(); |
640 | eventItem.id = m_eventQueueCount; | 640 | eventItem.id = m_eventQueueCount; |
641 | eventItem.events.Array.Add(new LLSDEmpty()); | 641 | eventItem.events.Array.Add(new LLSDEmpty()); |
642 | string res = LLSDHelpers.SerialiseLLSDReply(eventItem); | 642 | string res = LLSDHelpers.SerialiseLLSDReply(eventItem); |
643 | m_eventQueueCount++; | 643 | m_eventQueueCount++; |
644 | return res; | 644 | return res; |
645 | } | 645 | } |
646 | 646 | ||
647 | #endregion | 647 | #endregion |
648 | 648 | ||
649 | /// <summary> | 649 | /// <summary> |
650 | /// Called by the script task update handler. Provides a URL to which the client can upload a new asset. | 650 | /// Called by the script task update handler. Provides a URL to which the client can upload a new asset. |
651 | /// </summary> | 651 | /// </summary> |
652 | /// <param name="request"></param> | 652 | /// <param name="request"></param> |
653 | /// <param name="path"></param> | 653 | /// <param name="path"></param> |
654 | /// <param name="param"></param> | 654 | /// <param name="param"></param> |
655 | /// <param name="httpRequest">HTTP request header object</param> | 655 | /// <param name="httpRequest">HTTP request header object</param> |
656 | /// <param name="httpResponse">HTTP response header object</param> | 656 | /// <param name="httpResponse">HTTP response header object</param> |
657 | /// <returns></returns> | 657 | /// <returns></returns> |
658 | public string ScriptTaskInventory(string request, string path, string param, | 658 | public string ScriptTaskInventory(string request, string path, string param, |
659 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) | 659 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) |
660 | { | 660 | { |
661 | try | 661 | try |
662 | { | 662 | { |
663 | m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName); | 663 | m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName); |
664 | //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); | 664 | //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); |
665 | 665 | ||
666 | Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request)); | 666 | Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request)); |
667 | LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); | 667 | LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); |
668 | LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest); | 668 | LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest); |
669 | 669 | ||
670 | string capsBase = "/CAPS/" + m_capsObjectPath; | 670 | string capsBase = "/CAPS/" + m_capsObjectPath; |
671 | string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); | 671 | string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); |
672 | 672 | ||
673 | TaskInventoryScriptUpdater uploader = | 673 | TaskInventoryScriptUpdater uploader = |
674 | new TaskInventoryScriptUpdater( | 674 | new TaskInventoryScriptUpdater( |
675 | llsdUpdateRequest.item_id, | 675 | llsdUpdateRequest.item_id, |
676 | llsdUpdateRequest.task_id, | 676 | llsdUpdateRequest.task_id, |
677 | llsdUpdateRequest.is_script_running, | 677 | llsdUpdateRequest.is_script_running, |
678 | capsBase + uploaderPath, | 678 | capsBase + uploaderPath, |
679 | m_httpListener, | 679 | m_httpListener, |
680 | m_dumpAssetsToFile); | 680 | m_dumpAssetsToFile); |
681 | uploader.OnUpLoad += TaskScriptUpdated; | 681 | uploader.OnUpLoad += TaskScriptUpdated; |
682 | 682 | ||
683 | m_httpListener.AddStreamHandler( | 683 | m_httpListener.AddStreamHandler( |
684 | new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); | 684 | new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); |
685 | 685 | ||
686 | string protocol = "http://"; | 686 | string protocol = "http://"; |
687 | 687 | ||
688 | if (m_httpListener.UseSSL) | 688 | if (m_httpListener.UseSSL) |
689 | protocol = "https://"; | 689 | protocol = "https://"; |
690 | 690 | ||
691 | string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + | 691 | string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + |
692 | uploaderPath; | 692 | uploaderPath; |
693 | 693 | ||
694 | LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); | 694 | LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); |
695 | uploadResponse.uploader = uploaderURL; | 695 | uploadResponse.uploader = uploaderURL; |
696 | uploadResponse.state = "upload"; | 696 | uploadResponse.state = "upload"; |
697 | 697 | ||
698 | // m_log.InfoFormat("[CAPS]: " + | 698 | // m_log.InfoFormat("[CAPS]: " + |
699 | // "ScriptTaskInventory response: {0}", | 699 | // "ScriptTaskInventory response: {0}", |
700 | // LLSDHelpers.SerialiseLLSDReply(uploadResponse))); | 700 | // LLSDHelpers.SerialiseLLSDReply(uploadResponse))); |
701 | 701 | ||
702 | return LLSDHelpers.SerialiseLLSDReply(uploadResponse); | 702 | return LLSDHelpers.SerialiseLLSDReply(uploadResponse); |
703 | } | 703 | } |
704 | catch (Exception e) | 704 | catch (Exception e) |
705 | { | 705 | { |
706 | m_log.Error("[CAPS]: " + e.ToString()); | 706 | m_log.Error("[CAPS]: " + e.ToString()); |
707 | } | 707 | } |
708 | 708 | ||
709 | return null; | 709 | return null; |
710 | } | 710 | } |
711 | 711 | ||
712 | /// <summary> | 712 | /// <summary> |
713 | /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset. | 713 | /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset. |
714 | /// </summary> | 714 | /// </summary> |
715 | /// <param name="request"></param> | 715 | /// <param name="request"></param> |
716 | /// <param name="path"></param> | 716 | /// <param name="path"></param> |
717 | /// <param name="param"></param> | 717 | /// <param name="param"></param> |
718 | /// <returns></returns> | 718 | /// <returns></returns> |
719 | public string NoteCardAgentInventory(string request, string path, string param, | 719 | public string NoteCardAgentInventory(string request, string path, string param, |
720 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) | 720 | OSHttpRequest httpRequest, OSHttpResponse httpResponse) |
721 | { | 721 | { |
722 | //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request); | 722 | //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request); |
723 | //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request); | 723 | //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request); |
724 | 724 | ||
725 | //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request)); | 725 | //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request)); |
726 | Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request)); | 726 | Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request)); |
727 | LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); | 727 | LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); |
728 | LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest); | 728 | LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest); |
729 | 729 | ||
730 | string capsBase = "/CAPS/" + m_capsObjectPath; | 730 | string capsBase = "/CAPS/" + m_capsObjectPath; |
731 | string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); | 731 | string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); |
732 | 732 | ||
733 | ItemUpdater uploader = | 733 | ItemUpdater uploader = |
734 | new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); | 734 | new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); |
735 | uploader.OnUpLoad += ItemUpdated; | 735 | uploader.OnUpLoad += ItemUpdated; |
736 | 736 | ||
737 | m_httpListener.AddStreamHandler( | 737 | m_httpListener.AddStreamHandler( |
738 | new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); | 738 | new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); |
739 | 739 | ||
740 | string protocol = "http://"; | 740 | string protocol = "http://"; |
741 | 741 | ||
742 | if (m_httpListener.UseSSL) | 742 | if (m_httpListener.UseSSL) |
743 | protocol = "https://"; | 743 | protocol = "https://"; |
744 | 744 | ||
745 | string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + | 745 | string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + |
746 | uploaderPath; | 746 | uploaderPath; |
747 | 747 | ||
748 | LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); | 748 | LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); |
749 | uploadResponse.uploader = uploaderURL; | 749 | uploadResponse.uploader = uploaderURL; |
750 | uploadResponse.state = "upload"; | 750 | uploadResponse.state = "upload"; |
751 | 751 | ||
752 | // m_log.InfoFormat("[CAPS]: " + | 752 | // m_log.InfoFormat("[CAPS]: " + |
753 | // "NoteCardAgentInventory response: {0}", | 753 | // "NoteCardAgentInventory response: {0}", |
754 | // LLSDHelpers.SerialiseLLSDReply(uploadResponse))); | 754 | // LLSDHelpers.SerialiseLLSDReply(uploadResponse))); |
755 | 755 | ||
756 | return LLSDHelpers.SerialiseLLSDReply(uploadResponse); | 756 | return LLSDHelpers.SerialiseLLSDReply(uploadResponse); |
757 | } | 757 | } |
758 | 758 | ||
759 | /// <summary> | 759 | /// <summary> |
760 | /// | 760 | /// |
761 | /// </summary> | 761 | /// </summary> |
762 | /// <param name="llsdRequest"></param> | 762 | /// <param name="llsdRequest"></param> |
763 | /// <returns></returns> | 763 | /// <returns></returns> |
764 | public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest) | 764 | public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest) |
765 | { | 765 | { |
766 | //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); | 766 | //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); |
767 | //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); | 767 | //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); |
768 | 768 | ||
769 | if (llsdRequest.asset_type == "texture" || | 769 | if (llsdRequest.asset_type == "texture" || |
770 | llsdRequest.asset_type == "animation" || | 770 | llsdRequest.asset_type == "animation" || |
771 | llsdRequest.asset_type == "sound") | 771 | llsdRequest.asset_type == "sound") |
772 | { | 772 | { |
773 | IClientAPI client = null; | 773 | IClientAPI client = null; |
774 | IScene scene = null; | 774 | IScene scene = null; |
775 | if (GetClient != null) | 775 | if (GetClient != null) |
776 | { | 776 | { |
777 | client = GetClient(m_agentID); | 777 | client = GetClient(m_agentID); |
778 | scene = client.Scene; | 778 | scene = client.Scene; |
779 | 779 | ||
780 | IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>(); | 780 | IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>(); |
781 | 781 | ||
782 | if (mm != null) | 782 | if (mm != null) |
783 | { | 783 | { |
784 | if (!mm.UploadCovered(client)) | 784 | if (!mm.UploadCovered(client)) |
785 | { | 785 | { |
786 | if (client != null) | 786 | if (client != null) |
787 | client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); | 787 | client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); |
788 | 788 | ||
789 | LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); | 789 | LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); |
790 | errorResponse.uploader = ""; | 790 | errorResponse.uploader = ""; |
791 | errorResponse.state = "error"; | 791 | errorResponse.state = "error"; |
792 | return errorResponse; | 792 | return errorResponse; |
793 | } | 793 | } |
794 | } | 794 | } |
795 | } | 795 | } |
796 | } | 796 | } |
797 | 797 | ||
798 | 798 | ||
799 | string assetName = llsdRequest.name; | 799 | string assetName = llsdRequest.name; |
800 | string assetDes = llsdRequest.description; | 800 | string assetDes = llsdRequest.description; |
801 | string capsBase = "/CAPS/" + m_capsObjectPath; | 801 | string capsBase = "/CAPS/" + m_capsObjectPath; |
802 | UUID newAsset = UUID.Random(); | 802 | UUID newAsset = UUID.Random(); |
803 | UUID newInvItem = UUID.Random(); | 803 | UUID newInvItem = UUID.Random(); |
804 | UUID parentFolder = llsdRequest.folder_id; | 804 | UUID parentFolder = llsdRequest.folder_id; |
805 | string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); | 805 | string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); |
806 | 806 | ||
807 | AssetUploader uploader = | 807 | AssetUploader uploader = |
808 | new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, | 808 | new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, |
809 | llsdRequest.asset_type, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); | 809 | llsdRequest.asset_type, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile); |
810 | m_httpListener.AddStreamHandler( | 810 | m_httpListener.AddStreamHandler( |
811 | new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); | 811 | new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); |
812 | 812 | ||
813 | string protocol = "http://"; | 813 | string protocol = "http://"; |
814 | 814 | ||
815 | if (m_httpListener.UseSSL) | 815 | if (m_httpListener.UseSSL) |
816 | protocol = "https://"; | 816 | protocol = "https://"; |
817 | 817 | ||
818 | string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + | 818 | string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + |
819 | uploaderPath; | 819 | uploaderPath; |
820 | 820 | ||
821 | LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); | 821 | LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); |
822 | uploadResponse.uploader = uploaderURL; | 822 | uploadResponse.uploader = uploaderURL; |
823 | uploadResponse.state = "upload"; | 823 | uploadResponse.state = "upload"; |
824 | uploader.OnUpLoad += UploadCompleteHandler; | 824 | uploader.OnUpLoad += UploadCompleteHandler; |
825 | return uploadResponse; | 825 | return uploadResponse; |
826 | } | 826 | } |
827 | 827 | ||
828 | /// <summary> | 828 | /// <summary> |
829 | /// | 829 | /// |
830 | /// </summary> | 830 | /// </summary> |
831 | /// <param name="assetID"></param> | 831 | /// <param name="assetID"></param> |
832 | /// <param name="inventoryItem"></param> | 832 | /// <param name="inventoryItem"></param> |
833 | /// <param name="data"></param> | 833 | /// <param name="data"></param> |
834 | public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, | 834 | public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, |
835 | UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, | 835 | UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, |
836 | string assetType) | 836 | string assetType) |
837 | { | 837 | { |
838 | sbyte assType = 0; | 838 | sbyte assType = 0; |
839 | sbyte inType = 0; | 839 | sbyte inType = 0; |
840 | 840 | ||
841 | if (inventoryType == "sound") | 841 | if (inventoryType == "sound") |
842 | { | 842 | { |
843 | inType = 1; | 843 | inType = 1; |
844 | assType = 1; | 844 | assType = 1; |
845 | } | 845 | } |
846 | else if (inventoryType == "animation") | 846 | else if (inventoryType == "animation") |
847 | { | 847 | { |
848 | inType = 19; | 848 | inType = 19; |
849 | assType = 20; | 849 | assType = 20; |
850 | } | 850 | } |
851 | else if (inventoryType == "wearable") | 851 | else if (inventoryType == "wearable") |
852 | { | 852 | { |
853 | inType = 18; | 853 | inType = 18; |
854 | switch (assetType) | 854 | switch (assetType) |
855 | { | 855 | { |
856 | case "bodypart": | 856 | case "bodypart": |
857 | assType = 13; | 857 | assType = 13; |
858 | break; | 858 | break; |
859 | case "clothing": | 859 | case "clothing": |
860 | assType = 5; | 860 | assType = 5; |
861 | break; | 861 | break; |
862 | } | 862 | } |
863 | } | 863 | } |
864 | 864 | ||
865 | AssetBase asset; | 865 | AssetBase asset; |
866 | asset = new AssetBase(); | 866 | asset = new AssetBase(); |
867 | asset.FullID = assetID; | 867 | asset.FullID = assetID; |
868 | asset.Type = assType; | 868 | asset.Type = assType; |
869 | asset.Name = assetName; | 869 | asset.Name = assetName; |
870 | asset.Data = data; | 870 | asset.Data = data; |
871 | if (AddNewAsset != null) | 871 | if (AddNewAsset != null) |
872 | AddNewAsset(asset); | 872 | AddNewAsset(asset); |
873 | else if (m_assetCache != null) | 873 | else if (m_assetCache != null) |
874 | m_assetCache.Store(asset); | 874 | m_assetCache.Store(asset); |
875 | 875 | ||
876 | InventoryItemBase item = new InventoryItemBase(); | 876 | InventoryItemBase item = new InventoryItemBase(); |
877 | item.Owner = m_agentID; | 877 | item.Owner = m_agentID; |
878 | item.CreatorId = m_agentID.ToString(); | 878 | item.CreatorId = m_agentID.ToString(); |
879 | item.ID = inventoryItem; | 879 | item.ID = inventoryItem; |
880 | item.AssetID = asset.FullID; | 880 | item.AssetID = asset.FullID; |
881 | item.Description = assetDescription; | 881 | item.Description = assetDescription; |
882 | item.Name = assetName; | 882 | item.Name = assetName; |
883 | item.AssetType = assType; | 883 | item.AssetType = assType; |
884 | item.InvType = inType; | 884 | item.InvType = inType; |
885 | item.Folder = parentFolder; | 885 | item.Folder = parentFolder; |
886 | item.CurrentPermissions = 2147483647; | 886 | item.CurrentPermissions = 2147483647; |
887 | item.BasePermissions = 2147483647; | 887 | item.BasePermissions = 2147483647; |
888 | item.EveryOnePermissions = 0; | 888 | item.EveryOnePermissions = 0; |
889 | item.NextPermissions = 2147483647; | 889 | item.NextPermissions = 2147483647; |
890 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 890 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
891 | 891 | ||
892 | if (AddNewInventoryItem != null) | 892 | if (AddNewInventoryItem != null) |
893 | { | 893 | { |
894 | AddNewInventoryItem(m_agentID, item); | 894 | AddNewInventoryItem(m_agentID, item); |
895 | } | 895 | } |
896 | } | 896 | } |
897 | 897 | ||
898 | /// <summary> | 898 | /// <summary> |
899 | /// Called when new asset data for an agent inventory item update has been uploaded. | 899 | /// Called when new asset data for an agent inventory item update has been uploaded. |
900 | /// </summary> | 900 | /// </summary> |
901 | /// <param name="itemID">Item to update</param> | 901 | /// <param name="itemID">Item to update</param> |
902 | /// <param name="data">New asset data</param> | 902 | /// <param name="data">New asset data</param> |
903 | /// <returns></returns> | 903 | /// <returns></returns> |
904 | public UUID ItemUpdated(UUID itemID, byte[] data) | 904 | public UUID ItemUpdated(UUID itemID, byte[] data) |
905 | { | 905 | { |
906 | if (ItemUpdatedCall != null) | 906 | if (ItemUpdatedCall != null) |
907 | { | 907 | { |
908 | return ItemUpdatedCall(m_agentID, itemID, data); | 908 | return ItemUpdatedCall(m_agentID, itemID, data); |
909 | } | 909 | } |
910 | 910 | ||
911 | return UUID.Zero; | 911 | return UUID.Zero; |
912 | } | 912 | } |
913 | 913 | ||
914 | /// <summary> | 914 | /// <summary> |
915 | /// Called when new asset data for an agent inventory item update has been uploaded. | 915 | /// Called when new asset data for an agent inventory item update has been uploaded. |
916 | /// </summary> | 916 | /// </summary> |
917 | /// <param name="itemID">Item to update</param> | 917 | /// <param name="itemID">Item to update</param> |
918 | /// <param name="primID">Prim containing item to update</param> | 918 | /// <param name="primID">Prim containing item to update</param> |
919 | /// <param name="isScriptRunning">Signals whether the script to update is currently running</param> | 919 | /// <param name="isScriptRunning">Signals whether the script to update is currently running</param> |
920 | /// <param name="data">New asset data</param> | 920 | /// <param name="data">New asset data</param> |
921 | public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data) | 921 | public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data) |
922 | { | 922 | { |
923 | if (TaskScriptUpdatedCall != null) | 923 | if (TaskScriptUpdatedCall != null) |
924 | { | 924 | { |
925 | TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data); | 925 | TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data); |
926 | } | 926 | } |
927 | } | 927 | } |
928 | 928 | ||
929 | public class AssetUploader | 929 | public class AssetUploader |
930 | { | 930 | { |
931 | public event UpLoadedAsset OnUpLoad; | 931 | public event UpLoadedAsset OnUpLoad; |
932 | private UpLoadedAsset handlerUpLoad = null; | 932 | private UpLoadedAsset handlerUpLoad = null; |
933 | 933 | ||
934 | private string uploaderPath = String.Empty; | 934 | private string uploaderPath = String.Empty; |
935 | private UUID newAssetID; | 935 | private UUID newAssetID; |
936 | private UUID inventoryItemID; | 936 | private UUID inventoryItemID; |
937 | private UUID parentFolder; | 937 | private UUID parentFolder; |
938 | private IHttpServer httpListener; | 938 | private IHttpServer httpListener; |
939 | private bool m_dumpAssetsToFile; | 939 | private bool m_dumpAssetsToFile; |
940 | private string m_assetName = String.Empty; | 940 | private string m_assetName = String.Empty; |
941 | private string m_assetDes = String.Empty; | 941 | private string m_assetDes = String.Empty; |
942 | 942 | ||
943 | private string m_invType = String.Empty; | 943 | private string m_invType = String.Empty; |
944 | private string m_assetType = String.Empty; | 944 | private string m_assetType = String.Empty; |
945 | 945 | ||
946 | public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, | 946 | public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, |
947 | UUID parentFolderID, string invType, string assetType, string path, | 947 | UUID parentFolderID, string invType, string assetType, string path, |
948 | IHttpServer httpServer, bool dumpAssetsToFile) | 948 | IHttpServer httpServer, bool dumpAssetsToFile) |
949 | { | 949 | { |
950 | m_assetName = assetName; | 950 | m_assetName = assetName; |
951 | m_assetDes = description; | 951 | m_assetDes = description; |
952 | newAssetID = assetID; | 952 | newAssetID = assetID; |
953 | inventoryItemID = inventoryItem; | 953 | inventoryItemID = inventoryItem; |
954 | uploaderPath = path; | 954 | uploaderPath = path; |
955 | httpListener = httpServer; | 955 | httpListener = httpServer; |
956 | parentFolder = parentFolderID; | 956 | parentFolder = parentFolderID; |
957 | m_assetType = assetType; | 957 | m_assetType = assetType; |
958 | m_invType = invType; | 958 | m_invType = invType; |
959 | m_dumpAssetsToFile = dumpAssetsToFile; | 959 | m_dumpAssetsToFile = dumpAssetsToFile; |
960 | } | 960 | } |
961 | 961 | ||
962 | /// <summary> | 962 | /// <summary> |
963 | /// | 963 | /// |
964 | /// </summary> | 964 | /// </summary> |
965 | /// <param name="data"></param> | 965 | /// <param name="data"></param> |
966 | /// <param name="path"></param> | 966 | /// <param name="path"></param> |
967 | /// <param name="param"></param> | 967 | /// <param name="param"></param> |
968 | /// <returns></returns> | 968 | /// <returns></returns> |
969 | public string uploaderCaps(byte[] data, string path, string param) | 969 | public string uploaderCaps(byte[] data, string path, string param) |
970 | { | 970 | { |
971 | UUID inv = inventoryItemID; | 971 | UUID inv = inventoryItemID; |
972 | string res = String.Empty; | 972 | string res = String.Empty; |
973 | LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); | 973 | LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); |
974 | uploadComplete.new_asset = newAssetID.ToString(); | 974 | uploadComplete.new_asset = newAssetID.ToString(); |
975 | uploadComplete.new_inventory_item = inv; | 975 | uploadComplete.new_inventory_item = inv; |
976 | uploadComplete.state = "complete"; | 976 | uploadComplete.state = "complete"; |
977 | 977 | ||
978 | res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); | 978 | res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); |
979 | 979 | ||
980 | httpListener.RemoveStreamHandler("POST", uploaderPath); | 980 | httpListener.RemoveStreamHandler("POST", uploaderPath); |
981 | 981 | ||
982 | // TODO: probably make this a better set of extensions here | 982 | // TODO: probably make this a better set of extensions here |
983 | string extension = ".jp2"; | 983 | string extension = ".jp2"; |
984 | if (m_invType != "image") | 984 | if (m_invType != "image") |
985 | { | 985 | { |
986 | extension = ".dat"; | 986 | extension = ".dat"; |
987 | } | 987 | } |
988 | 988 | ||
989 | if (m_dumpAssetsToFile) | 989 | if (m_dumpAssetsToFile) |
990 | { | 990 | { |
991 | SaveAssetToFile(m_assetName + extension, data); | 991 | SaveAssetToFile(m_assetName + extension, data); |
992 | } | 992 | } |
993 | handlerUpLoad = OnUpLoad; | 993 | handlerUpLoad = OnUpLoad; |
994 | if (handlerUpLoad != null) | 994 | if (handlerUpLoad != null) |
995 | { | 995 | { |
996 | handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); | 996 | handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); |
997 | } | 997 | } |
998 | 998 | ||
999 | return res; | 999 | return res; |
1000 | } | 1000 | } |
1001 | ///Left this in and commented in case there are unforseen issues | 1001 | ///Left this in and commented in case there are unforseen issues |
1002 | //private void SaveAssetToFile(string filename, byte[] data) | 1002 | //private void SaveAssetToFile(string filename, byte[] data) |
1003 | //{ | 1003 | //{ |
1004 | // FileStream fs = File.Create(filename); | 1004 | // FileStream fs = File.Create(filename); |
1005 | // BinaryWriter bw = new BinaryWriter(fs); | 1005 | // BinaryWriter bw = new BinaryWriter(fs); |
1006 | // bw.Write(data); | 1006 | // bw.Write(data); |
1007 | // bw.Close(); | 1007 | // bw.Close(); |
1008 | // fs.Close(); | 1008 | // fs.Close(); |
1009 | //} | 1009 | //} |
1010 | private static void SaveAssetToFile(string filename, byte[] data) | 1010 | private static void SaveAssetToFile(string filename, byte[] data) |
1011 | { | 1011 | { |
1012 | string assetPath = "UserAssets"; | 1012 | string assetPath = "UserAssets"; |
1013 | if (!Directory.Exists(assetPath)) | 1013 | if (!Directory.Exists(assetPath)) |
1014 | { | 1014 | { |
1015 | Directory.CreateDirectory(assetPath); | 1015 | Directory.CreateDirectory(assetPath); |
1016 | } | 1016 | } |
1017 | FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename))); | 1017 | FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename))); |
1018 | BinaryWriter bw = new BinaryWriter(fs); | 1018 | BinaryWriter bw = new BinaryWriter(fs); |
1019 | bw.Write(data); | 1019 | bw.Write(data); |
1020 | bw.Close(); | 1020 | bw.Close(); |
1021 | fs.Close(); | 1021 | fs.Close(); |
1022 | } | 1022 | } |
1023 | } | 1023 | } |
1024 | 1024 | ||
1025 | /// <summary> | 1025 | /// <summary> |
1026 | /// This class is a callback invoked when a client sends asset data to | 1026 | /// This class is a callback invoked when a client sends asset data to |
1027 | /// an agent inventory notecard update url | 1027 | /// an agent inventory notecard update url |
1028 | /// </summary> | 1028 | /// </summary> |
1029 | public class ItemUpdater | 1029 | public class ItemUpdater |
1030 | { | 1030 | { |
1031 | public event UpdateItem OnUpLoad; | 1031 | public event UpdateItem OnUpLoad; |
1032 | 1032 | ||
1033 | private UpdateItem handlerUpdateItem = null; | 1033 | private UpdateItem handlerUpdateItem = null; |
1034 | 1034 | ||
1035 | private string uploaderPath = String.Empty; | 1035 | private string uploaderPath = String.Empty; |
1036 | private UUID inventoryItemID; | 1036 | private UUID inventoryItemID; |
1037 | private IHttpServer httpListener; | 1037 | private IHttpServer httpListener; |
1038 | private bool m_dumpAssetToFile; | 1038 | private bool m_dumpAssetToFile; |
1039 | 1039 | ||
1040 | public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile) | 1040 | public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile) |
1041 | { | 1041 | { |
1042 | m_dumpAssetToFile = dumpAssetToFile; | 1042 | m_dumpAssetToFile = dumpAssetToFile; |
1043 | 1043 | ||
1044 | inventoryItemID = inventoryItem; | 1044 | inventoryItemID = inventoryItem; |
1045 | uploaderPath = path; | 1045 | uploaderPath = path; |
1046 | httpListener = httpServer; | 1046 | httpListener = httpServer; |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | /// <summary> | 1049 | /// <summary> |
1050 | /// | 1050 | /// |
1051 | /// </summary> | 1051 | /// </summary> |
1052 | /// <param name="data"></param> | 1052 | /// <param name="data"></param> |
1053 | /// <param name="path"></param> | 1053 | /// <param name="path"></param> |
1054 | /// <param name="param"></param> | 1054 | /// <param name="param"></param> |
1055 | /// <returns></returns> | 1055 | /// <returns></returns> |
1056 | public string uploaderCaps(byte[] data, string path, string param) | 1056 | public string uploaderCaps(byte[] data, string path, string param) |
1057 | { | 1057 | { |
1058 | UUID inv = inventoryItemID; | 1058 | UUID inv = inventoryItemID; |
1059 | string res = String.Empty; | 1059 | string res = String.Empty; |
1060 | LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); | 1060 | LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); |
1061 | UUID assetID = UUID.Zero; | 1061 | UUID assetID = UUID.Zero; |
1062 | handlerUpdateItem = OnUpLoad; | 1062 | handlerUpdateItem = OnUpLoad; |
1063 | if (handlerUpdateItem != null) | 1063 | if (handlerUpdateItem != null) |
1064 | { | 1064 | { |
1065 | assetID = handlerUpdateItem(inv, data); | 1065 | assetID = handlerUpdateItem(inv, data); |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | uploadComplete.new_asset = assetID.ToString(); | 1068 | uploadComplete.new_asset = assetID.ToString(); |
1069 | uploadComplete.new_inventory_item = inv; | 1069 | uploadComplete.new_inventory_item = inv; |
1070 | uploadComplete.state = "complete"; | 1070 | uploadComplete.state = "complete"; |
1071 | 1071 | ||
1072 | res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); | 1072 | res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); |
1073 | 1073 | ||
1074 | httpListener.RemoveStreamHandler("POST", uploaderPath); | 1074 | httpListener.RemoveStreamHandler("POST", uploaderPath); |
1075 | 1075 | ||
1076 | if (m_dumpAssetToFile) | 1076 | if (m_dumpAssetToFile) |
1077 | { | 1077 | { |
1078 | SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data); | 1078 | SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data); |
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | return res; | 1081 | return res; |
1082 | } | 1082 | } |
1083 | ///Left this in and commented in case there are unforseen issues | 1083 | ///Left this in and commented in case there are unforseen issues |
1084 | //private void SaveAssetToFile(string filename, byte[] data) | 1084 | //private void SaveAssetToFile(string filename, byte[] data) |
1085 | //{ | 1085 | //{ |
1086 | // FileStream fs = File.Create(filename); | 1086 | // FileStream fs = File.Create(filename); |
1087 | // BinaryWriter bw = new BinaryWriter(fs); | 1087 | // BinaryWriter bw = new BinaryWriter(fs); |
1088 | // bw.Write(data); | 1088 | // bw.Write(data); |
1089 | // bw.Close(); | 1089 | // bw.Close(); |
1090 | // fs.Close(); | 1090 | // fs.Close(); |
1091 | //} | 1091 | //} |
1092 | private static void SaveAssetToFile(string filename, byte[] data) | 1092 | private static void SaveAssetToFile(string filename, byte[] data) |
1093 | { | 1093 | { |
1094 | string assetPath = "UserAssets"; | 1094 | string assetPath = "UserAssets"; |
1095 | if (!Directory.Exists(assetPath)) | 1095 | if (!Directory.Exists(assetPath)) |
1096 | { | 1096 | { |
1097 | Directory.CreateDirectory(assetPath); | 1097 | Directory.CreateDirectory(assetPath); |
1098 | } | 1098 | } |
1099 | FileStream fs = File.Create(Path.Combine(assetPath, filename)); | 1099 | FileStream fs = File.Create(Path.Combine(assetPath, filename)); |
1100 | BinaryWriter bw = new BinaryWriter(fs); | 1100 | BinaryWriter bw = new BinaryWriter(fs); |
1101 | bw.Write(data); | 1101 | bw.Write(data); |
1102 | bw.Close(); | 1102 | bw.Close(); |
1103 | fs.Close(); | 1103 | fs.Close(); |
1104 | } | 1104 | } |
1105 | } | 1105 | } |
1106 | 1106 | ||
1107 | /// <summary> | 1107 | /// <summary> |
1108 | /// This class is a callback invoked when a client sends asset data to | 1108 | /// This class is a callback invoked when a client sends asset data to |
1109 | /// a task inventory script update url | 1109 | /// a task inventory script update url |
1110 | /// </summary> | 1110 | /// </summary> |
1111 | public class TaskInventoryScriptUpdater | 1111 | public class TaskInventoryScriptUpdater |
1112 | { | 1112 | { |
1113 | public event UpdateTaskScript OnUpLoad; | 1113 | public event UpdateTaskScript OnUpLoad; |
1114 | 1114 | ||
1115 | private UpdateTaskScript handlerUpdateTaskScript = null; | 1115 | private UpdateTaskScript handlerUpdateTaskScript = null; |
1116 | 1116 | ||
1117 | private string uploaderPath = String.Empty; | 1117 | private string uploaderPath = String.Empty; |
1118 | private UUID inventoryItemID; | 1118 | private UUID inventoryItemID; |
1119 | private UUID primID; | 1119 | private UUID primID; |
1120 | private bool isScriptRunning; | 1120 | private bool isScriptRunning; |
1121 | private IHttpServer httpListener; | 1121 | private IHttpServer httpListener; |
1122 | private bool m_dumpAssetToFile; | 1122 | private bool m_dumpAssetToFile; |
1123 | 1123 | ||
1124 | public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning, | 1124 | public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning, |
1125 | string path, IHttpServer httpServer, bool dumpAssetToFile) | 1125 | string path, IHttpServer httpServer, bool dumpAssetToFile) |
1126 | { | 1126 | { |
1127 | m_dumpAssetToFile = dumpAssetToFile; | 1127 | m_dumpAssetToFile = dumpAssetToFile; |
1128 | 1128 | ||
1129 | this.inventoryItemID = inventoryItemID; | 1129 | this.inventoryItemID = inventoryItemID; |
1130 | this.primID = primID; | 1130 | this.primID = primID; |
1131 | 1131 | ||
1132 | // This comes in over the packet as an integer, but actually appears to be treated as a bool | 1132 | // This comes in over the packet as an integer, but actually appears to be treated as a bool |
1133 | this.isScriptRunning = (0 == isScriptRunning ? false : true); | 1133 | this.isScriptRunning = (0 == isScriptRunning ? false : true); |
1134 | 1134 | ||
1135 | uploaderPath = path; | 1135 | uploaderPath = path; |
1136 | httpListener = httpServer; | 1136 | httpListener = httpServer; |
1137 | } | 1137 | } |
1138 | 1138 | ||
1139 | /// <summary> | 1139 | /// <summary> |
1140 | /// | 1140 | /// |
1141 | /// </summary> | 1141 | /// </summary> |
1142 | /// <param name="data"></param> | 1142 | /// <param name="data"></param> |
1143 | /// <param name="path"></param> | 1143 | /// <param name="path"></param> |
1144 | /// <param name="param"></param> | 1144 | /// <param name="param"></param> |
1145 | /// <returns></returns> | 1145 | /// <returns></returns> |
1146 | public string uploaderCaps(byte[] data, string path, string param) | 1146 | public string uploaderCaps(byte[] data, string path, string param) |
1147 | { | 1147 | { |
1148 | try | 1148 | try |
1149 | { | 1149 | { |
1150 | // m_log.InfoFormat("[CAPS]: " + | 1150 | // m_log.InfoFormat("[CAPS]: " + |
1151 | // "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}", | 1151 | // "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}", |
1152 | // data, path, param)); | 1152 | // data, path, param)); |
1153 | 1153 | ||
1154 | string res = String.Empty; | 1154 | string res = String.Empty; |
1155 | LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete(); | 1155 | LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete(); |
1156 | 1156 | ||
1157 | handlerUpdateTaskScript = OnUpLoad; | 1157 | handlerUpdateTaskScript = OnUpLoad; |
1158 | if (handlerUpdateTaskScript != null) | 1158 | if (handlerUpdateTaskScript != null) |
1159 | { | 1159 | { |
1160 | handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data); | 1160 | handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data); |
1161 | } | 1161 | } |
1162 | 1162 | ||
1163 | uploadComplete.item_id = inventoryItemID; | 1163 | uploadComplete.item_id = inventoryItemID; |
1164 | uploadComplete.task_id = primID; | 1164 | uploadComplete.task_id = primID; |
1165 | uploadComplete.state = "complete"; | 1165 | uploadComplete.state = "complete"; |
1166 | 1166 | ||
1167 | res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); | 1167 | res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); |
1168 | 1168 | ||
1169 | httpListener.RemoveStreamHandler("POST", uploaderPath); | 1169 | httpListener.RemoveStreamHandler("POST", uploaderPath); |
1170 | 1170 | ||
1171 | if (m_dumpAssetToFile) | 1171 | if (m_dumpAssetToFile) |
1172 | { | 1172 | { |
1173 | SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data); | 1173 | SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data); |
1174 | } | 1174 | } |
1175 | 1175 | ||
1176 | // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res); | 1176 | // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res); |
1177 | 1177 | ||
1178 | return res; | 1178 | return res; |
1179 | } | 1179 | } |
1180 | catch (Exception e) | 1180 | catch (Exception e) |
1181 | { | 1181 | { |
1182 | m_log.Error("[CAPS]: " + e.ToString()); | 1182 | m_log.Error("[CAPS]: " + e.ToString()); |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | // XXX Maybe this should be some meaningful error packet | 1185 | // XXX Maybe this should be some meaningful error packet |
1186 | return null; | 1186 | return null; |
1187 | } | 1187 | } |
1188 | ///Left this in and commented in case there are unforseen issues | 1188 | ///Left this in and commented in case there are unforseen issues |
1189 | //private void SaveAssetToFile(string filename, byte[] data) | 1189 | //private void SaveAssetToFile(string filename, byte[] data) |
1190 | //{ | 1190 | //{ |
1191 | // FileStream fs = File.Create(filename); | 1191 | // FileStream fs = File.Create(filename); |
1192 | // BinaryWriter bw = new BinaryWriter(fs); | 1192 | // BinaryWriter bw = new BinaryWriter(fs); |
1193 | // bw.Write(data); | 1193 | // bw.Write(data); |
1194 | // bw.Close(); | 1194 | // bw.Close(); |
1195 | // fs.Close(); | 1195 | // fs.Close(); |
1196 | //} | 1196 | //} |
1197 | private static void SaveAssetToFile(string filename, byte[] data) | 1197 | private static void SaveAssetToFile(string filename, byte[] data) |
1198 | { | 1198 | { |
1199 | string assetPath = "UserAssets"; | 1199 | string assetPath = "UserAssets"; |
1200 | if (!Directory.Exists(assetPath)) | 1200 | if (!Directory.Exists(assetPath)) |
1201 | { | 1201 | { |
1202 | Directory.CreateDirectory(assetPath); | 1202 | Directory.CreateDirectory(assetPath); |
1203 | } | 1203 | } |
1204 | FileStream fs = File.Create(Path.Combine(assetPath, filename)); | 1204 | FileStream fs = File.Create(Path.Combine(assetPath, filename)); |
1205 | BinaryWriter bw = new BinaryWriter(fs); | 1205 | BinaryWriter bw = new BinaryWriter(fs); |
1206 | bw.Write(data); | 1206 | bw.Write(data); |
1207 | bw.Close(); | 1207 | bw.Close(); |
1208 | fs.Close(); | 1208 | fs.Close(); |
1209 | } | 1209 | } |
1210 | } | 1210 | } |
1211 | } | 1211 | } |
1212 | } | 1212 | } |