From c745df007d1730e59fbdb4ebf8440654d1675ade Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 25 Feb 2010 17:42:51 -0800 Subject: [PATCH] Added server-side Friends in connector. Untested. --- .../Handlers/Friends/FriendServerConnector.cs | 61 +++++ .../Friends/FriendsServerPostHandler.cs | 238 ++++++++++++++++++ .../Services/Interfaces/IFriendsService.cs | 28 +++ bin/OpenSim.Server.HG.ini.example | 1 + bin/OpenSim.Server.ini.example | 1 + bin/config-include/Grid.ini | 3 + bin/config-include/GridHypergrid.ini | 3 + 7 files changed, 335 insertions(+) create mode 100644 OpenSim/Server/Handlers/Friends/FriendServerConnector.cs create mode 100644 OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs diff --git a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs new file mode 100644 index 0000000000..074f8690a5 --- /dev/null +++ b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs @@ -0,0 +1,61 @@ +/* + * 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 Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; + +namespace OpenSim.Server.Handlers.Friends +{ + public class FriendsServiceConnector : ServiceConnector + { + private IFriendsService m_FriendsService; + private string m_ConfigName = "FriendsService"; + + public FriendsServiceConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); + + string gridService = serverConfig.GetString("LocalServiceModule", + String.Empty); + + if (gridService == String.Empty) + throw new Exception("No LocalServiceModule in config file"); + + Object[] args = new Object[] { config }; + m_FriendsService = ServerUtils.LoadPlugin(gridService, args); + + server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService)); + } + } +} diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs new file mode 100644 index 0000000000..fa655d2d71 --- /dev/null +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -0,0 +1,238 @@ +/* + * 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 Nini.Config; +using log4net; +using System; +using System.Reflection; +using System.IO; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml; +using System.Xml.Serialization; +using System.Collections.Generic; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; +using OpenSim.Framework; +using OpenSim.Framework.Servers.HttpServer; +using OpenMetaverse; + +namespace OpenSim.Server.Handlers.Friends +{ + public class FriendsServerPostHandler : BaseStreamHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IFriendsService m_FriendsService; + + public FriendsServerPostHandler(IFriendsService service) : + base("POST", "/friends") + { + m_FriendsService = service; + } + + 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(); + + switch (method) + { + case "getfriends": + return GetFriends(request); + + case "storefriend": + return StoreFriend(request); + + case "deletefriend": + return DeleteFriend(request); + + } + m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); + } + catch (Exception e) + { + m_log.DebugFormat("[FRIENDS HANDLER]: Exception {0}", e); + } + + return FailureResult(); + + } + + #region Method-specific handlers + + byte[] GetFriends(Dictionary request) + { + UUID principalID = UUID.Zero; + if (request.ContainsKey("PRINCIPALID")) + UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID); + else + m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends"); + + FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); + //m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count); + + Dictionary result = new Dictionary(); + if ((finfos == null) || ((finfos != null) && (finfos.Length == 0))) + result["result"] = "null"; + else + { + int i = 0; + foreach (FriendInfo finfo in finfos) + { + Dictionary rinfoDict = finfo.ToKeyValuePairs(); + result["friend" + i] = rinfoDict; + i++; + } + } + + string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[FRIENDS HANDLER]: resp string: {0}", xmlString); + UTF8Encoding encoding = new UTF8Encoding(); + return encoding.GetBytes(xmlString); + + } + + byte[] StoreFriend(Dictionary request) + { + FriendInfo friend = new FriendInfo(request); + + bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.TheirFlags); + + if (success) + return SuccessResult(); + else + return FailureResult(); + } + + byte[] DeleteFriend(Dictionary request) + { + UUID principalID = UUID.Zero; + if (request.ContainsKey("PRINCIPALID")) + UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID); + else + m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to delete friend"); + string friend = string.Empty; + if (request.ContainsKey("FRIEND")) + friend = request["FRIEND"].ToString(); + + bool success = m_FriendsService.Delete(principalID, friend); + if (success) + return SuccessResult(); + else + return FailureResult(); + } + + #endregion + + #region Misc + + private byte[] SuccessResult() + { + 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("Success")); + + rootElement.AppendChild(result); + + return DocToBytes(doc); + } + + private byte[] FailureResult() + { + return FailureResult(String.Empty); + } + + private byte[] FailureResult(string msg) + { + 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("Failure")); + + rootElement.AppendChild(result); + + XmlElement message = doc.CreateElement("", "Message", ""); + message.AppendChild(doc.CreateTextNode(msg)); + + rootElement.AppendChild(message); + + 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(); + } + + #endregion + } +} diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs index 811203c6d3..fc20224bc3 100644 --- a/OpenSim/Services/Interfaces/IFriendsService.cs +++ b/OpenSim/Services/Interfaces/IFriendsService.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using OpenMetaverse; using OpenSim.Framework; using System.Collections.Generic; @@ -37,6 +38,33 @@ namespace OpenSim.Services.Interfaces public string Friend; public int MyFlags; public int TheirFlags; + + public FriendInfo(Dictionary kvp) + { + PrincipalID = UUID.Zero; + if (kvp.ContainsKey("PrincipalID") && kvp["PrincipalID"] != null) + UUID.TryParse(kvp["PrincipalID"].ToString(), out PrincipalID); + Friend = string.Empty; + if (kvp.ContainsKey("Friend") && kvp["Friend"] != null) + Friend = kvp["Friend"].ToString(); + MyFlags = 0; + if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null) + Int32.TryParse(kvp["MyFlags"].ToString(), out MyFlags); + TheirFlags = 0; + if (kvp.ContainsKey("TheirFlags") && kvp["TheirFlags"] != null) + Int32.TryParse(kvp["TheirFlags"].ToString(), out TheirFlags); + } + + public Dictionary ToKeyValuePairs() + { + Dictionary result = new Dictionary(); + result["PricipalID"] = PrincipalID.ToString(); + result["Friend"] = Friend; + result["MyFlags"] = MyFlags.ToString(); + result["TheirFlags"] = TheirFlags.ToString(); + + return result; + } } public interface IFriendsService diff --git a/bin/OpenSim.Server.HG.ini.example b/bin/OpenSim.Server.HG.ini.example index fea0ea2948..732d123847 100644 --- a/bin/OpenSim.Server.HG.ini.example +++ b/bin/OpenSim.Server.HG.ini.example @@ -119,6 +119,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 SimulationService ="OpenSim.Services.Connectors.dll:SimulationServiceConnector" LibraryService = "OpenSim.Services.InventoryService.dll:LibraryService" UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" + FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" WelcomeMessage = "Welcome, Avatar!" ; Defaults for the users, if none is specified in the useraccounts table entry (ServiceURLs) diff --git a/bin/OpenSim.Server.ini.example b/bin/OpenSim.Server.ini.example index 54101b0dbb..e6508b19a5 100644 --- a/bin/OpenSim.Server.ini.example +++ b/bin/OpenSim.Server.ini.example @@ -120,5 +120,6 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 GridService = "OpenSim.Services.GridService.dll:GridService" SimulationService ="OpenSim.Services.Connectors.dll:SimulationServiceConnector" LibraryService = "OpenSim.Services.InventoryService.dll:LibraryService" + FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" WelcomeMessage = "Welcome, Avatar!" diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini index 56c76c6bce..a656e7b5ed 100644 --- a/bin/config-include/Grid.ini +++ b/bin/config-include/Grid.ini @@ -34,3 +34,6 @@ LocalServiceModule = "OpenSim.Services.InventoryService.dll:LibraryService" LibraryName = "OpenSim Library" DefaultLibrary = "./inventory/Libraries.xml" + +[Friends] + Connector = "OpenSim.Services.Connectors.dll:FriendsServiceConnector" diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index 73912788c6..36cefdcf87 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -40,3 +40,6 @@ StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" AllowHypergridMapSearch = true + +[Friends] + Connector = "OpenSim.Services.Connectors.dll:FriendsServiceConnector"