corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) 2006-2014, openmetaverse.org
3 * All rights reserved.
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 *
8 * - Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * - Neither the name of the openmetaverse.org nor the names
11 * of its contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26  
27 using System;
28 using System.Collections.Generic;
29 using System.Threading;
30 using System.Text;
31 using OpenMetaverse.StructuredData;
32 using OpenMetaverse.Http;
33  
34 namespace OpenMetaverse
35 {
36 public class RegistrationApi
37 {
38 const int REQUEST_TIMEOUT = 1000 * 100;
39  
40 private struct UserInfo
41 {
42 public string FirstName;
43 public string LastName;
44 public string Password;
45 }
46  
47 private struct RegistrationCaps
48 {
49 public Uri CreateUser;
50 public Uri CheckName;
51 public Uri GetLastNames;
52 public Uri GetErrorCodes;
53 }
54  
55 public struct LastName
56 {
57 public int ID;
58 public string Name;
59 }
60  
61 /// <summary>
62 /// See https://secure-web6.secondlife.com/developers/third_party_reg/#service_create_user or
63 /// https://wiki.secondlife.com/wiki/RegAPIDoc for description
64 /// </summary>
65 public class CreateUserParam
66 {
67 public string FirstName;
68 public LastName LastName;
69 public string Email;
70 public string Password;
71 public DateTime Birthdate;
72  
73 // optional:
74 public Nullable<int> LimitedToEstate;
75 public string StartRegionName;
76 public Nullable<Vector3> StartLocation;
77 public Nullable<Vector3> StartLookAt;
78 }
79  
80 private UserInfo _userInfo;
81 private RegistrationCaps _caps;
82 private int _initializing;
83 private List<LastName> _lastNames = new List<LastName>();
84 private Dictionary<int, string> _errors = new Dictionary<int, string>();
85  
86 public bool Initializing
87 {
88 get
89 {
90 System.Diagnostics.Debug.Assert(_initializing <= 0);
91 return (_initializing < 0);
92 }
93 }
94  
95 public List<LastName> LastNames
96 {
97 get
98 {
99 lock (_lastNames)
100 {
101 if (_lastNames.Count <= 0)
102 GatherLastNames();
103 }
104  
105 return _lastNames;
106 }
107 }
108  
109 public RegistrationApi(string firstName, string lastName, string password)
110 {
111 _initializing = -2;
112  
113 _userInfo = new UserInfo();
114  
115 _userInfo.FirstName = firstName;
116 _userInfo.LastName = lastName;
117 _userInfo.Password = password;
118  
119 GatherCaps();
120 }
121  
122 public void WaitForInitialization()
123 {
124 while (Initializing)
125 System.Threading.Thread.Sleep(10);
126 }
127  
128 public Uri RegistrationApiCaps
129 {
130 get { return new Uri("https://cap.secondlife.com/get_reg_capabilities"); }
131 }
132  
133 private void GatherCaps()
134 {
135 // build post data
136 byte[] postData = Encoding.ASCII.GetBytes(
137 String.Format("first_name={0}&last_name={1}&password={2}", _userInfo.FirstName, _userInfo.LastName,
138 _userInfo.Password));
139  
140 CapsClient request = new CapsClient(RegistrationApiCaps);
141 request.OnComplete += new CapsClient.CompleteCallback(GatherCapsResponse);
142 request.BeginGetResponse(postData, "application/x-www-form-urlencoded", REQUEST_TIMEOUT);
143 }
144  
145 private void GatherCapsResponse(CapsClient client, OSD response, Exception error)
146 {
147 if (response is OSDMap)
148 {
149 OSDMap respTable = (OSDMap)response;
150  
151 // parse
152 _caps = new RegistrationCaps();
153  
154 _caps.CreateUser = respTable["create_user"].AsUri();
155 _caps.CheckName = respTable["check_name"].AsUri();
156 _caps.GetLastNames = respTable["get_last_names"].AsUri();
157 _caps.GetErrorCodes = respTable["get_error_codes"].AsUri();
158  
159 // finalize
160 _initializing++;
161  
162 GatherErrorMessages();
163 }
164 }
165  
166 private void GatherErrorMessages()
167 {
168 if (_caps.GetErrorCodes == null)
169 throw new InvalidOperationException("access denied"); // this should work even for not-approved users
170  
171 CapsClient request = new CapsClient(_caps.GetErrorCodes);
172 request.OnComplete += new CapsClient.CompleteCallback(GatherErrorMessagesResponse);
173 request.BeginGetResponse(REQUEST_TIMEOUT);
174 }
175  
176 private void GatherErrorMessagesResponse(CapsClient client, OSD response, Exception error)
177 {
178 if (response is OSDMap)
179 {
180 // parse
181  
182 //FIXME: wtf?
183 //foreach (KeyValuePair<string, object> error in (Dictionary<string, object>)response)
184 //{
185 //StringBuilder sb = new StringBuilder();
186  
187 //sb.Append(error[1]);
188 //sb.Append(" (");
189 //sb.Append(error[0]);
190 //sb.Append("): ");
191 //sb.Append(error[2]);
192  
193 //_errors.Add((int)error[0], sb.ToString());
194 //}
195  
196 // finalize
197 _initializing++;
198 }
199 }
200  
201 public void GatherLastNames()
202 {
203 if (Initializing)
204 throw new InvalidOperationException("still initializing");
205  
206 if (_caps.GetLastNames == null)
207 throw new InvalidOperationException("access denied: only approved developers have access to the registration api");
208  
209 CapsClient request = new CapsClient(_caps.GetLastNames);
210 request.OnComplete += new CapsClient.CompleteCallback(GatherLastNamesResponse);
211 request.BeginGetResponse(REQUEST_TIMEOUT);
212  
213 // FIXME: Block
214 }
215  
216 private void GatherLastNamesResponse(CapsClient client, OSD response, Exception error)
217 {
218 if (response is OSDMap)
219 {
220 //LLSDMap respTable = (LLSDMap)response;
221  
222 //FIXME:
223 //_lastNames = new List<LastName>(respTable.Count);
224  
225 //for (Dictionary<string, object>.Enumerator it = respTable.GetEnumerator(); it.MoveNext(); )
226 //{
227 // LastName ln = new LastName();
228  
229 // ln.ID = int.Parse(it.Current.Key.ToString());
230 // ln.Name = it.Current.Value.ToString();
231  
232 // _lastNames.Add(ln);
233 //}
234  
235 //_lastNames.Sort(new Comparison<LastName>(delegate(LastName a, LastName b) { return a.Name.CompareTo(b.Name); }));
236 }
237 }
238  
239 public bool CheckName(string firstName, LastName lastName)
240 {
241 if (Initializing)
242 throw new InvalidOperationException("still initializing");
243  
244 if (_caps.CheckName == null)
245 throw new InvalidOperationException("access denied; only approved developers have access to the registration api");
246  
247 // Create the POST data
248 OSDMap query = new OSDMap();
249 query.Add("username", OSD.FromString(firstName));
250 query.Add("last_name_id", OSD.FromInteger(lastName.ID));
251 //byte[] postData = OSDParser.SerializeXmlBytes(query);
252  
253 CapsClient request = new CapsClient(_caps.CheckName);
254 request.OnComplete += new CapsClient.CompleteCallback(CheckNameResponse);
255 request.BeginGetResponse(REQUEST_TIMEOUT);
256  
257 // FIXME:
258 return false;
259 }
260  
261 private void CheckNameResponse(CapsClient client, OSD response, Exception error)
262 {
263 if (response.Type == OSDType.Boolean)
264 {
265 // FIXME:
266 //(bool)response;
267 }
268 else
269 {
270 // FIXME:
271 }
272 }
273  
274 /// <summary>
275 /// Returns the new user ID or throws an exception containing the error code
276 /// The error codes can be found here: https://wiki.secondlife.com/wiki/RegAPIError
277 /// </summary>
278 /// <param name="user">New user account to create</param>
279 /// <returns>The UUID of the new user account</returns>
280 public UUID CreateUser(CreateUserParam user)
281 {
282 if (Initializing)
283 throw new InvalidOperationException("still initializing");
284  
285 if (_caps.CreateUser == null)
286 throw new InvalidOperationException("access denied; only approved developers have access to the registration api");
287  
288 // Create the POST data
289 OSDMap query = new OSDMap();
290 query.Add("username", OSD.FromString(user.FirstName));
291 query.Add("last_name_id", OSD.FromInteger(user.LastName.ID));
292 query.Add("email", OSD.FromString(user.Email));
293 query.Add("password", OSD.FromString(user.Password));
294 query.Add("dob", OSD.FromString(user.Birthdate.ToString("yyyy-MM-dd")));
295  
296 if (user.LimitedToEstate != null)
297 query.Add("limited_to_estate", OSD.FromInteger(user.LimitedToEstate.Value));
298  
299 if (!string.IsNullOrEmpty(user.StartRegionName))
300 query.Add("start_region_name", OSD.FromInteger(user.LimitedToEstate.Value));
301  
302 if (user.StartLocation != null)
303 {
304 query.Add("start_local_x", OSD.FromReal(user.StartLocation.Value.X));
305 query.Add("start_local_y", OSD.FromReal(user.StartLocation.Value.Y));
306 query.Add("start_local_z", OSD.FromReal(user.StartLocation.Value.Z));
307 }
308  
309 if (user.StartLookAt != null)
310 {
311 query.Add("start_look_at_x", OSD.FromReal(user.StartLookAt.Value.X));
312 query.Add("start_look_at_y", OSD.FromReal(user.StartLookAt.Value.Y));
313 query.Add("start_look_at_z", OSD.FromReal(user.StartLookAt.Value.Z));
314 }
315  
316 //byte[] postData = OSDParser.SerializeXmlBytes(query);
317  
318 // Make the request
319 CapsClient request = new CapsClient(_caps.CreateUser);
320 request.OnComplete += new CapsClient.CompleteCallback(CreateUserResponse);
321 request.BeginGetResponse(REQUEST_TIMEOUT);
322  
323 // FIXME: Block
324 return UUID.Zero;
325 }
326  
327 private void CreateUserResponse(CapsClient client, OSD response, Exception error)
328 {
329 if (response is OSDMap)
330 {
331 // everything is okay
332 // FIXME:
333 //return new UUID(((Dictionary<string, object>)response)["agent_id"].ToString());
334 }
335 else
336 {
337 // an error happened
338 OSDArray al = (OSDArray)response;
339  
340 StringBuilder sb = new StringBuilder();
341  
342 foreach (OSD ec in al)
343 {
344 if (sb.Length > 0)
345 sb.Append("; ");
346  
347 sb.Append(_errors[ec.AsInteger()]);
348 }
349  
350 // FIXME:
351 //throw new Exception("failed to create user: " + sb.ToString());
352 }
353 }
354 }
355 }