diff options
Diffstat (limited to 'OpenSim/Services/UserAccountService/UserAccountService.cs')
-rw-r--r-- | OpenSim/Services/UserAccountService/UserAccountService.cs | 383 |
1 files changed, 347 insertions, 36 deletions
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index 2e19ece..48929ee 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs | |||
@@ -43,6 +43,7 @@ namespace OpenSim.Services.UserAccountService | |||
43 | public class UserAccountService : UserAccountServiceBase, IUserAccountService | 43 | public class UserAccountService : UserAccountServiceBase, IUserAccountService |
44 | { | 44 | { |
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | private static readonly UUID UUID_GRID_GOD = new UUID("6571e388-6218-4574-87db-f9379718315e"); | ||
46 | private static UserAccountService m_RootInstance; | 47 | private static UserAccountService m_RootInstance; |
47 | 48 | ||
48 | /// <summary> | 49 | /// <summary> |
@@ -85,38 +86,63 @@ namespace OpenSim.Services.UserAccountService | |||
85 | 86 | ||
86 | m_CreateDefaultAvatarEntries = userConfig.GetBoolean("CreateDefaultAvatarEntries", false); | 87 | m_CreateDefaultAvatarEntries = userConfig.GetBoolean("CreateDefaultAvatarEntries", false); |
87 | 88 | ||
88 | // In case there are several instances of this class in the same process, | 89 | // create a system grid god account |
89 | // the console commands are only registered for the root instance | 90 | UserAccount ggod = GetUserAccount(UUID.Zero, UUID_GRID_GOD); |
90 | if (m_RootInstance == null && MainConsole.Instance != null) | 91 | if(ggod == null) |
92 | { | ||
93 | UserAccountData d = new UserAccountData(); | ||
94 | |||
95 | d.FirstName = "GRID"; | ||
96 | d.LastName = "SERVICES"; | ||
97 | d.PrincipalID = UUID_GRID_GOD; | ||
98 | d.ScopeID = UUID.Zero; | ||
99 | d.Data = new Dictionary<string, string>(); | ||
100 | d.Data["Email"] = string.Empty; | ||
101 | d.Data["Created"] = Util.UnixTimeSinceEpoch().ToString(); | ||
102 | d.Data["UserLevel"] = "240"; | ||
103 | d.Data["UserFlags"] = "0"; | ||
104 | d.Data["ServiceURLs"] = string.Empty; | ||
105 | |||
106 | m_Database.Store(d); | ||
107 | } | ||
108 | |||
109 | if (m_RootInstance == null) | ||
91 | { | 110 | { |
92 | m_RootInstance = this; | 111 | m_RootInstance = this; |
93 | MainConsole.Instance.Commands.AddCommand("Users", false, | 112 | |
94 | "create user", | 113 | // In case there are several instances of this class in the same process, |
95 | "create user [<first> [<last> [<pass> [<email> [<user id>]]]]]", | 114 | // the console commands are only registered for the root instance |
96 | "Create a new user", HandleCreateUser); | 115 | if (MainConsole.Instance != null) |
97 | 116 | { | |
98 | MainConsole.Instance.Commands.AddCommand("Users", false, | 117 | |
99 | "reset user password", | 118 | MainConsole.Instance.Commands.AddCommand("Users", false, |
100 | "reset user password [<first> [<last> [<password>]]]", | 119 | "create user", |
101 | "Reset a user password", HandleResetUserPassword); | 120 | "create user [<first> [<last> [<pass> [<email> [<user id> [<model>]]]]]]", |
102 | 121 | "Create a new user", HandleCreateUser); | |
103 | MainConsole.Instance.Commands.AddCommand("Users", false, | 122 | |
104 | "reset user email", | 123 | MainConsole.Instance.Commands.AddCommand("Users", false, |
105 | "reset user email [<first> [<last> [<email>]]]", | 124 | "reset user password", |
106 | "Reset a user email address", HandleResetUserEmail); | 125 | "reset user password [<first> [<last> [<password>]]]", |
107 | 126 | "Reset a user password", HandleResetUserPassword); | |
108 | MainConsole.Instance.Commands.AddCommand("Users", false, | 127 | |
109 | "set user level", | 128 | MainConsole.Instance.Commands.AddCommand("Users", false, |
110 | "set user level [<first> [<last> [<level>]]]", | 129 | "reset user email", |
111 | "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, " | 130 | "reset user email [<first> [<last> [<email>]]]", |
112 | + "this account will be treated as god-moded. " | 131 | "Reset a user email address", HandleResetUserEmail); |
113 | + "It will also affect the 'login level' command. ", | 132 | |
114 | HandleSetUserLevel); | 133 | MainConsole.Instance.Commands.AddCommand("Users", false, |
115 | 134 | "set user level", | |
116 | MainConsole.Instance.Commands.AddCommand("Users", false, | 135 | "set user level [<first> [<last> [<level>]]]", |
117 | "show account", | 136 | "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, " |
118 | "show account <first> <last>", | 137 | + "this account will be treated as god-moded. " |
119 | "Show account details for the given user", HandleShowAccount); | 138 | + "It will also affect the 'login level' command. ", |
139 | HandleSetUserLevel); | ||
140 | |||
141 | MainConsole.Instance.Commands.AddCommand("Users", false, | ||
142 | "show account", | ||
143 | "show account <first> <last>", | ||
144 | "Show account details for the given user", HandleShowAccount); | ||
145 | } | ||
120 | } | 146 | } |
121 | } | 147 | } |
122 | 148 | ||
@@ -176,6 +202,10 @@ namespace OpenSim.Services.UserAccountService | |||
176 | Int32.TryParse(d.Data["UserLevel"], out u.UserLevel); | 202 | Int32.TryParse(d.Data["UserLevel"], out u.UserLevel); |
177 | if (d.Data.ContainsKey("UserFlags") && d.Data["UserFlags"] != null) | 203 | if (d.Data.ContainsKey("UserFlags") && d.Data["UserFlags"] != null) |
178 | Int32.TryParse(d.Data["UserFlags"], out u.UserFlags); | 204 | Int32.TryParse(d.Data["UserFlags"], out u.UserFlags); |
205 | if (d.Data.ContainsKey("UserCountry") && d.Data["UserCountry"] != null) | ||
206 | u.UserCountry = d.Data["UserCountry"].ToString(); | ||
207 | else | ||
208 | u.UserCountry = string.Empty; | ||
179 | 209 | ||
180 | if (d.Data.ContainsKey("ServiceURLs") && d.Data["ServiceURLs"] != null) | 210 | if (d.Data.ContainsKey("ServiceURLs") && d.Data["ServiceURLs"] != null) |
181 | { | 211 | { |
@@ -261,6 +291,19 @@ namespace OpenSim.Services.UserAccountService | |||
261 | return MakeUserAccount(d[0]); | 291 | return MakeUserAccount(d[0]); |
262 | } | 292 | } |
263 | 293 | ||
294 | public List<UserAccount> GetUserAccounts(UUID scopeID, List<string> IDs) | ||
295 | { | ||
296 | // do it one at a time db access should be fast, so no need to break its api | ||
297 | List<UserAccount> accs = new List<UserAccount>(); | ||
298 | UUID uuid = UUID.Zero; | ||
299 | foreach(string id in IDs) | ||
300 | { | ||
301 | if (UUID.TryParse(id, out uuid) && uuid != UUID.Zero) | ||
302 | accs.Add(GetUserAccount(scopeID, uuid)); | ||
303 | } | ||
304 | return accs; | ||
305 | } | ||
306 | |||
264 | public void InvalidateCache(UUID userID) | 307 | public void InvalidateCache(UUID userID) |
265 | { | 308 | { |
266 | } | 309 | } |
@@ -301,7 +344,22 @@ namespace OpenSim.Services.UserAccountService | |||
301 | 344 | ||
302 | public List<UserAccount> GetUserAccounts(UUID scopeID, string query) | 345 | public List<UserAccount> GetUserAccounts(UUID scopeID, string query) |
303 | { | 346 | { |
304 | UserAccountData[] d = m_Database.GetUsers(scopeID, query); | 347 | UserAccountData[] d = m_Database.GetUsers(scopeID, query.Trim()); |
348 | |||
349 | if (d == null) | ||
350 | return new List<UserAccount>(); | ||
351 | |||
352 | List<UserAccount> ret = new List<UserAccount>(); | ||
353 | |||
354 | foreach (UserAccountData data in d) | ||
355 | ret.Add(MakeUserAccount(data)); | ||
356 | |||
357 | return ret; | ||
358 | } | ||
359 | |||
360 | public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string where) | ||
361 | { | ||
362 | UserAccountData[] d = m_Database.GetUsersWhere(scopeID, where); | ||
305 | 363 | ||
306 | if (d == null) | 364 | if (d == null) |
307 | return new List<UserAccount>(); | 365 | return new List<UserAccount>(); |
@@ -321,7 +379,7 @@ namespace OpenSim.Services.UserAccountService | |||
321 | /// <summary> | 379 | /// <summary> |
322 | /// Handle the create user command from the console. | 380 | /// Handle the create user command from the console. |
323 | /// </summary> | 381 | /// </summary> |
324 | /// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email</param> | 382 | /// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email, userID, model name </param> |
325 | protected void HandleCreateUser(string module, string[] cmdparams) | 383 | protected void HandleCreateUser(string module, string[] cmdparams) |
326 | { | 384 | { |
327 | string firstName; | 385 | string firstName; |
@@ -329,6 +387,7 @@ namespace OpenSim.Services.UserAccountService | |||
329 | string password; | 387 | string password; |
330 | string email; | 388 | string email; |
331 | string rawPrincipalId; | 389 | string rawPrincipalId; |
390 | string model; | ||
332 | 391 | ||
333 | List<char> excluded = new List<char>(new char[]{' '}); | 392 | List<char> excluded = new List<char>(new char[]{' '}); |
334 | 393 | ||
@@ -353,11 +412,16 @@ namespace OpenSim.Services.UserAccountService | |||
353 | else | 412 | else |
354 | rawPrincipalId = cmdparams[6]; | 413 | rawPrincipalId = cmdparams[6]; |
355 | 414 | ||
415 | if (cmdparams.Length < 8) | ||
416 | model = MainConsole.Instance.CmdPrompt("Model name",""); | ||
417 | else | ||
418 | model = cmdparams[7]; | ||
419 | |||
356 | UUID principalId = UUID.Zero; | 420 | UUID principalId = UUID.Zero; |
357 | if (!UUID.TryParse(rawPrincipalId, out principalId)) | 421 | if (!UUID.TryParse(rawPrincipalId, out principalId)) |
358 | throw new Exception(string.Format("ID {0} is not a valid UUID", rawPrincipalId)); | 422 | throw new Exception(string.Format("ID {0} is not a valid UUID", rawPrincipalId)); |
359 | 423 | ||
360 | CreateUser(UUID.Zero, principalId, firstName, lastName, password, email); | 424 | CreateUser(UUID.Zero, principalId, firstName, lastName, password, email, model); |
361 | } | 425 | } |
362 | 426 | ||
363 | protected void HandleShowAccount(string module, string[] cmdparams) | 427 | protected void HandleShowAccount(string module, string[] cmdparams) |
@@ -512,7 +576,8 @@ namespace OpenSim.Services.UserAccountService | |||
512 | /// <param name="lastName"></param> | 576 | /// <param name="lastName"></param> |
513 | /// <param name="password"></param> | 577 | /// <param name="password"></param> |
514 | /// <param name="email"></param> | 578 | /// <param name="email"></param> |
515 | public UserAccount CreateUser(UUID scopeID, UUID principalID, string firstName, string lastName, string password, string email) | 579 | /// <param name="model"></param> |
580 | public UserAccount CreateUser(UUID scopeID, UUID principalID, string firstName, string lastName, string password, string email, string model = "") | ||
516 | { | 581 | { |
517 | UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); | 582 | UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); |
518 | if (null == account) | 583 | if (null == account) |
@@ -571,7 +636,12 @@ namespace OpenSim.Services.UserAccountService | |||
571 | } | 636 | } |
572 | 637 | ||
573 | if (m_CreateDefaultAvatarEntries) | 638 | if (m_CreateDefaultAvatarEntries) |
574 | CreateDefaultAppearanceEntries(account.PrincipalID); | 639 | { |
640 | if (String.IsNullOrEmpty(model)) | ||
641 | CreateDefaultAppearanceEntries(account.PrincipalID); | ||
642 | else | ||
643 | EstablishAppearance(account.PrincipalID, model); | ||
644 | } | ||
575 | } | 645 | } |
576 | 646 | ||
577 | m_log.InfoFormat( | 647 | m_log.InfoFormat( |
@@ -596,9 +666,11 @@ namespace OpenSim.Services.UserAccountService | |||
596 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID); | 666 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID); |
597 | 667 | ||
598 | InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, FolderType.BodyPart); | 668 | InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, FolderType.BodyPart); |
669 | // Get Current Outfit folder | ||
670 | InventoryFolderBase currentOutfitFolder = m_InventoryService.GetFolderForType(principalID, FolderType.CurrentOutfit); | ||
599 | 671 | ||
600 | InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID); | 672 | InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID); |
601 | eyes.AssetID = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7"); | 673 | eyes.AssetID = AvatarWearable.DEFAULT_EYES_ASSET; |
602 | eyes.Name = "Default Eyes"; | 674 | eyes.Name = "Default Eyes"; |
603 | eyes.CreatorId = principalID.ToString(); | 675 | eyes.CreatorId = principalID.ToString(); |
604 | eyes.AssetType = (int)AssetType.Bodypart; | 676 | eyes.AssetType = (int)AssetType.Bodypart; |
@@ -611,6 +683,7 @@ namespace OpenSim.Services.UserAccountService | |||
611 | eyes.NextPermissions = (uint)PermissionMask.All; | 683 | eyes.NextPermissions = (uint)PermissionMask.All; |
612 | eyes.Flags = (uint)WearableType.Eyes; | 684 | eyes.Flags = (uint)WearableType.Eyes; |
613 | m_InventoryService.AddItem(eyes); | 685 | m_InventoryService.AddItem(eyes); |
686 | CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Eyes, eyes.Name, eyes.ID, principalID, currentOutfitFolder.ID); | ||
614 | 687 | ||
615 | InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID); | 688 | InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID); |
616 | shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET; | 689 | shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET; |
@@ -626,6 +699,7 @@ namespace OpenSim.Services.UserAccountService | |||
626 | shape.NextPermissions = (uint)PermissionMask.All; | 699 | shape.NextPermissions = (uint)PermissionMask.All; |
627 | shape.Flags = (uint)WearableType.Shape; | 700 | shape.Flags = (uint)WearableType.Shape; |
628 | m_InventoryService.AddItem(shape); | 701 | m_InventoryService.AddItem(shape); |
702 | CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Shape, shape.Name, shape.ID, principalID, currentOutfitFolder.ID); | ||
629 | 703 | ||
630 | InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID); | 704 | InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID); |
631 | skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET; | 705 | skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET; |
@@ -641,6 +715,7 @@ namespace OpenSim.Services.UserAccountService | |||
641 | skin.NextPermissions = (uint)PermissionMask.All; | 715 | skin.NextPermissions = (uint)PermissionMask.All; |
642 | skin.Flags = (uint)WearableType.Skin; | 716 | skin.Flags = (uint)WearableType.Skin; |
643 | m_InventoryService.AddItem(skin); | 717 | m_InventoryService.AddItem(skin); |
718 | CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Skin, skin.Name, skin.ID, principalID, currentOutfitFolder.ID); | ||
644 | 719 | ||
645 | InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID); | 720 | InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID); |
646 | hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET; | 721 | hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET; |
@@ -656,6 +731,7 @@ namespace OpenSim.Services.UserAccountService | |||
656 | hair.NextPermissions = (uint)PermissionMask.All; | 731 | hair.NextPermissions = (uint)PermissionMask.All; |
657 | hair.Flags = (uint)WearableType.Hair; | 732 | hair.Flags = (uint)WearableType.Hair; |
658 | m_InventoryService.AddItem(hair); | 733 | m_InventoryService.AddItem(hair); |
734 | CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Hair, hair.Name, hair.ID, principalID, currentOutfitFolder.ID); | ||
659 | 735 | ||
660 | InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, FolderType.Clothing); | 736 | InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, FolderType.Clothing); |
661 | 737 | ||
@@ -673,6 +749,7 @@ namespace OpenSim.Services.UserAccountService | |||
673 | shirt.NextPermissions = (uint)PermissionMask.All; | 749 | shirt.NextPermissions = (uint)PermissionMask.All; |
674 | shirt.Flags = (uint)WearableType.Shirt; | 750 | shirt.Flags = (uint)WearableType.Shirt; |
675 | m_InventoryService.AddItem(shirt); | 751 | m_InventoryService.AddItem(shirt); |
752 | CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Shirt, shirt.Name, shirt.ID, principalID, currentOutfitFolder.ID); | ||
676 | 753 | ||
677 | InventoryItemBase pants = new InventoryItemBase(UUID.Random(), principalID); | 754 | InventoryItemBase pants = new InventoryItemBase(UUID.Random(), principalID); |
678 | pants.AssetID = AvatarWearable.DEFAULT_PANTS_ASSET; | 755 | pants.AssetID = AvatarWearable.DEFAULT_PANTS_ASSET; |
@@ -688,6 +765,7 @@ namespace OpenSim.Services.UserAccountService | |||
688 | pants.NextPermissions = (uint)PermissionMask.All; | 765 | pants.NextPermissions = (uint)PermissionMask.All; |
689 | pants.Flags = (uint)WearableType.Pants; | 766 | pants.Flags = (uint)WearableType.Pants; |
690 | m_InventoryService.AddItem(pants); | 767 | m_InventoryService.AddItem(pants); |
768 | CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Pants, pants.Name, pants.ID, principalID, currentOutfitFolder.ID); | ||
691 | 769 | ||
692 | if (m_AvatarService != null) | 770 | if (m_AvatarService != null) |
693 | { | 771 | { |
@@ -702,6 +780,7 @@ namespace OpenSim.Services.UserAccountService | |||
702 | wearables[AvatarWearable.PANTS] = new AvatarWearable(pants.ID, pants.AssetID); | 780 | wearables[AvatarWearable.PANTS] = new AvatarWearable(pants.ID, pants.AssetID); |
703 | 781 | ||
704 | AvatarAppearance ap = new AvatarAppearance(); | 782 | AvatarAppearance ap = new AvatarAppearance(); |
783 | // this loop works, but is questionable | ||
705 | for (int i = 0; i < 6; i++) | 784 | for (int i = 0; i < 6; i++) |
706 | { | 785 | { |
707 | ap.SetWearable(i, wearables[i]); | 786 | ap.SetWearable(i, wearables[i]); |
@@ -710,5 +789,237 @@ namespace OpenSim.Services.UserAccountService | |||
710 | m_AvatarService.SetAppearance(principalID, ap); | 789 | m_AvatarService.SetAppearance(principalID, ap); |
711 | } | 790 | } |
712 | } | 791 | } |
792 | |||
793 | protected void EstablishAppearance(UUID destinationAgent, string model) | ||
794 | { | ||
795 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Establishing new appearance for {0} - {1}", | ||
796 | destinationAgent.ToString(), model); | ||
797 | |||
798 | string[] modelSpecifiers = model.Split(); | ||
799 | if (modelSpecifiers.Length != 2) | ||
800 | { | ||
801 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Invalid model name \'{0}\'. Falling back to Ruth for {1}", | ||
802 | model, destinationAgent); | ||
803 | CreateDefaultAppearanceEntries(destinationAgent); | ||
804 | return; | ||
805 | } | ||
806 | |||
807 | // Does the source model exist? | ||
808 | UserAccount modelAccount = GetUserAccount(UUID.Zero, modelSpecifiers[0], modelSpecifiers[1]); | ||
809 | if (modelAccount == null) | ||
810 | { | ||
811 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Requested model \'{0}\' not found. Falling back to Ruth for {1}", | ||
812 | model, destinationAgent); | ||
813 | CreateDefaultAppearanceEntries(destinationAgent); | ||
814 | return; | ||
815 | } | ||
816 | |||
817 | // Does the source model have an established appearance herself? | ||
818 | AvatarAppearance modelAppearance = m_AvatarService.GetAppearance(modelAccount.PrincipalID); | ||
819 | if (modelAppearance == null) | ||
820 | { | ||
821 | m_log.WarnFormat("USER ACCOUNT SERVICE]: Requested model \'{0}\' does not have an established appearance. Falling back to Ruth for {1}", | ||
822 | model, destinationAgent); | ||
823 | CreateDefaultAppearanceEntries(destinationAgent); | ||
824 | return; | ||
825 | } | ||
826 | |||
827 | try | ||
828 | { | ||
829 | CopyWearablesAndAttachments(destinationAgent, modelAccount.PrincipalID, modelAppearance); | ||
830 | |||
831 | m_AvatarService.SetAppearance(destinationAgent, modelAppearance); | ||
832 | } | ||
833 | catch (Exception e) | ||
834 | { | ||
835 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring appearance for {0} : {1}", | ||
836 | destinationAgent, e.Message); | ||
837 | } | ||
838 | |||
839 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Finished establishing appearance for {0}", | ||
840 | destinationAgent.ToString()); | ||
841 | } | ||
842 | |||
843 | /// <summary> | ||
844 | /// This method is called by EstablishAppearance to do a copy all inventory items | ||
845 | /// worn or attached to the Clothing inventory folder of the receiving avatar. | ||
846 | /// In parallel the avatar wearables and attachments are updated. | ||
847 | /// </summary> | ||
848 | private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance) | ||
849 | { | ||
850 | // Get Clothing folder of receiver | ||
851 | InventoryFolderBase destinationFolder = m_InventoryService.GetFolderForType(destination, FolderType.Clothing); | ||
852 | // Get Current Outfit folder | ||
853 | InventoryFolderBase currentOutfitFolder = m_InventoryService.GetFolderForType(destination, FolderType.CurrentOutfit); | ||
854 | |||
855 | if (destinationFolder == null) | ||
856 | throw new Exception("Cannot locate folder(s)"); | ||
857 | |||
858 | // Missing destination folder? This should *never* be the case | ||
859 | if (destinationFolder.Type != (short)FolderType.Clothing) | ||
860 | { | ||
861 | destinationFolder = new InventoryFolderBase(); | ||
862 | |||
863 | destinationFolder.ID = UUID.Random(); | ||
864 | destinationFolder.Name = "Clothing"; | ||
865 | destinationFolder.Owner = destination; | ||
866 | destinationFolder.Type = (short)AssetType.Clothing; | ||
867 | destinationFolder.ParentID = m_InventoryService.GetRootFolder(destination).ID; | ||
868 | destinationFolder.Version = 1; | ||
869 | m_InventoryService.AddFolder(destinationFolder); // store base record | ||
870 | m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Created folder for destination {0}", source); | ||
871 | } | ||
872 | |||
873 | // Wearables | ||
874 | AvatarWearable[] wearables = avatarAppearance.Wearables; | ||
875 | AvatarWearable wearable; | ||
876 | |||
877 | for (int i = 0; i < wearables.Length; i++) | ||
878 | { | ||
879 | wearable = wearables[i]; | ||
880 | m_log.DebugFormat("[XXX]: Getting item {0} from avie {1}", wearable[0].ItemID, source); | ||
881 | if (wearable[0].ItemID != UUID.Zero) | ||
882 | { | ||
883 | // Get inventory item and copy it | ||
884 | InventoryItemBase item = m_InventoryService.GetItem(source, wearable[0].ItemID); | ||
885 | |||
886 | if (item != null) | ||
887 | { | ||
888 | InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); | ||
889 | destinationItem.Name = item.Name; | ||
890 | destinationItem.Owner = destination; | ||
891 | destinationItem.Description = item.Description; | ||
892 | destinationItem.InvType = item.InvType; | ||
893 | destinationItem.CreatorId = item.CreatorId; | ||
894 | destinationItem.CreatorData = item.CreatorData; | ||
895 | destinationItem.NextPermissions = item.NextPermissions; | ||
896 | destinationItem.CurrentPermissions = item.CurrentPermissions; | ||
897 | destinationItem.BasePermissions = item.BasePermissions; | ||
898 | destinationItem.EveryOnePermissions = item.EveryOnePermissions; | ||
899 | destinationItem.GroupPermissions = item.GroupPermissions; | ||
900 | destinationItem.AssetType = item.AssetType; | ||
901 | destinationItem.AssetID = item.AssetID; | ||
902 | destinationItem.GroupID = item.GroupID; | ||
903 | destinationItem.GroupOwned = item.GroupOwned; | ||
904 | destinationItem.SalePrice = item.SalePrice; | ||
905 | destinationItem.SaleType = item.SaleType; | ||
906 | destinationItem.Flags = item.Flags; | ||
907 | destinationItem.CreationDate = item.CreationDate; | ||
908 | destinationItem.Folder = destinationFolder.ID; | ||
909 | ApplyNextOwnerPermissions(destinationItem); | ||
910 | |||
911 | m_InventoryService.AddItem(destinationItem); | ||
912 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); | ||
913 | |||
914 | // Wear item | ||
915 | AvatarWearable newWearable = new AvatarWearable(); | ||
916 | newWearable.Wear(destinationItem.ID, wearable[0].AssetID); | ||
917 | avatarAppearance.SetWearable(i, newWearable); | ||
918 | |||
919 | // Add to Current Outfit | ||
920 | CreateCurrentOutfitLink((int)InventoryType.Wearable, item.Flags, item.Name, destinationItem.ID, destination, currentOutfitFolder.ID); | ||
921 | } | ||
922 | else | ||
923 | { | ||
924 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", wearable[0].ItemID, destinationFolder.ID); | ||
925 | } | ||
926 | } | ||
927 | } | ||
928 | |||
929 | // Attachments | ||
930 | List<AvatarAttachment> attachments = avatarAppearance.GetAttachments(); | ||
931 | |||
932 | foreach (AvatarAttachment attachment in attachments) | ||
933 | { | ||
934 | int attachpoint = attachment.AttachPoint; | ||
935 | UUID itemID = attachment.ItemID; | ||
936 | |||
937 | if (itemID != UUID.Zero) | ||
938 | { | ||
939 | // Get inventory item and copy it | ||
940 | InventoryItemBase item = m_InventoryService.GetItem(source, itemID); | ||
941 | |||
942 | if (item != null) | ||
943 | { | ||
944 | InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); | ||
945 | destinationItem.Name = item.Name; | ||
946 | destinationItem.Owner = destination; | ||
947 | destinationItem.Description = item.Description; | ||
948 | destinationItem.InvType = item.InvType; | ||
949 | destinationItem.CreatorId = item.CreatorId; | ||
950 | destinationItem.CreatorData = item.CreatorData; | ||
951 | destinationItem.NextPermissions = item.NextPermissions; | ||
952 | destinationItem.CurrentPermissions = item.CurrentPermissions; | ||
953 | destinationItem.BasePermissions = item.BasePermissions; | ||
954 | destinationItem.EveryOnePermissions = item.EveryOnePermissions; | ||
955 | destinationItem.GroupPermissions = item.GroupPermissions; | ||
956 | destinationItem.AssetType = item.AssetType; | ||
957 | destinationItem.AssetID = item.AssetID; | ||
958 | destinationItem.GroupID = item.GroupID; | ||
959 | destinationItem.GroupOwned = item.GroupOwned; | ||
960 | destinationItem.SalePrice = item.SalePrice; | ||
961 | destinationItem.SaleType = item.SaleType; | ||
962 | destinationItem.Flags = item.Flags; | ||
963 | destinationItem.CreationDate = item.CreationDate; | ||
964 | destinationItem.Folder = destinationFolder.ID; | ||
965 | ApplyNextOwnerPermissions(destinationItem); | ||
966 | |||
967 | m_InventoryService.AddItem(destinationItem); | ||
968 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); | ||
969 | |||
970 | // Attach item | ||
971 | avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID); | ||
972 | m_log.DebugFormat("[USER ACCOUNT SERVICE]: Attached {0}", destinationItem.ID); | ||
973 | |||
974 | // Add to Current Outfit | ||
975 | CreateCurrentOutfitLink(destinationItem.InvType, item.Flags, item.Name, destinationItem.ID, destination, currentOutfitFolder.ID); | ||
976 | } | ||
977 | else | ||
978 | { | ||
979 | m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID); | ||
980 | } | ||
981 | } | ||
982 | } | ||
983 | } | ||
984 | |||
985 | protected void CreateCurrentOutfitLink(int invType, uint itemType, string name, UUID itemID, UUID userID, UUID currentOutfitFolderUUID) | ||
986 | { | ||
987 | UUID LinkInvItem = UUID.Random(); | ||
988 | InventoryItemBase itembase = new InventoryItemBase(LinkInvItem, userID) | ||
989 | { | ||
990 | AssetID = itemID, | ||
991 | AssetType = (int)AssetType.Link, | ||
992 | CreatorId = userID.ToString(), | ||
993 | InvType = invType, | ||
994 | Description = "", | ||
995 | //Folder = m_InventoryService.GetFolderForType(userID, FolderType.CurrentOutfit).ID, | ||
996 | Folder = currentOutfitFolderUUID, | ||
997 | Flags = itemType, | ||
998 | Name = name, | ||
999 | BasePermissions = (uint)PermissionMask.Copy, | ||
1000 | CurrentPermissions = (uint)PermissionMask.Copy, | ||
1001 | EveryOnePermissions = (uint)PermissionMask.Copy, | ||
1002 | GroupPermissions = (uint)PermissionMask.Copy, | ||
1003 | NextPermissions = (uint)PermissionMask.Copy | ||
1004 | }; | ||
1005 | |||
1006 | m_InventoryService.AddItem(itembase); | ||
1007 | } | ||
1008 | |||
1009 | /// <summary> | ||
1010 | /// Apply next owner permissions. | ||
1011 | /// </summary> | ||
1012 | private void ApplyNextOwnerPermissions(InventoryItemBase item) | ||
1013 | { | ||
1014 | if (item.InvType == (int)InventoryType.Object) | ||
1015 | { | ||
1016 | uint perms = item.CurrentPermissions; | ||
1017 | item.CurrentPermissions = perms; | ||
1018 | } | ||
1019 | |||
1020 | item.CurrentPermissions &= item.NextPermissions; | ||
1021 | item.BasePermissions &= item.NextPermissions; | ||
1022 | item.EveryOnePermissions &= item.NextPermissions; | ||
1023 | } | ||
713 | } | 1024 | } |
714 | } | 1025 | } |