aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Capabilities
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Capabilities')
-rw-r--r--OpenSim/Capabilities/Caps.cs278
-rw-r--r--OpenSim/Capabilities/CapsHandlers.cs185
-rw-r--r--OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs116
-rw-r--r--OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs844
-rw-r--r--OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs82
-rw-r--r--OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs146
-rw-r--r--OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2ServerConnector.cs71
-rw-r--r--OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventory2HandlerTests.cs170
-rw-r--r--OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs293
-rw-r--r--OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs117
-rw-r--r--OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs69
-rw-r--r--OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs271
-rw-r--r--OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs78
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs424
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs394
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs73
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs64
-rw-r--r--OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs33
-rw-r--r--OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs171
-rw-r--r--OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs76
-rw-r--r--OpenSim/Capabilities/LLSD.cs686
-rw-r--r--OpenSim/Capabilities/LLSDArray.cs41
-rw-r--r--OpenSim/Capabilities/LLSDAssetUploadComplete.cs52
-rw-r--r--OpenSim/Capabilities/LLSDAssetUploadRequest.cs59
-rw-r--r--OpenSim/Capabilities/LLSDAssetUploadResponse.cs87
-rw-r--r--OpenSim/Capabilities/LLSDAvatarPicker.cs51
-rw-r--r--OpenSim/Capabilities/LLSDCapEvent.cs40
-rw-r--r--OpenSim/Capabilities/LLSDEmpty.cs37
-rw-r--r--OpenSim/Capabilities/LLSDEnvironmentSettings.cs68
-rw-r--r--OpenSim/Capabilities/LLSDHelpers.cs177
-rw-r--r--OpenSim/Capabilities/LLSDInventoryFolder.cs41
-rw-r--r--OpenSim/Capabilities/LLSDInventoryItem.cs105
-rw-r--r--OpenSim/Capabilities/LLSDItemUpdate.cs41
-rw-r--r--OpenSim/Capabilities/LLSDMapLayer.cs45
-rw-r--r--OpenSim/Capabilities/LLSDMapLayerResponse.cs40
-rw-r--r--OpenSim/Capabilities/LLSDMapRequest.cs39
-rw-r--r--OpenSim/Capabilities/LLSDMethod.cs31
-rw-r--r--OpenSim/Capabilities/LLSDMethodString.cs31
-rw-r--r--OpenSim/Capabilities/LLSDParcelVoiceInfoResponse.cs51
-rw-r--r--OpenSim/Capabilities/LLSDRemoteParcelResponse.cs42
-rw-r--r--OpenSim/Capabilities/LLSDStreamHandler.cs75
-rw-r--r--OpenSim/Capabilities/LLSDTaskInventoryUploadComplete.cs50
-rw-r--r--OpenSim/Capabilities/LLSDTaskScriptUpdate.cs50
-rw-r--r--OpenSim/Capabilities/LLSDTaskScriptUploadComplete.cs54
-rw-r--r--OpenSim/Capabilities/LLSDTest.cs40
-rw-r--r--OpenSim/Capabilities/LLSDType.cs55
-rw-r--r--OpenSim/Capabilities/LLSDVoiceAccountResponse.cs57
-rw-r--r--OpenSim/Capabilities/Properties/AssemblyInfo.cs33
48 files changed, 6133 insertions, 0 deletions
diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs
new file mode 100644
index 0000000..7492602
--- /dev/null
+++ b/OpenSim/Capabilities/Caps.cs
@@ -0,0 +1,278 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using System.Threading;
34using log4net;
35using Nini.Config;
36using OpenMetaverse;
37using OpenSim.Framework.Servers;
38using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Services.Interfaces;
40
41// using OpenSim.Region.Framework.Interfaces;
42
43namespace OpenSim.Framework.Capabilities
44{
45 /// <summary>
46 /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
47 /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want
48 /// to just pass the whole Scene into CAPS.
49 /// </summary>
50 public delegate IClientAPI GetClientDelegate(UUID agentID);
51
52 public class Caps
53 {
54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private string m_httpListenerHostName;
57 private uint m_httpListenPort;
58
59 /// <summary>
60 /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester.
61 /// </summary>
62 private string m_capsObjectPath;
63 public string CapsObjectPath { get { return m_capsObjectPath; } }
64
65 private CapsHandlers m_capsHandlers;
66
67 private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers
68 = new Dictionary<string, PollServiceEventArgs>();
69
70 private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
71
72 private IHttpServer m_httpListener;
73 private UUID m_agentID;
74 private string m_regionName;
75 private ManualResetEvent m_capsActive = new ManualResetEvent(false);
76
77 public UUID AgentID
78 {
79 get { return m_agentID; }
80 }
81
82 public string RegionName
83 {
84 get { return m_regionName; }
85 }
86
87 public string HostName
88 {
89 get { return m_httpListenerHostName; }
90 }
91
92 public uint Port
93 {
94 get { return m_httpListenPort; }
95 }
96
97 public IHttpServer HttpListener
98 {
99 get { return m_httpListener; }
100 }
101
102 public bool SSLCaps
103 {
104 get { return m_httpListener.UseSSL; }
105 }
106
107 public string SSLCommonName
108 {
109 get { return m_httpListener.SSLCommonName; }
110 }
111
112 public CapsHandlers CapsHandlers
113 {
114 get { return m_capsHandlers; }
115 }
116
117 public Dictionary<string, string> ExternalCapsHandlers
118 {
119 get { return m_externalCapsHandlers; }
120 }
121
122 public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
123 UUID agent, string regionName)
124 {
125 m_capsObjectPath = capsPath;
126 m_httpListener = httpServer;
127 m_httpListenerHostName = httpListen;
128
129 m_httpListenPort = httpPort;
130
131 if (httpServer != null && httpServer.UseSSL)
132 {
133 m_httpListenPort = httpServer.SSLPort;
134 httpListen = httpServer.SSLCommonName;
135 httpPort = httpServer.SSLPort;
136 }
137
138 m_agentID = agent;
139 m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort);
140 m_regionName = regionName;
141 m_capsActive.Reset();
142 }
143
144 ~Caps()
145 {
146 m_capsActive.Dispose();
147 }
148
149 /// <summary>
150 /// Register a handler. This allows modules to register handlers.
151 /// </summary>
152 /// <param name="capName"></param>
153 /// <param name="handler"></param>
154 public void RegisterHandler(string capName, IRequestHandler handler)
155 {
156 //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
157 m_capsHandlers[capName] = handler;
158 }
159
160 public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
161 {
162// m_log.DebugFormat(
163// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
164// capName, pollServiceHandler.Url, m_agentID, m_regionName);
165
166 m_pollServiceHandlers.Add(capName, pollServiceHandler);
167
168 m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
169
170// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
171// string protocol = "http";
172// string hostName = m_httpListenerHostName;
173//
174// if (MainServer.Instance.UseSSL)
175// {
176// hostName = MainServer.Instance.SSLCommonName;
177// port = MainServer.Instance.SSLPort;
178// protocol = "https";
179// }
180
181// RegisterHandler(
182// capName, String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, pollServiceHandler.Url));
183 }
184
185 /// <summary>
186 /// Register an external handler. The service for this capability is somewhere else
187 /// given by the URL.
188 /// </summary>
189 /// <param name="capsName"></param>
190 /// <param name="url"></param>
191 public void RegisterHandler(string capsName, string url)
192 {
193 m_externalCapsHandlers.Add(capsName, url);
194 }
195
196 /// <summary>
197 /// Remove all CAPS service handlers.
198 /// </summary>
199 public void DeregisterHandlers()
200 {
201 foreach (string capsName in m_capsHandlers.Caps)
202 {
203 m_capsHandlers.Remove(capsName);
204 }
205
206 foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
207 {
208 m_httpListener.RemovePollServiceHTTPHandler("", handler.Url);
209 }
210 }
211
212 public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
213 {
214 return m_pollServiceHandlers.TryGetValue(name, out pollHandler);
215 }
216
217 public Dictionary<string, PollServiceEventArgs> GetPollHandlers()
218 {
219 return new Dictionary<string, PollServiceEventArgs>(m_pollServiceHandlers);
220 }
221
222 /// <summary>
223 /// Return an LLSD-serializable Hashtable describing the
224 /// capabilities and their handler details.
225 /// </summary>
226 /// <param name="excludeSeed">If true, then exclude the seed cap.</param>
227 public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
228 {
229 Hashtable caps = CapsHandlers.GetCapsDetails(excludeSeed, requestedCaps);
230
231 lock (m_pollServiceHandlers)
232 {
233 foreach (KeyValuePair <string, PollServiceEventArgs> kvp in m_pollServiceHandlers)
234 {
235 if (!requestedCaps.Contains(kvp.Key))
236 continue;
237
238 string hostName = m_httpListenerHostName;
239 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
240 string protocol = "http";
241
242 if (MainServer.Instance.UseSSL)
243 {
244 hostName = MainServer.Instance.SSLCommonName;
245 port = MainServer.Instance.SSLPort;
246 protocol = "https";
247 }
248 //
249 // caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
250
251 caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
252 }
253 }
254
255 // Add the external too
256 foreach (KeyValuePair<string, string> kvp in ExternalCapsHandlers)
257 {
258 if (!requestedCaps.Contains(kvp.Key))
259 continue;
260
261 caps[kvp.Key] = kvp.Value;
262 }
263
264 return caps;
265 }
266
267 public void Activate()
268 {
269 m_capsActive.Set();
270 }
271
272 public bool WaitForActivation()
273 {
274 // Wait for 30s. If that elapses, return false and run without caps
275 return m_capsActive.WaitOne(120000);
276 }
277 }
278} \ No newline at end of file
diff --git a/OpenSim/Capabilities/CapsHandlers.cs b/OpenSim/Capabilities/CapsHandlers.cs
new file mode 100644
index 0000000..f5a40df
--- /dev/null
+++ b/OpenSim/Capabilities/CapsHandlers.cs
@@ -0,0 +1,185 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using System.Collections.Generic;
30using OpenSim.Framework.Servers;
31using OpenSim.Framework.Servers.HttpServer;
32
33namespace OpenSim.Framework.Capabilities
34{
35 /// <summary>
36 /// CapsHandlers is a cap handler container but also takes
37 /// care of adding and removing cap handlers to and from the
38 /// supplied BaseHttpServer.
39 /// </summary>
40 public class CapsHandlers
41 {
42 private Dictionary<string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
43 private IHttpServer m_httpListener;
44 private string m_httpListenerHostName;
45 private uint m_httpListenerPort;
46 private bool m_useSSL = false;
47
48 /// <summary></summary>
49 /// CapsHandlers is a cap handler container but also takes
50 /// care of adding and removing cap handlers to and from the
51 /// supplied BaseHttpServer.
52 /// </summary>
53 /// <param name="httpListener">base HTTP server</param>
54 /// <param name="httpListenerHostname">host name of the HTTP server</param>
55 /// <param name="httpListenerPort">HTTP port</param>
56 public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
57 {
58 m_httpListener = httpListener;
59 m_httpListenerHostName = httpListenerHostname;
60 m_httpListenerPort = httpListenerPort;
61 if (httpListener != null && httpListener.UseSSL)
62 m_useSSL = true;
63 else
64 m_useSSL = false;
65 }
66
67 /// <summary>
68 /// Remove the cap handler for a capability.
69 /// </summary>
70 /// <param name="capsName">name of the capability of the cap
71 /// handler to be removed</param>
72 public void Remove(string capsName)
73 {
74 lock (m_capsHandlers)
75 {
76 m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
77 m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path);
78 m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
79 m_capsHandlers.Remove(capsName);
80 }
81 }
82
83 public bool ContainsCap(string cap)
84 {
85 lock (m_capsHandlers)
86 return m_capsHandlers.ContainsKey(cap);
87 }
88
89 /// <summary>
90 /// The indexer allows us to treat the CapsHandlers object
91 /// in an intuitive dictionary like way.
92 /// </summary>
93 /// <remarks>
94 /// The indexer will throw an exception when you try to
95 /// retrieve a cap handler for a cap that is not contained in
96 /// CapsHandlers.
97 /// </remarks>
98 public IRequestHandler this[string idx]
99 {
100 get
101 {
102 lock (m_capsHandlers)
103 return m_capsHandlers[idx];
104 }
105
106 set
107 {
108 lock (m_capsHandlers)
109 {
110 if (m_capsHandlers.ContainsKey(idx))
111 {
112 m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
113 m_capsHandlers.Remove(idx);
114 }
115
116 if (null == value) return;
117
118 m_capsHandlers[idx] = value;
119 m_httpListener.AddStreamHandler(value);
120 }
121 }
122 }
123
124 /// <summary>
125 /// Return the list of cap names for which this CapsHandlers
126 /// object contains cap handlers.
127 /// </summary>
128 public string[] Caps
129 {
130 get
131 {
132 lock (m_capsHandlers)
133 {
134 string[] __keys = new string[m_capsHandlers.Keys.Count];
135 m_capsHandlers.Keys.CopyTo(__keys, 0);
136 return __keys;
137 }
138 }
139 }
140
141 /// <summary>
142 /// Return an LLSD-serializable Hashtable describing the
143 /// capabilities and their handler details.
144 /// </summary>
145 /// <param name="excludeSeed">If true, then exclude the seed cap.</param>
146 public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
147 {
148 Hashtable caps = new Hashtable();
149 string protocol = "http://";
150
151 if (m_useSSL)
152 protocol = "https://";
153
154 string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
155
156 lock (m_capsHandlers)
157 {
158 foreach (string capsName in m_capsHandlers.Keys)
159 {
160 if (excludeSeed && "SEED" == capsName)
161 continue;
162
163 if (requestedCaps != null && !requestedCaps.Contains(capsName))
164 continue;
165
166 caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
167 }
168 }
169
170 return caps;
171 }
172
173 /// <summary>
174 /// Returns a copy of the dictionary of all the HTTP cap handlers
175 /// </summary>
176 /// <returns>
177 /// The dictionary copy. The key is the capability name, the value is the HTTP handler.
178 /// </returns>
179 public Dictionary<string, IRequestHandler> GetCapsHandlers()
180 {
181 lock (m_capsHandlers)
182 return new Dictionary<string, IRequestHandler>(m_capsHandlers);
183 }
184 }
185} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs b/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs
new file mode 100644
index 0000000..5163169
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.IO;
32using System.Reflection;
33using System.Web;
34using log4net;
35using Nini.Config;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Capabilities;
39using OpenSim.Framework.Servers;
40using OpenSim.Framework.Servers.HttpServer;
41//using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Services.Interfaces;
43using Caps = OpenSim.Framework.Capabilities.Caps;
44
45namespace OpenSim.Capabilities.Handlers
46{
47 public class AvatarPickerSearchHandler : BaseStreamHandler
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private IPeople m_PeopleService;
52
53 public AvatarPickerSearchHandler(string path, IPeople peopleService, string name, string description)
54 : base("GET", path, name, description)
55 {
56 m_PeopleService = peopleService;
57 }
58
59 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
60 {
61 // Try to parse the texture ID from the request URL
62 NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
63 string names = query.GetOne("names");
64 string psize = query.GetOne("page_size");
65 string pnumber = query.GetOne("page");
66
67 if (m_PeopleService == null)
68 return FailureResponse(names, (int)System.Net.HttpStatusCode.InternalServerError, httpResponse);
69
70 if (string.IsNullOrEmpty(names) || names.Length < 3)
71 return FailureResponse(names, (int)System.Net.HttpStatusCode.BadRequest, httpResponse);
72
73 m_log.DebugFormat("[AVATAR PICKER SEARCH]: search for {0}", names);
74
75 int page_size = (string.IsNullOrEmpty(psize) ? 500 : Int32.Parse(psize));
76 int page_number = (string.IsNullOrEmpty(pnumber) ? 1 : Int32.Parse(pnumber));
77
78 // Full content request
79 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
80 //httpResponse.ContentLength = ??;
81 httpResponse.ContentType = "application/llsd+xml";
82
83 List<UserData> users = m_PeopleService.GetUserData(names, page_size, page_number);
84
85 LLSDAvatarPicker osdReply = new LLSDAvatarPicker();
86 osdReply.next_page_url = httpRequest.RawUrl;
87 foreach (UserData u in users)
88 osdReply.agents.Array.Add(ConvertUserData(u));
89
90 string reply = LLSDHelpers.SerialiseLLSDReply(osdReply);
91 return System.Text.Encoding.UTF8.GetBytes(reply);
92 }
93
94 private LLSDPerson ConvertUserData(UserData user)
95 {
96 LLSDPerson p = new LLSDPerson();
97 p.legacy_first_name = user.FirstName;
98 p.legacy_last_name = user.LastName;
99 p.display_name = user.FirstName + " " + user.LastName;
100 if (user.LastName.StartsWith("@"))
101 p.username = user.FirstName.ToLower() + user.LastName.ToLower();
102 else
103 p.username = user.FirstName.ToLower() + "." + user.LastName.ToLower();
104 p.id = user.Id;
105 p.is_display_name_default = false;
106 return p;
107 }
108
109 private byte[] FailureResponse(string names, int statuscode, IOSHttpResponse httpResponse)
110 {
111 m_log.Error("[AVATAR PICKER SEARCH]: Error searching for " + names);
112 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
113 return System.Text.Encoding.UTF8.GetBytes(string.Empty);
114 }
115 }
116} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs
new file mode 100644
index 0000000..53ed115
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs
@@ -0,0 +1,844 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Linq;
32using System.Reflection;
33using log4net;
34using Nini.Config;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Framework.Capabilities;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Services.Interfaces;
42using Caps = OpenSim.Framework.Capabilities.Caps;
43
44namespace OpenSim.Capabilities.Handlers
45{
46 public class FetchInvDescHandler
47 {
48 private static readonly ILog m_log =
49 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private IInventoryService m_InventoryService;
52 private ILibraryService m_LibraryService;
53 private IScene m_Scene;
54// private object m_fetchLock = new Object();
55
56 public FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s)
57 {
58 m_InventoryService = invService;
59 m_LibraryService = libService;
60 m_Scene = s;
61 }
62
63
64 public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
65 {
66 //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);
67
68 // nasty temporary hack here, the linden client falsely
69 // identifies the uuid 00000000-0000-0000-0000-000000000000
70 // as a string which breaks us
71 //
72 // correctly mark it as a uuid
73 //
74 request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
75
76 // another hack <integer>1</integer> results in a
77 // System.ArgumentException: Object type System.Int32 cannot
78 // be converted to target type: System.Boolean
79 //
80 request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
81 request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
82
83 Hashtable hash = new Hashtable();
84 try
85 {
86 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
87 }
88 catch (LLSD.LLSDParseException e)
89 {
90 m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
91 m_log.Error("Request: " + request);
92 }
93
94 ArrayList foldersrequested = (ArrayList)hash["folders"];
95
96 string response = "";
97 string bad_folders_response = "";
98
99 List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>();
100 for (int i = 0; i < foldersrequested.Count; i++)
101 {
102 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
103
104 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
105
106 try
107 {
108 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
109 }
110 catch (Exception e)
111 {
112 m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
113 continue;
114 }
115
116 // Filter duplicate folder ids that bad viewers may send
117 if (folders.Find(f => f.folder_id == llsdRequest.folder_id) == null)
118 folders.Add(llsdRequest);
119
120 }
121
122 if (folders.Count > 0)
123 {
124 List<UUID> bad_folders = new List<UUID>();
125 List<InventoryCollectionWithDescendents> invcollSet = Fetch(folders, bad_folders);
126 //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
127
128 if (invcollSet == null)
129 {
130 m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol.");
131#pragma warning disable 0612
132 return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse);
133#pragma warning restore 0612
134 }
135
136 string inventoryitemstr = string.Empty;
137 foreach (InventoryCollectionWithDescendents icoll in invcollSet)
138 {
139 LLSDInventoryDescendents reply = ToLLSD(icoll.Collection, icoll.Descendents);
140
141 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
142 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
143 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
144
145 response += inventoryitemstr;
146 }
147
148 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders));
149 foreach (UUID bad in bad_folders)
150 bad_folders_response += "<uuid>" + bad + "</uuid>";
151 }
152
153 if (response.Length == 0)
154 {
155 /* Viewers expect a bad_folders array when not available */
156 if (bad_folders_response.Length != 0)
157 {
158 response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
159 }
160 else
161 {
162 response = "<llsd><map><key>folders</key><array /></map></llsd>";
163 }
164 }
165 else
166 {
167 if (bad_folders_response.Length != 0)
168 {
169 response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
170 }
171 else
172 {
173 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
174 }
175 }
176
177 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request for {0} folders. Item count {1}", folders.Count, item_count);
178 //m_log.Debug("[WEB FETCH INV DESC HANDLER] " + response);
179
180 return response;
181
182 }
183
184 /// <summary>
185 /// Construct an LLSD reply packet to a CAPS inventory request
186 /// </summary>
187 /// <param name="invFetch"></param>
188 /// <returns></returns>
189 private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
190 {
191 LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
192 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
193 contents.agent_id = invFetch.owner_id;
194 contents.owner_id = invFetch.owner_id;
195 contents.folder_id = invFetch.folder_id;
196
197 reply.folders.Array.Add(contents);
198 InventoryCollection inv = new InventoryCollection();
199 inv.Folders = new List<InventoryFolderBase>();
200 inv.Items = new List<InventoryItemBase>();
201 int version = 0;
202 int descendents = 0;
203
204#pragma warning disable 0612
205 inv = Fetch(
206 invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
207 invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
208#pragma warning restore 0612
209
210 if (inv != null && inv.Folders != null)
211 {
212 foreach (InventoryFolderBase invFolder in inv.Folders)
213 {
214 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
215 }
216
217 descendents += inv.Folders.Count;
218 }
219
220 if (inv != null && inv.Items != null)
221 {
222 foreach (InventoryItemBase invItem in inv.Items)
223 {
224 contents.items.Array.Add(ConvertInventoryItem(invItem));
225 }
226 }
227
228 contents.descendents = descendents;
229 contents.version = version;
230
231 //m_log.DebugFormat(
232 // "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}",
233 // invFetch.folder_id,
234 // invFetch.fetch_items,
235 // invFetch.fetch_folders,
236 // contents.items.Array.Count,
237 // contents.categories.Array.Count,
238 // invFetch.owner_id);
239
240 return reply;
241 }
242
243 private LLSDInventoryDescendents ToLLSD(InventoryCollection inv, int descendents)
244 {
245 LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
246 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
247 contents.agent_id = inv.OwnerID;
248 contents.owner_id = inv.OwnerID;
249 contents.folder_id = inv.FolderID;
250
251 reply.folders.Array.Add(contents);
252
253 if (inv.Folders != null)
254 {
255 foreach (InventoryFolderBase invFolder in inv.Folders)
256 {
257 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
258 }
259
260 descendents += inv.Folders.Count;
261 }
262
263 if (inv.Items != null)
264 {
265 foreach (InventoryItemBase invItem in inv.Items)
266 {
267 contents.items.Array.Add(ConvertInventoryItem(invItem));
268 }
269 }
270
271 contents.descendents = descendents;
272 contents.version = inv.Version;
273
274 return reply;
275 }
276 /// <summary>
277 /// Old style. Soon to be deprecated.
278 /// </summary>
279 /// <param name="request"></param>
280 /// <param name="httpRequest"></param>
281 /// <param name="httpResponse"></param>
282 /// <returns></returns>
283 [Obsolete]
284 private string FetchInventoryDescendentsRequest(ArrayList foldersrequested, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
285 {
286 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count);
287
288 string response = "";
289 string bad_folders_response = "";
290
291 for (int i = 0; i < foldersrequested.Count; i++)
292 {
293 string inventoryitemstr = "";
294 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
295
296 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
297
298 try
299 {
300 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
301 }
302 catch (Exception e)
303 {
304 m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
305 }
306
307 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
308
309 if (null == reply)
310 {
311 bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>";
312 }
313 else
314 {
315 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
316 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
317 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
318 }
319
320 response += inventoryitemstr;
321 }
322
323 if (response.Length == 0)
324 {
325 /* Viewers expect a bad_folders array when not available */
326 if (bad_folders_response.Length != 0)
327 {
328 response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
329 }
330 else
331 {
332 response = "<llsd><map><key>folders</key><array /></map></llsd>";
333 }
334 }
335 else
336 {
337 if (bad_folders_response.Length != 0)
338 {
339 response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
340 }
341 else
342 {
343 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
344 }
345 }
346
347 // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
348 //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
349
350 return response;
351
352 // }
353 }
354
355 /// <summary>
356 /// Handle the caps inventory descendents fetch.
357 /// </summary>
358 /// <param name="agentID"></param>
359 /// <param name="folderID"></param>
360 /// <param name="ownerID"></param>
361 /// <param name="fetchFolders"></param>
362 /// <param name="fetchItems"></param>
363 /// <param name="sortOrder"></param>
364 /// <param name="version"></param>
365 /// <returns>An empty InventoryCollection if the inventory look up failed</returns>
366 [Obsolete]
367 private InventoryCollection Fetch(
368 UUID agentID, UUID folderID, UUID ownerID,
369 bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
370 {
371 //m_log.DebugFormat(
372 // "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
373 // fetchFolders, fetchItems, folderID, agentID);
374
375 // FIXME MAYBE: We're not handling sortOrder!
376
377 version = 0;
378 descendents = 0;
379
380 InventoryFolderImpl fold;
381 if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
382 {
383 if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
384 {
385 InventoryCollection ret = new InventoryCollection();
386 ret.Folders = new List<InventoryFolderBase>();
387 ret.Items = fold.RequestListOfItems();
388 descendents = ret.Folders.Count + ret.Items.Count;
389
390 return ret;
391 }
392 }
393
394 InventoryCollection contents = new InventoryCollection();
395
396 if (folderID != UUID.Zero)
397 {
398 InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID);
399
400 if (fetchedContents == null)
401 {
402 m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID);
403 return contents;
404 }
405 contents = fetchedContents;
406 InventoryFolderBase containingFolder = m_InventoryService.GetFolder(agentID, folderID);
407
408 if (containingFolder != null)
409 {
410 //m_log.DebugFormat(
411 // "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
412 // containingFolder.Name, containingFolder.ID, agentID);
413
414 version = containingFolder.Version;
415
416 if (fetchItems && containingFolder.Type != (short)FolderType.Trash)
417 {
418 List<InventoryItemBase> itemsToReturn = contents.Items;
419 List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn);
420
421 // descendents must only include the links, not the linked items we add
422 descendents = originalItems.Count;
423
424 // Add target items for links in this folder before the links themselves.
425 foreach (InventoryItemBase item in originalItems)
426 {
427 if (item.AssetType == (int)AssetType.Link)
428 {
429 InventoryItemBase linkedItem = m_InventoryService.GetItem(agentID, item.AssetID);
430
431 // Take care of genuinely broken links where the target doesn't exist
432 // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
433 // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
434 // rather than having to keep track of every folder requested in the recursion.
435 if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
436 itemsToReturn.Insert(0, linkedItem);
437 }
438 }
439
440 // Now scan for folder links and insert the items they target and those links at the head of the return data
441
442/* dont send contents of LinkFolders.
443from docs seems this was never a spec
444
445 foreach (InventoryItemBase item in originalItems)
446 {
447 if (item.AssetType == (int)AssetType.LinkFolder)
448 {
449 InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
450 List<InventoryItemBase> links = linkedFolderContents.Items;
451
452 itemsToReturn.InsertRange(0, links);
453
454 foreach (InventoryItemBase link in linkedFolderContents.Items)
455 {
456 // Take care of genuinely broken links where the target doesn't exist
457 // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
458 // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
459 // rather than having to keep track of every folder requested in the recursion.
460 if (link != null)
461 {
462// m_log.DebugFormat(
463// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
464// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
465
466 InventoryItemBase linkedItem
467 = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
468
469 if (linkedItem != null)
470 itemsToReturn.Insert(0, linkedItem);
471 }
472 }
473 }
474 }
475*/
476 }
477
478// foreach (InventoryItemBase item in contents.Items)
479// {
480// m_log.DebugFormat(
481// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
482// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
483// }
484
485 // =====
486
487//
488// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
489// {
490// m_log.DebugFormat(
491// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
492// linkedItem.Name, folderID, agentID);
493//
494// contents.Items.Add(linkedItem);
495// }
496//
497// // If the folder requested contains links, then we need to send those folders first, otherwise the links
498// // will be broken in the viewer.
499// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
500// foreach (InventoryItemBase item in contents.Items)
501// {
502// if (item.AssetType == (int)AssetType.Link)
503// {
504// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
505//
506// // Take care of genuinely broken links where the target doesn't exist
507// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
508// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
509// // rather than having to keep track of every folder requested in the recursion.
510// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
511// {
512// // We don't need to send the folder if source and destination of the link are in the same
513// // folder.
514// if (linkedItem.Folder != containingFolder.ID)
515// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
516// }
517// }
518// }
519//
520// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
521// {
522// m_log.DebugFormat(
523// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
524// linkedItemFolderId, folderID, agentID);
525//
526// int dummyVersion;
527// InventoryCollection linkedCollection
528// = Fetch(
529// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
530//
531// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
532// linkedFolder.Owner = agentID;
533// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
534//
535//// contents.Folders.AddRange(linkedCollection.Folders);
536//
537// contents.Folders.Add(linkedFolder);
538// contents.Items.AddRange(linkedCollection.Items);
539// }
540// }
541 }
542 }
543 else
544 {
545 // Lost items don't really need a version
546 version = 1;
547 }
548
549 return contents;
550
551 }
552
553 private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> fetchFolders, List<InventoryCollectionWithDescendents> result)
554 {
555 InventoryFolderImpl fold;
556 if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
557 {
558 List<LLSDFetchInventoryDescendents> libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner);
559 fetchFolders.RemoveAll(f => libfolders.Contains(f));
560
561 //m_log.DebugFormat("[XXX]: Found {0} library folders in request", libfolders.Count);
562
563 foreach (LLSDFetchInventoryDescendents f in libfolders)
564 {
565 if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
566 {
567 InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents();
568 ret.Collection = new InventoryCollection();
569 ret.Collection.Folders = new List<InventoryFolderBase>();
570 ret.Collection.Items = fold.RequestListOfItems();
571 ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
572 ret.Collection.FolderID = f.folder_id;
573 ret.Collection.Version = fold.Version;
574
575 ret.Descendents = ret.Collection.Items.Count;
576 result.Add(ret);
577
578 //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
579 }
580 }
581 }
582 }
583
584 private List<InventoryCollectionWithDescendents> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders)
585 {
586 //m_log.DebugFormat(
587 // "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);
588
589 // FIXME MAYBE: We're not handling sortOrder!
590
591 List<InventoryCollectionWithDescendents> result = new List<InventoryCollectionWithDescendents>();
592
593 AddLibraryFolders(fetchFolders, result);
594
595 // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
596 // and can kill the sim (all root folders have parent_id Zero)
597 LLSDFetchInventoryDescendents zero = fetchFolders.Find(f => f.folder_id == UUID.Zero);
598 if (zero != null)
599 {
600 fetchFolders.Remove(zero);
601 BadFolder(zero, null, bad_folders);
602 }
603
604 if (fetchFolders.Count > 0)
605 {
606 UUID[] fids = new UUID[fetchFolders.Count];
607 int i = 0;
608 foreach (LLSDFetchInventoryDescendents f in fetchFolders)
609 fids[i++] = f.folder_id;
610
611 //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));
612
613 InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids);
614
615 if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0))
616 {
617 m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id);
618 foreach (LLSDFetchInventoryDescendents freq in fetchFolders)
619 BadFolder(freq, null, bad_folders);
620 return null;
621 }
622
623 i = 0;
624 // Do some post-processing. May need to fetch more from inv server for links
625 foreach (InventoryCollection contents in fetchedContents)
626 {
627 // Find the original request
628 LLSDFetchInventoryDescendents freq = fetchFolders[i++];
629
630 InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents();
631 coll.Collection = contents;
632
633 if (BadFolder(freq, contents, bad_folders))
634 continue;
635
636 // Next: link management
637 ProcessLinks(freq, coll);
638
639 result.Add(coll);
640 }
641 }
642
643 return result;
644 }
645
646 private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders)
647 {
648 bool bad = false;
649 if (contents == null)
650 {
651 bad_folders.Add(freq.folder_id);
652 bad = true;
653 }
654
655 // The inventory server isn't sending FolderID in the collection...
656 // Must fetch it individually
657 else if (contents.FolderID == UUID.Zero)
658 {
659 InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id);
660
661 if (containingFolder != null)
662 {
663 contents.FolderID = containingFolder.ID;
664 contents.OwnerID = containingFolder.Owner;
665 contents.Version = containingFolder.Version;
666 }
667 else
668 {
669 // Was it really a request for folder Zero?
670 // This is an overkill, but Firestorm really asks for folder Zero.
671 // I'm leaving the code here for the time being, but commented.
672 if (freq.folder_id == UUID.Zero)
673 {
674 //coll.Collection.OwnerID = freq.owner_id;
675 //coll.Collection.FolderID = contents.FolderID;
676 //containingFolder = m_InventoryService.GetRootFolder(freq.owner_id);
677 //if (containingFolder != null)
678 //{
679 // m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Request for parent of folder {0}", containingFolder.ID);
680 // coll.Collection.Folders.Clear();
681 // coll.Collection.Folders.Add(containingFolder);
682 // if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
683 // {
684 // InventoryFolderBase lib = new InventoryFolderBase(m_LibraryService.LibraryRootFolder.ID, m_LibraryService.LibraryRootFolder.Owner);
685 // lib.Name = m_LibraryService.LibraryRootFolder.Name;
686 // lib.Type = m_LibraryService.LibraryRootFolder.Type;
687 // lib.Version = m_LibraryService.LibraryRootFolder.Version;
688 // coll.Collection.Folders.Add(lib);
689 // }
690 // coll.Collection.Items.Clear();
691 //}
692 }
693 else
694 {
695 m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
696 bad_folders.Add(freq.folder_id);
697 }
698 bad = true;
699 }
700 }
701
702 return bad;
703 }
704
705 private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll)
706 {
707 InventoryCollection contents = coll.Collection;
708
709 if (freq.fetch_items && contents.Items != null)
710 {
711 List<InventoryItemBase> itemsToReturn = contents.Items;
712
713 // descendents must only include the links, not the linked items we add
714 coll.Descendents = itemsToReturn.Count;
715
716 // Add target items for links in this folder before the links themselves.
717 List<UUID> itemIDs = new List<UUID>();
718 List<UUID> folderIDs = new List<UUID>();
719 foreach (InventoryItemBase item in itemsToReturn)
720 {
721 //m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType);
722 if (item.AssetType == (int)AssetType.Link)
723 itemIDs.Add(item.AssetID);
724
725// else if (item.AssetType == (int)AssetType.LinkFolder)
726// folderIDs.Add(item.AssetID);
727 }
728
729 //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count);
730
731 // Scan for folder links and insert the items they target and those links at the head of the return data
732 if (folderIDs.Count > 0)
733 {
734 InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray());
735 foreach (InventoryCollection linkedFolderContents in linkedFolders)
736 {
737 if (linkedFolderContents == null)
738 continue;
739
740 List<InventoryItemBase> links = linkedFolderContents.Items;
741
742 itemsToReturn.InsertRange(0, links);
743
744 }
745 }
746
747 if (itemIDs.Count > 0)
748 {
749 InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
750 if (linked == null)
751 {
752 // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated
753 m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one.");
754 linked = new InventoryItemBase[itemIDs.Count];
755 int i = 0;
756 foreach (UUID id in itemIDs)
757 {
758 linked[i++] = m_InventoryService.GetItem(freq.owner_id, id);
759 }
760 }
761
762 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id);
763 //foreach (InventoryItemBase item in itemsToReturn)
764 // m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder);
765
766 if (linked != null)
767 {
768 foreach (InventoryItemBase linkedItem in linked)
769 {
770 // Take care of genuinely broken links where the target doesn't exist
771 // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
772 // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
773 // rather than having to keep track of every folder requested in the recursion.
774 if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
775 {
776 itemsToReturn.Insert(0, linkedItem);
777 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
778 }
779 }
780 }
781 }
782 }
783
784 }
785
786 /// <summary>
787 /// Convert an internal inventory folder object into an LLSD object.
788 /// </summary>
789 /// <param name="invFolder"></param>
790 /// <returns></returns>
791 private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
792 {
793 LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
794 llsdFolder.folder_id = invFolder.ID;
795 llsdFolder.parent_id = invFolder.ParentID;
796 llsdFolder.name = invFolder.Name;
797 llsdFolder.type = invFolder.Type;
798 llsdFolder.preferred_type = -1;
799
800 return llsdFolder;
801 }
802
803 /// <summary>
804 /// Convert an internal inventory item object into an LLSD object.
805 /// </summary>
806 /// <param name="invItem"></param>
807 /// <returns></returns>
808 private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
809 {
810 LLSDInventoryItem llsdItem = new LLSDInventoryItem();
811 llsdItem.asset_id = invItem.AssetID;
812 llsdItem.created_at = invItem.CreationDate;
813 llsdItem.desc = invItem.Description;
814 llsdItem.flags = (int)invItem.Flags;
815 llsdItem.item_id = invItem.ID;
816 llsdItem.name = invItem.Name;
817 llsdItem.parent_id = invItem.Folder;
818 llsdItem.type = invItem.AssetType;
819 llsdItem.inv_type = invItem.InvType;
820
821 llsdItem.permissions = new LLSDPermissions();
822 llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
823 llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
824 llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
825 llsdItem.permissions.group_id = invItem.GroupID;
826 llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
827 llsdItem.permissions.is_owner_group = invItem.GroupOwned;
828 llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
829 llsdItem.permissions.owner_id = invItem.Owner;
830 llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
831 llsdItem.sale_info = new LLSDSaleInfo();
832 llsdItem.sale_info.sale_price = invItem.SalePrice;
833 llsdItem.sale_info.sale_type = invItem.SaleType;
834
835 return llsdItem;
836 }
837 }
838
839 class InventoryCollectionWithDescendents
840 {
841 public InventoryCollection Collection;
842 public int Descendents;
843 }
844}
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs
new file mode 100644
index 0000000..9dcfaa4
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34using OpenMetaverse;
35
36namespace OpenSim.Capabilities.Handlers
37{
38 public class FetchInvDescServerConnector : ServiceConnector
39 {
40 private IInventoryService m_InventoryService;
41 private ILibraryService m_LibraryService;
42 private string m_ConfigName = "CapsService";
43
44 public FetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
45 base(config, server, configName)
46 {
47 if (configName != String.Empty)
48 m_ConfigName = configName;
49
50 IConfig serverConfig = config.Configs[m_ConfigName];
51 if (serverConfig == null)
52 throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
53
54 string invService = serverConfig.GetString("InventoryService", String.Empty);
55
56 if (invService == String.Empty)
57 throw new Exception("No InventoryService in config file");
58
59 Object[] args = new Object[] { config };
60 m_InventoryService =
61 ServerUtils.LoadPlugin<IInventoryService>(invService, args);
62
63 if (m_InventoryService == null)
64 throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
65
66 string libService = serverConfig.GetString("LibraryService", String.Empty);
67 m_LibraryService =
68 ServerUtils.LoadPlugin<ILibraryService>(libService, args);
69
70 FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null);
71 IRequestHandler reqHandler
72 = new RestStreamHandler(
73 "POST",
74 "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
75 webFetchHandler.FetchInventoryDescendentsRequest,
76 "FetchInvDescendents",
77 null);
78 server.AddStreamHandler(reqHandler);
79 }
80
81 }
82}
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs
new file mode 100644
index 0000000..e239a90
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs
@@ -0,0 +1,146 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Reflection;
29using OpenMetaverse;
30using OpenMetaverse.StructuredData;
31using OpenSim.Framework;
32using OpenSim.Framework.Capabilities;
33using OpenSim.Framework.Servers.HttpServer;
34using OpenSim.Services.Interfaces;
35using OSDArray = OpenMetaverse.StructuredData.OSDArray;
36using OSDMap = OpenMetaverse.StructuredData.OSDMap;
37
38using log4net;
39
40namespace OpenSim.Capabilities.Handlers
41{
42 public class FetchInventory2Handler
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 private IInventoryService m_inventoryService;
47 private UUID m_agentID;
48
49 public FetchInventory2Handler(IInventoryService invService, UUID agentId)
50 {
51 m_inventoryService = invService;
52 m_agentID = agentId;
53 }
54
55 public string FetchInventoryRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
56 {
57 //m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
58
59 OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
60 OSDArray itemsRequested = (OSDArray)requestmap["items"];
61
62 string reply;
63 LLSDFetchInventory llsdReply = new LLSDFetchInventory();
64
65 UUID[] itemIDs = new UUID[itemsRequested.Count];
66 int i = 0;
67
68 foreach (OSDMap osdItemId in itemsRequested)
69 {
70 itemIDs[i++] = osdItemId["item_id"].AsUUID();
71 }
72
73 InventoryItemBase[] items = null;
74
75 if (m_agentID != UUID.Zero)
76 {
77 items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
78
79 if (items == null)
80 {
81 // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated
82 m_log.WarnFormat("[FETCH INVENTORY HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one.");
83 items = new InventoryItemBase[itemsRequested.Count];
84 foreach (UUID id in itemIDs)
85 items[i++] = m_inventoryService.GetItem(m_agentID, id);
86 }
87 }
88 else
89 {
90 items = new InventoryItemBase[itemsRequested.Count];
91 foreach (UUID id in itemIDs)
92 items[i++] = m_inventoryService.GetItem(UUID.Zero, id);
93 }
94
95 foreach (InventoryItemBase item in items)
96 {
97 if (item != null)
98 {
99 // We don't know the agent that this request belongs to so we'll use the agent id of the item
100 // which will be the same for all items.
101 llsdReply.agent_id = item.Owner;
102 llsdReply.items.Array.Add(ConvertInventoryItem(item));
103 }
104 }
105
106 reply = LLSDHelpers.SerialiseLLSDReply(llsdReply);
107
108 return reply;
109 }
110
111 /// <summary>
112 /// Convert an internal inventory item object into an LLSD object.
113 /// </summary>
114 /// <param name="invItem"></param>
115 /// <returns></returns>
116 private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
117 {
118 LLSDInventoryItem llsdItem = new LLSDInventoryItem();
119 llsdItem.asset_id = invItem.AssetID;
120 llsdItem.created_at = invItem.CreationDate;
121 llsdItem.desc = invItem.Description;
122 llsdItem.flags = ((int)invItem.Flags) & 0xff;
123 llsdItem.item_id = invItem.ID;
124 llsdItem.name = invItem.Name;
125 llsdItem.parent_id = invItem.Folder;
126 llsdItem.type = invItem.AssetType;
127 llsdItem.inv_type = invItem.InvType;
128
129 llsdItem.permissions = new LLSDPermissions();
130 llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
131 llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
132 llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
133 llsdItem.permissions.group_id = invItem.GroupID;
134 llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
135 llsdItem.permissions.is_owner_group = invItem.GroupOwned;
136 llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
137 llsdItem.permissions.owner_id = invItem.Owner;
138 llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
139 llsdItem.sale_info = new LLSDSaleInfo();
140 llsdItem.sale_info.sale_price = invItem.SalePrice;
141 llsdItem.sale_info.sale_type = invItem.SaleType;
142
143 return llsdItem;
144 }
145 }
146}
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2ServerConnector.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2ServerConnector.cs
new file mode 100644
index 0000000..618f075
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2ServerConnector.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34using OpenMetaverse;
35
36namespace OpenSim.Capabilities.Handlers
37{
38 public class FetchInventory2ServerConnector : ServiceConnector
39 {
40 private IInventoryService m_InventoryService;
41 private string m_ConfigName = "CapsService";
42
43 public FetchInventory2ServerConnector(IConfigSource config, IHttpServer server, string configName)
44 : base(config, server, configName)
45 {
46 if (configName != String.Empty)
47 m_ConfigName = configName;
48
49 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null)
51 throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
52
53 string invService = serverConfig.GetString("InventoryService", String.Empty);
54
55 if (invService == String.Empty)
56 throw new Exception("No InventoryService in config file");
57
58 Object[] args = new Object[] { config };
59 m_InventoryService = ServerUtils.LoadPlugin<IInventoryService>(invService, args);
60
61 if (m_InventoryService == null)
62 throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
63
64 FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService, UUID.Zero);
65 IRequestHandler reqHandler
66 = new RestStreamHandler(
67 "POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
68 server.AddStreamHandler(reqHandler);
69 }
70 }
71}
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventory2HandlerTests.cs b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventory2HandlerTests.cs
new file mode 100644
index 0000000..94c2c89
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventory2HandlerTests.cs
@@ -0,0 +1,170 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Net;
32using System.Text.RegularExpressions;
33using log4net;
34using log4net.Config;
35using NUnit.Framework;
36using OpenMetaverse;
37using OpenSim.Capabilities.Handlers;
38using OpenSim.Framework;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces;
42using OpenSim.Tests.Common;
43
44namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
45{
46 [TestFixture]
47 public class FetchInventory2HandlerTests : OpenSimTestCase
48 {
49 private UUID m_userID = UUID.Random();
50 private Scene m_scene;
51 private UUID m_rootFolderID;
52 private UUID m_notecardsFolder;
53 private UUID m_objectsFolder;
54
55 private void Init()
56 {
57 // Create an inventory that looks like this:
58 //
59 // /My Inventory
60 // <other system folders>
61 // /Objects
62 // Object 1
63 // Object 2
64 // Object 3
65 // /Notecards
66 // Notecard 1
67 // Notecard 2
68 // Notecard 3
69 // Notecard 4
70 // Notecard 5
71
72 m_scene = new SceneHelpers().SetupScene();
73
74 m_scene.InventoryService.CreateUserInventory(m_userID);
75
76 m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID;
77
78 InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object);
79 m_objectsFolder = of.ID;
80
81 // Add 3 objects
82 InventoryItemBase item;
83 for (int i = 1; i <= 3; i++)
84 {
85 item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-0000000000b" + i), m_userID);
86 item.AssetID = UUID.Random();
87 item.AssetType = (int)AssetType.Object;
88 item.Folder = m_objectsFolder;
89 item.Name = "Object " + i;
90 m_scene.InventoryService.AddItem(item);
91 }
92
93 InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Notecard);
94 m_notecardsFolder = ncf.ID;
95
96 // Add 5 notecards
97 for (int i = 1; i <= 5; i++)
98 {
99 item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-00000000000" + i), m_userID);
100 item.AssetID = UUID.Random();
101 item.AssetType = (int)AssetType.Notecard;
102 item.Folder = m_notecardsFolder;
103 item.Name = "Notecard " + i;
104 m_scene.InventoryService.AddItem(item);
105 }
106
107 }
108
109 [Test]
110 public void Test_001_RequestOne()
111 {
112 TestHelpers.InMethod();
113
114 Init();
115
116 FetchInventory2Handler handler = new FetchInventory2Handler(m_scene.InventoryService, m_userID);
117 TestOSHttpRequest req = new TestOSHttpRequest();
118 TestOSHttpResponse resp = new TestOSHttpResponse();
119
120 string request = "<llsd><map><key>items</key><array><map><key>item_id</key><uuid>";
121 request += "10000000-0000-0000-0000-000000000001"; // Notecard 1
122 request += "</uuid></map></array></map></llsd>";
123
124 string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp);
125
126 Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
127 Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
128 Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
129
130 Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Response does not contain item uuid");
131 Assert.That(llsdresponse.Contains("Notecard 1"), Is.True, "Response does not contain item Name");
132 Console.WriteLine(llsdresponse);
133 }
134
135 [Test]
136 public void Test_002_RequestMany()
137 {
138 TestHelpers.InMethod();
139
140 Init();
141
142 FetchInventory2Handler handler = new FetchInventory2Handler(m_scene.InventoryService, m_userID);
143 TestOSHttpRequest req = new TestOSHttpRequest();
144 TestOSHttpResponse resp = new TestOSHttpResponse();
145
146 string request = "<llsd><map><key>items</key><array>";
147 request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000001</uuid></map>"; // Notecard 1
148 request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000002</uuid></map>"; // Notecard 2
149 request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000003</uuid></map>"; // Notecard 3
150 request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000004</uuid></map>"; // Notecard 4
151 request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000005</uuid></map>"; // Notecard 5
152 request += "</array></map></llsd>";
153
154 string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp);
155
156 Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
157 Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
158 Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
159
160 Console.WriteLine(llsdresponse);
161 Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Response does not contain notecard 1");
162 Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000002"), Is.True, "Response does not contain notecard 2");
163 Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000003"), Is.True, "Response does not contain notecard 3");
164 Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000004"), Is.True, "Response does not contain notecard 4");
165 Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000005"), Is.True, "Response does not contain notecard 5");
166 }
167
168 }
169
170} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs
new file mode 100644
index 0000000..4143aa3
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs
@@ -0,0 +1,293 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Net;
32using System.Text.RegularExpressions;
33using log4net;
34using log4net.Config;
35using NUnit.Framework;
36using OpenMetaverse;
37using OpenSim.Capabilities.Handlers;
38using OpenSim.Framework;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces;
42using OpenSim.Tests.Common;
43
44namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
45{
46 [TestFixture]
47 public class FetchInventoryDescendents2HandlerTests : OpenSimTestCase
48 {
49 private UUID m_userID = UUID.Zero;
50 private Scene m_scene;
51 private UUID m_rootFolderID;
52 private int m_rootDescendents;
53 private UUID m_notecardsFolder;
54 private UUID m_objectsFolder;
55
56 private void Init()
57 {
58 // Create an inventory that looks like this:
59 //
60 // /My Inventory
61 // <other system folders>
62 // /Objects
63 // Some Object
64 // /Notecards
65 // Notecard 1
66 // Notecard 2
67 // /Test Folder
68 // Link to notecard -> /Notecards/Notecard 2
69 // Link to Objects folder -> /Objects
70
71 m_scene = new SceneHelpers().SetupScene();
72
73 m_scene.InventoryService.CreateUserInventory(m_userID);
74
75 m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID;
76
77 InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object);
78 m_objectsFolder = of.ID;
79
80 // Add an object
81 InventoryItemBase item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-00000000000b"), m_userID);
82 item.AssetID = UUID.Random();
83 item.AssetType = (int)AssetType.Object;
84 item.Folder = m_objectsFolder;
85 item.Name = "Some Object";
86 m_scene.InventoryService.AddItem(item);
87
88 InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Notecard);
89 m_notecardsFolder = ncf.ID;
90
91 // Add a notecard
92 item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-000000000001"), m_userID);
93 item.AssetID = UUID.Random();
94 item.AssetType = (int)AssetType.Notecard;
95 item.Folder = m_notecardsFolder;
96 item.Name = "Test Notecard 1";
97 m_scene.InventoryService.AddItem(item);
98 // Add another notecard
99 item.ID = new UUID("20000000-0000-0000-0000-000000000002");
100 item.AssetID = new UUID("a0000000-0000-0000-0000-00000000000a");
101 item.Name = "Test Notecard 2";
102 m_scene.InventoryService.AddItem(item);
103
104 // Add a folder
105 InventoryFolderBase folder = new InventoryFolderBase(new UUID("f0000000-0000-0000-0000-00000000000f"), "Test Folder", m_userID, m_rootFolderID);
106 m_scene.InventoryService.AddFolder(folder);
107
108 // Add a link to notecard 2 in Test Folder
109 item.AssetID = item.ID; // use item ID of notecard 2
110 item.ID = new UUID("40000000-0000-0000-0000-000000000004");
111 item.AssetType = (int)AssetType.Link;
112 item.Folder = folder.ID;
113 item.Name = "Link to notecard";
114 m_scene.InventoryService.AddItem(item);
115
116 // Add a link to the Objects folder in Test Folder
117 item.AssetID = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object).ID; // use item ID of Objects folder
118 item.ID = new UUID("50000000-0000-0000-0000-000000000005");
119 item.AssetType = (int)AssetType.LinkFolder;
120 item.Folder = folder.ID;
121 item.Name = "Link to Objects folder";
122 m_scene.InventoryService.AddItem(item);
123
124 InventoryCollection coll = m_scene.InventoryService.GetFolderContent(m_userID, m_rootFolderID);
125 m_rootDescendents = coll.Items.Count + coll.Folders.Count;
126 Console.WriteLine("Number of descendents: " + m_rootDescendents);
127 }
128
129 [Test]
130 public void Test_001_SimpleFolder()
131 {
132 TestHelpers.InMethod();
133
134 Init();
135
136 FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
137 TestOSHttpRequest req = new TestOSHttpRequest();
138 TestOSHttpResponse resp = new TestOSHttpResponse();
139
140 string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
141 request += m_rootFolderID;
142 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
143
144 string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
145
146 Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
147 Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
148 Assert.That(llsdresponse.Contains("00000000-0000-0000-0000-000000000000"), Is.True, "Response should contain userID");
149
150 string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
151 Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents");
152 Console.WriteLine(llsdresponse);
153 }
154
155 [Test]
156 public void Test_002_MultipleFolders()
157 {
158 TestHelpers.InMethod();
159
160 FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
161 TestOSHttpRequest req = new TestOSHttpRequest();
162 TestOSHttpResponse resp = new TestOSHttpResponse();
163
164 string request = "<llsd><map><key>folders</key><array>";
165 request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
166 request += m_rootFolderID;
167 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
168 request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
169 request += m_notecardsFolder;
170 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
171 request += "</array></map></llsd>";
172
173 string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
174 Console.WriteLine(llsdresponse);
175
176 string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
177 Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for root folder");
178 descendents = "descendents</key><integer>2</integer>";
179 Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Notecard folder");
180
181 Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Notecard 1 is missing from response");
182 Assert.That(llsdresponse.Contains("20000000-0000-0000-0000-000000000002"), Is.True, "Notecard 2 is missing from response");
183 }
184
185 [Test]
186 public void Test_003_Links()
187 {
188 TestHelpers.InMethod();
189
190 FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
191 TestOSHttpRequest req = new TestOSHttpRequest();
192 TestOSHttpResponse resp = new TestOSHttpResponse();
193
194 string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
195 request += "f0000000-0000-0000-0000-00000000000f";
196 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
197
198 string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
199 Console.WriteLine(llsdresponse);
200
201 string descendents = "descendents</key><integer>2</integer>";
202 Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Test Folder");
203
204 // Make sure that the note card link is included
205 Assert.That(llsdresponse.Contains("Link to notecard"), Is.True, "Link to notecard is missing");
206
207 //Make sure the notecard item itself is included
208 Assert.That(llsdresponse.Contains("Test Notecard 2"), Is.True, "Notecard 2 item (the source) is missing");
209
210 // Make sure that the source item is before the link item
211 int pos1 = llsdresponse.IndexOf("Test Notecard 2");
212 int pos2 = llsdresponse.IndexOf("Link to notecard");
213 Assert.Less(pos1, pos2, "Source of link is after link");
214
215 // Make sure the folder link is included
216 Assert.That(llsdresponse.Contains("Link to Objects folder"), Is.True, "Link to Objects folder is missing");
217
218/* contents of link folder are not supposed to be listed
219 // Make sure the objects inside the Objects folder are included
220 // Note: I'm not entirely sure this is needed, but that's what I found in the implementation
221 Assert.That(llsdresponse.Contains("Some Object"), Is.True, "Some Object item (contents of the source) is missing");
222*/
223 // Make sure that the source item is before the link item
224 pos1 = llsdresponse.IndexOf("Some Object");
225 pos2 = llsdresponse.IndexOf("Link to Objects folder");
226 Assert.Less(pos1, pos2, "Contents of source of folder link is after folder link");
227 }
228
229 [Test]
230 public void Test_004_DuplicateFolders()
231 {
232 TestHelpers.InMethod();
233
234 FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
235 TestOSHttpRequest req = new TestOSHttpRequest();
236 TestOSHttpResponse resp = new TestOSHttpResponse();
237
238 string request = "<llsd><map><key>folders</key><array>";
239 request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
240 request += m_rootFolderID;
241 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
242 request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
243 request += m_notecardsFolder;
244 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
245 request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
246 request += m_rootFolderID;
247 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
248 request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
249 request += m_notecardsFolder;
250 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
251 request += "</array></map></llsd>";
252
253 string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
254 Console.WriteLine(llsdresponse);
255
256 string root_folder = "<key>folder_id</key><uuid>" + m_rootFolderID + "</uuid>";
257 string notecards_folder = "<key>folder_id</key><uuid>" + m_notecardsFolder + "</uuid>";
258
259 Assert.That(llsdresponse.Contains(root_folder), "Missing root folder");
260 Assert.That(llsdresponse.Contains(notecards_folder), "Missing notecards folder");
261 int count = Regex.Matches(llsdresponse, root_folder).Count;
262 Assert.AreEqual(1, count, "More than 1 root folder in response");
263 count = Regex.Matches(llsdresponse, notecards_folder).Count;
264 Assert.AreEqual(2, count, "More than 1 notecards folder in response"); // Notecards will also be under root, so 2
265 }
266
267 [Test]
268 public void Test_005_FolderZero()
269 {
270 TestHelpers.InMethod();
271
272 Init();
273
274 FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
275 TestOSHttpRequest req = new TestOSHttpRequest();
276 TestOSHttpResponse resp = new TestOSHttpResponse();
277
278 string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
279 request += UUID.Zero;
280 request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
281
282 string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp);
283
284 Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
285 Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
286 Assert.That(llsdresponse.Contains("bad_folders</key><array><uuid>00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder");
287
288 Console.WriteLine(llsdresponse);
289 }
290
291 }
292
293} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs
new file mode 100644
index 0000000..41cfdb6
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesHandler.cs
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Collections.Specialized;
32using System.Reflection;
33using System.IO;
34using System.Web;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Services.Interfaces;
41using Caps = OpenSim.Framework.Capabilities.Caps;
42using OSDMap = OpenMetaverse.StructuredData.OSDMap;
43using OSDArray = OpenMetaverse.StructuredData.OSDArray;
44
45namespace OpenSim.Capabilities.Handlers
46{
47 public class GetDisplayNamesHandler : BaseStreamHandler
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 protected IUserManagement m_UserManagement;
52
53 public GetDisplayNamesHandler(string path, IUserManagement umService, string name, string description)
54 : base("GET", path, name, description)
55 {
56 m_UserManagement = umService;
57 }
58
59 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
60 {
61// m_log.DebugFormat("[GET_DISPLAY_NAMES]: called {0}", httpRequest.Url.Query);
62
63 NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
64 string[] ids = query.GetValues("ids");
65
66 if (m_UserManagement == null)
67 {
68 m_log.Error("[GET_DISPLAY_NAMES]: Cannot fetch display names without a user management component");
69 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
70 return new byte[0];
71 }
72
73 Dictionary<UUID,string> names = m_UserManagement.GetUsersNames(ids);
74
75 OSDMap osdReply = new OSDMap();
76 OSDArray agents = new OSDArray();
77
78 osdReply["agents"] = agents;
79 foreach (KeyValuePair<UUID,string> kvp in names)
80 {
81 if (string.IsNullOrEmpty(kvp.Value))
82 continue;
83 if(kvp.Key == UUID.Zero)
84 continue;
85
86 string[] parts = kvp.Value.Split(new char[] {' '});
87 OSDMap osdname = new OSDMap();
88 if(parts[0] == "Unknown")
89 {
90 osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1));
91 osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2));
92 }
93 else
94 {
95 osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8));
96 osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1));
97 }
98 osdname["display_name"] = OSD.FromString(kvp.Value);
99 osdname["legacy_first_name"] = parts[0];
100 osdname["legacy_last_name"] = parts[1];
101 osdname["username"] = OSD.FromString(kvp.Value);
102 osdname["id"] = OSD.FromUUID(kvp.Key);
103 osdname["is_display_name_default"] = OSD.FromBoolean(true);
104
105 agents.Add(osdname);
106 }
107
108 // Full content request
109 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
110 //httpResponse.ContentLength = ??;
111 httpResponse.ContentType = "application/llsd+xml";
112
113 string reply = OSDParser.SerializeLLSDXmlString(osdReply);
114 return System.Text.Encoding.UTF8.GetBytes(reply);
115 }
116 }
117}
diff --git a/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs
new file mode 100644
index 0000000..32da1c2
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/GetDisplayNames/GetDisplayNamesServerConnector.cs
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34using OpenMetaverse;
35
36namespace OpenSim.Capabilities.Handlers
37{
38 public class GetDisplayNamesServerConnector : ServiceConnector
39 {
40 private IUserManagement m_UserManagement;
41 private string m_ConfigName = "CapsService";
42
43 public GetDisplayNamesServerConnector(IConfigSource config, IHttpServer server, string configName) :
44 base(config, server, configName)
45 {
46 if (configName != String.Empty)
47 m_ConfigName = configName;
48
49 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null)
51 throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
52
53 string umService = serverConfig.GetString("AssetService", String.Empty);
54
55 if (umService == String.Empty)
56 throw new Exception("No AssetService in config file");
57
58 Object[] args = new Object[] { config };
59 m_UserManagement =
60 ServerUtils.LoadPlugin<IUserManagement>(umService, args);
61
62 if (m_UserManagement == null)
63 throw new Exception(String.Format("Failed to load UserManagement from {0}; config is {1}", umService, m_ConfigName));
64
65 server.AddStreamHandler(
66 new GetDisplayNamesHandler("/CAPS/agents/", m_UserManagement, "GetDisplayNames", null));
67 }
68 }
69} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
new file mode 100644
index 0000000..a9b81f3
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
@@ -0,0 +1,271 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using log4net;
35using Nini.Config;
36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Framework.Servers;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Services.Interfaces;
42using Caps = OpenSim.Framework.Capabilities.Caps;
43
44
45
46
47namespace OpenSim.Capabilities.Handlers
48{
49 public class GetMeshHandler
50 {
51 private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private IAssetService m_assetService;
55
56 public const string DefaultFormat = "vnd.ll.mesh";
57
58 public GetMeshHandler(IAssetService assService)
59 {
60 m_assetService = assService;
61 }
62 public Hashtable Handle(Hashtable request)
63 {
64 Hashtable ret = new Hashtable();
65 ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
66 ret["content_type"] = "text/plain";
67 ret["keepalive"] = false;
68 ret["reusecontext"] = false;
69 ret["int_bytes"] = 0;
70 ret["int_lod"] = 0;
71 string MeshStr = (string)request["mesh_id"];
72
73
74 //m_log.DebugFormat("[GETMESH]: called {0}", MeshStr);
75
76 if (m_assetService == null)
77 {
78 m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service");
79 }
80
81 UUID meshID;
82 if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID))
83 {
84 // m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID);
85
86
87 ret = ProcessGetMesh(request, UUID.Zero, null);
88
89
90 }
91 else
92 {
93 m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]);
94 }
95
96
97 return ret;
98 }
99 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
100 {
101 Hashtable responsedata = new Hashtable();
102 responsedata["int_response_code"] = 400; //501; //410; //404;
103 responsedata["content_type"] = "text/plain";
104 responsedata["keepalive"] = false;
105 responsedata["str_response_string"] = "Request wasn't what was expected";
106 responsedata["reusecontext"] = false;
107 responsedata["int_lod"] = 0;
108 responsedata["int_bytes"] = 0;
109
110 string meshStr = string.Empty;
111
112 if (request.ContainsKey("mesh_id"))
113 meshStr = request["mesh_id"].ToString();
114
115 UUID meshID = UUID.Zero;
116 if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
117 {
118 if (m_assetService == null)
119 {
120 responsedata["int_response_code"] = 404; //501; //410; //404;
121 responsedata["content_type"] = "text/plain";
122 responsedata["keepalive"] = false;
123 responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh.";
124 responsedata["reusecontext"] = false;
125 return responsedata;
126 }
127
128 AssetBase mesh = m_assetService.Get(meshID.ToString());
129
130 if (mesh != null)
131 {
132 if (mesh.Type == (SByte)AssetType.Mesh)
133 {
134
135 Hashtable headers = new Hashtable();
136 responsedata["headers"] = headers;
137
138 string range = String.Empty;
139
140 if (((Hashtable)request["headers"])["range"] != null)
141 range = (string)((Hashtable)request["headers"])["range"];
142
143 else if (((Hashtable)request["headers"])["Range"] != null)
144 range = (string)((Hashtable)request["headers"])["Range"];
145
146 if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics
147 {
148 // Range request
149 int start, end;
150 if (TryParseRange(range, out start, out end))
151 {
152 // Before clamping start make sure we can satisfy it in order to avoid
153 // sending back the last byte instead of an error status
154 if (start >= mesh.Data.Length)
155 {
156 responsedata["int_response_code"] = 404; //501; //410; //404;
157 responsedata["content_type"] = "text/plain";
158 responsedata["keepalive"] = false;
159 responsedata["str_response_string"] = "This range doesnt exist.";
160 responsedata["reusecontext"] = false;
161 responsedata["int_lod"] = 3;
162 return responsedata;
163 }
164 else
165 {
166 end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
167 start = Utils.Clamp(start, 0, end);
168 int len = end - start + 1;
169
170 //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
171
172 if (start > 20000)
173 {
174 responsedata["int_lod"] = 3;
175 }
176 else if (start < 4097)
177 {
178 responsedata["int_lod"] = 1;
179 }
180 else
181 {
182 responsedata["int_lod"] = 2;
183 }
184
185
186 if (start == 0 && len == mesh.Data.Length) // well redudante maybe
187 {
188 responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
189 responsedata["bin_response_data"] = mesh.Data;
190 responsedata["int_bytes"] = mesh.Data.Length;
191 responsedata["reusecontext"] = false;
192 responsedata["int_lod"] = 3;
193
194 }
195 else
196 {
197 responsedata["int_response_code"] =
198 (int)System.Net.HttpStatusCode.PartialContent;
199 headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end,
200 mesh.Data.Length);
201
202 byte[] d = new byte[len];
203 Array.Copy(mesh.Data, start, d, 0, len);
204 responsedata["bin_response_data"] = d;
205 responsedata["int_bytes"] = len;
206 responsedata["reusecontext"] = false;
207 }
208 }
209 }
210 else
211 {
212 m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
213 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
214 responsedata["content_type"] = "application/vnd.ll.mesh";
215 responsedata["int_response_code"] = 200;
216 responsedata["reusecontext"] = false;
217 responsedata["int_lod"] = 3;
218 }
219 }
220 else
221 {
222 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
223 responsedata["content_type"] = "application/vnd.ll.mesh";
224 responsedata["int_response_code"] = 200;
225 responsedata["reusecontext"] = false;
226 responsedata["int_lod"] = 3;
227 }
228 }
229 // Optionally add additional mesh types here
230 else
231 {
232 responsedata["int_response_code"] = 404; //501; //410; //404;
233 responsedata["content_type"] = "text/plain";
234 responsedata["keepalive"] = false;
235 responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
236 responsedata["reusecontext"] = false;
237 responsedata["int_lod"] = 1;
238 return responsedata;
239 }
240 }
241 else
242 {
243 responsedata["int_response_code"] = 404; //501; //410; //404;
244 responsedata["content_type"] = "text/plain";
245 responsedata["keepalive"] = false;
246 responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
247 responsedata["reusecontext"] = false;
248 responsedata["int_lod"] = 0;
249 return responsedata;
250 }
251 }
252
253 return responsedata;
254 }
255 private bool TryParseRange(string header, out int start, out int end)
256 {
257 if (header.StartsWith("bytes="))
258 {
259 string[] rangeValues = header.Substring(6).Split('-');
260 if (rangeValues.Length == 2)
261 {
262 if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
263 return true;
264 }
265 }
266
267 start = end = 0;
268 return false;
269 }
270 }
271} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs
new file mode 100644
index 0000000..b494aa4
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs
@@ -0,0 +1,78 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using Nini.Config;
29using OpenMetaverse;
30using OpenSim.Framework.Servers.HttpServer;
31using OpenSim.Server.Base;
32using OpenSim.Server.Handlers.Base;
33using OpenSim.Services.Interfaces;
34using System;
35
36namespace OpenSim.Capabilities.Handlers
37{
38 public class GetMeshServerConnector : ServiceConnector
39 {
40 private IAssetService m_AssetService;
41 private string m_ConfigName = "CapsService";
42
43 public GetMeshServerConnector(IConfigSource config, IHttpServer server, string configName) :
44 base(config, server, configName)
45 {
46 if (configName != String.Empty)
47 m_ConfigName = configName;
48
49 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null)
51 throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
52
53 string assetService = serverConfig.GetString("AssetService", String.Empty);
54
55 if (assetService == String.Empty)
56 throw new Exception("No AssetService in config file");
57
58 Object[] args = new Object[] { config };
59 m_AssetService =
60 ServerUtils.LoadPlugin<IAssetService>(assetService, args);
61
62 if (m_AssetService == null)
63 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
64
65 string rurl = serverConfig.GetString("GetMeshRedirectURL");
66
67 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
68 IRequestHandler reqHandler
69 = new RestHTTPHandler(
70 "GET",
71 "/CAPS/" + UUID.Random(),
72 httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
73 "GetMesh",
74 null);
75 server.AddStreamHandler(reqHandler); ;
76 }
77 }
78} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
new file mode 100644
index 0000000..e73cf9e
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
@@ -0,0 +1,424 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection;
34using System.IO;
35using System.Web;
36using log4net;
37using Nini.Config;
38using OpenMetaverse;
39using OpenMetaverse.StructuredData;
40using OpenMetaverse.Imaging;
41using OpenSim.Framework;
42using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenSim.Region.Framework.Interfaces;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47
48namespace OpenSim.Capabilities.Handlers
49{
50 public class GetTextureHandler
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private IAssetService m_assetService;
56
57 public const string DefaultFormat = "x-j2c";
58
59 public GetTextureHandler(IAssetService assService)
60 {
61 m_assetService = assService;
62 }
63
64 public Hashtable Handle(Hashtable request)
65 {
66 Hashtable ret = new Hashtable();
67 ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
68 ret["content_type"] = "text/plain";
69 ret["keepalive"] = false;
70 ret["reusecontext"] = false;
71 ret["int_bytes"] = 0;
72 string textureStr = (string)request["texture_id"];
73 string format = (string)request["format"];
74
75 //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
76
77 if (m_assetService == null)
78 {
79 m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
80 }
81
82 UUID textureID;
83 if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
84 {
85// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
86
87 string[] formats;
88 if (!string.IsNullOrEmpty(format))
89 {
90 formats = new string[1] { format.ToLower() };
91 }
92 else
93 {
94 formats = new string[1] { DefaultFormat }; // default
95 if (((Hashtable)request["headers"])["Accept"] != null)
96 formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
97 if (formats.Length == 0)
98 formats = new string[1] { DefaultFormat }; // default
99
100 }
101 // OK, we have an array with preferred formats, possibly with only one entry
102 bool foundtexture = false;
103 foreach (string f in formats)
104 {
105 foundtexture = FetchTexture(request, ret, textureID, f);
106 if (foundtexture)
107 break;
108 }
109 if (!foundtexture)
110 {
111 ret["int_response_code"] = 404;
112 ret["error_status_text"] = "not found";
113 ret["str_response_string"] = "not found";
114 ret["content_type"] = "text/plain";
115 ret["keepalive"] = false;
116 ret["reusecontext"] = false;
117 ret["int_bytes"] = 0;
118 }
119 }
120 else
121 {
122 m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
123 }
124
125// m_log.DebugFormat(
126// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
127// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
128 return ret;
129 }
130
131 /// <summary>
132 ///
133 /// </summary>
134 /// <param name="httpRequest"></param>
135 /// <param name="httpResponse"></param>
136 /// <param name="textureID"></param>
137 /// <param name="format"></param>
138 /// <returns>False for "caller try another codec"; true otherwise</returns>
139 private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format)
140 {
141// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
142 AssetBase texture;
143
144 string fullID = textureID.ToString();
145 if (format != DefaultFormat)
146 fullID = fullID + "-" + format;
147
148 // try the cache
149 texture = m_assetService.GetCached(fullID);
150
151 if (texture == null)
152 {
153 //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
154
155 // Fetch locally or remotely. Misses return a 404
156 texture = m_assetService.Get(textureID.ToString());
157
158 if (texture != null)
159 {
160 if (texture.Type != (sbyte)AssetType.Texture)
161 return true;
162
163 if (format == DefaultFormat)
164 {
165 WriteTextureData(request, response, texture, format);
166 return true;
167 }
168 else
169 {
170 AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
171 newTexture.Data = ConvertTextureData(texture, format);
172 if (newTexture.Data.Length == 0)
173 return false; // !!! Caller try another codec, please!
174
175 newTexture.Flags = AssetFlags.Collectable;
176 newTexture.Temporary = true;
177 newTexture.Local = true;
178 m_assetService.Store(newTexture);
179 WriteTextureData(request, response, newTexture, format);
180 return true;
181 }
182 }
183 }
184 else // it was on the cache
185 {
186 //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
187 WriteTextureData(request, response, texture, format);
188 return true;
189 }
190
191 //response = new Hashtable();
192
193
194 //WriteTextureData(request,response,null,format);
195 // not found
196 //m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
197 return false;
198 }
199
200 private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
201 {
202 Hashtable headers = new Hashtable();
203 response["headers"] = headers;
204
205 string range = String.Empty;
206
207 if (((Hashtable)request["headers"])["range"] != null)
208 range = (string)((Hashtable)request["headers"])["range"];
209
210 else if (((Hashtable)request["headers"])["Range"] != null)
211 range = (string)((Hashtable)request["headers"])["Range"];
212
213 if (!String.IsNullOrEmpty(range)) // JP2's only
214 {
215 // Range request
216 int start, end;
217 if (TryParseRange(range, out start, out end))
218 {
219 // Before clamping start make sure we can satisfy it in order to avoid
220 // sending back the last byte instead of an error status
221 if (start >= texture.Data.Length)
222 {
223// m_log.DebugFormat(
224// "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
225// texture.ID, start, texture.Data.Length);
226
227 // Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
228 // Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations
229 // of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
230 // received a very small texture may attempt to fetch bytes from the server past the
231 // range of data that it received originally. Whether this happens appears to depend on whether
232 // the viewer's estimation of how large a request it needs to make for certain discard levels
233 // (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
234 // level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
235 // here will cause the viewer to treat the texture as bad and never display the full resolution
236 // However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
237
238// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
239 // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
240 response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
241 }
242 else
243 {
244 // Handle the case where no second range value was given. This is equivalent to requesting
245 // the rest of the entity.
246 if (end == -1)
247 end = int.MaxValue;
248
249 end = Utils.Clamp(end, 0, texture.Data.Length - 1);
250 start = Utils.Clamp(start, 0, end);
251 int len = end - start + 1;
252
253// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
254
255 response["content-type"] = texture.Metadata.ContentType;
256
257 if (start == 0 && len == texture.Data.Length) // well redudante maybe
258 {
259 response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
260 response["bin_response_data"] = texture.Data;
261 response["int_bytes"] = texture.Data.Length;
262 }
263 else
264 {
265 response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
266 headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
267
268 byte[] d = new byte[len];
269 Array.Copy(texture.Data, start, d, 0, len);
270 response["bin_response_data"] = d;
271 response["int_bytes"] = len;
272 }
273// response.Body.Write(texture.Data, start, len);
274 }
275 }
276 else
277 {
278 m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
279 response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
280 }
281 }
282 else // JP2's or other formats
283 {
284 // Full content request
285 response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
286 if (format == DefaultFormat)
287 response["content_type"] = texture.Metadata.ContentType;
288 else
289 response["content_type"] = "image/" + format;
290
291 response["bin_response_data"] = texture.Data;
292 response["int_bytes"] = texture.Data.Length;
293
294// response.Body.Write(texture.Data, 0, texture.Data.Length);
295 }
296
297// if (response.StatusCode < 200 || response.StatusCode > 299)
298// m_log.WarnFormat(
299// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
300// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
301// else
302// m_log.DebugFormat(
303// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
304// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
305 }
306
307 /// <summary>
308 /// Parse a range header.
309 /// </summary>
310 /// <remarks>
311 /// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
312 /// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
313 /// Where there is no value, -1 is returned.
314 /// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
315 /// for start.</remarks>
316 /// <returns></returns>
317 /// <param name='header'></param>
318 /// <param name='start'>Start of the range. Undefined if this was not a number.</param>
319 /// <param name='end'>End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number.</param>
320 private bool TryParseRange(string header, out int start, out int end)
321 {
322 start = end = 0;
323
324 if (header.StartsWith("bytes="))
325 {
326 string[] rangeValues = header.Substring(6).Split('-');
327
328 if (rangeValues.Length == 2)
329 {
330 if (!Int32.TryParse(rangeValues[0], out start))
331 return false;
332
333 string rawEnd = rangeValues[1];
334
335 if (rawEnd == "")
336 {
337 end = -1;
338 return true;
339 }
340 else if (Int32.TryParse(rawEnd, out end))
341 {
342 return true;
343 }
344 }
345 }
346
347 start = end = 0;
348 return false;
349 }
350
351 private byte[] ConvertTextureData(AssetBase texture, string format)
352 {
353 m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
354 byte[] data = new byte[0];
355
356 MemoryStream imgstream = new MemoryStream();
357 Bitmap mTexture = null;
358 ManagedImage managedImage = null;
359 Image image = null;
360
361 try
362 {
363 // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
364
365 // Decode image to System.Drawing.Image
366 if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
367 {
368 // Save to bitmap
369 mTexture = new Bitmap(image);
370
371 using(EncoderParameters myEncoderParameters = new EncoderParameters())
372 {
373 myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L);
374
375 // Save bitmap to stream
376 ImageCodecInfo codec = GetEncoderInfo("image/" + format);
377 if (codec != null)
378 {
379 mTexture.Save(imgstream, codec, myEncoderParameters);
380 // Write the stream to a byte array for output
381 data = imgstream.ToArray();
382 }
383 else
384 m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
385 }
386 }
387 }
388 catch (Exception e)
389 {
390 m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message);
391 }
392 finally
393 {
394 // Reclaim memory, these are unmanaged resources
395 // If we encountered an exception, one or more of these will be null
396 if (mTexture != null)
397 mTexture.Dispose();
398
399 if (image != null)
400 image.Dispose();
401
402 if(managedImage != null)
403 managedImage.Clear();
404 if (imgstream != null)
405 imgstream.Dispose();
406 }
407
408 return data;
409 }
410
411 // From msdn
412 private static ImageCodecInfo GetEncoderInfo(String mimeType)
413 {
414 ImageCodecInfo[] encoders;
415 encoders = ImageCodecInfo.GetImageEncoders();
416 for (int j = 0; j < encoders.Length; ++j)
417 {
418 if (encoders[j].MimeType == mimeType)
419 return encoders[j];
420 }
421 return null;
422 }
423 }
424}
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs
new file mode 100644
index 0000000..0685c5e
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs
@@ -0,0 +1,394 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection;
34using System.IO;
35using System.Web;
36using log4net;
37using Nini.Config;
38using OpenMetaverse;
39using OpenMetaverse.StructuredData;
40using OpenMetaverse.Imaging;
41using OpenSim.Framework;
42using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenSim.Region.Framework.Interfaces;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47
48namespace OpenSim.Capabilities.Handlers
49{
50 public class GetTextureRobustHandler : BaseStreamHandler
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 private IAssetService m_assetService;
55
56 public const string DefaultFormat = "x-j2c";
57
58 // TODO: Change this to a config option
59 private string m_RedirectURL = null;
60
61 public GetTextureRobustHandler(string path, IAssetService assService, string name, string description, string redirectURL)
62 : base("GET", path, name, description)
63 {
64 m_assetService = assService;
65 m_RedirectURL = redirectURL;
66 if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
67 m_RedirectURL += "/";
68 }
69
70 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
71 {
72 // Try to parse the texture ID from the request URL
73 NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
74 string textureStr = query.GetOne("texture_id");
75 string format = query.GetOne("format");
76
77 //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
78
79 if (m_assetService == null)
80 {
81 m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
82 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
83 return null;
84 }
85
86 UUID textureID;
87 if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
88 {
89// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
90
91 string[] formats;
92 if (!string.IsNullOrEmpty(format))
93 {
94 formats = new string[1] { format.ToLower() };
95 }
96 else
97 {
98 formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
99 if (formats.Length == 0)
100 formats = new string[1] { DefaultFormat }; // default
101
102 }
103 // OK, we have an array with preferred formats, possibly with only one entry
104
105 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
106 foreach (string f in formats)
107 {
108 if (FetchTexture(httpRequest, httpResponse, textureID, f))
109 break;
110 }
111 }
112 else
113 {
114 m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
115 }
116
117// m_log.DebugFormat(
118// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
119// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
120
121 return null;
122 }
123
124 /// <summary>
125 ///
126 /// </summary>
127 /// <param name="httpRequest"></param>
128 /// <param name="httpResponse"></param>
129 /// <param name="textureID"></param>
130 /// <param name="format"></param>
131 /// <returns>False for "caller try another codec"; true otherwise</returns>
132 private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
133 {
134 // m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
135 AssetBase texture;
136
137 if(!String.IsNullOrEmpty(m_RedirectURL))
138 {
139 string textureUrl = m_RedirectURL + "?texture_id=" + textureID.ToString();
140 m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
141 httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
142 httpResponse.RedirectLocation = textureUrl;
143 return true;
144 }
145 else // no redirect
146 {
147 texture = m_assetService.Get(textureID.ToString());
148 if(texture != null)
149 {
150 if(texture.Type != (sbyte)AssetType.Texture)
151 {
152 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
153 return true;
154 }
155 if(format == DefaultFormat)
156 {
157 WriteTextureData(httpRequest, httpResponse, texture, format);
158 return true;
159 }
160 else
161 {
162 AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
163 newTexture.Data = ConvertTextureData(texture, format);
164 if(newTexture.Data.Length == 0)
165 return false; // !!! Caller try another codec, please!
166
167 newTexture.Flags = AssetFlags.Collectable;
168 newTexture.Temporary = true;
169 newTexture.Local = true;
170 WriteTextureData(httpRequest, httpResponse, newTexture, format);
171 return true;
172 }
173 }
174 }
175
176 // not found
177 // m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
178 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
179 return true;
180 }
181
182 private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
183 {
184 string range = request.Headers.GetOne("Range");
185
186 if (!String.IsNullOrEmpty(range)) // JP2's only
187 {
188 // Range request
189 int start, end;
190 if (TryParseRange(range, out start, out end))
191 {
192 // Before clamping start make sure we can satisfy it in order to avoid
193 // sending back the last byte instead of an error status
194 if (start >= texture.Data.Length)
195 {
196// m_log.DebugFormat(
197// "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
198// texture.ID, start, texture.Data.Length);
199
200 // Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
201 // Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations
202 // of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
203 // received a very small texture may attempt to fetch bytes from the server past the
204 // range of data that it received originally. Whether this happens appears to depend on whether
205 // the viewer's estimation of how large a request it needs to make for certain discard levels
206 // (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
207 // level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
208 // here will cause the viewer to treat the texture as bad and never display the full resolution
209 // However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
210
211// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
212// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
213// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
214 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
215 response.ContentType = texture.Metadata.ContentType;
216 }
217 else
218 {
219 // Handle the case where no second range value was given. This is equivalent to requesting
220 // the rest of the entity.
221 if (end == -1)
222 end = int.MaxValue;
223
224 end = Utils.Clamp(end, 0, texture.Data.Length - 1);
225 start = Utils.Clamp(start, 0, end);
226 int len = end - start + 1;
227
228// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
229
230 // Always return PartialContent, even if the range covered the entire data length
231 // We were accidentally sending back 404 before in this situation
232 // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
233 // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
234 //
235 // We also do not want to send back OK even if the whole range was satisfiable since this causes
236 // HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
237// if (end > maxEnd)
238// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
239// else
240 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
241
242 response.ContentLength = len;
243 response.ContentType = texture.Metadata.ContentType;
244 response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
245
246 response.Body.Write(texture.Data, start, len);
247 }
248 }
249 else
250 {
251 m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
252 response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
253 }
254 }
255 else // JP2's or other formats
256 {
257 // Full content request
258 response.StatusCode = (int)System.Net.HttpStatusCode.OK;
259 response.ContentLength = texture.Data.Length;
260 if (format == DefaultFormat)
261 response.ContentType = texture.Metadata.ContentType;
262 else
263 response.ContentType = "image/" + format;
264 response.Body.Write(texture.Data, 0, texture.Data.Length);
265 }
266
267// if (response.StatusCode < 200 || response.StatusCode > 299)
268// m_log.WarnFormat(
269// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
270// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
271// else
272// m_log.DebugFormat(
273// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
274// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
275 }
276
277 /// <summary>
278 /// Parse a range header.
279 /// </summary>
280 /// <remarks>
281 /// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
282 /// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
283 /// Where there is no value, -1 is returned.
284 /// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
285 /// for start.</remarks>
286 /// <returns></returns>
287 /// <param name='header'></param>
288 /// <param name='start'>Start of the range. Undefined if this was not a number.</param>
289 /// <param name='end'>End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number.</param>
290 private bool TryParseRange(string header, out int start, out int end)
291 {
292 start = end = 0;
293
294 if (header.StartsWith("bytes="))
295 {
296 string[] rangeValues = header.Substring(6).Split('-');
297
298 if (rangeValues.Length == 2)
299 {
300 if (!Int32.TryParse(rangeValues[0], out start))
301 return false;
302
303 string rawEnd = rangeValues[1];
304
305 if (rawEnd == "")
306 {
307 end = -1;
308 return true;
309 }
310 else if (Int32.TryParse(rawEnd, out end))
311 {
312 return true;
313 }
314 }
315 }
316
317 start = end = 0;
318 return false;
319 }
320
321 private byte[] ConvertTextureData(AssetBase texture, string format)
322 {
323 m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
324 byte[] data = new byte[0];
325
326 MemoryStream imgstream = new MemoryStream();
327 Bitmap mTexture = null;
328 ManagedImage managedImage = null;
329 Image image = null;
330
331 try
332 {
333 // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
334 // Decode image to System.Drawing.Image
335 if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
336 {
337 // Save to bitmap
338 mTexture = new Bitmap(image);
339
340 using(EncoderParameters myEncoderParameters = new EncoderParameters())
341 {
342 myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L);
343
344 // Save bitmap to stream
345 ImageCodecInfo codec = GetEncoderInfo("image/" + format);
346 if (codec != null)
347 {
348 mTexture.Save(imgstream, codec, myEncoderParameters);
349 // Write the stream to a byte array for output
350 data = imgstream.ToArray();
351 }
352 else
353 m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
354 }
355 }
356 }
357 catch (Exception e)
358 {
359 m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message);
360 }
361 finally
362 {
363 // Reclaim memory, these are unmanaged resources
364 // If we encountered an exception, one or more of these will be null
365 if (mTexture != null)
366 mTexture.Dispose();
367
368 if (image != null)
369 image.Dispose();
370
371 if(managedImage != null)
372 managedImage.Clear();
373
374 if (imgstream != null)
375 imgstream.Dispose();
376 }
377
378 return data;
379 }
380
381 // From msdn
382 private static ImageCodecInfo GetEncoderInfo(String mimeType)
383 {
384 ImageCodecInfo[] encoders;
385 encoders = ImageCodecInfo.GetImageEncoders();
386 for (int j = 0; j < encoders.Length; ++j)
387 {
388 if (encoders[j].MimeType == mimeType)
389 return encoders[j];
390 }
391 return null;
392 }
393 }
394}
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs
new file mode 100644
index 0000000..479cebb
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34using OpenMetaverse;
35
36
37namespace OpenSim.Capabilities.Handlers
38{
39 public class GetTextureServerConnector : ServiceConnector
40 {
41 private IAssetService m_AssetService;
42 private string m_ConfigName = "CapsService";
43
44 public GetTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
45 base(config, server, configName)
46 {
47 if (configName != String.Empty)
48 m_ConfigName = configName;
49
50 IConfig serverConfig = config.Configs[m_ConfigName];
51 if (serverConfig == null)
52 throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
53
54 string assetService = serverConfig.GetString("AssetService", String.Empty);
55
56 if (assetService == String.Empty)
57 throw new Exception("No AssetService in config file");
58
59 Object[] args = new Object[] { config };
60 m_AssetService =
61 ServerUtils.LoadPlugin<IAssetService>(assetService, args);
62
63 if (m_AssetService == null)
64 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
65
66 string rurl = serverConfig.GetString("GetTextureRedirectURL");
67 ;
68 server.AddStreamHandler(
69 new GetTextureRobustHandler("/CAPS/GetTexture/", m_AssetService, "GetTexture", null, rurl));
70 }
71 }
72}
73
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
new file mode 100644
index 0000000..61aa689
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using log4net;
32using log4net.Config;
33using NUnit.Framework;
34using OpenMetaverse;
35using OpenSim.Capabilities.Handlers;
36using OpenSim.Framework;
37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Tests.Common;
40
41/*
42namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
43{
44 [TestFixture]
45 public class GetTextureHandlerTests : OpenSimTestCase
46 {
47 [Test]
48 public void TestTextureNotFound()
49 {
50 TestHelpers.InMethod();
51
52 // Overkill - we only really need the asset service, not a whole scene.
53 Scene scene = new SceneHelpers().SetupScene();
54
55 GetTextureHandler handler = new GetTextureHandler("/gettexture", scene.AssetService, "TestGetTexture", null, null);
56 TestOSHttpRequest req = new TestOSHttpRequest();
57 TestOSHttpResponse resp = new TestOSHttpResponse();
58 req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
59 handler.Handle(null, null, req, resp);
60 Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound));
61 }
62 }
63}
64*/
diff --git a/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs b/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..387b3de
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Capabilities.Handlers")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("http://opensimulator.org")]
12[assembly: AssemblyProduct("OpenSim")]
13[assembly: AssemblyCopyright("OpenSimulator developers")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("32350823-e1df-45e3-b7fa-0a58b4372433")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
33
diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs
new file mode 100644
index 0000000..48274c1
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs
@@ -0,0 +1,171 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using log4net;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Framework.Capabilities;
34using OpenSim.Framework.Servers.HttpServer;
35using OpenSim.Services.Interfaces;
36using Caps = OpenSim.Framework.Capabilities.Caps;
37
38namespace OpenSim.Capabilities.Handlers
39{
40 public class UploadBakedTextureHandler
41 {
42
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 private Caps m_HostCapsObj;
46 private IAssetService m_assetService;
47
48 public UploadBakedTextureHandler(Caps caps, IAssetService assetService)
49 {
50 m_HostCapsObj = caps;
51 m_assetService = assetService;
52 }
53
54 /// <summary>
55 /// Handle a request from the client for a Uri to upload a baked texture.
56 /// </summary>
57 /// <param name="request"></param>
58 /// <param name="path"></param>
59 /// <param name="param"></param>
60 /// <param name="httpRequest"></param>
61 /// <param name="httpResponse"></param>
62 /// <returns>The upload response if the request is successful, null otherwise.</returns>
63 public string UploadBakedTexture(
64 string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
65 {
66 try
67 {
68 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
69 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
70
71 BakedTextureUploader uploader =
72 new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_HostCapsObj.AgentID);
73 uploader.OnUpLoad += BakedTextureUploaded;
74
75 m_HostCapsObj.HttpListener.AddStreamHandler(
76 new BinaryStreamHandler(
77 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null));
78
79 string protocol = "http://";
80
81 if (m_HostCapsObj.SSLCaps)
82 protocol = "https://";
83
84 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
85 m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
86
87 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
88 uploadResponse.uploader = uploaderURL;
89 uploadResponse.state = "upload";
90
91 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
92 }
93 catch (Exception e)
94 {
95 m_log.ErrorFormat("[UPLOAD BAKED TEXTURE HANDLER]: {0}{1}", e.Message, e.StackTrace);
96 }
97
98 return null;
99 }
100
101 /// <summary>
102 /// Called when a baked texture has been successfully uploaded by a client.
103 /// </summary>
104 /// <param name="assetID"></param>
105 /// <param name="data"></param>
106 private void BakedTextureUploaded(UUID assetID, byte[] data)
107 {
108 m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString());
109
110 AssetBase asset;
111 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
112 asset.Data = data;
113 asset.Temporary = true;
114 asset.Local = true;
115 m_assetService.Store(asset);
116 }
117 }
118
119 class BakedTextureUploader
120 {
121// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
122
123 public event Action<UUID, byte[]> OnUpLoad;
124
125 private string uploaderPath = String.Empty;
126 private UUID newAssetID;
127 private IHttpServer httpListener;
128 private UUID AgentId = UUID.Zero;
129
130 public BakedTextureUploader(string path, IHttpServer httpServer, UUID uUID)
131 {
132 newAssetID = UUID.Random();
133 uploaderPath = path;
134 httpListener = httpServer;
135 AgentId = uUID;
136 // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
137 }
138
139 /// <summary>
140 /// Handle raw uploaded baked texture data.
141 /// </summary>
142 /// <param name="data"></param>
143 /// <param name="path"></param>
144 /// <param name="param"></param>
145 /// <returns></returns>
146 public string uploaderCaps(byte[] data, string path, string param)
147 {
148 Action<UUID, byte[]> handlerUpLoad = OnUpLoad;
149
150 // Don't do this asynchronously, otherwise it's possible for the client to send set appearance information
151 // on another thread which might send out avatar updates before the asset has been put into the asset
152 // service.
153 if (handlerUpLoad != null)
154 handlerUpLoad(newAssetID, data);
155
156 string res = String.Empty;
157 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
158 uploadComplete.new_asset = newAssetID.ToString();
159 uploadComplete.new_inventory_item = UUID.Zero;
160 uploadComplete.state = "complete";
161
162 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
163
164 httpListener.RemoveStreamHandler("POST", uploaderPath);
165
166// m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID);
167
168 return res;
169 }
170 }
171} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs
new file mode 100644
index 0000000..fd484ba
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34using OpenMetaverse;
35
36namespace OpenSim.Capabilities.Handlers
37{
38 public class UploadBakedTextureServerConnector : ServiceConnector
39 {
40 private IAssetService m_AssetService;
41 private string m_ConfigName = "CapsService";
42
43 public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
44 base(config, server, configName)
45 {
46 if (configName != String.Empty)
47 m_ConfigName = configName;
48
49 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null)
51 throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
52
53 string assetService = serverConfig.GetString("AssetService", String.Empty);
54
55 if (assetService == String.Empty)
56 throw new Exception("No AssetService in config file");
57
58 Object[] args = new Object[] { config };
59 m_AssetService =
60 ServerUtils.LoadPlugin<IAssetService>(assetService, args);
61
62 if (m_AssetService == null)
63 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
64
65 // NEED TO FIX THIS
66 OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, "");
67 server.AddStreamHandler(new RestStreamHandler(
68 "POST",
69 "/CAPS/UploadBakedTexture/",
70 new UploadBakedTextureHandler(caps, m_AssetService).UploadBakedTexture,
71 "UploadBakedTexture",
72 "Upload Baked Texture Capability"));
73
74 }
75 }
76} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSD.cs b/OpenSim/Capabilities/LLSD.cs
new file mode 100644
index 0000000..fc41113
--- /dev/null
+++ b/OpenSim/Capabilities/LLSD.cs
@@ -0,0 +1,686 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Globalization;
31using System.IO;
32using System.Security.Cryptography;
33using System.Text;
34using System.Xml;
35using OpenMetaverse;
36
37namespace OpenSim.Framework.Capabilities
38{
39 /// <summary>
40 /// Borrowed from (a older version of) libsl for now, as their new llsd code doesn't work we our decoding code.
41 /// </summary>
42 public static class LLSD
43 {
44 /// <summary>
45 ///
46 /// </summary>
47 public class LLSDParseException : Exception
48 {
49 public LLSDParseException(string message) : base(message)
50 {
51 }
52 }
53
54 /// <summary>
55 ///
56 /// </summary>
57 public class LLSDSerializeException : Exception
58 {
59 public LLSDSerializeException(string message) : base(message)
60 {
61 }
62 }
63
64 /// <summary>
65 ///
66 /// </summary>
67 /// <param name="b"></param>
68 /// <returns></returns>
69 public static object LLSDDeserialize(byte[] b)
70 {
71 using (MemoryStream ms = new MemoryStream(b, false))
72 {
73 return LLSDDeserialize(ms);
74 }
75 }
76
77 /// <summary>
78 ///
79 /// </summary>
80 /// <param name="st"></param>
81 /// <returns></returns>
82 public static object LLSDDeserialize(Stream st)
83 {
84 using (XmlTextReader reader = new XmlTextReader(st))
85 {
86 reader.ProhibitDtd = true;
87
88 reader.Read();
89 SkipWS(reader);
90
91 if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
92 throw new LLSDParseException("Expected <llsd>");
93
94 reader.Read();
95 object ret = LLSDParseOne(reader);
96 SkipWS(reader);
97
98 if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
99 throw new LLSDParseException("Expected </llsd>");
100
101 return ret;
102 }
103 }
104
105 /// <summary>
106 ///
107 /// </summary>
108 /// <param name="obj"></param>
109 /// <returns></returns>
110 public static byte[] LLSDSerialize(object obj)
111 {
112 StringWriter sw = new StringWriter();
113 XmlTextWriter writer = new XmlTextWriter(sw);
114 writer.Formatting = Formatting.None;
115
116 writer.WriteStartElement(String.Empty, "llsd", String.Empty);
117 LLSDWriteOne(writer, obj);
118 writer.WriteEndElement();
119
120 writer.Close();
121
122 return Util.UTF8.GetBytes(sw.ToString());
123 }
124
125 /// <summary>
126 ///
127 /// </summary>
128 /// <param name="writer"></param>
129 /// <param name="obj"></param>
130 public static void LLSDWriteOne(XmlTextWriter writer, object obj)
131 {
132 if (obj == null)
133 {
134 writer.WriteStartElement(String.Empty, "undef", String.Empty);
135 writer.WriteEndElement();
136 return;
137 }
138
139 if (obj is string)
140 {
141 writer.WriteStartElement(String.Empty, "string", String.Empty);
142 writer.WriteString((string) obj);
143 writer.WriteEndElement();
144 }
145 else if (obj is int)
146 {
147 writer.WriteStartElement(String.Empty, "integer", String.Empty);
148 writer.WriteString(obj.ToString());
149 writer.WriteEndElement();
150 }
151 else if (obj is double)
152 {
153 writer.WriteStartElement(String.Empty, "real", String.Empty);
154 writer.WriteString(obj.ToString());
155 writer.WriteEndElement();
156 }
157 else if (obj is bool)
158 {
159 bool b = (bool) obj;
160 writer.WriteStartElement(String.Empty, "boolean", String.Empty);
161 writer.WriteString(b ? "1" : "0");
162 writer.WriteEndElement();
163 }
164 else if (obj is ulong)
165 {
166 throw new Exception("ulong in LLSD is currently not implemented, fix me!");
167 }
168 else if (obj is UUID)
169 {
170 UUID u = (UUID) obj;
171 writer.WriteStartElement(String.Empty, "uuid", String.Empty);
172 writer.WriteString(u.ToString());
173 writer.WriteEndElement();
174 }
175 else if (obj is Hashtable)
176 {
177 Hashtable h = obj as Hashtable;
178 writer.WriteStartElement(String.Empty, "map", String.Empty);
179 foreach (string key in h.Keys)
180 {
181 writer.WriteStartElement(String.Empty, "key", String.Empty);
182 writer.WriteString(key);
183 writer.WriteEndElement();
184 LLSDWriteOne(writer, h[key]);
185 }
186 writer.WriteEndElement();
187 }
188 else if (obj is ArrayList)
189 {
190 ArrayList a = obj as ArrayList;
191 writer.WriteStartElement(String.Empty, "array", String.Empty);
192 foreach (object item in a)
193 {
194 LLSDWriteOne(writer, item);
195 }
196 writer.WriteEndElement();
197 }
198 else if (obj is byte[])
199 {
200 byte[] b = obj as byte[];
201 writer.WriteStartElement(String.Empty, "binary", String.Empty);
202
203 writer.WriteStartAttribute(String.Empty, "encoding", String.Empty);
204 writer.WriteString("base64");
205 writer.WriteEndAttribute();
206
207 //// Calculate the length of the base64 output
208 //long length = (long)(4.0d * b.Length / 3.0d);
209 //if (length % 4 != 0) length += 4 - (length % 4);
210
211 //// Create the char[] for base64 output and fill it
212 //char[] tmp = new char[length];
213 //int i = Convert.ToBase64CharArray(b, 0, b.Length, tmp, 0);
214
215 //writer.WriteString(new String(tmp));
216
217 writer.WriteString(Convert.ToBase64String(b));
218 writer.WriteEndElement();
219 }
220 else
221 {
222 throw new LLSDSerializeException("Unknown type " + obj.GetType().Name);
223 }
224 }
225
226 /// <summary>
227 ///
228 /// </summary>
229 /// <param name="reader"></param>
230 /// <returns></returns>
231 public static object LLSDParseOne(XmlTextReader reader)
232 {
233 SkipWS(reader);
234 if (reader.NodeType != XmlNodeType.Element)
235 throw new LLSDParseException("Expected an element");
236
237 string dtype = reader.LocalName;
238 object ret = null;
239
240 switch (dtype)
241 {
242 case "undef":
243 {
244 if (reader.IsEmptyElement)
245 {
246 reader.Read();
247 return null;
248 }
249
250 reader.Read();
251 SkipWS(reader);
252 ret = null;
253 break;
254 }
255 case "boolean":
256 {
257 if (reader.IsEmptyElement)
258 {
259 reader.Read();
260 return false;
261 }
262
263 reader.Read();
264 string s = reader.ReadString().Trim();
265
266 if (s == String.Empty || s == "false" || s == "0")
267 ret = false;
268 else if (s == "true" || s == "1")
269 ret = true;
270 else
271 throw new LLSDParseException("Bad boolean value " + s);
272
273 break;
274 }
275 case "integer":
276 {
277 if (reader.IsEmptyElement)
278 {
279 reader.Read();
280 return 0;
281 }
282
283 reader.Read();
284 ret = Convert.ToInt32(reader.ReadString().Trim());
285 break;
286 }
287 case "real":
288 {
289 if (reader.IsEmptyElement)
290 {
291 reader.Read();
292 return 0.0f;
293 }
294
295 reader.Read();
296 ret = Convert.ToDouble(reader.ReadString().Trim());
297 break;
298 }
299 case "uuid":
300 {
301 if (reader.IsEmptyElement)
302 {
303 reader.Read();
304 return UUID.Zero;
305 }
306
307 reader.Read();
308 ret = new UUID(reader.ReadString().Trim());
309 break;
310 }
311 case "string":
312 {
313 if (reader.IsEmptyElement)
314 {
315 reader.Read();
316 return String.Empty;
317 }
318
319 reader.Read();
320 ret = reader.ReadString();
321 break;
322 }
323 case "binary":
324 {
325 if (reader.IsEmptyElement)
326 {
327 reader.Read();
328 return new byte[0];
329 }
330
331 if (reader.GetAttribute("encoding") != null &&
332 reader.GetAttribute("encoding") != "base64")
333 {
334 throw new LLSDParseException("Unknown encoding: " + reader.GetAttribute("encoding"));
335 }
336
337 reader.Read();
338 FromBase64Transform b64 = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces);
339 byte[] inp = Util.UTF8.GetBytes(reader.ReadString());
340 ret = b64.TransformFinalBlock(inp, 0, inp.Length);
341 break;
342 }
343 case "date":
344 {
345 reader.Read();
346 throw new Exception("LLSD TODO: date");
347 }
348 case "map":
349 {
350 return LLSDParseMap(reader);
351 }
352 case "array":
353 {
354 return LLSDParseArray(reader);
355 }
356 default:
357 throw new LLSDParseException("Unknown element <" + dtype + ">");
358 }
359
360 if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != dtype)
361 {
362 throw new LLSDParseException("Expected </" + dtype + ">");
363 }
364
365 reader.Read();
366 return ret;
367 }
368
369 /// <summary>
370 ///
371 /// </summary>
372 /// <param name="reader"></param>
373 /// <returns></returns>
374 public static Hashtable LLSDParseMap(XmlTextReader reader)
375 {
376 Hashtable ret = new Hashtable();
377
378 if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "map")
379 throw new LLSDParseException("Expected <map>");
380
381 if (reader.IsEmptyElement)
382 {
383 reader.Read();
384 return ret;
385 }
386
387 reader.Read();
388
389 while (true)
390 {
391 SkipWS(reader);
392 if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "map")
393 {
394 reader.Read();
395 break;
396 }
397
398 if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "key")
399 throw new LLSDParseException("Expected <key>");
400
401 string key = reader.ReadString();
402
403 if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "key")
404 throw new LLSDParseException("Expected </key>");
405
406 reader.Read();
407 object val = LLSDParseOne(reader);
408 ret[key] = val;
409 }
410
411 return ret; // TODO
412 }
413
414 /// <summary>
415 ///
416 /// </summary>
417 /// <param name="reader"></param>
418 /// <returns></returns>
419 public static ArrayList LLSDParseArray(XmlTextReader reader)
420 {
421 ArrayList ret = new ArrayList();
422
423 if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "array")
424 throw new LLSDParseException("Expected <array>");
425
426 if (reader.IsEmptyElement)
427 {
428 reader.Read();
429 return ret;
430 }
431
432 reader.Read();
433
434 while (true)
435 {
436 SkipWS(reader);
437
438 if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "array")
439 {
440 reader.Read();
441 break;
442 }
443
444 ret.Insert(ret.Count, LLSDParseOne(reader));
445 }
446
447 return ret; // TODO
448 }
449
450 /// <summary>
451 ///
452 /// </summary>
453 /// <param name="count"></param>
454 /// <returns></returns>
455 private static string GetSpaces(int count)
456 {
457 StringBuilder b = new StringBuilder();
458 for (int i = 0; i < count; i++) b.Append(" ");
459 return b.ToString();
460 }
461
462 /// <summary>
463 ///
464 /// </summary>
465 /// <param name="obj"></param>
466 /// <param name="indent"></param>
467 /// <returns></returns>
468 public static String LLSDDump(object obj, int indent)
469 {
470 if (obj == null)
471 {
472 return GetSpaces(indent) + "- undef\n";
473 }
474 else if (obj is string)
475 {
476 return GetSpaces(indent) + "- string \"" + (string) obj + "\"\n";
477 }
478 else if (obj is int)
479 {
480 return GetSpaces(indent) + "- integer " + obj.ToString() + "\n";
481 }
482 else if (obj is double)
483 {
484 return GetSpaces(indent) + "- float " + obj.ToString() + "\n";
485 }
486 else if (obj is UUID)
487 {
488 return GetSpaces(indent) + "- uuid " + ((UUID) obj).ToString() + Environment.NewLine;
489 }
490 else if (obj is Hashtable)
491 {
492 StringBuilder ret = new StringBuilder();
493 ret.Append(GetSpaces(indent) + "- map" + Environment.NewLine);
494 Hashtable map = (Hashtable) obj;
495
496 foreach (string key in map.Keys)
497 {
498 ret.Append(GetSpaces(indent + 2) + "- key \"" + key + "\"" + Environment.NewLine);
499 ret.Append(LLSDDump(map[key], indent + 3));
500 }
501
502 return ret.ToString();
503 }
504 else if (obj is ArrayList)
505 {
506 StringBuilder ret = new StringBuilder();
507 ret.Append(GetSpaces(indent) + "- array\n");
508 ArrayList list = (ArrayList) obj;
509
510 foreach (object item in list)
511 {
512 ret.Append(LLSDDump(item, indent + 2));
513 }
514
515 return ret.ToString();
516 }
517 else if (obj is byte[])
518 {
519 return GetSpaces(indent) + "- binary\n" + Utils.BytesToHexString((byte[]) obj, GetSpaces(indent)) +
520 Environment.NewLine;
521 }
522 else
523 {
524 return GetSpaces(indent) + "- unknown type " + obj.GetType().Name + Environment.NewLine;
525 }
526 }
527
528 public static object ParseTerseLLSD(string llsd)
529 {
530 int notused;
531 return ParseTerseLLSD(llsd, out notused);
532 }
533
534 public static object ParseTerseLLSD(string llsd, out int endPos)
535 {
536 if (llsd.Length == 0)
537 {
538 endPos = 0;
539 return null;
540 }
541
542 // Identify what type of object this is
543 switch (llsd[0])
544 {
545 case '!':
546 throw new LLSDParseException("Undefined value type encountered");
547 case '1':
548 endPos = 1;
549 return true;
550 case '0':
551 endPos = 1;
552 return false;
553 case 'i':
554 {
555 if (llsd.Length < 2) throw new LLSDParseException("Integer value type with no value");
556 int value;
557 endPos = FindEnd(llsd, 1);
558
559 if (Int32.TryParse(llsd.Substring(1, endPos - 1), out value))
560 return value;
561 else
562 throw new LLSDParseException("Failed to parse integer value type");
563 }
564 case 'r':
565 {
566 if (llsd.Length < 2) throw new LLSDParseException("Real value type with no value");
567 double value;
568 endPos = FindEnd(llsd, 1);
569
570 if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float,
571 Culture.NumberFormatInfo, out value))
572 return value;
573 else
574 throw new LLSDParseException("Failed to parse double value type");
575 }
576 case 'u':
577 {
578 if (llsd.Length < 17) throw new LLSDParseException("UUID value type with no value");
579 UUID value;
580 endPos = FindEnd(llsd, 1);
581
582 if (UUID.TryParse(llsd.Substring(1, endPos - 1), out value))
583 return value;
584 else
585 throw new LLSDParseException("Failed to parse UUID value type");
586 }
587 case 'b':
588 //byte[] value = new byte[llsd.Length - 1];
589 // This isn't the actual binary LLSD format, just the terse format sent
590 // at login so I don't even know if there is a binary type
591 throw new LLSDParseException("Binary value type is unimplemented");
592 case 's':
593 case 'l':
594 if (llsd.Length < 2) throw new LLSDParseException("String value type with no value");
595 endPos = FindEnd(llsd, 1);
596 return llsd.Substring(1, endPos - 1);
597 case 'd':
598 // Never seen one before, don't know what the format is
599 throw new LLSDParseException("Date value type is unimplemented");
600 case '[':
601 {
602 if (llsd.IndexOf(']') == -1) throw new LLSDParseException("Invalid array");
603
604 int pos = 0;
605 ArrayList array = new ArrayList();
606
607 while (llsd[pos] != ']')
608 {
609 ++pos;
610
611 // Advance past comma if need be
612 if (llsd[pos] == ',') ++pos;
613
614 // Allow a single whitespace character
615 if (pos < llsd.Length && llsd[pos] == ' ') ++pos;
616
617 int end;
618 array.Add(ParseTerseLLSD(llsd.Substring(pos), out end));
619 pos += end;
620 }
621
622 endPos = pos + 1;
623 return array;
624 }
625 case '{':
626 {
627 if (llsd.IndexOf('}') == -1) throw new LLSDParseException("Invalid map");
628
629 int pos = 0;
630 Hashtable hashtable = new Hashtable();
631
632 while (llsd[pos] != '}')
633 {
634 ++pos;
635
636 // Advance past comma if need be
637 if (llsd[pos] == ',') ++pos;
638
639 // Allow a single whitespace character
640 if (pos < llsd.Length && llsd[pos] == ' ') ++pos;
641
642 if (llsd[pos] != '\'') throw new LLSDParseException("Expected a map key");
643 int endquote = llsd.IndexOf('\'', pos + 1);
644 if (endquote == -1 || (endquote + 1) >= llsd.Length || llsd[endquote + 1] != ':')
645 throw new LLSDParseException("Invalid map format");
646 string key = llsd.Substring(pos, endquote - pos);
647 key = key.Replace("'", String.Empty);
648 pos += (endquote - pos) + 2;
649
650 int end;
651 hashtable.Add(key, ParseTerseLLSD(llsd.Substring(pos), out end));
652 pos += end;
653 }
654
655 endPos = pos + 1;
656 return hashtable;
657 }
658 default:
659 throw new Exception("Unknown value type");
660 }
661 }
662
663 private static int FindEnd(string llsd, int start)
664 {
665 int end = llsd.IndexOfAny(new char[] {',', ']', '}'});
666 if (end == -1) end = llsd.Length - 1;
667 return end;
668 }
669
670 /// <summary>
671 ///
672 /// </summary>
673 /// <param name="reader"></param>
674 private static void SkipWS(XmlTextReader reader)
675 {
676 while (
677 reader.NodeType == XmlNodeType.Comment ||
678 reader.NodeType == XmlNodeType.Whitespace ||
679 reader.NodeType == XmlNodeType.SignificantWhitespace ||
680 reader.NodeType == XmlNodeType.XmlDeclaration)
681 {
682 reader.Read();
683 }
684 }
685 }
686}
diff --git a/OpenSim/Capabilities/LLSDArray.cs b/OpenSim/Capabilities/LLSDArray.cs
new file mode 100644
index 0000000..3459e49
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDArray.cs
@@ -0,0 +1,41 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [LLSDType("ARRAY")]
33 public class OSDArray
34 {
35 public ArrayList Array = new ArrayList();
36
37 public OSDArray()
38 {
39 }
40 }
41} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDAssetUploadComplete.cs b/OpenSim/Capabilities/LLSDAssetUploadComplete.cs
new file mode 100644
index 0000000..476cf6e
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDAssetUploadComplete.cs
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenMetaverse;
30
31namespace OpenSim.Framework.Capabilities
32{
33
34 [LLSDType("MAP")]
35 public class LLSDAssetUploadComplete
36 {
37 public string new_asset = String.Empty;
38 public UUID new_inventory_item = UUID.Zero;
39// public UUID new_texture_folder_id = UUID.Zero;
40 public string state = String.Empty;
41 public LLSDAssetUploadError error = null;
42 //public bool success = false;
43 public int new_next_owner_mask = 0;
44 public int new_group_mask = 0;
45 public int new_everyone_mask = 0;
46 public int inventory_item_flags = 0;
47
48 public LLSDAssetUploadComplete()
49 {
50 }
51 }
52}
diff --git a/OpenSim/Capabilities/LLSDAssetUploadRequest.cs b/OpenSim/Capabilities/LLSDAssetUploadRequest.cs
new file mode 100644
index 0000000..6779cc1
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDAssetUploadRequest.cs
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenMetaverse;
30
31namespace OpenSim.Framework.Capabilities
32{
33 [OSDMap]
34 public class LLSDAssetResource
35 {
36 public OSDArray instance_list = new OSDArray();
37 public OSDArray texture_list = new OSDArray();
38 public OSDArray mesh_list = new OSDArray();
39 public string metric = String.Empty;
40 }
41
42 [OSDMap]
43 public class LLSDAssetUploadRequest
44 {
45 public string asset_type = String.Empty;
46 public string description = String.Empty;
47 public UUID folder_id = UUID.Zero;
48 public UUID texture_folder_id = UUID.Zero;
49 public int next_owner_mask = 0;
50 public int group_mask = 0;
51 public int everyone_mask = 0;
52 public string inventory_type = String.Empty;
53 public string name = String.Empty;
54 public LLSDAssetResource asset_resources = new LLSDAssetResource();
55 public LLSDAssetUploadRequest()
56 {
57 }
58 }
59}
diff --git a/OpenSim/Capabilities/LLSDAssetUploadResponse.cs b/OpenSim/Capabilities/LLSDAssetUploadResponse.cs
new file mode 100644
index 0000000..97491e3
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDAssetUploadResponse.cs
@@ -0,0 +1,87 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenMetaverse;
30
31namespace OpenSim.Framework.Capabilities
32{
33 [OSDMap]
34 public class LLSDAssetUploadError
35 {
36 public string message = String.Empty;
37 public UUID identifier = UUID.Zero;
38 }
39
40 [OSDMap]
41 public class LLSDAssetUploadResponsePricebrkDown
42 {
43 public int mesh_streaming;
44 public int mesh_physics;
45 public int mesh_instance;
46 public int texture;
47 public int model;
48 }
49
50 [OSDMap]
51 public class LLSDAssetUploadResponseData
52 {
53 public double resource_cost;
54 public double model_streaming_cost;
55 public double simulation_cost;
56 public double physics_cost;
57 public LLSDAssetUploadResponsePricebrkDown upload_price_breakdown = new LLSDAssetUploadResponsePricebrkDown();
58 }
59
60 [OSDMap]
61 public class LLSDAssetUploadResponse
62 {
63 public string uploader = String.Empty;
64 public string state = String.Empty;
65 public int upload_price = 0;
66 public LLSDAssetUploadResponseData data = null;
67 public LLSDAssetUploadError error = null;
68 public LLSDAssetUploadResponse()
69 {
70 }
71 }
72
73
74 [OSDMap]
75 public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
76 {
77 public int resource_cost;
78 public string state;
79 public int upload_price;
80 public string rsvp;
81
82 public LLSDNewFileAngentInventoryVariablePriceReplyResponse()
83 {
84 state = "confirm_upload";
85 }
86 }
87} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDAvatarPicker.cs b/OpenSim/Capabilities/LLSDAvatarPicker.cs
new file mode 100644
index 0000000..12e892c
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDAvatarPicker.cs
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [OSDMap]
33 public class LLSDAvatarPicker
34 {
35 public string next_page_url;
36 // an array of LLSDPerson
37 public OSDArray agents = new OSDArray();
38 }
39
40 [OSDMap]
41 public class LLSDPerson
42 {
43 public string username;
44 public string display_name;
45 //'display_name_next_update':d"1970-01-01T00:00:00Z"
46 public string legacy_first_name;
47 public string legacy_last_name;
48 public UUID id;
49 public bool is_display_name_default;
50 }
51} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDCapEvent.cs b/OpenSim/Capabilities/LLSDCapEvent.cs
new file mode 100644
index 0000000..63abd62
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDCapEvent.cs
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Capabilities
29{
30 [LLSDType("MAP")]
31 public class LLSDCapEvent
32 {
33 public int id = 0;
34 public OSDArray events = new OSDArray();
35
36 public LLSDCapEvent()
37 {
38 }
39 }
40} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDEmpty.cs b/OpenSim/Capabilities/LLSDEmpty.cs
new file mode 100644
index 0000000..f94fcba
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDEmpty.cs
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Capabilities
29{
30 [LLSDType("MAP")]
31 public class LLSDEmpty
32 {
33 public LLSDEmpty()
34 {
35 }
36 }
37} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDEnvironmentSettings.cs b/OpenSim/Capabilities/LLSDEnvironmentSettings.cs
new file mode 100644
index 0000000..39019af
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDEnvironmentSettings.cs
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31
32namespace OpenSim.Framework.Capabilities
33{
34 [OSDMap]
35 public class LLSDEnvironmentRequest
36 {
37 public UUID messageID;
38 public UUID regionID;
39 }
40
41 [OSDMap]
42 public class LLSDEnvironmentSetResponse
43 {
44 public UUID regionID;
45 public UUID messageID;
46 public Boolean success;
47 public String fail_reason;
48 }
49
50 public class EnvironmentSettings
51 {
52 /// <summary>
53 /// generates a empty llsd settings response for viewer
54 /// </summary>
55 /// <param name="messageID">the message UUID</param>
56 /// <param name="regionID">the region UUID</param>
57 public static string EmptySettings(UUID messageID, UUID regionID)
58 {
59 OSDArray arr = new OSDArray();
60 LLSDEnvironmentRequest msg = new LLSDEnvironmentRequest();
61 msg.messageID = messageID;
62 msg.regionID = regionID;
63 arr.Array.Add(msg);
64 return LLSDHelpers.SerialiseLLSDReply(arr);
65 }
66 }
67
68}
diff --git a/OpenSim/Capabilities/LLSDHelpers.cs b/OpenSim/Capabilities/LLSDHelpers.cs
new file mode 100644
index 0000000..d582267
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDHelpers.cs
@@ -0,0 +1,177 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.IO;
31using System.Reflection;
32using System.Xml;
33
34namespace OpenSim.Framework.Capabilities
35{
36 public class LLSDHelpers
37 {
38// private static readonly log4net.ILog m_log
39// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
40
41 public static string SerialiseLLSDReply(object obj)
42 {
43 StringWriter sw = new StringWriter();
44 XmlTextWriter writer = new XmlTextWriter(sw);
45 writer.Formatting = Formatting.None;
46 writer.WriteStartElement(String.Empty, "llsd", String.Empty);
47 SerializeOSDType(writer, obj);
48 writer.WriteEndElement();
49 writer.Close();
50
51 //m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
52
53 return sw.ToString();
54 }
55
56 private static void SerializeOSDType(XmlTextWriter writer, object obj)
57 {
58 Type myType = obj.GetType();
59 LLSDType[] llsdattributes = (LLSDType[]) myType.GetCustomAttributes(typeof (LLSDType), false);
60 if (llsdattributes.Length > 0)
61 {
62 switch (llsdattributes[0].ObjectType)
63 {
64 case "MAP":
65 writer.WriteStartElement(String.Empty, "map", String.Empty);
66 FieldInfo[] fields = myType.GetFields();
67 for (int i = 0; i < fields.Length; i++)
68 {
69 if (fields[i] != null && fields[i].GetValue(obj) != null)
70 {
71 object fieldValue = fields[i].GetValue(obj);
72 LLSDType[] fieldAttributes =
73 (LLSDType[]) fieldValue.GetType().GetCustomAttributes(typeof (LLSDType), false);
74 if (fieldAttributes.Length > 0)
75 {
76 writer.WriteStartElement(String.Empty, "key", String.Empty);
77 string fieldName = fields[i].Name;
78 fieldName = fieldName.Replace("___", "-");
79 writer.WriteString(fieldName);
80 writer.WriteEndElement();
81 SerializeOSDType(writer, fieldValue);
82 }
83 else
84 {
85 writer.WriteStartElement(String.Empty, "key", String.Empty);
86 string fieldName = fields[i].Name;
87 fieldName = fieldName.Replace("___", "-");
88 writer.WriteString(fieldName);
89 writer.WriteEndElement();
90 LLSD.LLSDWriteOne(writer, fieldValue);
91 // OpenMetaverse.StructuredData.LLSDParser.SerializeXmlElement(
92 // writer, OpenMetaverse.StructuredData.OSD.FromObject(fieldValue));
93 }
94 }
95 else
96 {
97 // TODO from ADAM: There is a nullref being caused by fields[i] being null
98 // on some computers. Unsure what is causing this, but would appreciate
99 // if sdague could take a look at this.
100 }
101 }
102 writer.WriteEndElement();
103 break;
104 case "ARRAY":
105 // OSDArray arrayObject = obj as OSDArray;
106 // ArrayList a = arrayObject.Array;
107 ArrayList a = (ArrayList) obj.GetType().GetField("Array").GetValue(obj);
108 if (a != null)
109 {
110 writer.WriteStartElement(String.Empty, "array", String.Empty);
111 foreach (object item in a)
112 {
113 SerializeOSDType(writer, item);
114 }
115 writer.WriteEndElement();
116 }
117 break;
118 }
119 }
120 else
121 {
122 LLSD.LLSDWriteOne(writer, obj);
123 //OpenMetaverse.StructuredData.LLSDParser.SerializeXmlElement(
124 // writer, OpenMetaverse.StructuredData.OSD.FromObject(obj));
125 }
126 }
127
128 public static object DeserialiseOSDMap(Hashtable llsd, object obj)
129 {
130 Type myType = obj.GetType();
131 LLSDType[] llsdattributes = (LLSDType[]) myType.GetCustomAttributes(typeof (LLSDType), false);
132 if (llsdattributes.Length > 0)
133 {
134 switch (llsdattributes[0].ObjectType)
135 {
136 case "MAP":
137 IDictionaryEnumerator enumerator = llsd.GetEnumerator();
138 while (enumerator.MoveNext())
139 {
140 string keyName = (string)enumerator.Key;
141 keyName = keyName.Replace("-","_");
142 FieldInfo field = myType.GetField(keyName);
143 if (field != null)
144 {
145 // if (enumerator.Value is OpenMetaverse.StructuredData.OSDMap)
146 if (enumerator.Value is Hashtable)
147 {
148 object fieldValue = field.GetValue(obj);
149 DeserialiseOSDMap((Hashtable) enumerator.Value, fieldValue);
150 // DeserialiseOSDMap((OpenMetaverse.StructuredData.OSDMap) enumerator.Value, fieldValue);
151 }
152 else if (enumerator.Value is ArrayList)
153 {
154 object fieldValue = field.GetValue(obj);
155 fieldValue.GetType().GetField("Array").SetValue(fieldValue, enumerator.Value);
156 //TODO
157 // the LLSD map/array types in the array need to be deserialised
158 // but first we need to know the right class to deserialise them into.
159 }
160 else if(enumerator.Value is Boolean && field.FieldType == typeof(int) )
161 {
162 int i = (bool)enumerator.Value ? 1 : 0;
163 field.SetValue(obj, (object)i);
164 }
165 else
166 {
167 field.SetValue(obj, enumerator.Value);
168 }
169 }
170 }
171 break;
172 }
173 }
174 return obj;
175 }
176 }
177}
diff --git a/OpenSim/Capabilities/LLSDInventoryFolder.cs b/OpenSim/Capabilities/LLSDInventoryFolder.cs
new file mode 100644
index 0000000..d085430
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDInventoryFolder.cs
@@ -0,0 +1,41 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [OSDMap]
33 public class LLSDInventoryFolder
34 {
35 public UUID folder_id;
36 public UUID parent_id;
37 public string name;
38 public int type;
39 public int preferred_type;
40 }
41}
diff --git a/OpenSim/Capabilities/LLSDInventoryItem.cs b/OpenSim/Capabilities/LLSDInventoryItem.cs
new file mode 100644
index 0000000..460a215
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDInventoryItem.cs
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [OSDMap]
33 public class LLSDInventoryItem
34 {
35 public UUID parent_id;
36
37 public UUID asset_id;
38 public UUID item_id;
39 public LLSDPermissions permissions;
40 public int type;
41 public int inv_type;
42 public int flags;
43
44 public LLSDSaleInfo sale_info;
45 public string name;
46 public string desc;
47 public int created_at;
48 }
49
50 [OSDMap]
51 public class LLSDPermissions
52 {
53 public UUID creator_id;
54 public UUID owner_id;
55 public UUID group_id;
56 public int base_mask;
57 public int owner_mask;
58 public int group_mask;
59 public int everyone_mask;
60 public int next_owner_mask;
61 public bool is_owner_group;
62 }
63
64 [OSDMap]
65 public class LLSDSaleInfo
66 {
67 public int sale_price;
68 public int sale_type;
69 }
70
71 [OSDMap]
72 public class LLSDInventoryDescendents
73 {
74 public OSDArray folders = new OSDArray();
75 }
76
77 [OSDMap]
78 public class LLSDFetchInventoryDescendents
79 {
80 public UUID folder_id;
81 public UUID owner_id;
82 public int sort_order;
83 public bool fetch_folders;
84 public bool fetch_items;
85 }
86
87 [OSDMap]
88 public class LLSDInventoryFolderContents
89 {
90 public UUID agent_id;
91 public int descendents;
92 public UUID folder_id;
93 public OSDArray categories = new OSDArray();
94 public OSDArray items = new OSDArray();
95 public UUID owner_id;
96 public int version;
97 }
98
99 [OSDMap]
100 public class LLSDFetchInventory
101 {
102 public UUID agent_id;
103 public OSDArray items = new OSDArray();
104 }
105} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDItemUpdate.cs b/OpenSim/Capabilities/LLSDItemUpdate.cs
new file mode 100644
index 0000000..96e2b61
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDItemUpdate.cs
@@ -0,0 +1,41 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [OSDMap]
33 public class LLSDItemUpdate
34 {
35 public UUID item_id;
36
37 public LLSDItemUpdate()
38 {
39 }
40 }
41}
diff --git a/OpenSim/Capabilities/LLSDMapLayer.cs b/OpenSim/Capabilities/LLSDMapLayer.cs
new file mode 100644
index 0000000..4aeb1ff
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDMapLayer.cs
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [LLSDType("MAP")]
33 public class OSDMapLayer
34 {
35 public int Left = 0;
36 public int Right = 0;
37 public int Top = 0;
38 public int Bottom = 0;
39 public UUID ImageID = UUID.Zero;
40
41 public OSDMapLayer()
42 {
43 }
44 }
45}
diff --git a/OpenSim/Capabilities/LLSDMapLayerResponse.cs b/OpenSim/Capabilities/LLSDMapLayerResponse.cs
new file mode 100644
index 0000000..839e34c
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDMapLayerResponse.cs
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Capabilities
29{
30 [LLSDType("MAP")]
31 public class LLSDMapLayerResponse
32 {
33 public LLSDMapRequest AgentData = new LLSDMapRequest();
34 public OSDArray LayerData = new OSDArray();
35
36 public LLSDMapLayerResponse()
37 {
38 }
39 }
40} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDMapRequest.cs b/OpenSim/Capabilities/LLSDMapRequest.cs
new file mode 100644
index 0000000..debf387
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDMapRequest.cs
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Capabilities
29{
30 [LLSDType("MAP")]
31 public class LLSDMapRequest
32 {
33 public int Flags = 0;
34
35 public LLSDMapRequest()
36 {
37 }
38 }
39} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDMethod.cs b/OpenSim/Capabilities/LLSDMethod.cs
new file mode 100644
index 0000000..cd2574d
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDMethod.cs
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Capabilities
29{
30 public delegate TResponse LLSDMethod<TRequest, TResponse>(TRequest request);
31} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDMethodString.cs b/OpenSim/Capabilities/LLSDMethodString.cs
new file mode 100644
index 0000000..38700d5
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDMethodString.cs
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Capabilities
29{
30 public delegate TResponse LLSDMethodString<TRequest, TResponse>(TRequest request, string path);
31}
diff --git a/OpenSim/Capabilities/LLSDParcelVoiceInfoResponse.cs b/OpenSim/Capabilities/LLSDParcelVoiceInfoResponse.cs
new file mode 100644
index 0000000..b34a668
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDParcelVoiceInfoResponse.cs
@@ -0,0 +1,51 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSimulator Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System.Collections;
30
31namespace OpenSim.Framework.Capabilities
32{
33 [OSDMap]
34 public class LLSDParcelVoiceInfoResponse
35 {
36 public int parcel_local_id;
37 public string region_name;
38 public Hashtable voice_credentials;
39
40 public LLSDParcelVoiceInfoResponse()
41 {
42 }
43
44 public LLSDParcelVoiceInfoResponse(string region, int localID, Hashtable creds)
45 {
46 region_name = region;
47 parcel_local_id = localID;
48 voice_credentials = creds;
49 }
50 }
51} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDRemoteParcelResponse.cs b/OpenSim/Capabilities/LLSDRemoteParcelResponse.cs
new file mode 100644
index 0000000..13d69d3
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDRemoteParcelResponse.cs
@@ -0,0 +1,42 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSimulator Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using OpenMetaverse;
30
31namespace OpenSim.Framework.Capabilities
32{
33 [LLSDType("MAP")]
34 public class LLSDRemoteParcelResponse
35 {
36 public UUID parcel_id;
37
38 public LLSDRemoteParcelResponse()
39 {
40 }
41 }
42}
diff --git a/OpenSim/Capabilities/LLSDStreamHandler.cs b/OpenSim/Capabilities/LLSDStreamHandler.cs
new file mode 100644
index 0000000..4f1b10a
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDStreamHandler.cs
@@ -0,0 +1,75 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using System.IO;
30using System.Text;
31using OpenSim.Framework.Servers;
32using OpenSim.Framework.Servers.HttpServer;
33
34namespace OpenSim.Framework.Capabilities
35{
36 public class LLSDStreamhandler<TRequest, TResponse> : BaseStreamHandler
37 where TRequest : new()
38 {
39 private LLSDMethod<TRequest, TResponse> m_method;
40
41 public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
42 : this(httpMethod, path, method, null, null) {}
43
44 public LLSDStreamhandler(
45 string httpMethod, string path, LLSDMethod<TRequest, TResponse> method, string name, string description)
46 : base(httpMethod, path, name, description)
47 {
48 m_method = method;
49 }
50
51 protected override byte[] ProcessRequest(string path, Stream request,
52 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
53 {
54 //Encoding encoding = Util.UTF8;
55 //StreamReader streamReader = new StreamReader(request, false);
56
57 //string requestBody = streamReader.ReadToEnd();
58 //streamReader.Close();
59
60 // OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)
61 // OpenMetaverse.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request));
62
63 Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request);
64 if(hash == null)
65 return new byte[0];
66
67 TRequest llsdRequest = new TRequest();
68 LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
69
70 TResponse response = m_method(llsdRequest);
71
72 return Util.UTF8NoBomEncoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
73 }
74 }
75}
diff --git a/OpenSim/Capabilities/LLSDTaskInventoryUploadComplete.cs b/OpenSim/Capabilities/LLSDTaskInventoryUploadComplete.cs
new file mode 100644
index 0000000..47fdaca
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDTaskInventoryUploadComplete.cs
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [OSDMap]
33 public class LLSDTaskInventoryUploadComplete
34 {
35 /// <summary>
36 /// The task inventory item that was updated
37 /// </summary>
38 public UUID item_id;
39
40 /// <summary>
41 /// The task that was updated
42 /// </summary>
43 public UUID task_id;
44
45 /// <summary>
46 /// State of the upload. So far have only even seen this set to "complete"
47 /// </summary>
48 public string state;
49 }
50}
diff --git a/OpenSim/Capabilities/LLSDTaskScriptUpdate.cs b/OpenSim/Capabilities/LLSDTaskScriptUpdate.cs
new file mode 100644
index 0000000..9d7c17f
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDTaskScriptUpdate.cs
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [OSDMap]
33 public class LLSDTaskScriptUpdate
34 {
35 /// <summary>
36 /// The item containing the script to update
37 /// </summary>
38 public UUID item_id;
39
40 /// <summary>
41 /// The task containing the script
42 /// </summary>
43 public UUID task_id;
44
45 /// <summary>
46 /// Signals whether the script is currently active
47 /// </summary>
48 public int is_script_running;
49 }
50}
diff --git a/OpenSim/Capabilities/LLSDTaskScriptUploadComplete.cs b/OpenSim/Capabilities/LLSDTaskScriptUploadComplete.cs
new file mode 100644
index 0000000..d308831
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDTaskScriptUploadComplete.cs
@@ -0,0 +1,54 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29using System;
30using System.Collections;
31
32namespace OpenSim.Framework.Capabilities
33{
34 [OSDMap]
35 public class LLSDTaskScriptUploadComplete
36 {
37 /// <summary>
38 /// The task inventory item that was updated
39 /// </summary>
40 public UUID new_asset;
41
42 /// <summary>
43 /// Was it compiled?
44 /// </summary>
45 public bool compiled;
46
47 /// <summary>
48 /// State of the upload. So far have only even seen this set to "complete"
49 /// </summary>
50 public string state;
51
52 public OSDArray errors;
53 }
54}
diff --git a/OpenSim/Capabilities/LLSDTest.cs b/OpenSim/Capabilities/LLSDTest.cs
new file mode 100644
index 0000000..5f77c3d
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDTest.cs
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Capabilities
29{
30 [LLSDType("MAP")]
31 public class LLSDTest
32 {
33 public int Test1 = 20;
34 public int Test2 = 10;
35
36 public LLSDTest()
37 {
38 }
39 }
40} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDType.cs b/OpenSim/Capabilities/LLSDType.cs
new file mode 100644
index 0000000..d5ca1ab
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDType.cs
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29
30namespace OpenSim.Framework.Capabilities
31{
32 [AttributeUsage(AttributeTargets.Class)]
33 public class LLSDType : Attribute
34 {
35 protected string myType;
36
37 public LLSDType(string type)
38 {
39 myType = type;
40 }
41
42 public string ObjectType
43 {
44 get { return myType; }
45 }
46 }
47
48 [AttributeUsage(AttributeTargets.Class)]
49 public class OSDMap : LLSDType
50 {
51 public OSDMap() : base("MAP")
52 {
53 }
54 }
55} \ No newline at end of file
diff --git a/OpenSim/Capabilities/LLSDVoiceAccountResponse.cs b/OpenSim/Capabilities/LLSDVoiceAccountResponse.cs
new file mode 100644
index 0000000..53c11e7
--- /dev/null
+++ b/OpenSim/Capabilities/LLSDVoiceAccountResponse.cs
@@ -0,0 +1,57 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSimulator Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29namespace OpenSim.Framework.Capabilities
30{
31 [OSDMap]
32 public class LLSDVoiceAccountResponse
33 {
34 public string username;
35 public string password;
36 public string voice_sip_uri_hostname;
37 public string voice_account_server_name;
38
39 public LLSDVoiceAccountResponse()
40 {
41 }
42
43 public LLSDVoiceAccountResponse(string user, string pass)
44 {
45 username = user;
46 password = pass;
47 }
48
49 public LLSDVoiceAccountResponse(string user, string pass, string sipUriHost, string accountServer)
50 {
51 username = user;
52 password = pass;
53 voice_sip_uri_hostname = sipUriHost;
54 voice_account_server_name = accountServer;
55 }
56 }
57} \ No newline at end of file
diff --git a/OpenSim/Capabilities/Properties/AssemblyInfo.cs b/OpenSim/Capabilities/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..72a5240
--- /dev/null
+++ b/OpenSim/Capabilities/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Capabilities")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("http://opensimulator.org")]
12[assembly: AssemblyProduct("OpenSim")]
13[assembly: AssemblyCopyright("OpenSimulator developers")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("7d1a55b1-8fab-42ff-9c83-066a9cc34d76")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32[assembly: AssemblyVersion("0.7.6.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")]