diff --git a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs
index 237ffc7ee3..b22c4cc6fd 100644
--- a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs
@@ -328,12 +328,16 @@ namespace OpenSim.Server.Handlers.UserAccounts
if (request.ContainsKey("Email"))
email = request["Email"].ToString();
+ string model = "";
+ if (request.ContainsKey("Model"))
+ model = request["Model"].ToString();
+
UserAccount createdUserAccount = null;
if (m_UserAccountService is UserAccountService)
createdUserAccount
= ((UserAccountService)m_UserAccountService).CreateUser(
- scopeID, principalID, firstName, lastName, password, email);
+ scopeID, principalID, firstName, lastName, password, email, model);
if (createdUserAccount == null)
return FailureResult();
@@ -393,4 +397,4 @@ namespace OpenSim.Server.Handlers.UserAccounts
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs
index 668fe53730..bb50536007 100644
--- a/OpenSim/Services/UserAccountService/UserAccountService.cs
+++ b/OpenSim/Services/UserAccountService/UserAccountService.cs
@@ -544,7 +544,8 @@ namespace OpenSim.Services.UserAccountService
///
///
///
- public UserAccount CreateUser(UUID scopeID, UUID principalID, string firstName, string lastName, string password, string email)
+ ///
+ public UserAccount CreateUser(UUID scopeID, UUID principalID, string firstName, string lastName, string password, string email, string model = "")
{
UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
if (null == account)
@@ -603,7 +604,12 @@ namespace OpenSim.Services.UserAccountService
}
if (m_CreateDefaultAvatarEntries)
- CreateDefaultAppearanceEntries(account.PrincipalID);
+ {
+ if (String.IsNullOrEmpty(model))
+ CreateDefaultAppearanceEntries(account.PrincipalID);
+ else
+ EstablishAppearance(account.PrincipalID, model);
+ }
}
m_log.InfoFormat(
@@ -734,6 +740,7 @@ namespace OpenSim.Services.UserAccountService
wearables[AvatarWearable.PANTS] = new AvatarWearable(pants.ID, pants.AssetID);
AvatarAppearance ap = new AvatarAppearance();
+ // this loop works, but is questionable
for (int i = 0; i < 6; i++)
{
ap.SetWearable(i, wearables[i]);
@@ -742,5 +749,205 @@ namespace OpenSim.Services.UserAccountService
m_AvatarService.SetAppearance(principalID, ap);
}
}
+
+ protected void EstablishAppearance(UUID destinationAgent, string model)
+ {
+ m_log.DebugFormat("[USER ACCOUNT SERVICE]: Establishing new appearance for {0} - {1}",
+ destinationAgent.ToString(), model);
+
+ string[] modelSpecifiers = model.Split();
+ if (modelSpecifiers.Length != 2)
+ {
+ m_log.WarnFormat("[USER ACCOUNT SERVICE]: Invalid model name \'{0}\'. Falling back to Ruth for {1}",
+ model, destinationAgent);
+ CreateDefaultAppearanceEntries(destinationAgent);
+ return;
+ }
+
+ // Does the source model exist?
+ UserAccount modelAccount = GetUserAccount(UUID.Zero, modelSpecifiers[0], modelSpecifiers[1]);
+ if (modelAccount == null)
+ {
+ m_log.WarnFormat("[USER ACCOUNT SERVICE]: Requested model \'{0}\' not found. Falling back to Ruth for {1}",
+ model, destinationAgent);
+ CreateDefaultAppearanceEntries(destinationAgent);
+ return;
+ }
+
+ // Does the source model have an established appearance herself?
+ AvatarAppearance modelAppearance = m_AvatarService.GetAppearance(modelAccount.PrincipalID);
+ if (modelAppearance == null)
+ {
+ m_log.WarnFormat("USER ACCOUNT SERVICE]: Requested model \'{0}\' does not have an established appearance. Falling back to Ruth for {1}",
+ model, destinationAgent);
+ CreateDefaultAppearanceEntries(destinationAgent);
+ return;
+ }
+
+ try
+ {
+ CopyWearablesAndAttachments(destinationAgent, modelAccount.PrincipalID, modelAppearance);
+
+ m_AvatarService.SetAppearance(destinationAgent, modelAppearance);
+ }
+ catch (Exception e)
+ {
+ m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring appearance for {0} : {1}",
+ destinationAgent, e.Message);
+ }
+
+ m_log.DebugFormat("[USER ACCOUNT SERVICE]: Finished establishing appearance for {0}",
+ destinationAgent.ToString());
+ }
+
+ ///
+ /// This method is called by EstablishAppearance to do a copy all inventory items
+ /// worn or attached to the Clothing inventory folder of the receiving avatar.
+ /// In parallel the avatar wearables and attachments are updated.
+ ///
+ private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance)
+ {
+ // Get Clothing folder of receiver
+ InventoryFolderBase destinationFolder = m_InventoryService.GetFolderForType(destination, FolderType.Clothing);
+
+ if (destinationFolder == null)
+ throw new Exception("Cannot locate folder(s)");
+
+ // Missing destination folder? This should *never* be the case
+ if (destinationFolder.Type != (short)FolderType.Clothing)
+ {
+ destinationFolder = new InventoryFolderBase();
+
+ destinationFolder.ID = UUID.Random();
+ destinationFolder.Name = "Clothing";
+ destinationFolder.Owner = destination;
+ destinationFolder.Type = (short)AssetType.Clothing;
+ destinationFolder.ParentID = m_InventoryService.GetRootFolder(destination).ID;
+ destinationFolder.Version = 1;
+ m_InventoryService.AddFolder(destinationFolder); // store base record
+ m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Created folder for destination {0}", source);
+ }
+
+ // Wearables
+ AvatarWearable[] wearables = avatarAppearance.Wearables;
+ AvatarWearable wearable;
+
+ for (int i = 0; i < wearables.Length; i++)
+ {
+ wearable = wearables[i];
+ if (wearable[0].ItemID != UUID.Zero)
+ {
+ // Get inventory item and copy it
+ InventoryItemBase item = m_InventoryService.GetItem(source, wearable[0].ItemID);
+
+ if (item != null)
+ {
+ InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
+ destinationItem.Name = item.Name;
+ destinationItem.Owner = destination;
+ destinationItem.Description = item.Description;
+ destinationItem.InvType = item.InvType;
+ destinationItem.CreatorId = item.CreatorId;
+ destinationItem.CreatorData = item.CreatorData;
+ destinationItem.NextPermissions = item.NextPermissions;
+ destinationItem.CurrentPermissions = item.CurrentPermissions;
+ destinationItem.BasePermissions = item.BasePermissions;
+ destinationItem.EveryOnePermissions = item.EveryOnePermissions;
+ destinationItem.GroupPermissions = item.GroupPermissions;
+ destinationItem.AssetType = item.AssetType;
+ destinationItem.AssetID = item.AssetID;
+ destinationItem.GroupID = item.GroupID;
+ destinationItem.GroupOwned = item.GroupOwned;
+ destinationItem.SalePrice = item.SalePrice;
+ destinationItem.SaleType = item.SaleType;
+ destinationItem.Flags = item.Flags;
+ destinationItem.CreationDate = item.CreationDate;
+ destinationItem.Folder = destinationFolder.ID;
+ ApplyNextOwnerPermissions(destinationItem);
+
+ m_InventoryService.AddItem(destinationItem);
+ m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);
+
+ // Wear item
+ AvatarWearable newWearable = new AvatarWearable();
+ newWearable.Wear(destinationItem.ID, wearable[0].AssetID);
+ avatarAppearance.SetWearable(i, newWearable);
+ }
+ else
+ {
+ m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", wearable[0].ItemID, destinationFolder.ID);
+ }
+ }
+ }
+
+ // Attachments
+ List attachments = avatarAppearance.GetAttachments();
+
+ foreach (AvatarAttachment attachment in attachments)
+ {
+ int attachpoint = attachment.AttachPoint;
+ UUID itemID = attachment.ItemID;
+
+ if (itemID != UUID.Zero)
+ {
+ // Get inventory item and copy it
+ InventoryItemBase item = m_InventoryService.GetItem(source, itemID);
+
+ if (item != null)
+ {
+ InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
+ destinationItem.Name = item.Name;
+ destinationItem.Owner = destination;
+ destinationItem.Description = item.Description;
+ destinationItem.InvType = item.InvType;
+ destinationItem.CreatorId = item.CreatorId;
+ destinationItem.CreatorData = item.CreatorData;
+ destinationItem.NextPermissions = item.NextPermissions;
+ destinationItem.CurrentPermissions = item.CurrentPermissions;
+ destinationItem.BasePermissions = item.BasePermissions;
+ destinationItem.EveryOnePermissions = item.EveryOnePermissions;
+ destinationItem.GroupPermissions = item.GroupPermissions;
+ destinationItem.AssetType = item.AssetType;
+ destinationItem.AssetID = item.AssetID;
+ destinationItem.GroupID = item.GroupID;
+ destinationItem.GroupOwned = item.GroupOwned;
+ destinationItem.SalePrice = item.SalePrice;
+ destinationItem.SaleType = item.SaleType;
+ destinationItem.Flags = item.Flags;
+ destinationItem.CreationDate = item.CreationDate;
+ destinationItem.Folder = destinationFolder.ID;
+ ApplyNextOwnerPermissions(destinationItem);
+
+ m_InventoryService.AddItem(destinationItem);
+ m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);
+
+ // Attach item
+ avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID);
+ m_log.DebugFormat("[USER ACCOUNT SERVICE]: Attached {0}", destinationItem.ID);
+ }
+ else
+ {
+ m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Apply next owner permissions.
+ ///
+ private void ApplyNextOwnerPermissions(InventoryItemBase item)
+ {
+ if (item.InvType == (int)InventoryType.Object)
+ {
+ uint perms = item.CurrentPermissions;
+ PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);
+ item.CurrentPermissions = perms;
+ }
+
+ item.CurrentPermissions &= item.NextPermissions;
+ item.BasePermissions &= item.NextPermissions;
+ item.EveryOnePermissions &= item.NextPermissions;
+ }
}
}