29 using System.Collections.Generic;
30 using System.Reflection;
32 using OpenSim.Framework;
33 using OpenSim.Framework.Client;
34 using OpenSim.Framework.Monitoring;
35 using OpenSim.Region.Framework.Interfaces;
36 using OpenSim.Region.Framework.Scenes;
37 using OpenSim.Services.Connectors.Hypergrid;
38 using OpenSim.Services.Interfaces;
39 using OpenSim.Server.Base;
48 namespace OpenSim.
Region.CoreModules.Framework.EntityTransfer
50 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"HGEntityTransferModule")]
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 private int m_levelHGTeleport = 0;
66 protected List<AvatarAppearance> ExportedAppearance
70 if (m_ExportedAppearances != null)
71 return m_ExportedAppearances;
73 m_ExportedAppearances =
new List<AvatarAppearance>();
74 m_Attachs =
new List<AvatarAttachment>();
76 string[] names = m_AccountName.Split(
new char[] {
',' }, StringSplitOptions.RemoveEmptyEntries);
78 foreach (
string name
in names)
80 string[] parts = name.Trim().Split();
81 if (parts.Length != 2)
83 m_log.WarnFormat(
"[HG ENTITY TRANSFER MODULE]: Wrong user account name format {0}. Specify 'First Last'", name);
86 UserAccount account = Scene.UserAccountService.GetUserAccount(UUID.Zero, parts[0], parts[1]);
89 m_log.WarnFormat(
"[HG ENTITY TRANSFER MODULE]: Unknown account {0}", m_AccountName);
94 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Successfully retrieved appearance for {0}", name);
99 item = Scene.InventoryService.GetItem(item);
101 a.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID);
103 m_log.WarnFormat(
"[HG ENTITY TRANSFER MODULE]: Unable to retrieve item {0} from inventory {1}", att.ItemID, name);
106 m_ExportedAppearances.Add(a);
107 m_Attachs.AddRange(a.GetAttachments());
110 return m_ExportedAppearances;
117 private JobEngine m_incomingSceneObjectEngine;
119 #region ISharedRegionModule
121 public override string Name
123 get {
return "HGEntityTransferModule"; }
128 IConfig moduleConfig = source.Configs[
"Modules"];
130 if (moduleConfig != null)
132 string name = moduleConfig.GetString(
"EntityTransferModule",
"");
135 IConfig transferConfig = source.Configs[
"EntityTransfer"];
136 if (transferConfig != null)
138 m_levelHGTeleport = transferConfig.GetInt(
"LevelHGTeleport", 0);
140 m_RestrictAppearanceAbroad = transferConfig.GetBoolean(
"RestrictAppearanceAbroad",
false);
141 if (m_RestrictAppearanceAbroad)
143 m_AccountName = transferConfig.GetString(
"AccountForAppearance", string.Empty);
144 if (m_AccountName ==
string.Empty)
145 m_log.WarnFormat(
"[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is on, but no account has been given for avatar appearance!");
149 InitialiseCommon(source);
150 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
157 base.AddRegion(scene);
164 m_incomingSceneObjectEngine
166 string.Format(
"HG Incoming Scene Object Engine ({0})", scene.
Name),
167 "HG INCOMING SCENE OBJECT ENGINE");
169 StatsManager.RegisterStat(
171 "HGIncomingAttachmentsWaiting",
172 "Number of incoming attachments waiting for processing.",
179 stat => stat.Value = m_incomingSceneObjectEngine.JobsWaiting,
182 m_incomingSceneObjectEngine.Start();
188 client.OnTeleportHomeRequest += TriggerTeleportHome;
189 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
190 client.OnConnectionClosed +=
new Action<IClientAPI>(OnConnectionClosed);
195 base.RegionLoaded(scene);
209 base.RemoveRegion(scene);
214 m_incomingSceneObjectEngine.Stop();
220 #region HG overrides of IEntityTransferModule
224 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID);
225 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionName, flags);
228 if ((flags & (
int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
230 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Destination region is hyperlink");
231 GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID, agentID, agentHomeURI, out message);
232 if (real_destination != null)
233 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: GetFinalDestination: ServerURI={0}", real_destination.ServerURI);
235 m_log.WarnFormat(
"[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion of region {0} from Gatekeeper {1} failed: {2}", region.RegionID, region.ServerURI, message);
236 return real_destination;
247 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
248 if (flags == -1 || (flags & (
int)
OpenSim.Framework.RegionFlags.Hyperlink) != 0)
256 base.AgentHasMovedAway(sp, logout);
260 Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
261 string userId = Scene.UserManagementModule.GetUserUUI(sp.UUID);
262 Scene.GridUserService.LoggedOut(userId, UUID.Zero, Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
268 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI);
269 reason = string.Empty;
271 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
272 if (flags == -1 || (flags & (
int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
278 m_log.WarnFormat(
"[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
279 reason =
"Hypergrid teleport not allowed";
283 if (agentCircuit.
ServiceURLs.ContainsKey(
"HomeURI"))
285 string userAgentDriver = agentCircuit.ServiceURLs[
"HomeURI"].ToString();
288 if (userAgentDriver.Equals(m_ThisHomeURI) && m_UAS != null)
294 source.RawServerURI = m_GatekeeperURI;
296 bool success = connector.LoginAgentToGrid(source, agentCircuit, reg, finalDestination,
false, out reason);
300 Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
306 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Agent does not have a HomeURI address");
311 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout);
316 TeleportHome(
id, client);
321 reason =
"Please wear your grid's allowed appearance before teleporting to another grid";
322 if (!m_RestrictAppearanceAbroad)
327 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
328 if (flags == -1 || (flags & (
int)
OpenSim.Framework.RegionFlags.Hyperlink) != 0)
333 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
336 for (
int i = 0; i < sp.Appearance.Wearables.Length ; i++)
338 for (
int j = 0; j < sp.Appearance.Wearables[i].Count; j++)
353 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
367 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
387 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Attachment not allowed to go outside {0}", att.AttachPoint);
394 reason = string.Empty;
441 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
445 if (uMan != null && uMan.IsLocalGridUser(
id))
448 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: User is local");
449 return base.TeleportHome(id, client);
455 if (aCircuit == null || (aCircuit != null && !aCircuit.
ServiceURLs.ContainsKey(
"HomeURI")))
457 client.SendTeleportFailed(
"Your information has been lost");
458 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information");
463 Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY;
468 finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt);
472 m_log.Debug(
"[HG ENTITY TRANSFER MODULE]: GetHomeRegion call failed ", e);
475 if (finalDestination == null)
477 client.SendTeleportFailed(
"Your home region could not be found");
478 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Agent's home region not found");
485 client.SendTeleportFailed(
"Internal error");
486 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be");
490 GridRegion homeGatekeeper = MakeRegion(aCircuit);
492 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
493 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
507 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
512 base.RequestTeleportLandmark(remoteClient, lm);
516 GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
521 Scene.RequestTeleportLocation(
522 remoteClient, info.RegionHandle, lm.Position,
530 gatekeeper.ServerURI = lm.Gatekeeper;
531 string homeURI = Scene.GetAgentHomeURI(remoteClient.AgentId);
534 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper,
new UUID(lm.
RegionID), remoteClient.AgentId, homeURI, out message);
536 if (finalDestination != null)
538 ScenePresence sp = Scene.GetScenePresence(remoteClient.AgentId);
543 sp.ControllingClient.SendAgentAlertMessage(message,
true);
546 string reason = string.Empty;
547 if (!ValidateGenericConditions(sp, gatekeeper, finalDestination, 0, out reason))
549 sp.ControllingClient.SendTeleportFailed(reason);
554 sp, gatekeeper, finalDestination, lm.
Position, Vector3.UnitX,
560 remoteClient.SendTeleportFailed(message);
566 private void RemoveIncomingSceneObjectJobs(
string commonIdToRemove)
572 while ((job = m_incomingSceneObjectEngine.RemoveNextJob()) != null)
574 if (job.CommonId != commonIdToRemove)
575 jobsToReinsert.Add(job);
581 "[HG ENTITY TRANSFER]: Removing {0} jobs with common ID {1} and reinserting {2} other jobs",
582 jobsRemoved, commonIdToRemove, jobsToReinsert.Count);
584 if (jobsToReinsert.Count > 0)
586 foreach (
JobEngine.Job jobToReinsert in jobsToReinsert)
587 m_incomingSceneObjectEngine.QueueJob(jobToReinsert);
595 return base.HandleIncomingSceneObject(so, newPosition);
599 return base.HandleIncomingSceneObject(so, newPosition);
602 AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.OwnerID);
603 if (aCircuit != null)
608 base.HandleIncomingSceneObject(so, newPosition);
614 m_incomingSceneObjectEngine.QueueJob(
615 string.Format(
"HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name),
618 string url = aCircuit.ServiceURLs[
"AssetServerURI"].ToString();
623 IDictionary<UUID, sbyte> ids =
new Dictionary<UUID, sbyte>();
626 uuidGatherer.AddForInspection(so);
628 while (!uuidGatherer.Complete)
630 int tickStart = Util.EnvironmentTickCount();
632 UUID? nextUuid = uuidGatherer.NextUuidToInspect;
633 uuidGatherer.GatherNext();
639 int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
641 if (ticksElapsed > 30000)
644 "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as gather of {1} from {2} took {3} ms to respond (> {4} ms)",
645 so.OwnerID, so.Name, url, ticksElapsed, 30000);
647 RemoveIncomingSceneObjectJobs(so.
OwnerID.ToString());
657 foreach (KeyValuePair<UUID, sbyte> kvp
in ids)
659 int tickStart = Util.EnvironmentTickCount();
661 uuidGatherer.FetchAsset(kvp.Key);
663 int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
665 if (ticksElapsed > 30000)
668 "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as fetch of {1} from {2} took {3} ms to respond (> {4} ms)",
669 so.OwnerID, kvp.Key, url, ticksElapsed, 30000);
671 RemoveIncomingSceneObjectJobs(so.
OwnerID.ToString());
677 base.HandleIncomingSceneObject(so, newPosition);
683 so.OwnerID.ToString());
693 #region IUserAgentVerificationModule
699 string url = aCircuit.ServiceURLs[
"HomeURI"].ToString();
701 return security.VerifyClient(aCircuit.SessionID, token);
706 "[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!",
707 aCircuit.firstname, aCircuit.lastname);
725 m_UAS.LogoutAgent(obj.AgentId, obj.SessionId);
732 string url = aCircuit.ServiceURLs[
"HomeURI"].ToString();
734 security.LogoutAgent(obj.AgentId, obj.SessionId);
739 m_log.DebugFormat(
"[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId);
750 if (!aCircuit.
ServiceURLs.ContainsKey(
"HomeURI") ||
751 (aCircuit.ServiceURLs.ContainsKey(
"HomeURI") && !Uri.TryCreate(aCircuit.
ServiceURLs[
"HomeURI"].ToString(), UriKind.Absolute, out uri)))
754 region.ExternalHostName = uri.Host;
755 region.HttpPort = (uint)uri.Port;
757 region.RegionName = string.Empty;
758 region.InternalEndPoint =
new System.Net.IPEndPoint(System.Net.IPAddress.Parse(
"0.0.0.0"), (
int)0);
IAssetService AssetService
bool m_RestrictAppearanceAbroad
bool VerifyClient(AgentCircuitData aCircuit, string token)
Contains the Avatar's Appearance and methods to manipulate the appearance.
IUserManagement UserManagementModule
AvatarAppearance Appearance
OpenSim.Services.Interfaces.GridRegion GridRegion
Holds individual statistic details
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
bool IsChildAgent
If true, then the agent has no avatar in the scene. The agent exists to relay data from a region that...
Dictionary< string, object > ServiceURLs
override void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
override bool NeedsClosing(GridRegion reg, bool OutViewRange)
bool IsLocalGridUser(UUID uuid)
ISceneAgent SceneAgent
The scene agent for this client. This will only be set if the client has an agent in a scene (i...
override void OnNewClient(IClientAPI client)
override bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition)
bool IsAttachmentCheckFull()
Check both the attachment property and the relevant properties of the underlying root part...
override void TriggerTeleportHome(UUID id, IClientAPI client)
Circuit data for an agent. Connection information shared between regions that accept UDP connections ...
Inventory Item - contains all the properties associated with an individual inventory piece...
List< AvatarAttachment > m_Attachs
override GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message)
virtual AvatarWearable[] Wearables
StatVerbosity
Verbosity of stat.
List< AvatarAttachment > GetAttachments()
Get a list of the attachments.
string ServerURI
A well-formed URI for the host region server (namely "http://" + ExternalHostName) ...
Interactive OpenSim region server
override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
Tries to teleport agent to landmark.
override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout)
override void AgentHasMovedAway(ScenePresence sp, bool logout)
Clean up operations once an agent has moved away through cross or teleport.
override void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
override void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
override void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
List< AvatarAppearance > m_ExportedAppearances
override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
uint teleportFlags
How this agent got here
override bool TeleportHome(UUID id, IClientAPI client)
Teleports the agent for the given client to their home destination.
virtual RegionInfo RegionInfo
This maintains the relationship between a UUID and a user name.
MeasuresOfInterest
Measures of interest for this stat.