diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 70942139f8..1d7889d6c8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -26,10 +26,8 @@ */ using System; -using System.IO; using System.Collections; using System.Collections.Generic; -using System.Xml; using System.Reflection; using log4net; using Nini.Config; @@ -40,16 +38,16 @@ using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.Friends; using OpenSim.Server.Base; using OpenSim.Framework.Servers.HttpServer; -using log4net; using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.Avatar.Friends { - public class FriendsModule : BaseStreamHandler, ISharedRegionModule, IFriendsModule + public class FriendsModule : ISharedRegionModule, IFriendsModule { protected class UserFriendData { @@ -72,12 +70,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected int m_Port = 0; - protected List m_Scenes = new List(); protected IPresenceService m_PresenceService = null; protected IFriendsService m_FriendsService = null; + protected FriendsSimConnector m_FriendsSimConnector; + protected Dictionary m_Friends = new Dictionary(); @@ -117,22 +115,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - public FriendsModule() - : base("POST", "/friends") - { - } - public void Initialise(IConfigSource config) { IConfig friendsConfig = config.Configs["Friends"]; if (friendsConfig != null) { - m_Port = friendsConfig.GetInt("Port", m_Port); + int mPort = friendsConfig.GetInt("Port", 0); string connector = friendsConfig.GetString("Connector", String.Empty); Object[] args = new Object[] { config }; m_FriendsService = ServerUtils.LoadPlugin(connector, args); + m_FriendsSimConnector = new FriendsSimConnector(); + + // Instantiate the request handler + IHttpServer server = MainServer.GetHttpServer((uint)mPort); + server.AddStreamHandler(new FriendsRequestHandler(this)); + } if (m_FriendsService == null) @@ -141,10 +140,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends throw new Exception("Connector load error"); } - IHttpServer server = MainServer.GetHttpServer((uint)m_Port); - - server.AddStreamHandler(this); - } public void PostInitialise() @@ -175,41 +170,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends m_Scenes.Remove(scene); } - public override byte[] Handle(string path, Stream requestData, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); - body = body.Trim(); - - m_log.DebugFormat("[XXX]: query String: {0}", body); - - try - { - Dictionary request = - ServerUtils.ParseQueryString(body); - - if (!request.ContainsKey("METHOD")) - return FailureResult(); - - string method = request["METHOD"].ToString(); - request.Remove("METHOD"); - - switch (method) - { - case "TEST": - break; - } - } - catch (Exception e) - { - m_log.Debug("[FRIENDS]: Exception {0}" + e.ToString()); - } - - return FailureResult(); - } - public string Name { get { return "FriendsModule"; } @@ -239,49 +199,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return 0; } - private byte[] FailureResult() - { - return BoolResult(false); - } - - private byte[] SuccessResult() - { - return BoolResult(true); - } - - private byte[] BoolResult(bool value) - { - XmlDocument doc = new XmlDocument(); - - XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, - "", ""); - - doc.AppendChild(xmlnode); - - XmlElement rootElement = doc.CreateElement("", "ServerResponse", - ""); - - doc.AppendChild(rootElement); - - XmlElement result = doc.CreateElement("", "RESULT", ""); - result.AppendChild(doc.CreateTextNode(value.ToString())); - - rootElement.AppendChild(result); - - return DocToBytes(doc); - } - - private byte[] DocToBytes(XmlDocument doc) - { - MemoryStream ms = new MemoryStream(); - XmlTextWriter xw = new XmlTextWriter(ms, null); - xw.Formatting = Formatting.Indented; - doc.WriteTo(xw); - xw.Flush(); - - return ms.ToArray(); - } - private void OnNewClient(IClientAPI client) { client.OnInstantMessage += OnInstantMessage; @@ -460,8 +377,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends UUID principalID = new UUID(im.fromAgentID); UUID friendID = new UUID(im.toAgentID); - // this user wants to be friends with the other user + // This user wants to be friends with the other user. + // Let's add both relations to the DB, but one of them is inactive (-1) FriendsService.StoreFriend(principalID, friendID.ToString(), 1); + FriendsService.StoreFriend(friendID, principalID.ToString(), -1); // Now let's ask the other user to be friends with this user ForwardFriendshipOffer(principalID, friendID, im); @@ -476,7 +395,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // the prospective friend in this sim as root agent friendClient.SendInstantMessage(im); // we're done - return; + return ; } // The prospective friend is not here [as root]. Let's forward. @@ -485,35 +404,123 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (friendSession != null) { GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - // ... - // m_FriendsSimConnector.FriendshipOffered(region, agentID, friemdID, im.message); + m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message); } + + // If the prospective friend is not online, he'll get the message upon login. } private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List callingCardFolders) { FriendsService.StoreFriend(agentID, friendID.ToString(), 1); - // TODO: Notify the new friend + // + // Notify the friend + // + + IClientAPI friendClient = LocateClientObject(friendID); + if (friendClient != null) + { + // the prospective friend in this sim as root agent + GridInstantMessage im = new GridInstantMessage(client.Scene, client.AgentId, client.Name, friendID, + (byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, client.AgentId.ToString(), false, Vector3.Zero); + friendClient.SendInstantMessage(im); + // we're done + return; + } + + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); + PresenceInfo friendSession = PresenceInfo.GetOnlinePresence(friendSessions); + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + m_FriendsSimConnector.FriendshipApproved(region, agentID, friendID); + } } private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List callingCardFolders) { - // TODO: Notify the friend-wanna-be + FriendsService.Delete(agentID, friendID.ToString()); + FriendsService.Delete(friendID, agentID.ToString()); + + // + // Notify the friend + // + + IClientAPI friendClient = LocateClientObject(friendID); + if (friendClient != null) + { + // the prospective friend in this sim as root agent + + GridInstantMessage im = new GridInstantMessage(client.Scene, client.AgentId, client.Name, friendID, + (byte)OpenMetaverse.InstantMessageDialog.FriendshipDeclined, client.AgentId.ToString(), false, Vector3.Zero); + friendClient.SendInstantMessage(im); + // we're done + return; + } + + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); + PresenceInfo friendSession = PresenceInfo.GetOnlinePresence(friendSessions); + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + m_FriendsSimConnector.FriendshipDenied(region, agentID, friendID); + } } private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) { FriendsService.Delete(agentID, exfriendID.ToString()); + FriendsService.Delete(exfriendID, agentID.ToString()); - // TODO: Notify the exfriend + client.SendTerminateFriend(exfriendID); + + // + // Notify the friend + // + + IClientAPI friendClient = LocateClientObject(exfriendID); + if (friendClient != null) + { + // the prospective friend in this sim as root agent + friendClient.SendTerminateFriend(exfriendID); + // we're done + return; + } + + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { exfriendID.ToString() }); + PresenceInfo friendSession = PresenceInfo.GetOnlinePresence(friendSessions); + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID); + } } private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) { FriendsService.StoreFriend(requester, target.ToString(), rights); - // TODO: Notify the friend + // + // Notify the friend + // + + IClientAPI friendClient = LocateClientObject(target); + if (friendClient != null) + { + // the prospective friend in this sim as root agent + //friendClient.???; + // we're done + return; + } + + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); + PresenceInfo friendSession = PresenceInfo.GetOnlinePresence(friendSessions); + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + m_FriendsSimConnector.GrantRights(region, requester, target); + } } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs new file mode 100644 index 0000000000..cde54ed3fd --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs @@ -0,0 +1,134 @@ +/* + * 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.IO; +using System.Reflection; +using System.Xml; + +using OpenSim.Framework; +using OpenSim.Server.Base; +using OpenSim.Framework.Servers.HttpServer; + +using OpenMetaverse; +using log4net; + +namespace OpenSim.Region.CoreModules.Avatar.Friends +{ + public class FriendsRequestHandler : BaseStreamHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private FriendsModule m_FriendsModule; + + public FriendsRequestHandler(FriendsModule fmodule) + : base("POST", "/friends") + { + m_FriendsModule = fmodule; + } + + public override byte[] Handle(string path, Stream requestData, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + StreamReader sr = new StreamReader(requestData); + string body = sr.ReadToEnd(); + sr.Close(); + body = body.Trim(); + + m_log.DebugFormat("[XXX]: query String: {0}", body); + + try + { + Dictionary request = + ServerUtils.ParseQueryString(body); + + if (!request.ContainsKey("METHOD")) + return FailureResult(); + + string method = request["METHOD"].ToString(); + request.Remove("METHOD"); + + switch (method) + { + case "TEST": + break; + } + } + catch (Exception e) + { + m_log.Debug("[FRIENDS]: Exception {0}" + e.ToString()); + } + + return FailureResult(); + } + + private byte[] FailureResult() + { + return BoolResult(false); + } + + private byte[] SuccessResult() + { + return BoolResult(true); + } + + private byte[] BoolResult(bool value) + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + XmlElement result = doc.CreateElement("", "RESULT", ""); + result.AppendChild(doc.CreateTextNode(value.ToString())); + + rootElement.AppendChild(result); + + return DocToBytes(doc); + } + + private byte[] DocToBytes(XmlDocument doc) + { + MemoryStream ms = new MemoryStream(); + XmlTextWriter xw = new XmlTextWriter(ms, null); + xw.Formatting = Formatting.Indented; + doc.WriteTo(xw); + xw.Flush(); + + return ms.ToArray(); + } + + } +} diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs new file mode 100644 index 0000000000..94746ef0f0 --- /dev/null +++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs @@ -0,0 +1,66 @@ +/* + * 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 OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenMetaverse; + +namespace OpenSim.Services.Connectors.Friends +{ + public class FriendsSimConnector + { + + public bool FriendshipOffered(GridRegion region, UUID userID, UUID friendID, string message) + { + return true; + } + + public bool FriendshipApproved(GridRegion region, UUID userID, UUID friendID) + { + return true; + } + + public bool FriendshipDenied(GridRegion region, UUID userID, UUID friendID) + { + return true; + } + + public bool FriendshipTerminated(GridRegion region, UUID userID, UUID friendID) + { + return true; + } + + public bool GrantRights(GridRegion region, UUID requester, UUID target) + { + return true; + } + } +}