Files
libremetaverse/libsecondlife/libsecondlife.Utilities/RegistrationApi.cs
John Hurliman 037b7b0aed Initial check-in of the new CAPS rewrite. Current issues:
* Original CapsEventQueue is still being used until a bug in the new one can be resolved
* New progress callbacks are not being utilized (yet)
* Listener classes (CapsListener and EventQueueListener) are only stubs right now

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1518 52acb1d6-8a22-11de-b505-999d5b087335
2007-12-06 00:58:28 +00:00

328 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Text;
using libsecondlife.StructuredData;
using libsecondlife.Capabilities;
namespace libsecondlife
{
public class RegistrationApi
{
private struct UserInfo
{
public string FirstName;
public string LastName;
public string Password;
}
private struct RegistrationCaps
{
public Uri CreateUser;
public Uri CheckName;
public Uri GetLastNames;
public Uri GetErrorCodes;
}
public struct LastName
{
public int ID;
public string Name;
}
/// <summary>
/// see https://secure-web6.secondlife.com/developers/third_party_reg/#service_create_user or
/// https://wiki.secondlife.com/wiki/RegAPIDoc for description
/// </summary>
public class CreateUserParam
{
public string FirstName;
public LastName LastName;
public string Email;
public string Password;
public DateTime Birthdate;
// optional:
public Nullable<int> LimitedToEstate;
public string StartRegionName;
public Nullable<LLVector3> StartLocation;
public Nullable<LLVector3> StartLookAt;
}
private UserInfo _userInfo;
private RegistrationCaps _caps;
private int _initializing;
private List<LastName> _lastNames = new List<LastName>();
private Dictionary<int, string> _errors = new Dictionary<int, string>();
public bool Initializing
{
get
{
System.Diagnostics.Debug.Assert(_initializing <= 0);
return (_initializing < 0);
}
}
public List<LastName> LastNames
{
get
{
lock (_lastNames)
{
if (_lastNames.Count <= 0)
GatherLastNames();
}
return _lastNames;
}
}
public RegistrationApi(string firstName, string lastName, string password)
{
_initializing = -2;
_userInfo = new UserInfo();
_userInfo.FirstName = firstName;
_userInfo.LastName = lastName;
_userInfo.Password = password;
GatherCaps();
}
public void WaitForInitialization()
{
while (Initializing)
System.Threading.Thread.Sleep(10);
}
public Uri RegistrationApiCaps
{
get { return new Uri("https://cap.secondlife.com/get_reg_capabilities"); }
}
private void GatherCaps()
{
// build post data
byte[] postData = Encoding.ASCII.GetBytes(
String.Format("first_name={0}&last_name={1}&password={2}", _userInfo.FirstName, _userInfo.LastName,
_userInfo.Password));
CapsClient request = new CapsClient(RegistrationApiCaps);
request.OnComplete += new CapsClient.CompleteCallback(GatherCapsResponse);
request.StartRequest(postData);
}
private void GatherCapsResponse(CapsClient client, LLSD response, Exception error)
{
if (response is LLSDMap)
{
LLSDMap respTable = (LLSDMap)response;
// parse
_caps = new RegistrationCaps();
_caps.CreateUser = respTable["create_user"].AsUri();
_caps.CheckName = respTable["check_name"].AsUri();
_caps.GetLastNames = respTable["get_last_names"].AsUri();
_caps.GetErrorCodes = respTable["get_error_codes"].AsUri();
// finalize
_initializing++;
GatherErrorMessages();
}
}
private void GatherErrorMessages()
{
if (_caps.GetErrorCodes == null)
throw new InvalidOperationException("access denied"); // this should work even for not-approved users
CapsClient request = new CapsClient(_caps.GetErrorCodes);
request.OnComplete += new CapsClient.CompleteCallback(GatherErrorMessagesResponse);
request.StartRequest();
}
private void GatherErrorMessagesResponse(CapsClient client, LLSD response, Exception error)
{
if (response is LLSDMap)
{
// parse
//FIXME: wtf?
//foreach (KeyValuePair<string, object> error in (Dictionary<string, object>)response)
//{
//StringBuilder sb = new StringBuilder();
//sb.Append(error[1]);
//sb.Append(" (");
//sb.Append(error[0]);
//sb.Append("): ");
//sb.Append(error[2]);
//_errors.Add((int)error[0], sb.ToString());
//}
// finalize
_initializing++;
}
}
public void GatherLastNames()
{
if (Initializing)
throw new InvalidOperationException("still initializing");
if (_caps.GetLastNames == null)
throw new InvalidOperationException("access denied: only approved developers have access to the registration api");
CapsClient request = new CapsClient(_caps.GetLastNames);
request.OnComplete += new CapsClient.CompleteCallback(GatherLastNamesResponse);
request.StartRequest();
// FIXME: Block
}
private void GatherLastNamesResponse(CapsClient client, LLSD response, Exception error)
{
if (response is LLSDMap)
{
LLSDMap respTable = (LLSDMap)response;
//FIXME:
//_lastNames = new List<LastName>(respTable.Count);
//for (Dictionary<string, object>.Enumerator it = respTable.GetEnumerator(); it.MoveNext(); )
//{
// LastName ln = new LastName();
// ln.ID = int.Parse(it.Current.Key.ToString());
// ln.Name = it.Current.Value.ToString();
// _lastNames.Add(ln);
//}
//_lastNames.Sort(new Comparison<LastName>(delegate(LastName a, LastName b) { return a.Name.CompareTo(b.Name); }));
}
}
public bool CheckName(string firstName, LastName lastName)
{
if (Initializing)
throw new InvalidOperationException("still initializing");
if (_caps.CheckName == null)
throw new InvalidOperationException("access denied; only approved developers have access to the registration api");
// Create the POST data
LLSDMap query = new LLSDMap();
query.Add("username", LLSD.FromString(firstName));
query.Add("last_name_id", LLSD.FromInteger(lastName.ID));
byte[] postData = LLSDParser.SerializeXmlBytes(query);
CapsClient request = new CapsClient(_caps.CheckName);
request.OnComplete += new CapsClient.CompleteCallback(CheckNameResponse);
request.StartRequest();
// FIXME:
return false;
}
private void CheckNameResponse(CapsClient client, LLSD response, Exception error)
{
if (response.Type == LLSDType.Boolean)
{
// FIXME:
//(bool)response;
}
else
{
// FIXME:
}
}
/// <summary>
/// Returns the new user ID or throws an exception containing the error code
/// The error codes can be found here: https://wiki.secondlife.com/wiki/RegAPIError
/// </summary>
/// <param name="user">New user account to create</param>
/// <returns>The UUID of the new user account</returns>
public LLUUID CreateUser(CreateUserParam user)
{
if (Initializing)
throw new InvalidOperationException("still initializing");
if (_caps.CreateUser == null)
throw new InvalidOperationException("access denied; only approved developers have access to the registration api");
// Create the POST data
LLSDMap query = new LLSDMap();
query.Add("username", LLSD.FromString(user.FirstName));
query.Add("last_name_id", LLSD.FromInteger(user.LastName.ID));
query.Add("email", LLSD.FromString(user.Email));
query.Add("password", LLSD.FromString(user.Password));
query.Add("dob", LLSD.FromString(user.Birthdate.ToString("yyyy-MM-dd")));
if (user.LimitedToEstate != null)
query.Add("limited_to_estate", LLSD.FromInteger(user.LimitedToEstate.Value));
if (!string.IsNullOrEmpty(user.StartRegionName))
query.Add("start_region_name", LLSD.FromInteger(user.LimitedToEstate.Value));
if (user.StartLocation != null)
{
query.Add("start_local_x", LLSD.FromReal(user.StartLocation.Value.X));
query.Add("start_local_y", LLSD.FromReal(user.StartLocation.Value.Y));
query.Add("start_local_z", LLSD.FromReal(user.StartLocation.Value.Z));
}
if (user.StartLookAt != null)
{
query.Add("start_look_at_x", LLSD.FromReal(user.StartLookAt.Value.X));
query.Add("start_look_at_y", LLSD.FromReal(user.StartLookAt.Value.Y));
query.Add("start_look_at_z", LLSD.FromReal(user.StartLookAt.Value.Z));
}
byte[] postData = LLSDParser.SerializeXmlBytes(query);
// Make the request
CapsClient request = new CapsClient(_caps.CreateUser);
request.OnComplete += new CapsClient.CompleteCallback(CreateUserResponse);
request.StartRequest();
// FIXME: Block
return LLUUID.Zero;
}
private void CreateUserResponse(CapsClient client, LLSD response, Exception error)
{
if (response is LLSDMap)
{
// everything is okay
// FIXME:
//return new LLUUID(((Dictionary<string, object>)response)["agent_id"].ToString());
}
else
{
// an error happened
LLSDArray al = (LLSDArray)response;
StringBuilder sb = new StringBuilder();
foreach (LLSD ec in al)
{
if (sb.Length > 0)
sb.Append("; ");
sb.Append(_errors[ec.AsInteger()]);
}
// FIXME:
//throw new Exception("failed to create user: " + sb.ToString());
}
}
}
}