View of /trunk/GridServer/Extensions/OpenSimXmlRpc.cs
Parent Directory
|
Revision Log
Revision 69 -
(download)
(annotate)
Tue Jan 13 20:22:52 2009 UTC (4 years, 5 months ago) by jhurliman
File size: 41201 byte(s)
Tue Jan 13 20:22:52 2009 UTC (4 years, 5 months ago) by jhurliman
File size: 41201 byte(s)
* Moved authentication checks from the backend to the frontend. This allows insecure frontends such as the OpenSim connectors, or partial information to be displayed such as the BrowseFrontend * Fixed HTTP connection handling in OpenSimInventoryFrontend * Continued work on GridServer, attempting to unify the interface architecture of AssetServer and GridServer
/*
* Copyright (c) 2008 Intel Corporation
* All rights reserved.
* 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 Intel Corporation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``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 INTEL OR ITS
* 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.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using ExtensionLoader;
using ExtensionLoader.Config;
using HttpServer;
using Nwc.XmlRpc;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace GridServer.Extensions
{
public class OpenSimXmlRpc : IExtension<GridServer>
{
// XML-RPC error codes, from http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
const int METHOD_NOT_FOUND = -32601;
const int INTERNAL_ERROR = -32603;
delegate XmlRpcResponse XmlRpcMethod(XmlRpcRequest request);
GridServer server;
XmlRpcRequestDeserializer deserializer = new XmlRpcRequestDeserializer();
Dictionary<string, XmlRpcMethod> methods = new Dictionary<string, XmlRpcMethod>();
int minimumLoginLevel = 0;
Random random = new Random();
Uri gridServer;
string defaultWelcomeMessage;
uint defaultHomeX;
uint defaultHomeY;
public OpenSimXmlRpc()
{
}
public void Start(GridServer server)
{
this.server = server;
#region Default setting loading
try
{
IConfig extensionConfig = server.ConfigFile.Configs["Config"];
gridServer = new Uri(extensionConfig.GetString("GridServer"));
defaultWelcomeMessage = extensionConfig.GetString("DefaultWelcomeMessage");
defaultHomeX = (uint)extensionConfig.GetInt("DefaultHomeRegionX");
defaultHomeY = (uint)extensionConfig.GetInt("DefaultHomeRegionY");
}
catch (Exception)
{
Logger.Log.Error("Failed to load [Config] section from " + GridServer.CONFIG_FILE);
}
#endregion Default setting loading
server.HttpServer.AddHandler("post", "text/xml", @"^/$", XmlRpcRequestHandler);
AddXmlRpcHandler("login_to_simulator", LoginMethod);
AddXmlRpcHandler("get_user_by_name", GetUserByNameMethod);
AddXmlRpcHandler("get_user_by_uuid", GetUserByUUIDMethod);
AddXmlRpcHandler("get_avatar_picker_avatar", GetAvatarPickerAvatarMethod);
AddXmlRpcHandler("add_new_user_friend", AddFriendMethod);
AddXmlRpcHandler("remove_user_friend", RemoveFriendMethod);
AddXmlRpcHandler("update_user_friend_perms", UpdateFriendPermsMethod);
AddXmlRpcHandler("get_user_friend_list", GetFriendListMethod);
AddXmlRpcHandler("get_avatar_appearance", GetAvatarAppearanceMethod);
AddXmlRpcHandler("update_avatar_appearance", UpdateAvatarAppearanceMethod);
AddXmlRpcHandler("update_user_current_region", UpdateCurrentRegionMethod);
AddXmlRpcHandler("logout_of_simulator", LogOffUserMethod);
AddXmlRpcHandler("get_agent_by_uuid", GetAgentByUUIDMethod);
AddXmlRpcHandler("check_auth_session", CheckAuthSessionMethod);
AddXmlRpcHandler("set_login_params", SetLoginParamsMethod);
AddXmlRpcHandler("region_startup", RegionStartupMethod);
AddXmlRpcHandler("region_shutdown", RegionShutdownMethod);
AddXmlRpcHandler("agent_location", AgentLocationMethod);
AddXmlRpcHandler("agent_leaving", AgentLeavingMethod);
AddXmlRpcHandler("register_messageserver", RegisterMessageServerMethod);
AddXmlRpcHandler("agent_change_region", UserMovedtoRegionMethod);
AddXmlRpcHandler("deregister_messageserver", DeRegisterMessageServerMethod);
AddXmlRpcHandler("get_grid_info", GridInfoMethod);
AddXmlRpcHandler("update_user_profile", UpdateUserProfileMethod);
}
public void Stop()
{
}
void AddXmlRpcHandler(string methodName, XmlRpcMethod method)
{
methods[methodName] = method;
}
bool XmlRpcRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response)
{
XmlRpcRequest rpcRequest = null;
XmlRpcResponse rpcResponse = null;
try
{ rpcRequest = deserializer.Deserialize(new StreamReader(request.Body)) as XmlRpcRequest; }
catch (XmlException ex)
{ Logger.Log.Warn("Failed to deserialize incoming XML-RPC request: " + ex.Message); }
if (request != null)
{
XmlRpcMethod method;
string methodName = rpcRequest.MethodName;
response.ContentType = "text/xml";
// FIXME: Add support to HttpServer.dll for this
//response.ContentEncoding = Encoding.UTF8;
response.Chunked = false;
if (!String.IsNullOrEmpty(methodName) && methods.TryGetValue(methodName, out method))
{
rpcRequest.Params.Add(request.RemoteEndPoint);
rpcRequest.Params.Add(request.Uri);
try
{
rpcResponse = method(rpcRequest);
string responseString = XmlRpcResponseSerializer.Singleton.Serialize(response);
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
// Set the content-length, otherwise the LL viewer freaks out
response.ContentLength = buffer.Length;
response.Body.Write(buffer, 0, buffer.Length);
response.Body.Flush();
}
catch (Exception ex)
{
Logger.Log.ErrorFormat("XML-RPC method {0} threw exception: {1}", methodName, ex.ToString());
rpcResponse = new XmlRpcResponse();
rpcResponse.SetFault(INTERNAL_ERROR, String.Format("Requested method [{0}] threw exception: {1}", methodName, ex.Message));
XmlRpcResponseSerializer.Singleton.Serialize(new XmlTextWriter(response.Body, Encoding.UTF8), response);
}
}
else
{
rpcResponse = new XmlRpcResponse();
rpcResponse.SetFault(METHOD_NOT_FOUND, String.Format("Requested method [{0}] not found", methodName));
XmlRpcResponseSerializer.Singleton.Serialize(new XmlTextWriter(response.Body, Encoding.UTF8), response);
}
}
else
{
response.Status = HttpStatusCode.BadRequest;
}
return true;
}
void LogoutAvatar(UUID authToken, Avatar avatar)
{
// FIXME: Notify the simulator this avatar is logging out
server.SessionProvider.RemoveSession(authToken);
}
#region Login XML responses
public XmlRpcResponse CreateFailureResponse(string reason, string message, bool loginSuccess)
{
Hashtable responseData = new Hashtable(3);
responseData["reason"] = reason;
responseData["message"] = message;
responseData["login"] = loginSuccess.ToString().ToLower();
XmlRpcResponse response = new XmlRpcResponse();
response.Value = responseData;
return response;
}
public XmlRpcResponse CreateLoginFailedResponse()
{
return CreateFailureResponse(
"key",
"Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.",
false);
}
public XmlRpcResponse CreateLoginGridErrorResponse()
{
return CreateFailureResponse(
"key",
"Error connecting to grid. Could not perceive credentials from login XML.",
false);
}
public XmlRpcResponse CreateLoginBlockedResponse()
{
return CreateFailureResponse(
"presence",
"Logins are currently restricted. Please try again later",
false);
}
public XmlRpcResponse CreateLoginInternalErrorResponse()
{
return CreateFailureResponse(
"key",
"The login server failed to complete the login process. Please try again later",
false);
}
#endregion Login XML responses
#region Grid service XML responses
XmlRpcResponse AvatarToXmlRPCResponse(Avatar avatar)
{
Hashtable responseData = new Hashtable();
// Account information
responseData["firstname"] = avatar.GetAttribute(AvatarAttributes.FIRST_NAME).AsString();
responseData["lastname"] = avatar.GetAttribute(AvatarAttributes.LAST_NAME).AsString();
responseData["uuid"] = avatar.ID.ToString();
// Server Information
responseData["server_inventory"] = avatar.GetAttribute(AvatarAttributes.INVENTORY_SERVER).AsString();
responseData["server_asset"] = avatar.GetAttribute(AvatarAttributes.ASSET_SERVER).AsString();
// Profile Information
responseData["profile_about"] = avatar.GetAttribute(AvatarAttributes.AVATAR_BIOGRAPHY).AsString();
responseData["profile_firstlife_about"] = avatar.GetAttribute(AvatarAttributes.AVATAR_IMAGE_ID).AsString();
responseData["profile_firstlife_image"] = avatar.GetAttribute(AvatarAttributes.IMAGE_ID).AsUUID().ToString();
responseData["profile_can_do"] = avatar.GetAttribute(AvatarAttributes.AVATAR_CAN_DO).AsUInteger().ToString();
responseData["profile_want_do"] = avatar.GetAttribute(AvatarAttributes.AVATAR_WANT_DO).AsUInteger().ToString();
responseData["profile_image"] = avatar.GetAttribute(AvatarAttributes.AVATAR_IMAGE_ID).AsUUID().ToString();
DateTime date = (avatar.Attributes.ContainsKey(AvatarAttributes.BIRTH_DATE) ? avatar.GetAttribute(AvatarAttributes.BIRTH_DATE).AsDate() : OpenMetaverse.Utils.Epoch);
responseData["profile_created"] = ((int)OpenMetaverse.Utils.DateTimeToUnixTime(date)).ToString();
date = (avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_LAST_LOGIN_DATE) ? avatar.GetAttribute(AvatarAttributes.AVATAR_LAST_LOGIN_DATE).AsDate() : OpenMetaverse.Utils.Epoch);
responseData["profile_lastlogin"] = ((int)OpenMetaverse.Utils.DateTimeToUnixTime(date)).ToString();
// Home region information
OSDArray array = (OSDArray)avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_POSITION);
responseData["home_coordinates_x"] = array[0].AsString();
responseData["home_coordinates_y"] = array[1].AsString();
responseData["home_coordinates_z"] = array[2].AsString();
uint homeRegionX = (uint)avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_REGION_X).AsInteger();
uint homeRegionY = (uint)avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_REGION_Y).AsInteger();
responseData["home_region"] = OpenMetaverse.Utils.UIntsToLong(homeRegionX, homeRegionY);
responseData["home_region_id"] = avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_REGION_ID).AsUUID().ToString();
array = (OSDArray)avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_LOOKAT);
responseData["home_look_x"] = array[0].AsString();
responseData["home_look_y"] = array[1].AsString();
responseData["home_look_z"] = array[2].AsString();
// User flags and data
responseData["user_flags"] = avatar.GetAttribute(AvatarAttributes.AVATAR_FLAGS).AsString();
responseData["god_level"] = avatar.GetAttribute(AvatarAttributes.AVATAR_GOD_LEVEL).AsString();
responseData["custom_type"] = String.Empty;
responseData["partner"] = avatar.GetAttribute(AvatarAttributes.AVATAR_PARTNER_ID).AsUUID().ToString();
XmlRpcResponse response = new XmlRpcResponse();
response.Value = responseData;
return response;
}
XmlRpcResponse CreateUnknownUserErrorResponse()
{
Hashtable responseData = new Hashtable(2);
responseData["error_type"] = "unknown_user";
responseData["error_desc"] = "The user requested is not in the database";
XmlRpcResponse response = new XmlRpcResponse();
response.Value = responseData;
return response;
}
#endregion Grid service XML responses
#region XML-RPC Methods
XmlRpcResponse LoginMethod(XmlRpcRequest request)
{
Hashtable requestData = (Hashtable)request.Params[0];
bool validLogin = requestData.ContainsKey("first") && requestData.ContainsKey("last") &&
(requestData.ContainsKey("passwd") || requestData.Contains("web_login_key"));
if (validLogin)
{
string startLocation = (requestData.ContainsKey("start") ? (string)requestData["start"] : "last");
string version = (requestData.ContainsKey("version") ? (string)requestData["version"] : "Unknown");
string firstName = (string)requestData["first"];
string lastName = (string)requestData["last"];
string passHash = (string)requestData["passwd"];
Logger.Log.InfoFormat("Received XML-RPC login request for {0} {1} with client \"{2}\" to destination {3}",
firstName, lastName, version, startLocation);
if (!String.IsNullOrEmpty(passHash))
{
// loginkey is first + last + hash
string loginKey = String.Format("{0}{1}{2}", firstName, lastName, passHash);
Avatar avatar;
if (server.AvatarProvider.TryGetAvatar(loginKey, out avatar))
{
int godLevel = (avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_GOD_LEVEL) ?
avatar.GetAttribute(AvatarAttributes.AVATAR_GOD_LEVEL).AsInteger() :
0);
if (godLevel >= minimumLoginLevel)
{
UUID authToken;
// Check if this avatar is already logged in. If so, destroy the old session
if (server.SessionProvider.TryGetSession(avatar.ID, out authToken))
LogoutAvatar(authToken, avatar);
if ((authToken = server.SessionProvider.CreateSession(avatar.ID)) != UUID.Zero)
{
// Session is created, construct the login response
LindenLogin response = new LindenLogin();
response.AgentID = avatar.ID;
response.BuddyList = GetBuddyList(avatar.ID);
SetClassifiedCategories(ref response);
response.CircuitCode = random.Next();
response.FirstName = avatar.GetAttribute(AvatarAttributes.FIRST_NAME).AsString();
response.HomeLookAt = avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_LOOKAT).AsVector3();
response.HomePosition = avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_POSITION).AsVector3();
response.HomeRegionX = (uint)avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_REGION_X).AsInteger();
response.HomeRegionY = (uint)avatar.GetAttribute(AvatarAttributes.AVATAR_HOME_REGION_Y).AsInteger();
response.LastName = avatar.GetAttribute(AvatarAttributes.LAST_NAME).AsString();
response.Login = true;
response.LookAt = avatar.GetAttribute(AvatarAttributes.AVATAR_LAST_LOOKAT).AsVector3();
response.Message = defaultWelcomeMessage;
response.RegionX = (uint)avatar.GetAttribute(AvatarAttributes.AVATAR_LAST_REGION_X).AsInteger();
response.RegionY = (uint)avatar.GetAttribute(AvatarAttributes.AVATAR_LAST_REGION_Y).AsInteger();
response.SecureSessionID = UUID.Random();
response.SeedCapability = GetSeedCapability(avatar.ID);
response.SessionID = UUID.Random();
FetchInventory(avatar, ref response);
FetchGridInfo(startLocation, avatar, ref response);
return response.ToXmlRpcResponse();
}
else
{
return CreateLoginInternalErrorResponse();
}
}
else
{
return CreateLoginBlockedResponse();
}
}
else
{
return CreateLoginFailedResponse();
}
}
else
{
string webLoginKey = (string)requestData["web_login_key"];
Logger.Log.Error("web_login_key is not supported yet");
return CreateLoginFailedResponse();
}
}
else
{
return CreateLoginGridErrorResponse();
}
}
string GetSeedCapability(UUID avatarID)
{
//FIXME:
return String.Empty;
}
Hashtable GetBuddyList(UUID avatarID)
{
// TODO: Buddy list support
return new Hashtable(0);
}
void SetClassifiedCategories(ref LindenLogin response)
{
response.AddClassifiedCategory(1, "Shopping");
response.AddClassifiedCategory(2, "Land Rental");
response.AddClassifiedCategory(3, "Property Rental");
response.AddClassifiedCategory(4, "Special Attraction");
response.AddClassifiedCategory(5, "New Products");
response.AddClassifiedCategory(6, "Employment");
response.AddClassifiedCategory(7, "Wanted");
response.AddClassifiedCategory(8, "Service");
response.AddClassifiedCategory(9, "Personal");
}
void FetchInventory(Avatar avatar, ref LindenLogin response)
{
Uri inventoryServer = avatar.GetAttribute(AvatarAttributes.INVENTORY_SERVER).AsUri();
UUID libraryOwner = avatar.GetAttribute(AvatarAttributes.AVATAR_LIBRARY_OWNER).AsUUID();
UUID inventoryRoot = UUID.Zero;
UUID libraryRoot = UUID.Zero;
if (inventoryServer.IsAbsoluteUri)
{
// Active gestures
List<InventoryItem> items = OpenSimGridComm.GetActiveGestures(inventoryServer, avatar.ID);
ArrayList activeGestures = new ArrayList(items.Count);
foreach (InventoryItem item in items)
{
Hashtable itemData = new Hashtable();
itemData["item_id"] = item.ID.ToString();
itemData["asset_id"] = item.AssetID.ToString();
}
response.ActiveGestures = activeGestures;
// Agent inventory skeleton
List<InventoryFolder> inventoryFolders = OpenSimGridComm.GetInventoryFolders(inventoryServer, avatar.ID);
ArrayList agentInventory = new ArrayList(inventoryFolders.Count);
foreach (InventoryFolder folder in inventoryFolders)
{
Hashtable folderData = new Hashtable();
folderData["name"] = folder.Name;
folderData["parent_id"] = folder.ParentID.ToString();
folderData["version"] = (int)folder.Version;
folderData["type_default"] = (int)folder.Type;
folderData["folder_id"] = folder.ID.ToString();
agentInventory.Add(folderData);
}
if (agentInventory.Count == 0)
{
Logger.Log.WarnFormat("Inventory skeleton could be fetched for avatar {0}, sending a temporary root folder",
avatar.ID);
response.InventoryRoot = UUID.Random();
Hashtable folderData = new Hashtable();
folderData["name"] = "Temporary Inventory";
folderData["parent_id"] = UUID.Zero.ToString();
folderData["version"] = 1;
folderData["type_default"] = 8; // Folder
folderData["folder_id"] = response.InventoryRoot.ToString();
agentInventory.Add(folderData);
}
else
{
response.InventoryRoot = inventoryRoot;
}
response.AgentInventory = agentInventory;
// Library inventory skeleton
List<InventoryFolder> libraryFolders = OpenSimGridComm.GetInventoryFolders(inventoryServer, libraryOwner);
ArrayList libraryInventory = new ArrayList(libraryFolders.Count);
foreach (InventoryFolder folder in libraryFolders)
{
Hashtable folderData = new Hashtable();
folderData["name"] = folder.Name;
folderData["parent_id"] = folder.ParentID.ToString();
folderData["version"] = (int)folder.Version;
folderData["type_default"] = (int)folder.Type;
folderData["folder_id"] = folder.ID.ToString();
libraryInventory.Add(folderData);
}
if (libraryInventory.Count == 0)
{
Logger.Log.WarnFormat("Library skeleton could be fetched for avatar {0}, sending a temporary root folder",
avatar.ID);
response.InventoryLibRoot = UUID.Random();
Hashtable folderData = new Hashtable();
folderData["name"] = "Temporary Library";
folderData["parent_id"] = UUID.Zero.ToString();
folderData["version"] = 1;
folderData["type_default"] = 8; // Folder
folderData["folder_id"] = response.InventoryLibRoot.ToString();
libraryInventory.Add(folderData);
}
else
{
response.InventoryLibRoot = libraryRoot;
}
response.InventoryLibrary = libraryInventory;
// Library owner
if (libraryOwner == UUID.Zero && libraryFolders.Count > 0)
libraryRoot = libraryFolders[0].Owner;
response.InventoryLibraryOwner = libraryOwner;
}
else
{
Logger.Log.ErrorFormat("Logging in with avatar {0} {1} that has no inventory server",
avatar.GetAttribute(AvatarAttributes.FIRST_NAME).AsString(),
avatar.GetAttribute(AvatarAttributes.LAST_NAME).AsString());
}
}
void FetchGridInfo(string startLocation, Avatar avatar, ref LindenLogin response)
{
Vector3 position = new Vector3(128f, 128f, 128f);
RegionProfileData regionInfo = null;
switch (startLocation)
{
case "home":
case "safe":
// Try and get the home location for this avatar
if (avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_HOME_REGION_X) &&
avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_HOME_REGION_Y))
{
regionInfo = OpenSimGridComm.RequestSimProfileData(
avatar.Attributes[AvatarAttributes.AVATAR_HOME_REGION_X].AsUInteger(),
avatar.Attributes[AvatarAttributes.AVATAR_HOME_REGION_Y].AsUInteger(),
gridServer, null, null);
response.StartLocation = "home";
}
break;
case "last":
// Try and get the last location for this avatar
if (avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_LAST_REGION_X) &&
avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_LAST_REGION_Y))
{
regionInfo = OpenSimGridComm.RequestSimProfileData(
avatar.Attributes[AvatarAttributes.AVATAR_LAST_REGION_X].AsUInteger(),
avatar.Attributes[AvatarAttributes.AVATAR_LAST_REGION_Y].AsUInteger(),
gridServer, null, null);
response.StartLocation = "last";
}
// Try and fall back on the home location if last is not set
else if (avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_HOME_REGION_X) &&
avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_HOME_REGION_Y))
{
regionInfo = OpenSimGridComm.RequestSimProfileData(
avatar.Attributes[AvatarAttributes.AVATAR_HOME_REGION_X].AsUInteger(),
avatar.Attributes[AvatarAttributes.AVATAR_HOME_REGION_Y].AsUInteger(),
gridServer, null, null);
response.StartLocation = "home";
}
break;
default:
Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
Match uriMatch = reURI.Match(startLocation);
if (uriMatch != null)
{
regionInfo = OpenSimGridComm.RequestSimProfileData(uriMatch.Groups["region"].ToString(), gridServer, null, null);
if (regionInfo != null)
{
Single.TryParse(uriMatch.Groups["x"].Value, out position.X);
Single.TryParse(uriMatch.Groups["y"].Value, out position.Y);
Single.TryParse(uriMatch.Groups["z"].Value, out position.Z);
}
}
if (regionInfo == null)
Logger.Log.Warn("Can't locate a simulator from custom login URI: " + startLocation);
break;
}
// Try the default fallback region
if (regionInfo == null)
{
regionInfo = OpenSimGridComm.RequestSimProfileData(
defaultHomeX,
defaultHomeY,
gridServer, null, null);
response.StartLocation = "safe";
}
if (regionInfo != null)
{
response.SimAddress = OpenSimGridComm.GetIPFromURL(regionInfo.ServerURI).ToString();
string[] urlSplit = regionInfo.ServerURI.Split(new char[] { '/', ':' });
if (urlSplit.Length < 5 || !UInt32.TryParse(urlSplit[4], out response.SimPort))
response.SimPort = 80;
response.RegionX = regionInfo.LocationX;
response.RegionY = regionInfo.LocationY;
string opensimHack = UUID.Random().ToString().Substring(0, 32);
response.SeedCapability = new Uri(new Uri(regionInfo.HttpServerURI), "CAPS/" + opensimHack).ToString() + "0000/";
if (OpenSimGridComm.NotifySimulatorOfLogin(regionInfo, response.SessionID, response.SecureSessionID, response.FirstName,
response.LastName, response.AgentID, response.CircuitCode, position, opensimHack))
{
// Set home attributes if they have not been set yet
if (!avatar.Attributes.ContainsKey(AvatarAttributes.AVATAR_HOME_POSITION))
{
avatar.Attributes[AvatarAttributes.AVATAR_HOME_REGION_X] = OSD.FromInteger((int)regionInfo.LocationX);
avatar.Attributes[AvatarAttributes.AVATAR_HOME_REGION_Y] = OSD.FromInteger((int)regionInfo.LocationY);
avatar.Attributes[AvatarAttributes.AVATAR_HOME_POSITION] = OSD.FromVector3(position);
avatar.Attributes[AvatarAttributes.AVATAR_HOME_LOOKAT] = OSD.FromVector3(position + Vector3.UnitZ);
}
// Set last attributes
avatar.Attributes[AvatarAttributes.AVATAR_LAST_REGION_X] = OSD.FromInteger((int)regionInfo.LocationX);
avatar.Attributes[AvatarAttributes.AVATAR_LAST_REGION_Y] = OSD.FromInteger((int)regionInfo.LocationY);
avatar.Attributes[AvatarAttributes.AVATAR_LAST_POSITION] = OSD.FromVector3(position);
avatar.Attributes[AvatarAttributes.AVATAR_LAST_LOOKAT] = OSD.FromVector3(position + Vector3.UnitZ);
if (!server.AvatarProvider.SaveAvatar(avatar))
{
Logger.Log.Error("Failed saving avatar data, login is bailing out");
// FIXME: Notify the simulator of the logout
response.Login = false;
response.ErrorReason = "key";
response.Message = "Failed to update avatar profile information. Please try again later";
}
}
else
{
Logger.Log.ErrorFormat("Failed to notify simulator {0} about new login", regionInfo.RegionName);
response.Login = false;
response.ErrorReason = "presence";
response.Message = "Could not contact the target simulator. Please try again later or try logging in to another simulator";
}
}
else
{
Logger.Log.ErrorFormat("Could not find default fallback simulator at {0},{1}, is the grid service running?",
defaultHomeX, defaultHomeY);
response.Login = false;
response.ErrorReason = "presence";
response.Message = "Could not find a valid simulator to login to. Grid server may be down";
}
}
XmlRpcResponse GetUserByNameMethod(XmlRpcRequest request)
{
Hashtable requestData = request.Params[0] as Hashtable;
if (requestData != null && requestData.ContainsKey("avatar_name"))
{
string avatarName = requestData["avatar_name"] as string;
string[] firstLast = avatarName.Split(' ');
if (firstLast.Length == 2)
{
Avatar foundAvatar = null;
bool eof = false;
int pos = 0;
#region Avatar name search
// Search through all of the avatars for a name match
while (foundAvatar == null && !eof)
{
int count = server.AvatarProvider.ForEach(
delegate(Avatar avatar)
{
if (foundAvatar == null &&
avatar.GetAttribute(AvatarAttributes.FIRST_NAME).AsString() == firstLast[0] &&
avatar.GetAttribute(AvatarAttributes.LAST_NAME).AsString() == firstLast[1])
{
foundAvatar = avatar;
}
}, pos, 100);
if (count > 0)
pos += count;
else
eof = true;
}
#endregion Avatar name search
if (foundAvatar != null)
return AvatarToXmlRPCResponse(foundAvatar);
}
}
return CreateUnknownUserErrorResponse();
}
XmlRpcResponse GetUserByUUIDMethod(XmlRpcRequest request)
{
Hashtable requestData = request.Params[0] as Hashtable;
UUID avatarID;
if (requestData != null && requestData.ContainsKey("avatar_uuid") && UUID.TryParse((string)requestData["avatar_uuid"], out avatarID))
{
Avatar foundAvatar;
if (server.AvatarProvider.TryGetAvatar(avatarID, out foundAvatar))
return AvatarToXmlRPCResponse(foundAvatar);
}
return CreateUnknownUserErrorResponse();
}
XmlRpcResponse GetAvatarPickerAvatarMethod(XmlRpcRequest request)
{
Hashtable requestData = (Hashtable)request.Params[0];
List<Avatar> results;
UUID queryID = UUID.Zero;
if (requestData.ContainsKey("avquery") && requestData.Contains("queryid") && UUID.TryParse((string)requestData["queryid"], out queryID))
{
string query = (string)requestData["avquery"];
results = server.AvatarProvider.AvatarSearch(query);
}
else
{
results = new List<Avatar>();
}
Hashtable responseData = new Hashtable();
responseData["queryid"] = queryID.ToString();
responseData["avcount"] = results.Count.ToString();
for (int i = 0; i < results.Count; i++)
{
Avatar avatar = results[i];
responseData["avatarid" + i] = avatar.ID.ToString();
responseData["firstname" + i] = avatar.GetAttribute(AvatarAttributes.FIRST_NAME).AsString();
responseData["lastname" + i] = avatar.GetAttribute(AvatarAttributes.LAST_NAME).AsString();
}
XmlRpcResponse response = new XmlRpcResponse();
response.Value = responseData;
return response;
}
XmlRpcResponse AddFriendMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse RemoveFriendMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse UpdateFriendPermsMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse GetFriendListMethod(XmlRpcRequest request)
{
// FIXME: Implement friends list support
Hashtable responseData = new Hashtable();
responseData["avcount"] = "0";
//for (int i = 0; i < returnUsers.Count; i++)
//{
//responseData["ownerID" + i] = returnUsers[i].FriendListOwner.ToString();
//responseData["friendID" + i] = returnUsers[i].Friend.ToString();
//responseData["ownerPerms" + i] = returnUsers[i].FriendListOwnerPerms.ToString();
//responseData["friendPerms" + i] = returnUsers[i].FriendPerms.ToString();
//}
XmlRpcResponse response = new XmlRpcResponse();
response.Value = responseData;
return response;
}
XmlRpcResponse GetAvatarAppearanceMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse UpdateAvatarAppearanceMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse UpdateCurrentRegionMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse LogOffUserMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse GetAgentByUUIDMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse CheckAuthSessionMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse SetLoginParamsMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse RegionStartupMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse RegionShutdownMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse AgentLocationMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse AgentLeavingMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse RegisterMessageServerMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse UserMovedtoRegionMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse DeRegisterMessageServerMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse GridInfoMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
XmlRpcResponse UpdateUserProfileMethod(XmlRpcRequest request)
{
// FIXME:
return new XmlRpcResponse();
}
#endregion XML-RPC Methods
}
}
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

