diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index ed0211956c..e0c404bba1 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -187,7 +187,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // Is the user a local user? UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID); string url = string.Empty; - PresenceInfo upd; if (account == null) // foreign user url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI"); diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs new file mode 100644 index 0000000000..c82cfd2d75 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -0,0 +1,244 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using Mono.Addins; + +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Connectors.Hypergrid; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.CoreModules.Avatar.Lure +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class HGLureModule : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private readonly List m_scenes = new List(); + + private IMessageTransferModule m_TransferModule = null; + private bool m_Enabled = false; + + private string m_ThisGridURL; + + private ExpiringCache m_PendingLures = new ExpiringCache(); + + public void Initialise(IConfigSource config) + { + if (config.Configs["Messaging"] != null) + { + if (config.Configs["Messaging"].GetString("LureModule", string.Empty) == "HGLureModule") + { + m_Enabled = true; + + m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty); + m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); + } + } + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock (m_scenes) + { + m_scenes.Add(scene); + scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage; + scene.EventManager.OnNewClient += OnNewClient; + } + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + if (m_TransferModule == null) + { + m_TransferModule = + scene.RequestModuleInterface(); + + if (m_TransferModule == null) + { + m_log.Error("[LURE MODULE]: No message transfer module, lures will not work!"); + + m_Enabled = false; + m_scenes.Clear(); + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage; + } + } + + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock (m_scenes) + { + m_scenes.Remove(scene); + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage; + } + } + + void OnNewClient(IClientAPI client) + { + client.OnInstantMessage += OnInstantMessage; + client.OnStartLure += OnStartLure; + client.OnTeleportLureRequest += OnTeleportLureRequest; + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "HGLureModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + void OnInstantMessage(IClientAPI client, GridInstantMessage im) + { + } + + void OnIncomingInstantMessage(GridInstantMessage im) + { + if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) + { + UUID sessionID = new UUID(im.imSessionID); + m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message); + m_PendingLures.Add(sessionID, im, 7200); // 2 hours + + // Forward. We do this, because the IM module explicitly rejects + // IMs of this type + if (m_TransferModule != null) + m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); + + } + } + + public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client) + { + if (!(client.Scene is Scene)) + return; + + Scene scene = (Scene)(client.Scene); + ScenePresence presence = scene.GetScenePresence(client.AgentId); + + message += "@" + m_ThisGridURL; + + m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message); + + GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, + client.FirstName+" "+client.LastName, targetid, + (byte)InstantMessageDialog.RequestTeleport, false, + message, UUID.Random(), false, presence.AbsolutePosition, + new Byte[0]); + m.RegionID = client.Scene.RegionInfo.RegionID.Guid; + + if (m_TransferModule != null) + { + m_TransferModule.SendInstantMessage(m, + delegate(bool success) { }); + } + } + + public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client) + { + if (!(client.Scene is Scene)) + return; + + Scene scene = (Scene)(client.Scene); + + GridInstantMessage im = null; + if (m_PendingLures.TryGetValue(lureID, out im)) + { + m_PendingLures.Remove(lureID); + Lure(client, teleportFlags, im); + } + else + m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID); + + } + + private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im) + { + Scene scene = (Scene)(client.Scene); + GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID)); + if (region != null) + scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags); + else // we don't have that region here. Check if it's HG + { + string[] parts = im.message.Split(new char[] { '@' }); + if (parts.Length > 1) + { + string url = parts[parts.Length - 1]; // the last part + if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'})) + { + m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position); + GatekeeperServiceConnector gConn = new GatekeeperServiceConnector(); + GridRegion gatekeeper = new GridRegion(); + gatekeeper.ServerURI = url; + GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID)); + if (finalDestination != null) + { + ScenePresence sp = scene.GetScenePresence(client.AgentId); + IEntityTransferModule transferMod = scene.RequestModuleInterface(); + IEventQueue eq = sp.Scene.RequestModuleInterface(); + if (transferMod != null && sp != null && eq != null) + transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq); + } + } + } + } + } + } +} diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index d1d7df2d9e..d295384279 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs @@ -45,16 +45,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure private readonly List m_scenes = new List(); private IMessageTransferModule m_TransferModule = null; - private bool m_Enabled = true; + private bool m_Enabled = false; public void Initialise(IConfigSource config) { if (config.Configs["Messaging"] != null) { if (config.Configs["Messaging"].GetString( - "LureModule", "LureModule") != + "LureModule", "LureModule") == "LureModule") - m_Enabled = false; + { + m_Enabled = true; + m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name); + } } } @@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure public void RegionLoaded(Scene scene) { + if (!m_Enabled) + return; + if (m_TransferModule == null) { m_TransferModule = @@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure public void RemoveRegion(Scene scene) { + if (!m_Enabled) + return; + lock (m_scenes) { m_scenes.Remove(scene); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 6e4ec8175a..ec084fbaf2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -248,7 +248,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } - protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) + public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) { if (reg == null || finalDestination == null) { diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 8b96de46fd..07e97d5630 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -40,6 +40,9 @@ namespace OpenSim.Region.Framework.Interfaces void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags); + void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, + Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq); + void TeleportHome(UUID id, IClientAPI client); bool Cross(ScenePresence agent, bool isFlying); diff --git a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs index 138313aedd..74b742280f 100644 --- a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs @@ -125,7 +125,6 @@ namespace OpenSim.Server.Handlers.Hypergrid UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); UUID.TryParse((string)requestData["im_session_id"], out imSessionID); UUID.TryParse((string)requestData["region_id"], out RegionID); - try { timestamp = (uint)Convert.ToInt32((string)requestData["timestamp"]); @@ -185,45 +184,9 @@ namespace OpenSim.Server.Handlers.Hypergrid { } - try - { - pos_x = (uint)Convert.ToInt32((string)requestData["position_x"]); - } - catch (ArgumentException) - { - } - catch (FormatException) - { - } - catch (OverflowException) - { - } - try - { - pos_y = (uint)Convert.ToInt32((string)requestData["position_y"]); - } - catch (ArgumentException) - { - } - catch (FormatException) - { - } - catch (OverflowException) - { - } - try - { - pos_z = (uint)Convert.ToInt32((string)requestData["position_z"]); - } - catch (ArgumentException) - { - } - catch (FormatException) - { - } - catch (OverflowException) - { - } + float.TryParse((string)requestData["position_x"], out pos_x); + float.TryParse((string)requestData["position_y"], out pos_y); + float.TryParse((string)requestData["position_z"], out pos_z); Position = new Vector3(pos_x, pos_y, pos_z); @@ -243,7 +206,7 @@ namespace OpenSim.Server.Handlers.Hypergrid gim.fromAgentName = fromAgentName; gim.fromGroup = fromGroup; gim.imSessionID = imSessionID.Guid; - gim.RegionID = UUID.Zero.Guid; // RegionID.Guid; + gim.RegionID = RegionID.Guid; gim.timestamp = timestamp; gim.toAgentID = toAgentID.Guid; gim.message = message; diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs index e94e3358e9..161be02e26 100644 --- a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs +++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs @@ -123,6 +123,7 @@ namespace OpenSim.Services.Connectors.InstantMessage gim["position_z"] = msg.Position.Z.ToString(); gim["region_id"] = msg.RegionID.ToString(); gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None); + return gim; } diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 486ba76a58..29f0de3af8 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -46,6 +46,12 @@ ;; Robust server in port 8002, but not always) Gatekeeper="http://mygridserver.com:8002" +[Messaging] + ;; change this to the address of your Gatekeeper service + ;; (usually bundled with the rest of the services in one + ;; Robust server in port 8002, but not always) + Gatekeeper = "http://mygridserver.com:8002" + [AvatarService] ; ; change this to your grid-wide grid server diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index 72b74127d4..510a315647 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -69,7 +69,8 @@ Connector = "OpenSim.Services.Connectors.dll:FriendsServicesConnector" [Messaging] - MessageTransferModule = HGMessageTransferModule + MessageTransferModule = HGMessageTransferModule + LureModule = HGLureModule [HGInstantMessageService] LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index df93cee589..931a77bb20 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -70,6 +70,11 @@ ;; change this to the address of your simulator Gatekeeper="http://127.0.0.1:9000" +[Messaging] + ; === HG ONLY === + ;; change this to the address of your simulator + Gatekeeper = "http://127.0.0.1:9000" + [LibraryModule] ; Set this if you want to change the name of the OpenSim Library ;LibraryName = "My World's Library" diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 7d1ff60c2d..44ca3acaca 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -36,7 +36,8 @@ Module = "BasicProfileModule" [Messaging] - MessageTransferModule = HGMessageTransferModule + MessageTransferModule = HGMessageTransferModule + LureModule = HGLureModule [SimulationDataStore] LocalServiceModule = "OpenSim.Services.Connectors.dll:SimulationDataService"