diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs new file mode 100644 index 0000000..28593fc --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | |||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Interfaces; | ||
34 | using OpenSim.Region.Framework.Scenes; | ||
35 | using OpenSim.Services.Connectors.Hypergrid; | ||
36 | using OpenSim.Services.Interfaces; | ||
37 | using OpenSim.Server.Base; | ||
38 | |||
39 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
40 | |||
41 | using OpenMetaverse; | ||
42 | using log4net; | ||
43 | using Nini.Config; | ||
44 | |||
45 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | ||
46 | { | ||
47 | public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule | ||
48 | { | ||
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | private bool m_Initialized = false; | ||
52 | |||
53 | private GatekeeperServiceConnector m_GatekeeperConnector; | ||
54 | |||
55 | #region ISharedRegionModule | ||
56 | |||
57 | public override string Name | ||
58 | { | ||
59 | get { return "HGEntityTransferModule"; } | ||
60 | } | ||
61 | |||
62 | public override void Initialise(IConfigSource source) | ||
63 | { | ||
64 | IConfig moduleConfig = source.Configs["Modules"]; | ||
65 | if (moduleConfig != null) | ||
66 | { | ||
67 | string name = moduleConfig.GetString("EntityTransferModule", ""); | ||
68 | if (name == Name) | ||
69 | { | ||
70 | m_agentsInTransit = new List<UUID>(); | ||
71 | |||
72 | m_Enabled = true; | ||
73 | m_log.InfoFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
78 | public override void AddRegion(Scene scene) | ||
79 | { | ||
80 | base.AddRegion(scene); | ||
81 | if (m_Enabled) | ||
82 | { | ||
83 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | protected override void OnNewClient(IClientAPI client) | ||
88 | { | ||
89 | client.OnTeleportHomeRequest += TeleportHome; | ||
90 | client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); | ||
91 | } | ||
92 | |||
93 | |||
94 | public override void RegionLoaded(Scene scene) | ||
95 | { | ||
96 | base.RegionLoaded(scene); | ||
97 | if (m_Enabled) | ||
98 | if (!m_Initialized) | ||
99 | { | ||
100 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); | ||
101 | m_Initialized = true; | ||
102 | } | ||
103 | |||
104 | } | ||
105 | public override void RemoveRegion(Scene scene) | ||
106 | { | ||
107 | base.AddRegion(scene); | ||
108 | if (m_Enabled) | ||
109 | { | ||
110 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | |||
115 | #endregion | ||
116 | |||
117 | #region HG overrides of IEntiryTransferModule | ||
118 | |||
119 | protected override GridRegion GetFinalDestination(GridRegion region) | ||
120 | { | ||
121 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); | ||
122 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); | ||
123 | if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | ||
124 | { | ||
125 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); | ||
126 | return m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); | ||
127 | } | ||
128 | return region; | ||
129 | } | ||
130 | |||
131 | protected override bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) | ||
132 | { | ||
133 | if (base.NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | ||
134 | return true; | ||
135 | |||
136 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); | ||
137 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | ||
138 | return true; | ||
139 | |||
140 | return false; | ||
141 | } | ||
142 | |||
143 | protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) | ||
144 | { | ||
145 | reason = string.Empty; | ||
146 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); | ||
147 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | ||
148 | { | ||
149 | // this user is going to another grid | ||
150 | if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) | ||
151 | { | ||
152 | string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); | ||
153 | IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); | ||
154 | bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); | ||
155 | if (success) | ||
156 | // Log them out of this grid | ||
157 | m_aScene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); | ||
158 | |||
159 | return success; | ||
160 | } | ||
161 | else | ||
162 | { | ||
163 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent does not have a HomeURI address"); | ||
164 | return false; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); | ||
169 | } | ||
170 | |||
171 | public override void TeleportHome(UUID id, IClientAPI client) | ||
172 | { | ||
173 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); | ||
174 | |||
175 | // Let's find out if this is a foreign user or a local user | ||
176 | UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, id); | ||
177 | if (account != null) | ||
178 | { | ||
179 | // local grid user | ||
180 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local"); | ||
181 | base.TeleportHome(id, client); | ||
182 | return; | ||
183 | } | ||
184 | |||
185 | // Foreign user wants to go home | ||
186 | // | ||
187 | AgentCircuitData aCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | ||
188 | if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("HomeURI"))) | ||
189 | { | ||
190 | client.SendTeleportFailed("Your information has been lost"); | ||
191 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); | ||
196 | Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; | ||
197 | GridRegion finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt); | ||
198 | if (finalDestination == null) | ||
199 | { | ||
200 | client.SendTeleportFailed("Your home region could not be found"); | ||
201 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId); | ||
206 | if (sp == null) | ||
207 | { | ||
208 | client.SendTeleportFailed("Internal error"); | ||
209 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be"); | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | ||
214 | GridRegion homeGatekeeper = MakeRegion(aCircuit); | ||
215 | |||
216 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}:{5}", | ||
217 | aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ExternalHostName, homeGatekeeper.HttpPort, homeGatekeeper.RegionName); | ||
218 | |||
219 | DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); | ||
220 | } | ||
221 | #endregion | ||
222 | |||
223 | #region IUserAgentVerificationModule | ||
224 | |||
225 | public bool VerifyClient(AgentCircuitData aCircuit, string token) | ||
226 | { | ||
227 | if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) | ||
228 | { | ||
229 | string url = aCircuit.ServiceURLs["HomeURI"].ToString(); | ||
230 | IUserAgentService security = new UserAgentServiceConnector(url); | ||
231 | return security.VerifyClient(aCircuit.SessionID, token); | ||
232 | } | ||
233 | |||
234 | return false; | ||
235 | } | ||
236 | |||
237 | void OnConnectionClosed(IClientAPI obj) | ||
238 | { | ||
239 | if (obj.IsLoggingOut) | ||
240 | { | ||
241 | AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); | ||
242 | |||
243 | if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) | ||
244 | { | ||
245 | string url = aCircuit.ServiceURLs["HomeURI"].ToString(); | ||
246 | IUserAgentService security = new UserAgentServiceConnector(url); | ||
247 | security.LogoutAgent(obj.AgentId, obj.SessionId); | ||
248 | //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Sent logout call to UserAgentService @ {0}", url); | ||
249 | } | ||
250 | else | ||
251 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | #endregion | ||
256 | |||
257 | private GridRegion MakeRegion(AgentCircuitData aCircuit) | ||
258 | { | ||
259 | GridRegion region = new GridRegion(); | ||
260 | |||
261 | Uri uri = null; | ||
262 | if (!aCircuit.ServiceURLs.ContainsKey("HomeURI") || | ||
263 | (aCircuit.ServiceURLs.ContainsKey("HomeURI") && !Uri.TryCreate(aCircuit.ServiceURLs["HomeURI"].ToString(), UriKind.Absolute, out uri))) | ||
264 | return null; | ||
265 | |||
266 | region.ExternalHostName = uri.Host; | ||
267 | region.HttpPort = (uint)uri.Port; | ||
268 | region.RegionName = string.Empty; | ||
269 | region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); | ||
270 | return region; | ||
271 | } | ||
272 | } | ||
273 | } | ||