diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index c63b0a4d0e..b51570f0cc 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -323,6 +323,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
}
+ // Validate assorted conditions
+ string reason = string.Empty;
+ if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason))
+ {
+ sp.ControllingClient.SendTeleportFailed(reason);
+ return;
+ }
+
//
// This is it
//
@@ -354,6 +362,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
+ // Nothing to validate here
+ protected virtual bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
+ {
+ reason = String.Empty;
+ return true;
+ }
+
///
/// Determines whether this instance is within the max transfer distance.
///
@@ -568,7 +583,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
//sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
- if (!UpdateAgent(reg, finalDestination, agent))
+ if (!UpdateAgent(reg, finalDestination, agent, sp))
{
// Region doesn't take it
m_log.WarnFormat(
@@ -695,7 +710,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return success;
}
- protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent)
+ protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp)
{
return Scene.SimulationService.UpdateAgent(finalDestination, agent);
}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 08863c2d05..f3c5873bd5 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -54,6 +54,47 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private GatekeeperServiceConnector m_GatekeeperConnector;
+ protected bool m_RestrictAppearanceAbroad;
+ protected string m_AccountName;
+ protected AvatarAppearance m_ExportedAppearance;
+
+ protected AvatarAppearance ExportedAppearance
+ {
+ get
+ {
+ if (m_ExportedAppearance != null)
+ return m_ExportedAppearance;
+
+ string[] parts = m_AccountName.Split();
+ if (parts.Length != 2)
+ {
+ m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Wrong user account name format {0}. Specify 'First Last'", m_AccountName);
+ return null;
+ }
+ UserAccount account = Scene.UserAccountService.GetUserAccount(UUID.Zero, parts[0], parts[1]);
+ if (account == null)
+ {
+ m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unknown account {0}", m_AccountName);
+ return null;
+ }
+ m_ExportedAppearance = Scene.AvatarService.GetAppearance(account.PrincipalID);
+ if (m_ExportedAppearance != null)
+ m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Successfully retrieved appearance for {0}", m_AccountName);
+
+ foreach (AvatarAttachment att in m_ExportedAppearance.GetAttachments())
+ {
+ InventoryItemBase item = new InventoryItemBase(att.ItemID, account.PrincipalID);
+ item = Scene.InventoryService.GetItem(item);
+ if (item != null)
+ m_ExportedAppearance.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID);
+ else
+ m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to retrieve item {0} from inventory", att.ItemID);
+ }
+ return m_ExportedAppearance;
+ }
+ }
+
+
#region ISharedRegionModule
public override string Name
@@ -72,8 +113,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
IConfig transferConfig = source.Configs["EntityTransfer"];
if (transferConfig != null)
+ {
m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0);
+ m_RestrictAppearanceAbroad = transferConfig.GetBoolean("RestrictAppearanceAbroad", false);
+ if (m_RestrictAppearanceAbroad)
+ {
+ m_AccountName = transferConfig.GetString("AccountForAppearance", string.Empty);
+ if (m_AccountName == string.Empty)
+ m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is on, but no account has been given for avatar appearance!");
+ }
+ }
+
InitialiseCommon(source);
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
}
@@ -195,6 +246,109 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
}
+ protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
+ {
+ reason = "Please wear your grid's allowed appearance before teleporting to another grid";
+ if (!m_RestrictAppearanceAbroad)
+ return true;
+
+ // The rest is only needed for controlling appearance
+
+ int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
+ if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
+ {
+ // this user is going to another grid
+ if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID))
+ {
+ m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
+
+ // Check wearables
+ for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
+ {
+ for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++)
+ {
+ if (sp.Appearance.Wearables[i] == null)
+ continue;
+
+ if (ExportedAppearance.Wearables[i] == null)
+ {
+ m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
+ return false;
+ }
+
+ if (sp.Appearance.Wearables[i][j].AssetID != ExportedAppearance.Wearables[i][j].AssetID)
+ {
+ m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
+ return false;
+ }
+ }
+ }
+
+ // Check attachments
+
+ foreach (AvatarAttachment att in sp.Appearance.GetAttachments())
+ {
+ bool found = false;
+ foreach (AvatarAttachment att2 in ExportedAppearance.GetAttachments())
+ {
+ if (att2.AssetID == att.AssetID)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Attachment not allowed to go outside {0}", att.AttachPoint);
+ return false;
+ }
+ }
+ }
+ }
+
+ reason = string.Empty;
+ return true;
+ }
+
+
+ //protected override bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agentData, ScenePresence sp)
+ //{
+ // int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
+ // if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
+ // {
+ // // this user is going to another grid
+ // if (m_RestrictAppearanceAbroad && Scene.UserManagementModule.IsLocalGridUser(agentData.AgentID))
+ // {
+ // // We need to strip the agent off its appearance
+ // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Sending generic appearance");
+
+ // // Delete existing npc attachments
+ // Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
+
+ // // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet since it doesn't transfer attachments
+ // AvatarAppearance newAppearance = new AvatarAppearance(ExportedAppearance, true);
+ // sp.Appearance = newAppearance;
+
+ // // Rez needed npc attachments
+ // Scene.AttachmentsModule.RezAttachments(sp);
+
+
+ // IAvatarFactoryModule module = Scene.RequestModuleInterface();
+ // //module.SendAppearance(sp.UUID);
+ // module.RequestRebake(sp, false);
+
+ // Scene.AttachmentsModule.CopyAttachments(sp, agentData);
+ // agentData.Appearance = sp.Appearance;
+ // }
+ // }
+
+ // foreach (AvatarAttachment a in agentData.Appearance.GetAttachments())
+ // m_log.DebugFormat("[XXX]: {0}-{1}", a.ItemID, a.AssetID);
+
+
+ // return base.UpdateAgent(reg, finalDestination, agentData, sp);
+ //}
+
public override void TeleportHome(UUID id, IClientAPI client)
{
m_log.DebugFormat(
diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
index 91cc6ebc66..556a0da49c 100644
--- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
@@ -573,6 +573,7 @@ namespace OpenSim.Services.HypergridService
private bool IsPartOfAppearance(UUID principalID, UUID itemID)
{
AvatarAppearance a = GetAppearance(principalID);
+
if (a == null)
return false;
diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini
index cc6c587de7..b0ae351c3d 100644
--- a/bin/config-include/StandaloneHypergrid.ini
+++ b/bin/config-include/StandaloneHypergrid.ini
@@ -153,6 +153,7 @@
; For the InventoryServiceInConnector
LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService"
UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
+ AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
;; The interface that local users get when they are in other grids
;; This restricts/filters the asset operations from the outside