diff options
Diffstat (limited to 'OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs')
-rw-r--r-- | OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs | 860 |
1 files changed, 0 insertions, 860 deletions
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs deleted file mode 100644 index 3cda984..0000000 --- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs +++ /dev/null | |||
@@ -1,860 +0,0 @@ | |||
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 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Xml; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Servers; | ||
35 | using OpenSim.Framework.Servers.HttpServer; | ||
36 | using OpenSim.Services.Interfaces; | ||
37 | |||
38 | namespace OpenSim.ApplicationPlugins.Rest.Inventory | ||
39 | { | ||
40 | |||
41 | public class RestAppearanceServices : IRest | ||
42 | { | ||
43 | // private static readonly int PARM_USERID = 0; | ||
44 | |||
45 | // private static readonly int PARM_PATH = 1; | ||
46 | |||
47 | // private bool enabled = false; | ||
48 | private string qPrefix = "appearance"; | ||
49 | |||
50 | /// <summary> | ||
51 | /// The constructor makes sure that the service prefix is absolute | ||
52 | /// and the registers the service handler and the allocator. | ||
53 | /// </summary> | ||
54 | |||
55 | public RestAppearanceServices() | ||
56 | { | ||
57 | Rest.Log.InfoFormat("{0} User appearance services initializing", MsgId); | ||
58 | Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version); | ||
59 | |||
60 | // If a relative path was specified for the handler's domain, | ||
61 | // add the standard prefix to make it absolute, e.g. /admin | ||
62 | |||
63 | if (!qPrefix.StartsWith(Rest.UrlPathSeparator)) | ||
64 | { | ||
65 | Rest.Log.InfoFormat("{0} Domain is relative, adding absolute prefix", MsgId); | ||
66 | qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix); | ||
67 | qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix); | ||
68 | Rest.Log.InfoFormat("{0} Domain is now <{1}>", MsgId, qPrefix); | ||
69 | } | ||
70 | |||
71 | // Register interface using the absolute URI. | ||
72 | |||
73 | Rest.Plugin.AddPathHandler(DoAppearance,qPrefix,Allocate); | ||
74 | |||
75 | // Activate if everything went OK | ||
76 | |||
77 | // enabled = true; | ||
78 | |||
79 | Rest.Log.InfoFormat("{0} User appearance services initialization complete", MsgId); | ||
80 | } | ||
81 | |||
82 | /// <summary> | ||
83 | /// Post-construction, pre-enabled initialization opportunity | ||
84 | /// Not currently exploited. | ||
85 | /// </summary> | ||
86 | |||
87 | public void Initialize() | ||
88 | { | ||
89 | } | ||
90 | |||
91 | /// <summary> | ||
92 | /// Called by the plug-in to halt service processing. Local processing is | ||
93 | /// disabled. | ||
94 | /// </summary> | ||
95 | |||
96 | public void Close() | ||
97 | { | ||
98 | // enabled = false; | ||
99 | Rest.Log.InfoFormat("{0} User appearance services closing down", MsgId); | ||
100 | } | ||
101 | |||
102 | /// <summary> | ||
103 | /// This property is declared locally because it is used a lot and | ||
104 | /// brevity is nice. | ||
105 | /// </summary> | ||
106 | |||
107 | internal string MsgId | ||
108 | { | ||
109 | get { return Rest.MsgId; } | ||
110 | } | ||
111 | |||
112 | #region Interface | ||
113 | |||
114 | /// <summary> | ||
115 | /// The plugin (RestHandler) calls this method to allocate the request | ||
116 | /// state carrier for a new request. It is destroyed when the request | ||
117 | /// completes. All request-instance specific state is kept here. This | ||
118 | /// is registered when this service provider is registered. | ||
119 | /// </summary> | ||
120 | /// <param name=request>Inbound HTTP request information</param> | ||
121 | /// <param name=response>Outbound HTTP request information</param> | ||
122 | /// <param name=qPrefix>REST service domain prefix</param> | ||
123 | /// <returns>A RequestData instance suitable for this service</returns> | ||
124 | |||
125 | private RequestData Allocate(OSHttpRequest request, OSHttpResponse response, string prefix) | ||
126 | { | ||
127 | return (RequestData) new AppearanceRequestData(request, response, prefix); | ||
128 | } | ||
129 | |||
130 | /// <summary> | ||
131 | /// This method is registered with the handler when this service provider | ||
132 | /// is initialized. It is called whenever the plug-in identifies this service | ||
133 | /// provider as the best match for a given request. | ||
134 | /// It handles all aspects of inventory REST processing, i.e. /admin/inventory | ||
135 | /// </summary> | ||
136 | /// <param name=hdata>A consolidated HTTP request work area</param> | ||
137 | |||
138 | private void DoAppearance(RequestData hdata) | ||
139 | { | ||
140 | // !!! REFACTORIMG PROBLEM. This needs rewriting for 0.7 | ||
141 | |||
142 | //AppearanceRequestData rdata = (AppearanceRequestData) hdata; | ||
143 | |||
144 | //Rest.Log.DebugFormat("{0} DoAppearance ENTRY", MsgId); | ||
145 | |||
146 | //// If we're disabled, do nothing. | ||
147 | |||
148 | //if (!enabled) | ||
149 | //{ | ||
150 | // return; | ||
151 | //} | ||
152 | |||
153 | //// Now that we know this is a serious attempt to | ||
154 | //// access inventory data, we should find out who | ||
155 | //// is asking, and make sure they are authorized | ||
156 | //// to do so. We need to validate the caller's | ||
157 | //// identity before revealing anything about the | ||
158 | //// status quo. Authenticate throws an exception | ||
159 | //// via Fail if no identity information is present. | ||
160 | //// | ||
161 | //// With the present HTTP server we can't use the | ||
162 | //// builtin authentication mechanisms because they | ||
163 | //// would be enforced for all in-bound requests. | ||
164 | //// Instead we look at the headers ourselves and | ||
165 | //// handle authentication directly. | ||
166 | |||
167 | //try | ||
168 | //{ | ||
169 | // if (!rdata.IsAuthenticated) | ||
170 | // { | ||
171 | // rdata.Fail(Rest.HttpStatusCodeNotAuthorized,String.Format("user \"{0}\" could not be authenticated", rdata.userName)); | ||
172 | // } | ||
173 | //} | ||
174 | //catch (RestException e) | ||
175 | //{ | ||
176 | // if (e.statusCode == Rest.HttpStatusCodeNotAuthorized) | ||
177 | // { | ||
178 | // Rest.Log.WarnFormat("{0} User not authenticated", MsgId); | ||
179 | // Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, rdata.request.Headers.Get("Authorization")); | ||
180 | // } | ||
181 | // else | ||
182 | // { | ||
183 | // Rest.Log.ErrorFormat("{0} User authentication failed", MsgId); | ||
184 | // Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, rdata.request.Headers.Get("Authorization")); | ||
185 | // } | ||
186 | // throw (e); | ||
187 | //} | ||
188 | |||
189 | //Rest.Log.DebugFormat("{0} Authenticated {1}", MsgId, rdata.userName); | ||
190 | |||
191 | //// We can only get here if we are authorized | ||
192 | //// | ||
193 | //// The requestor may have specified an UUID or | ||
194 | //// a conjoined FirstName LastName string. We'll | ||
195 | //// try both. If we fail with the first, UUID, | ||
196 | //// attempt, we try the other. As an example, the | ||
197 | //// URI for a valid inventory request might be: | ||
198 | //// | ||
199 | //// http://<host>:<port>/admin/inventory/Arthur Dent | ||
200 | //// | ||
201 | //// Indicating that this is an inventory request for | ||
202 | //// an avatar named Arthur Dent. This is ALL that is | ||
203 | //// required to designate a GET for an entire | ||
204 | //// inventory. | ||
205 | //// | ||
206 | |||
207 | //// Do we have at least a user agent name? | ||
208 | |||
209 | //if (rdata.Parameters.Length < 1) | ||
210 | //{ | ||
211 | // Rest.Log.WarnFormat("{0} Appearance: No user agent identifier specified", MsgId); | ||
212 | // rdata.Fail(Rest.HttpStatusCodeBadRequest, "no user identity specified"); | ||
213 | //} | ||
214 | |||
215 | //// The first parameter MUST be the agent identification, either an UUID | ||
216 | //// or a space-separated First-name Last-Name specification. We check for | ||
217 | //// an UUID first, if anyone names their character using a valid UUID | ||
218 | //// that identifies another existing avatar will cause this a problem... | ||
219 | |||
220 | //try | ||
221 | //{ | ||
222 | // rdata.uuid = new UUID(rdata.Parameters[PARM_USERID]); | ||
223 | // Rest.Log.DebugFormat("{0} UUID supplied", MsgId); | ||
224 | // rdata.userProfile = Rest.UserServices.GetUserProfile(rdata.uuid); | ||
225 | //} | ||
226 | //catch | ||
227 | //{ | ||
228 | // string[] names = rdata.Parameters[PARM_USERID].Split(Rest.CA_SPACE); | ||
229 | // if (names.Length == 2) | ||
230 | // { | ||
231 | // Rest.Log.DebugFormat("{0} Agent Name supplied [2]", MsgId); | ||
232 | // rdata.userProfile = Rest.UserServices.GetUserProfile(names[0],names[1]); | ||
233 | // } | ||
234 | // else | ||
235 | // { | ||
236 | // Rest.Log.WarnFormat("{0} A Valid UUID or both first and last names must be specified", MsgId); | ||
237 | // rdata.Fail(Rest.HttpStatusCodeBadRequest, "invalid user identity"); | ||
238 | // } | ||
239 | //} | ||
240 | |||
241 | //// If the user profile is null then either the server is broken, or the | ||
242 | //// user is not known. We always assume the latter case. | ||
243 | |||
244 | //if (rdata.userProfile != null) | ||
245 | //{ | ||
246 | // Rest.Log.DebugFormat("{0} User profile obtained for agent {1} {2}", | ||
247 | // MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName); | ||
248 | //} | ||
249 | //else | ||
250 | //{ | ||
251 | // Rest.Log.WarnFormat("{0} No user profile for {1}", MsgId, rdata.path); | ||
252 | // rdata.Fail(Rest.HttpStatusCodeNotFound, "unrecognized user identity"); | ||
253 | //} | ||
254 | |||
255 | //// If we get to here, then we have effectively validated the user's | ||
256 | |||
257 | //switch (rdata.method) | ||
258 | //{ | ||
259 | // case Rest.HEAD : // Do the processing, set the status code, suppress entity | ||
260 | // DoGet(rdata); | ||
261 | // rdata.buffer = null; | ||
262 | // break; | ||
263 | |||
264 | // case Rest.GET : // Do the processing, set the status code, return entity | ||
265 | // DoGet(rdata); | ||
266 | // break; | ||
267 | |||
268 | // case Rest.PUT : // Update named element | ||
269 | // DoUpdate(rdata); | ||
270 | // break; | ||
271 | |||
272 | // case Rest.POST : // Add new information to identified context. | ||
273 | // DoExtend(rdata); | ||
274 | // break; | ||
275 | |||
276 | // case Rest.DELETE : // Delete information | ||
277 | // DoDelete(rdata); | ||
278 | // break; | ||
279 | |||
280 | // default : | ||
281 | // Rest.Log.WarnFormat("{0} Method {1} not supported for {2}", | ||
282 | // MsgId, rdata.method, rdata.path); | ||
283 | // rdata.Fail(Rest.HttpStatusCodeMethodNotAllowed, | ||
284 | // String.Format("{0} not supported", rdata.method)); | ||
285 | // break; | ||
286 | //} | ||
287 | } | ||
288 | |||
289 | #endregion Interface | ||
290 | |||
291 | #region method-specific processing | ||
292 | |||
293 | /// <summary> | ||
294 | /// This method implements GET processing for user's appearance. | ||
295 | /// </summary> | ||
296 | /// <param name=rdata>HTTP service request work area</param> | ||
297 | |||
298 | // private void DoGet(AppearanceRequestData rdata) | ||
299 | // { | ||
300 | // AvatarData adata = Rest.AvatarServices.GetAvatar(rdata.userProfile.ID); | ||
301 | // | ||
302 | // if (adata == null) | ||
303 | // { | ||
304 | // rdata.Fail(Rest.HttpStatusCodeNoContent, | ||
305 | // String.Format("appearance data not found for user {0} {1}", | ||
306 | // rdata.userProfile.FirstName, rdata.userProfile.SurName)); | ||
307 | // } | ||
308 | // rdata.userAppearance = adata.ToAvatarAppearance(rdata.userProfile.ID); | ||
309 | // | ||
310 | // rdata.initXmlWriter(); | ||
311 | // | ||
312 | // FormatUserAppearance(rdata); | ||
313 | // | ||
314 | // // Indicate a successful request | ||
315 | // | ||
316 | // rdata.Complete(); | ||
317 | // | ||
318 | // // Send the response to the user. The body will be implicitly | ||
319 | // // constructed from the result of the XML writer. | ||
320 | // | ||
321 | // rdata.Respond(String.Format("Appearance {0} Normal completion", rdata.method)); | ||
322 | // } | ||
323 | |||
324 | /// <summary> | ||
325 | /// POST adds NEW information to the user profile database. | ||
326 | /// This effectively resets the appearance before applying those | ||
327 | /// characteristics supplied in the request. | ||
328 | /// </summary> | ||
329 | |||
330 | // private void DoExtend(AppearanceRequestData rdata) | ||
331 | // { | ||
332 | // | ||
333 | // bool created = false; | ||
334 | // bool modified = false; | ||
335 | // string newnode = String.Empty; | ||
336 | // | ||
337 | // Rest.Log.DebugFormat("{0} POST ENTRY", MsgId); | ||
338 | // | ||
339 | // //AvatarAppearance old = Rest.AvatarServices.GetUserAppearance(rdata.userProfile.ID); | ||
340 | // | ||
341 | // rdata.userAppearance = new AvatarAppearance(); | ||
342 | // | ||
343 | // // Although the following behavior is admitted by HTTP I am becoming | ||
344 | // // increasingly doubtful that it is appropriate for REST. If I attempt to | ||
345 | // // add a new record, and it already exists, then it seems to me that the | ||
346 | // // attempt should fail, rather than update the existing record. | ||
347 | // AvatarData adata = null; | ||
348 | // if (GetUserAppearance(rdata)) | ||
349 | // { | ||
350 | // modified = rdata.userAppearance != null; | ||
351 | // created = !modified; | ||
352 | // adata = new AvatarData(rdata.userAppearance); | ||
353 | // Rest.AvatarServices.SetAvatar(rdata.userProfile.ID, adata); | ||
354 | // // Rest.UserServices.UpdateUserProfile(rdata.userProfile); | ||
355 | // } | ||
356 | // else | ||
357 | // { | ||
358 | // created = true; | ||
359 | // adata = new AvatarData(rdata.userAppearance); | ||
360 | // Rest.AvatarServices.SetAvatar(rdata.userProfile.ID, adata); | ||
361 | // // Rest.UserServices.UpdateUserProfile(rdata.userProfile); | ||
362 | // } | ||
363 | // | ||
364 | // if (created) | ||
365 | // { | ||
366 | // newnode = String.Format("{0} {1}", rdata.userProfile.FirstName, | ||
367 | // rdata.userProfile.SurName); | ||
368 | // // Must include a location header with a URI that identifies the new resource. | ||
369 | // | ||
370 | // rdata.AddHeader(Rest.HttpHeaderLocation,String.Format("http://{0}{1}:{2}{3}{4}", | ||
371 | // rdata.hostname,rdata.port,rdata.path,Rest.UrlPathSeparator, newnode)); | ||
372 | // rdata.Complete(Rest.HttpStatusCodeCreated); | ||
373 | // | ||
374 | // } | ||
375 | // else | ||
376 | // { | ||
377 | // if (modified) | ||
378 | // { | ||
379 | // rdata.Complete(Rest.HttpStatusCodeOK); | ||
380 | // } | ||
381 | // else | ||
382 | // { | ||
383 | // rdata.Complete(Rest.HttpStatusCodeNoContent); | ||
384 | // } | ||
385 | // } | ||
386 | // | ||
387 | // rdata.Respond(String.Format("Appearance {0} : Normal completion", rdata.method)); | ||
388 | // | ||
389 | // } | ||
390 | |||
391 | /// <summary> | ||
392 | /// This updates the user's appearance. not all aspects need to be provided, | ||
393 | /// only those supplied will be changed. | ||
394 | /// </summary> | ||
395 | |||
396 | // private void DoUpdate(AppearanceRequestData rdata) | ||
397 | // { | ||
398 | // | ||
399 | // // REFACTORING PROBLEM This was commented out. It doesn't work for 0.7 | ||
400 | // | ||
401 | // //bool created = false; | ||
402 | // //bool modified = false; | ||
403 | // | ||
404 | // | ||
405 | // //rdata.userAppearance = Rest.AvatarServices.GetUserAppearance(rdata.userProfile.ID); | ||
406 | // | ||
407 | // //// If the user exists then this is considered a modification regardless | ||
408 | // //// of what may, or may not be, specified in the payload. | ||
409 | // | ||
410 | // //if (rdata.userAppearance != null) | ||
411 | // //{ | ||
412 | // // modified = true; | ||
413 | // // Rest.AvatarServices.UpdateUserAppearance(rdata.userProfile.ID, rdata.userAppearance); | ||
414 | // // Rest.UserServices.UpdateUserProfile(rdata.userProfile); | ||
415 | // //} | ||
416 | // | ||
417 | // //if (created) | ||
418 | // //{ | ||
419 | // // rdata.Complete(Rest.HttpStatusCodeCreated); | ||
420 | // //} | ||
421 | // //else | ||
422 | // //{ | ||
423 | // // if (modified) | ||
424 | // // { | ||
425 | // // rdata.Complete(Rest.HttpStatusCodeOK); | ||
426 | // // } | ||
427 | // // else | ||
428 | // // { | ||
429 | // // rdata.Complete(Rest.HttpStatusCodeNoContent); | ||
430 | // // } | ||
431 | // //} | ||
432 | // | ||
433 | // rdata.Respond(String.Format("Appearance {0} : Normal completion", rdata.method)); | ||
434 | // | ||
435 | // } | ||
436 | |||
437 | /// <summary> | ||
438 | /// Delete the specified user's appearance. This actually performs a reset | ||
439 | /// to the default avatar appearance, if the info is already there. | ||
440 | /// Existing ownership is preserved. All prior updates are lost and can not | ||
441 | /// be recovered. | ||
442 | /// </summary> | ||
443 | // private void DoDelete(AppearanceRequestData rdata) | ||
444 | // { | ||
445 | // AvatarData adata = Rest.AvatarServices.GetAvatar(rdata.userProfile.ID); | ||
446 | // | ||
447 | // if (adata != null) | ||
448 | // { | ||
449 | // AvatarAppearance old = adata.ToAvatarAppearance(rdata.userProfile.ID); | ||
450 | // rdata.userAppearance = new AvatarAppearance(); | ||
451 | // rdata.userAppearance.Owner = old.Owner; | ||
452 | // adata = new AvatarData(rdata.userAppearance); | ||
453 | // | ||
454 | // Rest.AvatarServices.SetAvatar(rdata.userProfile.ID, adata); | ||
455 | // | ||
456 | // rdata.Complete(); | ||
457 | // } | ||
458 | // else | ||
459 | // { | ||
460 | // | ||
461 | // rdata.Complete(Rest.HttpStatusCodeNoContent); | ||
462 | // } | ||
463 | // | ||
464 | // rdata.Respond(String.Format("Appearance {0} : Normal completion", rdata.method)); | ||
465 | // } | ||
466 | |||
467 | #endregion method-specific processing | ||
468 | |||
469 | private bool GetUserAppearance(AppearanceRequestData rdata) | ||
470 | { | ||
471 | |||
472 | XmlReader xml; | ||
473 | bool indata = false; | ||
474 | |||
475 | rdata.initXmlReader(); | ||
476 | xml = rdata.reader; | ||
477 | |||
478 | while (xml.Read()) | ||
479 | { | ||
480 | switch (xml.NodeType) | ||
481 | { | ||
482 | case XmlNodeType.Element : | ||
483 | switch (xml.Name) | ||
484 | { | ||
485 | case "Appearance" : | ||
486 | if (xml.MoveToAttribute("Height")) | ||
487 | { | ||
488 | rdata.userAppearance.AvatarHeight = (float) Convert.ToDouble(xml.Value); | ||
489 | indata = true; | ||
490 | } | ||
491 | // if (xml.MoveToAttribute("Owner")) | ||
492 | // { | ||
493 | // rdata.userAppearance.Owner = (UUID)xml.Value; | ||
494 | // indata = true; | ||
495 | // } | ||
496 | if (xml.MoveToAttribute("Serial")) | ||
497 | { | ||
498 | rdata.userAppearance.Serial = Convert.ToInt32(xml.Value); | ||
499 | indata = true; | ||
500 | } | ||
501 | break; | ||
502 | /* | ||
503 | case "Body" : | ||
504 | if (xml.MoveToAttribute("Item")) | ||
505 | { | ||
506 | rdata.userAppearance.BodyItem = (UUID)xml.Value; | ||
507 | indata = true; | ||
508 | } | ||
509 | if (xml.MoveToAttribute("Asset")) | ||
510 | { | ||
511 | rdata.userAppearance.BodyAsset = (UUID)xml.Value; | ||
512 | indata = true; | ||
513 | } | ||
514 | break; | ||
515 | case "Skin" : | ||
516 | if (xml.MoveToAttribute("Item")) | ||
517 | { | ||
518 | rdata.userAppearance.SkinItem = (UUID)xml.Value; | ||
519 | indata = true; | ||
520 | } | ||
521 | if (xml.MoveToAttribute("Asset")) | ||
522 | { | ||
523 | rdata.userAppearance.SkinAsset = (UUID)xml.Value; | ||
524 | indata = true; | ||
525 | } | ||
526 | break; | ||
527 | case "Hair" : | ||
528 | if (xml.MoveToAttribute("Item")) | ||
529 | { | ||
530 | rdata.userAppearance.HairItem = (UUID)xml.Value; | ||
531 | indata = true; | ||
532 | } | ||
533 | if (xml.MoveToAttribute("Asset")) | ||
534 | { | ||
535 | rdata.userAppearance.HairAsset = (UUID)xml.Value; | ||
536 | indata = true; | ||
537 | } | ||
538 | break; | ||
539 | case "Eyes" : | ||
540 | if (xml.MoveToAttribute("Item")) | ||
541 | { | ||
542 | rdata.userAppearance.EyesItem = (UUID)xml.Value; | ||
543 | indata = true; | ||
544 | } | ||
545 | if (xml.MoveToAttribute("Asset")) | ||
546 | { | ||
547 | rdata.userAppearance.EyesAsset = (UUID)xml.Value; | ||
548 | indata = true; | ||
549 | } | ||
550 | break; | ||
551 | case "Shirt" : | ||
552 | if (xml.MoveToAttribute("Item")) | ||
553 | { | ||
554 | rdata.userAppearance.ShirtItem = (UUID)xml.Value; | ||
555 | indata = true; | ||
556 | } | ||
557 | if (xml.MoveToAttribute("Asset")) | ||
558 | { | ||
559 | rdata.userAppearance.ShirtAsset = (UUID)xml.Value; | ||
560 | indata = true; | ||
561 | } | ||
562 | break; | ||
563 | case "Pants" : | ||
564 | if (xml.MoveToAttribute("Item")) | ||
565 | { | ||
566 | rdata.userAppearance.PantsItem = (UUID)xml.Value; | ||
567 | indata = true; | ||
568 | } | ||
569 | if (xml.MoveToAttribute("Asset")) | ||
570 | { | ||
571 | rdata.userAppearance.PantsAsset = (UUID)xml.Value; | ||
572 | indata = true; | ||
573 | } | ||
574 | break; | ||
575 | case "Shoes" : | ||
576 | if (xml.MoveToAttribute("Item")) | ||
577 | { | ||
578 | rdata.userAppearance.ShoesItem = (UUID)xml.Value; | ||
579 | indata = true; | ||
580 | } | ||
581 | if (xml.MoveToAttribute("Asset")) | ||
582 | { | ||
583 | rdata.userAppearance.ShoesAsset = (UUID)xml.Value; | ||
584 | indata = true; | ||
585 | } | ||
586 | break; | ||
587 | case "Socks" : | ||
588 | if (xml.MoveToAttribute("Item")) | ||
589 | { | ||
590 | rdata.userAppearance.SocksItem = (UUID)xml.Value; | ||
591 | indata = true; | ||
592 | } | ||
593 | if (xml.MoveToAttribute("Asset")) | ||
594 | { | ||
595 | rdata.userAppearance.SocksAsset = (UUID)xml.Value; | ||
596 | indata = true; | ||
597 | } | ||
598 | break; | ||
599 | case "Jacket" : | ||
600 | if (xml.MoveToAttribute("Item")) | ||
601 | { | ||
602 | rdata.userAppearance.JacketItem = (UUID)xml.Value; | ||
603 | indata = true; | ||
604 | } | ||
605 | if (xml.MoveToAttribute("Asset")) | ||
606 | { | ||
607 | rdata.userAppearance.JacketAsset = (UUID)xml.Value; | ||
608 | indata = true; | ||
609 | } | ||
610 | break; | ||
611 | case "Gloves" : | ||
612 | if (xml.MoveToAttribute("Item")) | ||
613 | { | ||
614 | rdata.userAppearance.GlovesItem = (UUID)xml.Value; | ||
615 | indata = true; | ||
616 | } | ||
617 | if (xml.MoveToAttribute("Asset")) | ||
618 | { | ||
619 | rdata.userAppearance.GlovesAsset = (UUID)xml.Value; | ||
620 | indata = true; | ||
621 | } | ||
622 | break; | ||
623 | case "UnderShirt" : | ||
624 | if (xml.MoveToAttribute("Item")) | ||
625 | { | ||
626 | rdata.userAppearance.UnderShirtItem = (UUID)xml.Value; | ||
627 | indata = true; | ||
628 | } | ||
629 | if (xml.MoveToAttribute("Asset")) | ||
630 | { | ||
631 | rdata.userAppearance.UnderShirtAsset = (UUID)xml.Value; | ||
632 | indata = true; | ||
633 | } | ||
634 | break; | ||
635 | case "UnderPants" : | ||
636 | if (xml.MoveToAttribute("Item")) | ||
637 | { | ||
638 | rdata.userAppearance.UnderPantsItem = (UUID)xml.Value; | ||
639 | indata = true; | ||
640 | } | ||
641 | if (xml.MoveToAttribute("Asset")) | ||
642 | { | ||
643 | rdata.userAppearance.UnderPantsAsset = (UUID)xml.Value; | ||
644 | indata = true; | ||
645 | } | ||
646 | break; | ||
647 | case "Skirt" : | ||
648 | if (xml.MoveToAttribute("Item")) | ||
649 | { | ||
650 | rdata.userAppearance.SkirtItem = (UUID)xml.Value; | ||
651 | indata = true; | ||
652 | } | ||
653 | if (xml.MoveToAttribute("Asset")) | ||
654 | { | ||
655 | rdata.userAppearance.SkirtAsset = (UUID)xml.Value; | ||
656 | indata = true; | ||
657 | } | ||
658 | break; | ||
659 | */ | ||
660 | case "Attachment" : | ||
661 | { | ||
662 | |||
663 | int ap; | ||
664 | UUID asset; | ||
665 | UUID item; | ||
666 | |||
667 | if (xml.MoveToAttribute("AtPoint")) | ||
668 | { | ||
669 | ap = Convert.ToInt32(xml.Value); | ||
670 | if (xml.MoveToAttribute("Asset")) | ||
671 | { | ||
672 | asset = new UUID(xml.Value); | ||
673 | if (xml.MoveToAttribute("Asset")) | ||
674 | { | ||
675 | item = new UUID(xml.Value); | ||
676 | rdata.userAppearance.SetAttachment(ap, item, asset); | ||
677 | indata = true; | ||
678 | } | ||
679 | } | ||
680 | } | ||
681 | } | ||
682 | break; | ||
683 | case "Texture" : | ||
684 | if (xml.MoveToAttribute("Default")) | ||
685 | { | ||
686 | rdata.userAppearance.Texture = new Primitive.TextureEntry(new UUID(xml.Value)); | ||
687 | indata = true; | ||
688 | } | ||
689 | break; | ||
690 | case "Face" : | ||
691 | { | ||
692 | uint index; | ||
693 | if (xml.MoveToAttribute("Index")) | ||
694 | { | ||
695 | index = Convert.ToUInt32(xml.Value); | ||
696 | if (xml.MoveToAttribute("Id")) | ||
697 | { | ||
698 | rdata.userAppearance.Texture.CreateFace(index).TextureID = new UUID(xml.Value); | ||
699 | indata = true; | ||
700 | } | ||
701 | } | ||
702 | } | ||
703 | break; | ||
704 | case "VisualParameters" : | ||
705 | { | ||
706 | xml.ReadContentAsBase64(rdata.userAppearance.VisualParams, | ||
707 | 0, rdata.userAppearance.VisualParams.Length); | ||
708 | indata = true; | ||
709 | } | ||
710 | break; | ||
711 | } | ||
712 | break; | ||
713 | } | ||
714 | } | ||
715 | |||
716 | return indata; | ||
717 | |||
718 | } | ||
719 | |||
720 | private void FormatPart(AppearanceRequestData rdata, string part, UUID item, UUID asset) | ||
721 | { | ||
722 | if (item != UUID.Zero || asset != UUID.Zero) | ||
723 | { | ||
724 | rdata.writer.WriteStartElement(part); | ||
725 | if (item != UUID.Zero) | ||
726 | { | ||
727 | rdata.writer.WriteAttributeString("Item",item.ToString()); | ||
728 | } | ||
729 | |||
730 | if (asset != UUID.Zero) | ||
731 | { | ||
732 | rdata.writer.WriteAttributeString("Asset",asset.ToString()); | ||
733 | } | ||
734 | rdata.writer.WriteEndElement(); | ||
735 | } | ||
736 | } | ||
737 | |||
738 | private void FormatUserAppearance(AppearanceRequestData rdata) | ||
739 | { | ||
740 | |||
741 | Rest.Log.DebugFormat("{0} FormatUserAppearance", MsgId); | ||
742 | |||
743 | if (rdata.userAppearance != null) | ||
744 | { | ||
745 | |||
746 | Rest.Log.DebugFormat("{0} FormatUserAppearance: appearance object exists", MsgId); | ||
747 | rdata.writer.WriteStartElement("Appearance"); | ||
748 | |||
749 | rdata.writer.WriteAttributeString("Height", rdata.userAppearance.AvatarHeight.ToString()); | ||
750 | // if (rdata.userAppearance.Owner != UUID.Zero) | ||
751 | // rdata.writer.WriteAttributeString("Owner", rdata.userAppearance.Owner.ToString()); | ||
752 | rdata.writer.WriteAttributeString("Serial", rdata.userAppearance.Serial.ToString()); | ||
753 | |||
754 | /* | ||
755 | FormatPart(rdata, "Body", rdata.userAppearance.BodyItem, rdata.userAppearance.BodyAsset); | ||
756 | FormatPart(rdata, "Skin", rdata.userAppearance.SkinItem, rdata.userAppearance.SkinAsset); | ||
757 | FormatPart(rdata, "Hair", rdata.userAppearance.HairItem, rdata.userAppearance.HairAsset); | ||
758 | FormatPart(rdata, "Eyes", rdata.userAppearance.EyesItem, rdata.userAppearance.EyesAsset); | ||
759 | |||
760 | FormatPart(rdata, "Shirt", rdata.userAppearance.ShirtItem, rdata.userAppearance.ShirtAsset); | ||
761 | FormatPart(rdata, "Pants", rdata.userAppearance.PantsItem, rdata.userAppearance.PantsAsset); | ||
762 | FormatPart(rdata, "Skirt", rdata.userAppearance.SkirtItem, rdata.userAppearance.SkirtAsset); | ||
763 | FormatPart(rdata, "Shoes", rdata.userAppearance.ShoesItem, rdata.userAppearance.ShoesAsset); | ||
764 | FormatPart(rdata, "Socks", rdata.userAppearance.SocksItem, rdata.userAppearance.SocksAsset); | ||
765 | |||
766 | FormatPart(rdata, "Jacket", rdata.userAppearance.JacketItem, rdata.userAppearance.JacketAsset); | ||
767 | FormatPart(rdata, "Gloves", rdata.userAppearance.GlovesItem, rdata.userAppearance.GlovesAsset); | ||
768 | |||
769 | FormatPart(rdata, "UnderShirt", rdata.userAppearance.UnderShirtItem, rdata.userAppearance.UnderShirtAsset); | ||
770 | FormatPart(rdata, "UnderPants", rdata.userAppearance.UnderPantsItem, rdata.userAppearance.UnderPantsAsset); | ||
771 | */ | ||
772 | Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting attachments", MsgId); | ||
773 | |||
774 | rdata.writer.WriteStartElement("Attachments"); | ||
775 | List<AvatarAttachment> attachments = rdata.userAppearance.GetAttachments(); | ||
776 | foreach (AvatarAttachment attach in attachments) | ||
777 | { | ||
778 | rdata.writer.WriteStartElement("Attachment"); | ||
779 | rdata.writer.WriteAttributeString("AtPoint", attach.AttachPoint.ToString()); | ||
780 | rdata.writer.WriteAttributeString("Item", attach.ItemID.ToString()); | ||
781 | rdata.writer.WriteAttributeString("Asset", attach.AssetID.ToString()); | ||
782 | rdata.writer.WriteEndElement(); | ||
783 | } | ||
784 | rdata.writer.WriteEndElement(); | ||
785 | |||
786 | Primitive.TextureEntry texture = rdata.userAppearance.Texture; | ||
787 | |||
788 | if (texture != null && (texture.DefaultTexture != null || texture.FaceTextures != null)) | ||
789 | { | ||
790 | Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting textures", MsgId); | ||
791 | |||
792 | rdata.writer.WriteStartElement("Texture"); | ||
793 | |||
794 | if (texture.DefaultTexture != null) | ||
795 | { | ||
796 | Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting default texture", MsgId); | ||
797 | rdata.writer.WriteAttributeString("Default", | ||
798 | texture.DefaultTexture.TextureID.ToString()); | ||
799 | } | ||
800 | |||
801 | if (texture.FaceTextures != null) | ||
802 | { | ||
803 | |||
804 | Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting face textures", MsgId); | ||
805 | |||
806 | for (int i=0; i<texture.FaceTextures.Length;i++) | ||
807 | { | ||
808 | if (texture.FaceTextures[i] != null) | ||
809 | { | ||
810 | rdata.writer.WriteStartElement("Face"); | ||
811 | rdata.writer.WriteAttributeString("Index", i.ToString()); | ||
812 | rdata.writer.WriteAttributeString("Id", | ||
813 | texture.FaceTextures[i].TextureID.ToString()); | ||
814 | rdata.writer.WriteEndElement(); | ||
815 | } | ||
816 | } | ||
817 | } | ||
818 | |||
819 | rdata.writer.WriteEndElement(); | ||
820 | } | ||
821 | |||
822 | Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting visual parameters", MsgId); | ||
823 | |||
824 | rdata.writer.WriteStartElement("VisualParameters"); | ||
825 | rdata.writer.WriteBase64(rdata.userAppearance.VisualParams,0, | ||
826 | rdata.userAppearance.VisualParams.Length); | ||
827 | rdata.writer.WriteEndElement(); | ||
828 | rdata.writer.WriteFullEndElement(); | ||
829 | } | ||
830 | |||
831 | Rest.Log.DebugFormat("{0} FormatUserAppearance: completed", MsgId); | ||
832 | |||
833 | return; | ||
834 | } | ||
835 | |||
836 | #region appearance RequestData extension | ||
837 | |||
838 | internal class AppearanceRequestData : RequestData | ||
839 | { | ||
840 | |||
841 | /// <summary> | ||
842 | /// These are the inventory specific request/response state | ||
843 | /// extensions. | ||
844 | /// </summary> | ||
845 | |||
846 | internal UUID uuid = UUID.Zero; | ||
847 | internal UserProfileData userProfile = null; | ||
848 | internal AvatarAppearance userAppearance = null; | ||
849 | |||
850 | internal AppearanceRequestData(OSHttpRequest request, OSHttpResponse response, string prefix) | ||
851 | : base(request, response, prefix) | ||
852 | { | ||
853 | } | ||
854 | |||
855 | } | ||
856 | |||
857 | #endregion Appearance RequestData extension | ||
858 | |||
859 | } | ||
860 | } | ||