opensim – Blame information for rev 13

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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.Generic;
30 using System.Reflection;
31 using log4net;
32 using Nini.Config;
33 using OpenMetaverse;
34 using OpenSim.Data;
35 using OpenSim.Framework;
36 using OpenSim.Services.Interfaces;
37 using OpenSim.Framework.Console;
38 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39 using PermissionMask = OpenSim.Framework.PermissionMask;
40  
41 namespace OpenSim.Services.UserAccountService
42 {
43 public class UserAccountService : UserAccountServiceBase, IUserAccountService
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 private static UserAccountService m_RootInstance;
47  
48 /// <summary>
49 /// Should we create default entries (minimum body parts/clothing, avatar wearable entries) for a new avatar?
50 /// </summary>
51 private bool m_CreateDefaultAvatarEntries;
52  
53 protected IGridService m_GridService;
54 protected IAuthenticationService m_AuthenticationService;
55 protected IGridUserService m_GridUserService;
56 protected IInventoryService m_InventoryService;
57 protected IAvatarService m_AvatarService;
58  
59 public UserAccountService(IConfigSource config)
60 : base(config)
61 {
62 IConfig userConfig = config.Configs["UserAccountService"];
63 if (userConfig == null)
64 throw new Exception("No UserAccountService configuration");
65  
66 string gridServiceDll = userConfig.GetString("GridService", string.Empty);
67 if (gridServiceDll != string.Empty)
68 m_GridService = LoadPlugin<IGridService>(gridServiceDll, new Object[] { config });
69  
70 string authServiceDll = userConfig.GetString("AuthenticationService", string.Empty);
71 if (authServiceDll != string.Empty)
72 m_AuthenticationService = LoadPlugin<IAuthenticationService>(authServiceDll, new Object[] { config });
73  
74 string presenceServiceDll = userConfig.GetString("GridUserService", string.Empty);
75 if (presenceServiceDll != string.Empty)
76 m_GridUserService = LoadPlugin<IGridUserService>(presenceServiceDll, new Object[] { config });
77  
78 string invServiceDll = userConfig.GetString("InventoryService", string.Empty);
79 if (invServiceDll != string.Empty)
80 m_InventoryService = LoadPlugin<IInventoryService>(invServiceDll, new Object[] { config });
81  
82 string avatarServiceDll = userConfig.GetString("AvatarService", string.Empty);
83 if (avatarServiceDll != string.Empty)
84 m_AvatarService = LoadPlugin<IAvatarService>(avatarServiceDll, new Object[] { config });
85  
86 m_CreateDefaultAvatarEntries = userConfig.GetBoolean("CreateDefaultAvatarEntries", false);
87  
88 // In case there are several instances of this class in the same process,
89 // the console commands are only registered for the root instance
90 if (m_RootInstance == null && MainConsole.Instance != null)
91 {
92 m_RootInstance = this;
93 MainConsole.Instance.Commands.AddCommand("Users", false,
94 "create user",
95 "create user [<first> [<last> [<pass> [<email> [<user id>]]]]]",
96 "Create a new user", HandleCreateUser);
97  
98 MainConsole.Instance.Commands.AddCommand("Users", false,
99 "reset user password",
100 "reset user password [<first> [<last> [<password>]]]",
101 "Reset a user password", HandleResetUserPassword);
102  
103 MainConsole.Instance.Commands.AddCommand("Users", false,
104 "set user level",
105 "set user level [<first> [<last> [<level>]]]",
106 "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, "
107 + "this account will be treated as god-moded. "
108 + "It will also affect the 'login level' command. ",
109 HandleSetUserLevel);
110  
111 MainConsole.Instance.Commands.AddCommand("Users", false,
112 "show account",
113 "show account <first> <last>",
114 "Show account details for the given user", HandleShowAccount);
115 }
116 }
117  
118 #region IUserAccountService
119  
120 public UserAccount GetUserAccount(UUID scopeID, string firstName,
121 string lastName)
122 {
123 // m_log.DebugFormat(
124 // "[USER ACCOUNT SERVICE]: Retrieving account by username for {0} {1}, scope {2}",
125 // firstName, lastName, scopeID);
126  
127 UserAccountData[] d;
128  
129 if (scopeID != UUID.Zero)
130 {
131 d = m_Database.Get(
132 new string[] { "ScopeID", "FirstName", "LastName" },
133 new string[] { scopeID.ToString(), firstName, lastName });
134 if (d.Length < 1)
135 {
136 d = m_Database.Get(
137 new string[] { "ScopeID", "FirstName", "LastName" },
138 new string[] { UUID.Zero.ToString(), firstName, lastName });
139 }
140 }
141 else
142 {
143 d = m_Database.Get(
144 new string[] { "FirstName", "LastName" },
145 new string[] { firstName, lastName });
146 }
147  
148 if (d.Length < 1)
149 return null;
150  
151 return MakeUserAccount(d[0]);
152 }
153  
154 private UserAccount MakeUserAccount(UserAccountData d)
155 {
156 UserAccount u = new UserAccount();
157 u.FirstName = d.FirstName;
158 u.LastName = d.LastName;
159 u.PrincipalID = d.PrincipalID;
160 u.ScopeID = d.ScopeID;
161 if (d.Data.ContainsKey("Email") && d.Data["Email"] != null)
162 u.Email = d.Data["Email"].ToString();
163 else
164 u.Email = string.Empty;
165 u.Created = Convert.ToInt32(d.Data["Created"].ToString());
166 if (d.Data.ContainsKey("UserTitle") && d.Data["UserTitle"] != null)
167 u.UserTitle = d.Data["UserTitle"].ToString();
168 else
169 u.UserTitle = string.Empty;
170 if (d.Data.ContainsKey("UserLevel") && d.Data["UserLevel"] != null)
171 Int32.TryParse(d.Data["UserLevel"], out u.UserLevel);
172 if (d.Data.ContainsKey("UserFlags") && d.Data["UserFlags"] != null)
173 Int32.TryParse(d.Data["UserFlags"], out u.UserFlags);
174  
175 if (d.Data.ContainsKey("ServiceURLs") && d.Data["ServiceURLs"] != null)
176 {
177 string[] URLs = d.Data["ServiceURLs"].ToString().Split(new char[] { ' ' });
178 u.ServiceURLs = new Dictionary<string, object>();
179  
180 foreach (string url in URLs)
181 {
182 string[] parts = url.Split(new char[] { '=' });
183  
184 if (parts.Length != 2)
185 continue;
186  
187 string name = System.Web.HttpUtility.UrlDecode(parts[0]);
188 string val = System.Web.HttpUtility.UrlDecode(parts[1]);
189  
190 u.ServiceURLs[name] = val;
191 }
192 }
193 else
194 u.ServiceURLs = new Dictionary<string, object>();
195  
196 return u;
197 }
198  
199 public UserAccount GetUserAccount(UUID scopeID, string email)
200 {
201 UserAccountData[] d;
202  
203 if (scopeID != UUID.Zero)
204 {
205 d = m_Database.Get(
206 new string[] { "ScopeID", "Email" },
207 new string[] { scopeID.ToString(), email });
208 if (d.Length < 1)
209 {
210 d = m_Database.Get(
211 new string[] { "ScopeID", "Email" },
212 new string[] { UUID.Zero.ToString(), email });
213 }
214 }
215 else
216 {
217 d = m_Database.Get(
218 new string[] { "Email" },
219 new string[] { email });
220 }
221  
222 if (d.Length < 1)
223 return null;
224  
225 return MakeUserAccount(d[0]);
226 }
227  
228 public UserAccount GetUserAccount(UUID scopeID, UUID principalID)
229 {
230 UserAccountData[] d;
231  
232 if (scopeID != UUID.Zero)
233 {
234 d = m_Database.Get(
235 new string[] { "ScopeID", "PrincipalID" },
236 new string[] { scopeID.ToString(), principalID.ToString() });
237 if (d.Length < 1)
238 {
239 d = m_Database.Get(
240 new string[] { "ScopeID", "PrincipalID" },
241 new string[] { UUID.Zero.ToString(), principalID.ToString() });
242 }
243 }
244 else
245 {
246 d = m_Database.Get(
247 new string[] { "PrincipalID" },
248 new string[] { principalID.ToString() });
249 }
250  
251 if (d.Length < 1)
252 {
253 return null;
254 }
255  
256 return MakeUserAccount(d[0]);
257 }
258  
259 public bool StoreUserAccount(UserAccount data)
260 {
261 // m_log.DebugFormat(
262 // "[USER ACCOUNT SERVICE]: Storing user account for {0} {1} {2}, scope {3}",
263 // data.FirstName, data.LastName, data.PrincipalID, data.ScopeID);
264  
265 UserAccountData d = new UserAccountData();
266  
267 d.FirstName = data.FirstName;
268 d.LastName = data.LastName;
269 d.PrincipalID = data.PrincipalID;
270 d.ScopeID = data.ScopeID;
271 d.Data = new Dictionary<string, string>();
272 d.Data["Email"] = data.Email;
273 d.Data["Created"] = data.Created.ToString();
274 d.Data["UserLevel"] = data.UserLevel.ToString();
275 d.Data["UserFlags"] = data.UserFlags.ToString();
276 if (data.UserTitle != null)
277 d.Data["UserTitle"] = data.UserTitle.ToString();
278  
279 List<string> parts = new List<string>();
280  
281 foreach (KeyValuePair<string, object> kvp in data.ServiceURLs)
282 {
283 string key = System.Web.HttpUtility.UrlEncode(kvp.Key);
284 string val = System.Web.HttpUtility.UrlEncode(kvp.Value.ToString());
285 parts.Add(key + "=" + val);
286 }
287  
288 d.Data["ServiceURLs"] = string.Join(" ", parts.ToArray());
289  
290 return m_Database.Store(d);
291 }
292  
293 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
294 {
295 UserAccountData[] d = m_Database.GetUsers(scopeID, query);
296  
297 if (d == null)
298 return new List<UserAccount>();
299  
300 List<UserAccount> ret = new List<UserAccount>();
301  
302 foreach (UserAccountData data in d)
303 ret.Add(MakeUserAccount(data));
304  
305 return ret;
306 }
307  
308 #endregion
309  
310 #region Console commands
311  
312 /// <summary>
313 /// Handle the create user command from the console.
314 /// </summary>
315 /// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email</param>
316 protected void HandleCreateUser(string module, string[] cmdparams)
317 {
318 string firstName;
319 string lastName;
320 string password;
321 string email;
322 string rawPrincipalId;
323  
324 List<char> excluded = new List<char>(new char[]{' '});
325  
326 if (cmdparams.Length < 3)
327 firstName = MainConsole.Instance.CmdPrompt("First name", "Default", excluded);
328 else firstName = cmdparams[2];
329  
330 if (cmdparams.Length < 4)
331 lastName = MainConsole.Instance.CmdPrompt("Last name", "User", excluded);
332 else lastName = cmdparams[3];
333  
334 if (cmdparams.Length < 5)
335 password = MainConsole.Instance.PasswdPrompt("Password");
336 else password = cmdparams[4];
337  
338 if (cmdparams.Length < 6)
339 email = MainConsole.Instance.CmdPrompt("Email", "");
340 else email = cmdparams[5];
341  
342 if (cmdparams.Length < 7)
343 rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
344 else
345 rawPrincipalId = cmdparams[6];
346  
347 UUID principalId = UUID.Zero;
348 if (!UUID.TryParse(rawPrincipalId, out principalId))
349 throw new Exception(string.Format("ID {0} is not a valid UUID", rawPrincipalId));
350  
351 CreateUser(UUID.Zero, principalId, firstName, lastName, password, email);
352 }
353  
354 protected void HandleShowAccount(string module, string[] cmdparams)
355 {
356 if (cmdparams.Length != 4)
357 {
358 MainConsole.Instance.Output("Usage: show account <first-name> <last-name>");
359 return;
360 }
361  
362 string firstName = cmdparams[2];
363 string lastName = cmdparams[3];
364  
365 UserAccount ua = GetUserAccount(UUID.Zero, firstName, lastName);
366  
367 if (ua == null)
368 {
369 MainConsole.Instance.OutputFormat("No user named {0} {1}", firstName, lastName);
370 return;
371 }
372  
373 MainConsole.Instance.OutputFormat("Name: {0}", ua.Name);
374 MainConsole.Instance.OutputFormat("ID: {0}", ua.PrincipalID);
375 MainConsole.Instance.OutputFormat("Title: {0}", ua.UserTitle);
376 MainConsole.Instance.OutputFormat("E-mail: {0}", ua.Email);
377 MainConsole.Instance.OutputFormat("Created: {0}", Utils.UnixTimeToDateTime(ua.Created));
378 MainConsole.Instance.OutputFormat("Level: {0}", ua.UserLevel);
379 MainConsole.Instance.OutputFormat("Flags: {0}", ua.UserFlags);
380 foreach (KeyValuePair<string, Object> kvp in ua.ServiceURLs)
381 MainConsole.Instance.OutputFormat("{0}: {1}", kvp.Key, kvp.Value);
382 }
383  
384 protected void HandleResetUserPassword(string module, string[] cmdparams)
385 {
386 string firstName;
387 string lastName;
388 string newPassword;
389  
390 if (cmdparams.Length < 4)
391 firstName = MainConsole.Instance.CmdPrompt("First name");
392 else firstName = cmdparams[3];
393  
394 if (cmdparams.Length < 5)
395 lastName = MainConsole.Instance.CmdPrompt("Last name");
396 else lastName = cmdparams[4];
397  
398 if (cmdparams.Length < 6)
399 newPassword = MainConsole.Instance.PasswdPrompt("New password");
400 else newPassword = cmdparams[5];
401  
402 UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
403 if (account == null)
404 {
405 MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName);
406 return;
407 }
408  
409 bool success = false;
410 if (m_AuthenticationService != null)
411 success = m_AuthenticationService.SetPassword(account.PrincipalID, newPassword);
412  
413 if (!success)
414 MainConsole.Instance.OutputFormat("Unable to reset password for account {0} {1}.", firstName, lastName);
415 else
416 MainConsole.Instance.OutputFormat("Password reset for user {0} {1}", firstName, lastName);
417 }
418  
419 protected void HandleSetUserLevel(string module, string[] cmdparams)
420 {
421 string firstName;
422 string lastName;
423 string rawLevel;
424 int level;
425  
426 if (cmdparams.Length < 4)
427 firstName = MainConsole.Instance.CmdPrompt("First name");
428 else firstName = cmdparams[3];
429  
430 if (cmdparams.Length < 5)
431 lastName = MainConsole.Instance.CmdPrompt("Last name");
432 else lastName = cmdparams[4];
433  
434 UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
435 if (account == null) {
436 MainConsole.Instance.OutputFormat("No such user");
437 return;
438 }
439  
440 if (cmdparams.Length < 6)
441 rawLevel = MainConsole.Instance.CmdPrompt("User level");
442 else rawLevel = cmdparams[5];
443  
444 if(int.TryParse(rawLevel, out level) == false) {
445 MainConsole.Instance.OutputFormat("Invalid user level");
446 return;
447 }
448  
449 account.UserLevel = level;
450  
451 bool success = StoreUserAccount(account);
452 if (!success)
453 MainConsole.Instance.OutputFormat("Unable to set user level for account {0} {1}.", firstName, lastName);
454 else
455 MainConsole.Instance.OutputFormat("User level set for user {0} {1} to {2}", firstName, lastName, level);
456 }
457  
458 #endregion
459  
460 /// <summary>
461 /// Create a user
462 /// </summary>
463 /// <param name="scopeID">Allows hosting of multiple grids in a single database. Normally left as UUID.Zero</param>
464 /// <param name="principalID">ID of the user</param>
465 /// <param name="firstName"></param>
466 /// <param name="lastName"></param>
467 /// <param name="password"></param>
468 /// <param name="email"></param>
469 public UserAccount CreateUser(UUID scopeID, UUID principalID, string firstName, string lastName, string password, string email)
470 {
471 UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
472 if (null == account)
473 {
474 account = new UserAccount(UUID.Zero, principalID, firstName, lastName, email);
475 if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0))
476 {
477 account.ServiceURLs = new Dictionary<string, object>();
478 account.ServiceURLs["HomeURI"] = string.Empty;
479 account.ServiceURLs["GatekeeperURI"] = string.Empty;
480 account.ServiceURLs["InventoryServerURI"] = string.Empty;
481 account.ServiceURLs["AssetServerURI"] = string.Empty;
482 }
483  
484 if (StoreUserAccount(account))
485 {
486 bool success;
487 if (m_AuthenticationService != null)
488 {
489 success = m_AuthenticationService.SetPassword(account.PrincipalID, password);
490 if (!success)
491 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set password for account {0} {1}.",
492 firstName, lastName);
493 }
494  
495 GridRegion home = null;
496 if (m_GridService != null)
497 {
498 List<GridRegion> defaultRegions = m_GridService.GetDefaultRegions(UUID.Zero);
499 if (defaultRegions != null && defaultRegions.Count >= 1)
500 home = defaultRegions[0];
501  
502 if (m_GridUserService != null && home != null)
503 m_GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
504 else
505 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set home for account {0} {1}.",
506 firstName, lastName);
507 }
508 else
509 {
510 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to retrieve home region for account {0} {1}.",
511 firstName, lastName);
512 }
513  
514 if (m_InventoryService != null)
515 {
516 success = m_InventoryService.CreateUserInventory(account.PrincipalID);
517 if (!success)
518 {
519 m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
520 firstName, lastName);
521 }
522 else
523 {
524 m_log.DebugFormat(
525 "[USER ACCOUNT SERVICE]: Created user inventory for {0} {1}", firstName, lastName);
526 }
527  
528 if (m_CreateDefaultAvatarEntries)
529 CreateDefaultAppearanceEntries(account.PrincipalID);
530 }
531  
532 m_log.InfoFormat(
533 "[USER ACCOUNT SERVICE]: Account {0} {1} {2} created successfully",
534 firstName, lastName, account.PrincipalID);
535 }
536 else
537 {
538 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName);
539 }
540 }
541 else
542 {
543 m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName);
544 }
545  
546 return account;
547 }
548  
549 protected void CreateDefaultAppearanceEntries(UUID principalID)
550 {
551 m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID);
552  
553 InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Bodypart);
554  
555 InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID);
556 eyes.AssetID = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
557 eyes.Name = "Default Eyes";
558 eyes.CreatorId = principalID.ToString();
559 eyes.AssetType = (int)AssetType.Bodypart;
560 eyes.InvType = (int)InventoryType.Wearable;
561 eyes.Folder = bodyPartsFolder.ID;
562 eyes.BasePermissions = (uint)PermissionMask.All;
563 eyes.CurrentPermissions = (uint)PermissionMask.All;
564 eyes.EveryOnePermissions = (uint)PermissionMask.All;
565 eyes.GroupPermissions = (uint)PermissionMask.All;
566 eyes.NextPermissions = (uint)PermissionMask.All;
567 eyes.Flags = (uint)WearableType.Eyes;
568 m_InventoryService.AddItem(eyes);
569  
570 InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID);
571 shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET;
572 shape.Name = "Default Shape";
573 shape.CreatorId = principalID.ToString();
574 shape.AssetType = (int)AssetType.Bodypart;
575 shape.InvType = (int)InventoryType.Wearable;
576 shape.Folder = bodyPartsFolder.ID;
577 shape.BasePermissions = (uint)PermissionMask.All;
578 shape.CurrentPermissions = (uint)PermissionMask.All;
579 shape.EveryOnePermissions = (uint)PermissionMask.All;
580 shape.GroupPermissions = (uint)PermissionMask.All;
581 shape.NextPermissions = (uint)PermissionMask.All;
582 shape.Flags = (uint)WearableType.Shape;
583 m_InventoryService.AddItem(shape);
584  
585 InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID);
586 skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET;
587 skin.Name = "Default Skin";
588 skin.CreatorId = principalID.ToString();
589 skin.AssetType = (int)AssetType.Bodypart;
590 skin.InvType = (int)InventoryType.Wearable;
591 skin.Folder = bodyPartsFolder.ID;
592 skin.BasePermissions = (uint)PermissionMask.All;
593 skin.CurrentPermissions = (uint)PermissionMask.All;
594 skin.EveryOnePermissions = (uint)PermissionMask.All;
595 skin.GroupPermissions = (uint)PermissionMask.All;
596 skin.NextPermissions = (uint)PermissionMask.All;
597 skin.Flags = (uint)WearableType.Skin;
598 m_InventoryService.AddItem(skin);
599  
600 InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID);
601 hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET;
602 hair.Name = "Default Hair";
603 hair.CreatorId = principalID.ToString();
604 hair.AssetType = (int)AssetType.Bodypart;
605 hair.InvType = (int)InventoryType.Wearable;
606 hair.Folder = bodyPartsFolder.ID;
607 hair.BasePermissions = (uint)PermissionMask.All;
608 hair.CurrentPermissions = (uint)PermissionMask.All;
609 hair.EveryOnePermissions = (uint)PermissionMask.All;
610 hair.GroupPermissions = (uint)PermissionMask.All;
611 hair.NextPermissions = (uint)PermissionMask.All;
612 hair.Flags = (uint)WearableType.Hair;
613 m_InventoryService.AddItem(hair);
614  
615 if (m_AvatarService != null)
616 {
617 m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default avatar entries for {0}", principalID);
618  
619 AvatarWearable[] wearables = new AvatarWearable[6];
620 wearables[AvatarWearable.EYES] = new AvatarWearable(eyes.ID, eyes.AssetID);
621 wearables[AvatarWearable.BODY] = new AvatarWearable(shape.ID, shape.AssetID);
622 wearables[AvatarWearable.SKIN] = new AvatarWearable(skin.ID, skin.AssetID);
623 wearables[AvatarWearable.HAIR] = new AvatarWearable(hair.ID, hair.AssetID);
624  
625 AvatarAppearance ap = new AvatarAppearance();
12 vero 626 for (int i = 0; i < 4; i++)
1 eva 627 {
628 ap.SetWearable(i, wearables[i]);
629 }
630  
631 m_AvatarService.SetAppearance(principalID, ap);
632 }
633 }
634 }
635 }