///<summary>
/// This method is called if a given model avatar name can not be found. If the external
/// file has already been loaded once, then control returns immediately. If not, then it
/// looks for a default appearance file. This file contains XML definitions of zero or more named
/// avatars, each avatar can specify zero or more "outfits". Each outfit is a collection
/// of items that together, define a particular ensemble for the avatar. Each avatar should
/// indicate which outfit is the default, and this outfit will be automatically worn. The
/// other outfits are provided to allow "real" avatars a way to easily change their outfits.
/// </summary>
private bool createDefaultAvatars()
{
// Only load once
if (daload)
{
return false;
}
m_log.DebugFormat("[RADMIN] Creating default avatar entries");
daload = true;
// Load processing starts here...
try
{
string dafn = null;
//m_config may be null if RemoteAdmin configuration secition is missing or disabled in OpenSim.ini
if (m_config != null)
{
dafn = m_config.GetString("default_appearance", "default_appearance.xml");
}
if (File.Exists(dafn))
{
XmlDocument doc = new XmlDocument();
string name = "*unknown*";
string email = "anon@anon";
uint regX = 1000;
uint regY = 1000;
string passwd = UUID.Random().ToString(); // No requirement to sign-in.
CachedUserInfo UI;
UUID ID = UUID.Zero;
AvatarAppearance mava;
XmlNodeList avatars;
XmlNodeList assets;
XmlNode perms = null;
bool include = false;
bool select = false;
UICallback uic;
IInventoryService iserv = m_app.SceneManager.CurrentOrFirstScene.InventoryService;
IAssetService aserv = m_app.SceneManager.CurrentOrFirstScene.AssetService;
doc.LoadXml(File.ReadAllText(dafn));
// Load up any included assets. Duplicates will be ignored
assets = doc.GetElementsByTagName("RequiredAsset");
foreach (XmlNode asset in assets)
{
AssetBase rass = new AssetBase();
rass.FullID = UUID.Random();
rass.Name = GetStringAttribute(asset,"name","");
rass.Description = GetStringAttribute(asset,"desc","");
rass.Type = SByte.Parse(GetStringAttribute(asset,"type",""));
rass.Local = Boolean.Parse(GetStringAttribute(asset,"local",""));
rass.Temporary = Boolean.Parse(GetStringAttribute(asset,"temporary",""));
rass.Data = Convert.FromBase64String(asset.InnerText);
aserv.Store(rass);
}
avatars = doc.GetElementsByTagName("Avatar");
// The document may contain multiple avatars
foreach (XmlElement avatar in avatars)
{
m_log.DebugFormat("[RADMIN] Loading appearance for {0}, gender = {1}",
GetStringAttribute(avatar,"name","?"), GetStringAttribute(avatar,"gender","?"));
// Create the user identified by the avatar entry
try
{
// Only the name value is mandatory
name = GetStringAttribute(avatar,"name",name);
email = GetStringAttribute(avatar,"email",email);
regX = GetUnsignedAttribute(avatar,"regx",regX);
regY = GetUnsignedAttribute(avatar,"regy",regY);
passwd = GetStringAttribute(avatar,"password",passwd);
string[] nomens = name.Split();
UI = m_app.CommunicationsManager.UserProfileCacheService.GetUserDetails(nomens[0], nomens[1]);
if (null == UI)
{
ID = m_app.CommunicationsManager.UserAdminService.AddUser(nomens[0], nomens[1],
passwd, email, regX, regY);
if (ID == UUID.Zero)
{
m_log.ErrorFormat("[RADMIN] Avatar {0} {1} was not created", nomens[0], nomens[1]);
return false;
}
}
else
{
ID = UI.UserProfile.ID;
}
m_log.DebugFormat("[RADMIN] User {0}[{1}] created or retrieved", name, ID);
include = true;
}
catch (Exception e)
{
m_log.DebugFormat("[RADMIN] Error creating user {0} : {1}", name, e.Message);
include = false;
}
// OK, User has been created OK, now we can install the inventory.
// First retrieve the current inventory (the user may already exist)
// Note that althought he inventory is retrieved, the hierarchy has
// not been interpreted at all.
if (include)
{
uic = new UICallback();
// Request the inventory
iserv.GetUserInventory(ID, uic.callback);
// While the inventory is being fetched, setup for appearance processing
if ((mava = m_app.CommunicationsManager.AvatarService.GetUserAppearance(ID)) == null)
{
mava = new AvatarAppearance();
}
{
AvatarWearable[] wearables = mava.Wearables;
for (int i=0; i<wearables.Length; i++)
{
wearables[i] = new AvatarWearable();
}
}
// Wait for the inventory to arrive
uic.GetInventory();
// We can only get dresssed if an inventory is forthcoming
if (uic.OK)
try
{
m_log.DebugFormat("[RADMIN] {0} folders, {1} items in inventory",
uic.folders.Count, uic.items.Count);
InventoryFolderImpl cfolder = uic.root.FindFolderForType(5);
// This should *never* be the case
if (cfolder == null)
{
cfolder = new InventoryFolderImpl();
cfolder.Name = "Clothing";
cfolder.Type = 5;
cfolder.Version = 1;
cfolder.Owner = ID;
uic.root.AddChildFolder(cfolder); // make connection
iserv.AddFolder(cfolder); // store base record
m_log.ErrorFormat("[RADMIN] Created clothing folder for {0}/{1}", name, ID);
}
// OK, now we have an inventory for the user, read in the outfits from the
// default appearance XMl file.
XmlNodeList outfits = avatar.GetElementsByTagName("Ensemble");
InventoryFolderImpl efolder;
string oname;
UUID assetid;
foreach (XmlElement outfit in outfits)
{
m_log.DebugFormat("[RADMIN] Loading outfit {0} for {1}",
GetStringAttribute(outfit,"name","?"), GetStringAttribute(avatar,"name","?"));
oname = GetStringAttribute(outfit,"name","");
select = (GetStringAttribute(outfit,"default","no") == "yes");
efolder = null;
// If the folder already exists, re-use it. The defaults may
// change over time. Augment only.
foreach (InventoryFolderImpl folder in uic.folders)
{
if (folder.Name == oname && folder.ParentID == cfolder.ID)
{
efolder = folder;
break;
}
}
// Otherwise, we must create the folder.
if (efolder == null)
{
m_log.DebugFormat("[RADMIN] Creating outfit folder {0} for {1}", oname, name);
efolder = new InventoryFolderImpl();
efolder.ID = UUID.Random();
efolder.Name = oname;
efolder.Type = 5;
efolder.Version = 1;
efolder.Owner = ID;
cfolder.AddChildFolder(efolder); // make connection
iserv.AddFolder(efolder); // store base record
m_log.DebugFormat("[RADMIN] Adding outfile folder {0} to folder {1}", efolder.ID, cfolder.ID);
}
// Now get the pieces that make up the outfit
XmlNodeList items = outfit.GetElementsByTagName("Item");
foreach (XmlElement item in items)
{
assetid = UUID.Zero;
XmlNodeList children = item.ChildNodes;
foreach (XmlNode child in children)
{
switch (child.Name)
{
case "Permissions" :
m_log.DebugFormat("[RADMIN] Permissions specified");
perms = child;
break;
case "Asset" :
assetid = new UUID(child.InnerText);
break;
}
}
InventoryItemBase iitem = null;
if ((iitem = efolder.FindAsset(assetid)) == null)
{
iitem = new InventoryItemBase();
iitem.ID = UUID.Random();
iitem.Name = GetStringAttribute(item,"name","");
iitem.Description = GetStringAttribute(item,"desc","");
iitem.InvType = GetIntegerAttribute(item,"invtype",-1);
iitem.AssetType = GetIntegerAttribute(item,"assettype",-1);
iitem.Flags = GetUnsignedAttribute(item,"flags",0);
iitem.AssetID = assetid; // associated asset
iitem.Folder = efolder.ID; // Parent folder
iitem.Owner = ID; // Agent ID
iitem.BasePermissions = GetUnsignedAttribute(perms,"base",0x7fffffff);
iitem.NextPermissions = GetUnsignedAttribute(perms,"next",0x7fffffff);
iitem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff);
iitem.GroupPermissions = GetUnsignedAttribute(perms,"group",0x7fffffff);
iitem.EveryOnePermissions = GetUnsignedAttribute(perms,"everyone",0x7fffffff);
m_log.DebugFormat("[RADMIN] Adding item {0} to folder {1}", iitem.ID, efolder.ID);
iserv.AddItem(iitem);
}
// Record whether or not the item is to be initially worn
try
{
if (select && (GetStringAttribute(item, "wear", "false") == "true"))
{
mava.Wearables[iitem.Flags].ItemID = iitem.ID;
mava.Wearables[iitem.Flags].AssetID = iitem.AssetID;
}
}
catch {}
} // foreach item in outfit
m_log.DebugFormat("[RADMIN] Outfit {0} load completed", oname);
} // foreach outfit
m_log.DebugFormat("[RADMIN] Inventory update complete for {0}", name);
m_app.CommunicationsManager.AvatarService.UpdateUserAppearance(ID, mava);
}
catch (Exception e)
{
m_log.WarnFormat("[RADMIN] Inventory processing incomplete for user {0} : {1}",
name, e.Message);
}
else
{
m_log.WarnFormat("[RADMIN] Unable to retrieve inventory for {0}[{1}]",
name, ID);
// continue to next avatar
}
} // End of include
}
m_log.DebugFormat("[RADMIN] Default avatar loading complete");
}
else
{
m_log.DebugFormat("[RADMIN] No default avatar information available");
return false;
}
}
catch (Exception e)
{
m_log.WarnFormat("[RADMIN] Exception whilst loading default avatars ; {0}", e.Message);
return false;
}
return true;
}