In Core Profiles: as a fallback, try to get profiles from foreign grids using the OpenProfile protocol
Resolves http://opensimulator.org/mantis/view.php?id=69540.8.0.3
							parent
							
								
									f90aee696a
								
							
						
					
					
						commit
						368b29a680
					
				|  | @ -0,0 +1,193 @@ | |||
| /* | ||||
|  * Copyright (c) Contributors, http://opensimulator.org/ | ||||
|  * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  *     * Redistributions of source code must retain the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer. | ||||
|  *     * Redistributions in binary form must reproduce the above copyright | ||||
|  *       notice, this list of conditions and the following disclaimer in the | ||||
|  *       documentation and/or other materials provided with the distribution. | ||||
|  *     * Neither the name of the OpenSimulator Project nor the | ||||
|  *       names of its contributors may be used to endorse or promote products | ||||
|  *       derived from this software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||||
|  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||||
|  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Net; | ||||
| using System.Net.Sockets; | ||||
| using System.Reflection; | ||||
| using System.Text; | ||||
| using System.Xml; | ||||
| using log4net; | ||||
| using Nwc.XmlRpc; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| 
 | ||||
| namespace OpenSim.Region.CoreModules.Avatar.UserProfiles | ||||
| { | ||||
|     /// <summary> | ||||
|     /// A client for accessing a profile server using the OpenProfile protocol. | ||||
|     /// </summary> | ||||
|     /// <remarks> | ||||
|     /// This class was adapted from the full OpenProfile class. Since it's only a client, and not a server, | ||||
|     /// it's much simpler. | ||||
|     /// </remarks> | ||||
|     public class OpenProfileClient | ||||
|     { | ||||
|         static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|          | ||||
|         private string m_serverURI; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Creates a client for accessing a foreign grid's profile server using the OpenProfile protocol. | ||||
|         /// </summary> | ||||
|         /// <param name="serverURI">The grid's profile server URL</param> | ||||
|         public OpenProfileClient(string serverURI) | ||||
|         { | ||||
|             m_serverURI = serverURI; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets an avatar's profile using the OpenProfile protocol. | ||||
|         /// </summary> | ||||
|         /// <param name="props">On success, this will contain the avatar's profile</param> | ||||
|         /// <returns>Success/failure</returns> | ||||
|         /// <remarks> | ||||
|         /// There are two profile modules currently in use in OpenSim: the older one is OpenProfile, and the newer | ||||
|         /// one is UserProfileModule (this file). This method attempts to read an avatar's profile from a foreign | ||||
|         /// grid using the OpenProfile protocol. | ||||
|         /// </remarks> | ||||
|         public bool RequestAvatarPropertiesUsingOpenProfile(ref UserProfileProperties props) | ||||
|         { | ||||
|             Hashtable ReqHash = new Hashtable(); | ||||
|             ReqHash["avatar_id"] = props.UserId.ToString(); | ||||
| 
 | ||||
|             Hashtable profileData = GenericXMLRPCRequest(ReqHash, "avatar_properties_request", m_serverURI); | ||||
| 
 | ||||
|             ArrayList dataArray = (ArrayList)profileData["data"]; | ||||
| 
 | ||||
|             if (dataArray == null || dataArray[0] == null) | ||||
|                 return false; | ||||
|             profileData = (Hashtable)dataArray[0]; | ||||
| 
 | ||||
|             props.WebUrl = string.Empty; | ||||
|             props.AboutText = String.Empty; | ||||
|             props.FirstLifeText = String.Empty; | ||||
|             props.ImageId = UUID.Zero; | ||||
|             props.FirstLifeImageId = UUID.Zero; | ||||
|             props.PartnerId = UUID.Zero; | ||||
| 
 | ||||
|             if (profileData["ProfileUrl"] != null) | ||||
|                 props.WebUrl = profileData["ProfileUrl"].ToString(); | ||||
|             if (profileData["AboutText"] != null) | ||||
|                 props.AboutText = profileData["AboutText"].ToString(); | ||||
|             if (profileData["FirstLifeAboutText"] != null) | ||||
|                 props.FirstLifeText = profileData["FirstLifeAboutText"].ToString(); | ||||
|             if (profileData["Image"] != null) | ||||
|                 props.ImageId = new UUID(profileData["Image"].ToString()); | ||||
|             if (profileData["FirstLifeImage"] != null) | ||||
|                 props.FirstLifeImageId = new UUID(profileData["FirstLifeImage"].ToString()); | ||||
|             if (profileData["Partner"] != null) | ||||
|                 props.PartnerId = new UUID(profileData["Partner"].ToString()); | ||||
| 
 | ||||
|             props.WantToMask = 0; | ||||
|             props.WantToText = String.Empty; | ||||
|             props.SkillsMask = 0; | ||||
|             props.SkillsText = String.Empty; | ||||
|             props.Language = String.Empty; | ||||
| 
 | ||||
|             if (profileData["wantmask"] != null) | ||||
|                 props.WantToMask = Convert.ToInt32(profileData["wantmask"].ToString()); | ||||
|             if (profileData["wanttext"] != null) | ||||
|                 props.WantToText = profileData["wanttext"].ToString(); | ||||
| 
 | ||||
|             if (profileData["skillsmask"] != null) | ||||
|                 props.SkillsMask = Convert.ToInt32(profileData["skillsmask"].ToString()); | ||||
|             if (profileData["skillstext"] != null) | ||||
|                 props.SkillsText = profileData["skillstext"].ToString(); | ||||
| 
 | ||||
|             if (profileData["languages"] != null) | ||||
|                 props.Language = profileData["languages"].ToString(); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         private Hashtable GenericXMLRPCRequest(Hashtable ReqParams, string method, string server) | ||||
|         { | ||||
|             ArrayList SendParams = new ArrayList(); | ||||
|             SendParams.Add(ReqParams); | ||||
| 
 | ||||
|             XmlRpcResponse Resp; | ||||
|             try | ||||
|             { | ||||
|                 XmlRpcRequest Req = new XmlRpcRequest(method, SendParams); | ||||
|                 Resp = Req.Send(server, 30000); | ||||
|             } | ||||
|             catch (WebException ex) | ||||
|             { | ||||
|                 m_log.ErrorFormat("[PROFILE]: Unable to connect to Profile " + | ||||
|                         "Server {0}.  Exception {1}", server, ex); | ||||
| 
 | ||||
|                 Hashtable ErrorHash = new Hashtable(); | ||||
|                 ErrorHash["success"] = false; | ||||
|                 ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; | ||||
|                 ErrorHash["errorURI"] = ""; | ||||
| 
 | ||||
|                 return ErrorHash; | ||||
|             } | ||||
|             catch (SocketException ex) | ||||
|             { | ||||
|                 m_log.ErrorFormat( | ||||
|                         "[PROFILE]: Unable to connect to Profile Server {0}. Method {1}, params {2}. " + | ||||
|                         "Exception {3}", server, method, ReqParams, ex); | ||||
| 
 | ||||
|                 Hashtable ErrorHash = new Hashtable(); | ||||
|                 ErrorHash["success"] = false; | ||||
|                 ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; | ||||
|                 ErrorHash["errorURI"] = ""; | ||||
| 
 | ||||
|                 return ErrorHash; | ||||
|             } | ||||
|             catch (XmlException ex) | ||||
|             { | ||||
|                 m_log.ErrorFormat( | ||||
|                         "[PROFILE]: Unable to connect to Profile Server {0}. Method {1}, params {2}. " + | ||||
|                         "Exception {3}", server, method, ReqParams.ToString(), ex); | ||||
|                 Hashtable ErrorHash = new Hashtable(); | ||||
|                 ErrorHash["success"] = false; | ||||
|                 ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; | ||||
|                 ErrorHash["errorURI"] = ""; | ||||
| 
 | ||||
|                 return ErrorHash; | ||||
|             } | ||||
|             if (Resp.IsFault) | ||||
|             { | ||||
|                 Hashtable ErrorHash = new Hashtable(); | ||||
|                 ErrorHash["success"] = false; | ||||
|                 ErrorHash["errorMessage"] = "Unable to fetch profile data at this time. "; | ||||
|                 ErrorHash["errorURI"] = ""; | ||||
|                 return ErrorHash; | ||||
|             } | ||||
|             Hashtable RespData = (Hashtable)Resp.Value; | ||||
| 
 | ||||
|             return RespData; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -47,7 +47,7 @@ using OpenSim.Services.Interfaces; | |||
| using Mono.Addins; | ||||
| using OpenSim.Services.Connectors.Hypergrid; | ||||
| 
 | ||||
| namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | ||||
| namespace OpenSim.Region.CoreModules.Avatar.UserProfiles | ||||
| { | ||||
|     [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")] | ||||
|     public class UserProfileModule : IProfileModule, INonSharedRegionModule | ||||
|  | @ -999,7 +999,31 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | |||
|             string result = string.Empty; | ||||
| 
 | ||||
|             props.UserId = avatarID; | ||||
|             GetProfileData(ref props, out result); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 GetProfileData(ref props, out result); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 if (foreign) | ||||
|                 { | ||||
|                     // Check if the foreign grid is using OpenProfile. | ||||
|                     // If any error occurs then discard it, and report the original error. | ||||
|                     try | ||||
|                     { | ||||
|                         OpenProfileClient client = new OpenProfileClient(serverURI); | ||||
|                         if (!client.RequestAvatarPropertiesUsingOpenProfile(ref props)) | ||||
|                             throw e; | ||||
|                     } | ||||
|                     catch (Exception) | ||||
|                     { | ||||
|                         throw e; | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                     throw; | ||||
|             } | ||||
| 
 | ||||
|             remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, charterMember , props.FirstLifeText, flags, | ||||
|                                               props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Oren Hurvitz
						Oren Hurvitz