aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Server/Handlers
diff options
context:
space:
mode:
authorMelanie2011-06-09 02:05:04 +0100
committerMelanie2011-06-09 02:05:04 +0100
commit326c46ba70cea70ddfe4aef9a6b73edff63e126a (patch)
tree5e76347b0d77f58717d8e5e4f3b8787ff01a18d7 /OpenSim/Server/Handlers
parentMake the last otem in a list created with llCSV2List findable (diff)
parentConsistency fix on the last commit. (diff)
downloadopensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.zip
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.gz
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.bz2
opensim-SC_OLD-326c46ba70cea70ddfe4aef9a6b73edff63e126a.tar.xz
Merge branch 'master' into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Server/Handlers')
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendServerConnector.cs6
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs65
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs71
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs320
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs243
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs219
6 files changed, 915 insertions, 9 deletions
diff --git a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
index 074f869..5784bdf 100644
--- a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
@@ -46,14 +46,14 @@ namespace OpenSim.Server.Handlers.Friends
46 if (serverConfig == null) 46 if (serverConfig == null)
47 throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); 47 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
48 48
49 string gridService = serverConfig.GetString("LocalServiceModule", 49 string theService = serverConfig.GetString("LocalServiceModule",
50 String.Empty); 50 String.Empty);
51 51
52 if (gridService == String.Empty) 52 if (theService == String.Empty)
53 throw new Exception("No LocalServiceModule in config file"); 53 throw new Exception("No LocalServiceModule in config file");
54 54
55 Object[] args = new Object[] { config }; 55 Object[] args = new Object[] { config };
56 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(gridService, args); 56 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
57 57
58 server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService)); 58 server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService));
59 } 59 }
diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
index b168bb3..fc97d8c 100644
--- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
@@ -82,12 +82,18 @@ namespace OpenSim.Server.Handlers.Friends
82 case "getfriends": 82 case "getfriends":
83 return GetFriends(request); 83 return GetFriends(request);
84 84
85 case "getfriends_string":
86 return GetFriendsString(request);
87
85 case "storefriend": 88 case "storefriend":
86 return StoreFriend(request); 89 return StoreFriend(request);
87 90
88 case "deletefriend": 91 case "deletefriend":
89 return DeleteFriend(request); 92 return DeleteFriend(request);
90 93
94 case "deletefriend_string":
95 return DeleteFriendString(request);
96
91 } 97 }
92 m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); 98 m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
93 } 99 }
@@ -111,7 +117,25 @@ namespace OpenSim.Server.Handlers.Friends
111 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends"); 117 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
112 118
113 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); 119 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
114 //m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count); 120
121 return PackageFriends(finfos);
122 }
123
124 byte[] GetFriendsString(Dictionary<string, object> request)
125 {
126 string principalID = string.Empty;
127 if (request.ContainsKey("PRINCIPALID"))
128 principalID = request["PRINCIPALID"].ToString();
129 else
130 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
131
132 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
133
134 return PackageFriends(finfos);
135 }
136
137 private byte[] PackageFriends(FriendInfo[] finfos)
138 {
115 139
116 Dictionary<string, object> result = new Dictionary<string, object>(); 140 Dictionary<string, object> result = new Dictionary<string, object>();
117 if ((finfos == null) || ((finfos != null) && (finfos.Length == 0))) 141 if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
@@ -136,9 +160,9 @@ namespace OpenSim.Server.Handlers.Friends
136 160
137 byte[] StoreFriend(Dictionary<string, object> request) 161 byte[] StoreFriend(Dictionary<string, object> request)
138 { 162 {
139 FriendInfo friend = new FriendInfo(request); 163 string principalID = string.Empty, friend = string.Empty; int flags = 0;
140 164 FromKeyValuePairs(request, out principalID, out friend, out flags);
141 bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.MyFlags); 165 bool success = m_FriendsService.StoreFriend(principalID, friend, flags);
142 166
143 if (success) 167 if (success)
144 return SuccessResult(); 168 return SuccessResult();
@@ -163,7 +187,25 @@ namespace OpenSim.Server.Handlers.Friends
163 else 187 else
164 return FailureResult(); 188 return FailureResult();
165 } 189 }
166 190
191 byte[] DeleteFriendString(Dictionary<string, object> request)
192 {
193 string principalID = string.Empty;
194 if (request.ContainsKey("PRINCIPALID"))
195 principalID = request["PRINCIPALID"].ToString();
196 else
197 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to delete friend");
198 string friend = string.Empty;
199 if (request.ContainsKey("FRIEND"))
200 friend = request["FRIEND"].ToString();
201
202 bool success = m_FriendsService.Delete(principalID, friend);
203 if (success)
204 return SuccessResult();
205 else
206 return FailureResult();
207 }
208
167 #endregion 209 #endregion
168 210
169 #region Misc 211 #region Misc
@@ -233,6 +275,19 @@ namespace OpenSim.Server.Handlers.Friends
233 return ms.ToArray(); 275 return ms.ToArray();
234 } 276 }
235 277
278 void FromKeyValuePairs(Dictionary<string, object> kvp, out string principalID, out string friend, out int flags)
279 {
280 principalID = string.Empty;
281 if (kvp.ContainsKey("PrincipalID") && kvp["PrincipalID"] != null)
282 principalID = kvp["PrincipalID"].ToString();
283 friend = string.Empty;
284 if (kvp.ContainsKey("Friend") && kvp["Friend"] != null)
285 friend = kvp["Friend"].ToString();
286 flags = 0;
287 if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null)
288 Int32.TryParse(kvp["MyFlags"].ToString(), out flags);
289 }
290
236 #endregion 291 #endregion
237 } 292 }
238} 293}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
new file mode 100644
index 0000000..82a7220
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
@@ -0,0 +1,71 @@
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
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34
35namespace OpenSim.Server.Handlers.Hypergrid
36{
37 public class HGFriendsServerConnector : ServiceConnector
38 {
39 private IFriendsService m_FriendsService;
40 private IUserAgentService m_UserAgentService;
41 private string m_ConfigName = "HGFriendsService";
42
43 public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) :
44 base(config, server, configName)
45 {
46 if (configName != string.Empty)
47 m_ConfigName = configName;
48
49 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null)
51 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
52
53 string theService = serverConfig.GetString("LocalServiceModule",
54 String.Empty);
55
56 if (theService == String.Empty)
57 throw new Exception("No LocalServiceModule in config file");
58
59 Object[] args = new Object[] { config };
60 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
61
62 theService = serverConfig.GetString("UserAgentService", string.Empty);
63 if (theService == String.Empty)
64 throw new Exception("No UserAgentService in " + m_ConfigName);
65
66 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(theService, args);
67
68 server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService));
69 }
70 }
71}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
new file mode 100644
index 0000000..5c89d0f
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
@@ -0,0 +1,320 @@
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
28using Nini.Config;
29using log4net;
30using System;
31using System.Reflection;
32using System.IO;
33using System.Net;
34using System.Text;
35using System.Text.RegularExpressions;
36using System.Xml;
37using System.Xml.Serialization;
38using System.Collections.Generic;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenMetaverse;
45
46namespace OpenSim.Server.Handlers.Hypergrid
47{
48 public class HGFriendsServerPostHandler : BaseStreamHandler
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private IFriendsService m_FriendsService;
53 private IUserAgentService m_UserAgentService;
54
55 public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) :
56 base("POST", "/hgfriends")
57 {
58 m_FriendsService = service;
59 m_UserAgentService = uservice;
60 m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On");
61 }
62
63 public override byte[] Handle(string path, Stream requestData,
64 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
65 {
66 StreamReader sr = new StreamReader(requestData);
67 string body = sr.ReadToEnd();
68 sr.Close();
69 body = body.Trim();
70
71 //m_log.DebugFormat("[XXX]: query String: {0}", body);
72
73 try
74 {
75 Dictionary<string, object> request =
76 ServerUtils.ParseQueryString(body);
77
78 if (!request.ContainsKey("METHOD"))
79 return FailureResult();
80
81 string method = request["METHOD"].ToString();
82
83 switch (method)
84 {
85 case "getfriendperms":
86 return GetFriendPerms(request);
87
88 case "newfriendship":
89 return NewFriendship(request);
90
91 case "deletefriendship":
92 return DeleteFriendship(request);
93 }
94 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
95 }
96 catch (Exception e)
97 {
98 m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e);
99 }
100
101 return FailureResult();
102
103 }
104
105 #region Method-specific handlers
106
107 byte[] GetFriendPerms(Dictionary<string, object> request)
108 {
109 if (!VerifyServiceKey(request))
110 return FailureResult();
111
112 UUID principalID = UUID.Zero;
113 if (request.ContainsKey("PRINCIPALID"))
114 UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
115 else
116 {
117 m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friend perms");
118 return FailureResult();
119 }
120
121 UUID friendID = UUID.Zero;
122 if (request.ContainsKey("FRIENDID"))
123 UUID.TryParse(request["FRIENDID"].ToString(), out friendID);
124 else
125 {
126 m_log.WarnFormat("[HGFRIENDS HANDLER]: no friendID in request to get friend perms");
127 return FailureResult();
128 }
129
130 string perms = "0";
131 FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID);
132 foreach (FriendInfo finfo in friendsInfo)
133 {
134 if (finfo.Friend.StartsWith(friendID.ToString()))
135 return SuccessResult(finfo.TheirFlags.ToString());
136 }
137
138 return FailureResult("Friend not found");
139 }
140
141 byte[] NewFriendship(Dictionary<string, object> request)
142 {
143 if (!VerifyServiceKey(request))
144 return FailureResult();
145
146 // OK, can proceed
147 FriendInfo friend = new FriendInfo(request);
148 UUID friendID;
149 string tmp = string.Empty;
150 if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
151 return FailureResult();
152
153
154 m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend);
155
156 // If the friendship already exists, return fail
157 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
158 foreach (FriendInfo finfo in finfos)
159 if (finfo.Friend.StartsWith(friendID.ToString()))
160 return FailureResult();
161
162 // the user needs to confirm when he gets home
163 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
164
165 if (success)
166 return SuccessResult();
167 else
168 return FailureResult();
169 }
170
171 byte[] DeleteFriendship(Dictionary<string, object> request)
172 {
173 FriendInfo friend = new FriendInfo(request);
174 string secret = string.Empty;
175 if (request.ContainsKey("SECRET"))
176 secret = request["SECRET"].ToString();
177
178 if (secret == string.Empty)
179 return FailureResult();
180
181 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
182 foreach (FriendInfo finfo in finfos)
183 {
184 // We check the secret here
185 if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
186 {
187 m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
188 m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
189 m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
190
191 return SuccessResult();
192 }
193 }
194
195 return FailureResult();
196 }
197
198 #endregion
199
200 #region Misc
201
202 private bool VerifyServiceKey(Dictionary<string, object> request)
203 {
204 if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
205 {
206 m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
207 return false;
208 }
209
210 string serviceKey = request["KEY"].ToString();
211 string sessionStr = request["SESSIONID"].ToString();
212 UUID sessionID;
213 UUID.TryParse(sessionStr, out sessionID);
214
215 if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
216 {
217 m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
218 return false;
219 }
220
221 m_log.DebugFormat("[HGFRIENDS HANDLER]: Verification ok");
222 return true;
223 }
224
225 private byte[] SuccessResult()
226 {
227 XmlDocument doc = new XmlDocument();
228
229 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
230 "", "");
231
232 doc.AppendChild(xmlnode);
233
234 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
235 "");
236
237 doc.AppendChild(rootElement);
238
239 XmlElement result = doc.CreateElement("", "Result", "");
240 result.AppendChild(doc.CreateTextNode("Success"));
241
242 rootElement.AppendChild(result);
243
244 return DocToBytes(doc);
245 }
246
247 private byte[] SuccessResult(string value)
248 {
249 XmlDocument doc = new XmlDocument();
250
251 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
252 "", "");
253
254 doc.AppendChild(xmlnode);
255
256 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
257 "");
258
259 doc.AppendChild(rootElement);
260
261 XmlElement result = doc.CreateElement("", "Result", "");
262 result.AppendChild(doc.CreateTextNode("Success"));
263
264 rootElement.AppendChild(result);
265
266 XmlElement message = doc.CreateElement("", "Value", "");
267 message.AppendChild(doc.CreateTextNode(value));
268
269 rootElement.AppendChild(message);
270
271 return DocToBytes(doc);
272 }
273
274
275 private byte[] FailureResult()
276 {
277 return FailureResult(String.Empty);
278 }
279
280 private byte[] FailureResult(string msg)
281 {
282 XmlDocument doc = new XmlDocument();
283
284 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
285 "", "");
286
287 doc.AppendChild(xmlnode);
288
289 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
290 "");
291
292 doc.AppendChild(rootElement);
293
294 XmlElement result = doc.CreateElement("", "Result", "");
295 result.AppendChild(doc.CreateTextNode("Failure"));
296
297 rootElement.AppendChild(result);
298
299 XmlElement message = doc.CreateElement("", "Message", "");
300 message.AppendChild(doc.CreateTextNode(msg));
301
302 rootElement.AppendChild(message);
303
304 return DocToBytes(doc);
305 }
306
307 private byte[] DocToBytes(XmlDocument doc)
308 {
309 MemoryStream ms = new MemoryStream();
310 XmlTextWriter xw = new XmlTextWriter(ms, null);
311 xw.Formatting = Formatting.Indented;
312 doc.WriteTo(xw);
313 xw.Flush();
314
315 return ms.ToArray();
316 }
317
318 #endregion
319 }
320}
diff --git a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs
new file mode 100644
index 0000000..80eb5d2
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs
@@ -0,0 +1,243 @@
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33
34using Nini.Config;
35using OpenSim.Framework;
36using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces;
38using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Server.Handlers.Base;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41
42using log4net;
43using Nwc.XmlRpc;
44using OpenMetaverse;
45
46namespace OpenSim.Server.Handlers.Hypergrid
47{
48 public class InstantMessageServerConnector : ServiceConnector
49 {
50 private static readonly ILog m_log =
51 LogManager.GetLogger(
52 MethodBase.GetCurrentMethod().DeclaringType);
53
54 private IInstantMessage m_IMService;
55
56 public InstantMessageServerConnector(IConfigSource config, IHttpServer server) :
57 this(config, server, null)
58 {
59 }
60
61 public InstantMessageServerConnector(IConfigSource config, IHttpServer server, IInstantMessageSimConnector simConnector) :
62 base(config, server, String.Empty)
63 {
64 IConfig gridConfig = config.Configs["HGInstantMessageService"];
65 if (gridConfig != null)
66 {
67 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
68
69 Object[] args = new Object[] { config, simConnector };
70 m_IMService = ServerUtils.LoadPlugin<IInstantMessage>(serviceDll, args);
71 }
72 if (m_IMService == null)
73 throw new Exception("InstantMessage server connector cannot proceed because of missing service");
74
75 server.AddXmlRPCHandler("grid_instant_message", ProcessInstantMessage, false);
76
77 }
78
79 public IInstantMessage GetService()
80 {
81 return m_IMService;
82 }
83
84 protected virtual XmlRpcResponse ProcessInstantMessage(XmlRpcRequest request, IPEndPoint remoteClient)
85 {
86 bool successful = false;
87
88 try
89 {
90 // various rational defaults
91 UUID fromAgentID = UUID.Zero;
92 UUID toAgentID = UUID.Zero;
93 UUID imSessionID = UUID.Zero;
94 uint timestamp = 0;
95 string fromAgentName = "";
96 string message = "";
97 byte dialog = (byte)0;
98 bool fromGroup = false;
99 byte offline = (byte)0;
100 uint ParentEstateID = 0;
101 Vector3 Position = Vector3.Zero;
102 UUID RegionID = UUID.Zero;
103 byte[] binaryBucket = new byte[0];
104
105 float pos_x = 0;
106 float pos_y = 0;
107 float pos_z = 0;
108 //m_log.Info("Processing IM");
109
110
111 Hashtable requestData = (Hashtable)request.Params[0];
112 // Check if it's got all the data
113 if (requestData.ContainsKey("from_agent_id")
114 && requestData.ContainsKey("to_agent_id") && requestData.ContainsKey("im_session_id")
115 && requestData.ContainsKey("timestamp") && requestData.ContainsKey("from_agent_name")
116 && requestData.ContainsKey("message") && requestData.ContainsKey("dialog")
117 && requestData.ContainsKey("from_group")
118 && requestData.ContainsKey("offline") && requestData.ContainsKey("parent_estate_id")
119 && requestData.ContainsKey("position_x") && requestData.ContainsKey("position_y")
120 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
121 && requestData.ContainsKey("binary_bucket"))
122 {
123 // Do the easy way of validating the UUIDs
124 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
125 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
126 UUID.TryParse((string)requestData["im_session_id"], out imSessionID);
127 UUID.TryParse((string)requestData["region_id"], out RegionID);
128 try
129 {
130 timestamp = (uint)Convert.ToInt32((string)requestData["timestamp"]);
131 }
132 catch (ArgumentException)
133 {
134 }
135 catch (FormatException)
136 {
137 }
138 catch (OverflowException)
139 {
140 }
141
142 fromAgentName = (string)requestData["from_agent_name"];
143 message = (string)requestData["message"];
144 if (message == null)
145 message = string.Empty;
146
147 // Bytes don't transfer well over XMLRPC, so, we Base64 Encode them.
148 string requestData1 = (string)requestData["dialog"];
149 if (string.IsNullOrEmpty(requestData1))
150 {
151 dialog = 0;
152 }
153 else
154 {
155 byte[] dialogdata = Convert.FromBase64String(requestData1);
156 dialog = dialogdata[0];
157 }
158
159 if ((string)requestData["from_group"] == "TRUE")
160 fromGroup = true;
161
162 string requestData2 = (string)requestData["offline"];
163 if (String.IsNullOrEmpty(requestData2))
164 {
165 offline = 0;
166 }
167 else
168 {
169 byte[] offlinedata = Convert.FromBase64String(requestData2);
170 offline = offlinedata[0];
171 }
172
173 try
174 {
175 ParentEstateID = (uint)Convert.ToInt32((string)requestData["parent_estate_id"]);
176 }
177 catch (ArgumentException)
178 {
179 }
180 catch (FormatException)
181 {
182 }
183 catch (OverflowException)
184 {
185 }
186
187 float.TryParse((string)requestData["position_x"], out pos_x);
188 float.TryParse((string)requestData["position_y"], out pos_y);
189 float.TryParse((string)requestData["position_z"], out pos_z);
190
191 Position = new Vector3(pos_x, pos_y, pos_z);
192
193 string requestData3 = (string)requestData["binary_bucket"];
194 if (string.IsNullOrEmpty(requestData3))
195 {
196 binaryBucket = new byte[0];
197 }
198 else
199 {
200 binaryBucket = Convert.FromBase64String(requestData3);
201 }
202
203 // Create a New GridInstantMessageObject the the data
204 GridInstantMessage gim = new GridInstantMessage();
205 gim.fromAgentID = fromAgentID.Guid;
206 gim.fromAgentName = fromAgentName;
207 gim.fromGroup = fromGroup;
208 gim.imSessionID = imSessionID.Guid;
209 gim.RegionID = RegionID.Guid;
210 gim.timestamp = timestamp;
211 gim.toAgentID = toAgentID.Guid;
212 gim.message = message;
213 gim.dialog = dialog;
214 gim.offline = offline;
215 gim.ParentEstateID = ParentEstateID;
216 gim.Position = Position;
217 gim.binaryBucket = binaryBucket;
218
219 successful = m_IMService.IncomingInstantMessage(gim);
220
221 }
222 }
223 catch (Exception e)
224 {
225 m_log.Error("[INSTANT MESSAGE]: Caught unexpected exception:", e);
226 successful = false;
227 }
228
229 //Send response back to region calling if it was successful
230 // calling region uses this to know when to look up a user's location again.
231 XmlRpcResponse resp = new XmlRpcResponse();
232 Hashtable respdata = new Hashtable();
233 if (successful)
234 respdata["success"] = "TRUE";
235 else
236 respdata["success"] = "FALSE";
237 resp.Value = respdata;
238
239 return resp;
240 }
241
242 }
243}
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
index 0e8ce80..72a4aea 100644
--- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
@@ -52,15 +52,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
52// MethodBase.GetCurrentMethod().DeclaringType); 52// MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private IUserAgentService m_HomeUsersService; 54 private IUserAgentService m_HomeUsersService;
55 private string[] m_AuthorizedCallers;
56
57 private bool m_VerifyCallers = false;
55 58
56 public UserAgentServerConnector(IConfigSource config, IHttpServer server) : 59 public UserAgentServerConnector(IConfigSource config, IHttpServer server) :
60 this(config, server, null)
61 {
62 }
63
64 public UserAgentServerConnector(IConfigSource config, IHttpServer server, IFriendsSimConnector friendsConnector) :
57 base(config, server, String.Empty) 65 base(config, server, String.Empty)
58 { 66 {
59 IConfig gridConfig = config.Configs["UserAgentService"]; 67 IConfig gridConfig = config.Configs["UserAgentService"];
60 if (gridConfig != null) 68 if (gridConfig != null)
61 { 69 {
62 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty); 70 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
63 Object[] args = new Object[] { config }; 71
72 Object[] args = new Object[] { config, friendsConnector };
64 m_HomeUsersService = ServerUtils.LoadPlugin<IUserAgentService>(serviceDll, args); 73 m_HomeUsersService = ServerUtils.LoadPlugin<IUserAgentService>(serviceDll, args);
65 } 74 }
66 if (m_HomeUsersService == null) 75 if (m_HomeUsersService == null)
@@ -69,12 +78,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
69 string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1"); 78 string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1");
70 bool proxy = gridConfig.GetBoolean("HasProxy", false); 79 bool proxy = gridConfig.GetBoolean("HasProxy", false);
71 80
81 m_VerifyCallers = gridConfig.GetBoolean("VerifyCallers", false);
82 string csv = gridConfig.GetString("AuthorizedCallers", "127.0.0.1");
83 csv = csv.Replace(" ", "");
84 m_AuthorizedCallers = csv.Split(',');
85
72 server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false); 86 server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false);
73 server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false); 87 server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false);
74 server.AddXmlRPCHandler("verify_agent", VerifyAgent, false); 88 server.AddXmlRPCHandler("verify_agent", VerifyAgent, false);
75 server.AddXmlRPCHandler("verify_client", VerifyClient, false); 89 server.AddXmlRPCHandler("verify_client", VerifyClient, false);
76 server.AddXmlRPCHandler("logout_agent", LogoutAgent, false); 90 server.AddXmlRPCHandler("logout_agent", LogoutAgent, false);
77 91
92 server.AddXmlRPCHandler("status_notification", StatusNotification, false);
93 server.AddXmlRPCHandler("get_online_friends", GetOnlineFriends, false);
94 server.AddXmlRPCHandler("get_server_urls", GetServerURLs, false);
95
96 server.AddXmlRPCHandler("locate_user", LocateUser, false);
97 server.AddXmlRPCHandler("get_uui", GetUUI, false);
98
78 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); 99 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler);
79 } 100 }
80 101
@@ -194,5 +215,201 @@ namespace OpenSim.Server.Handlers.Hypergrid
194 215
195 } 216 }
196 217
218 public XmlRpcResponse StatusNotification(XmlRpcRequest request, IPEndPoint remoteClient)
219 {
220 Hashtable hash = new Hashtable();
221 hash["result"] = "false";
222
223 Hashtable requestData = (Hashtable)request.Params[0];
224 //string host = (string)requestData["host"];
225 //string portstr = (string)requestData["port"];
226 if (requestData.ContainsKey("userID") && requestData.ContainsKey("online"))
227 {
228 string userID_str = (string)requestData["userID"];
229 UUID userID = UUID.Zero;
230 UUID.TryParse(userID_str, out userID);
231 List<string> ids = new List<string>();
232 foreach (object key in requestData.Keys)
233 {
234 if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null)
235 ids.Add(requestData[key].ToString());
236 }
237 bool online = false;
238 bool.TryParse(requestData["online"].ToString(), out online);
239
240 // let's spawn a thread for this, because it may take a long time...
241 List<UUID> friendsOnline = m_HomeUsersService.StatusNotification(ids, userID, online);
242 if (friendsOnline.Count > 0)
243 {
244 int i = 0;
245 foreach (UUID id in friendsOnline)
246 {
247 hash["friend_" + i.ToString()] = id.ToString();
248 i++;
249 }
250 }
251 else
252 hash["result"] = "No Friends Online";
253
254 }
255
256 XmlRpcResponse response = new XmlRpcResponse();
257 response.Value = hash;
258 return response;
259
260 }
261
262 public XmlRpcResponse GetOnlineFriends(XmlRpcRequest request, IPEndPoint remoteClient)
263 {
264 Hashtable hash = new Hashtable();
265
266 Hashtable requestData = (Hashtable)request.Params[0];
267 //string host = (string)requestData["host"];
268 //string portstr = (string)requestData["port"];
269 if (requestData.ContainsKey("userID"))
270 {
271 string userID_str = (string)requestData["userID"];
272 UUID userID = UUID.Zero;
273 UUID.TryParse(userID_str, out userID);
274 List<string> ids = new List<string>();
275 foreach (object key in requestData.Keys)
276 {
277 if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null)
278 ids.Add(requestData[key].ToString());
279 }
280
281 //List<UUID> online = m_HomeUsersService.GetOnlineFriends(userID, ids);
282 //if (online.Count > 0)
283 //{
284 // int i = 0;
285 // foreach (UUID id in online)
286 // {
287 // hash["friend_" + i.ToString()] = id.ToString();
288 // i++;
289 // }
290 //}
291 //else
292 // hash["result"] = "No Friends Online";
293 }
294
295 XmlRpcResponse response = new XmlRpcResponse();
296 response.Value = hash;
297 return response;
298
299 }
300
301 public XmlRpcResponse GetServerURLs(XmlRpcRequest request, IPEndPoint remoteClient)
302 {
303 Hashtable hash = new Hashtable();
304
305 Hashtable requestData = (Hashtable)request.Params[0];
306 //string host = (string)requestData["host"];
307 //string portstr = (string)requestData["port"];
308 if (requestData.ContainsKey("userID"))
309 {
310 string userID_str = (string)requestData["userID"];
311 UUID userID = UUID.Zero;
312 UUID.TryParse(userID_str, out userID);
313
314 Dictionary<string, object> serverURLs = m_HomeUsersService.GetServerURLs(userID);
315 if (serverURLs.Count > 0)
316 {
317 foreach (KeyValuePair<string, object> kvp in serverURLs)
318 hash["SRV_" + kvp.Key] = kvp.Value.ToString();
319 }
320 else
321 hash["result"] = "No Service URLs";
322 }
323
324 XmlRpcResponse response = new XmlRpcResponse();
325 response.Value = hash;
326 return response;
327
328 }
329
330 /// <summary>
331 /// Locates the user.
332 /// This is a sensitive operation, only authorized IP addresses can perform it.
333 /// </summary>
334 /// <param name="request"></param>
335 /// <param name="remoteClient"></param>
336 /// <returns></returns>
337 public XmlRpcResponse LocateUser(XmlRpcRequest request, IPEndPoint remoteClient)
338 {
339 Hashtable hash = new Hashtable();
340
341 bool authorized = true;
342 if (m_VerifyCallers)
343 {
344 authorized = false;
345 foreach (string s in m_AuthorizedCallers)
346 if (s == remoteClient.Address.ToString())
347 {
348 authorized = true;
349 break;
350 }
351 }
352
353 if (authorized)
354 {
355 Hashtable requestData = (Hashtable)request.Params[0];
356 //string host = (string)requestData["host"];
357 //string portstr = (string)requestData["port"];
358 if (requestData.ContainsKey("userID"))
359 {
360 string userID_str = (string)requestData["userID"];
361 UUID userID = UUID.Zero;
362 UUID.TryParse(userID_str, out userID);
363
364 string url = m_HomeUsersService.LocateUser(userID);
365 if (url != string.Empty)
366 hash["URL"] = url;
367 else
368 hash["result"] = "Unable to locate user";
369 }
370 }
371
372 XmlRpcResponse response = new XmlRpcResponse();
373 response.Value = hash;
374 return response;
375
376 }
377
378 /// <summary>
379 /// Locates the user.
380 /// This is a sensitive operation, only authorized IP addresses can perform it.
381 /// </summary>
382 /// <param name="request"></param>
383 /// <param name="remoteClient"></param>
384 /// <returns></returns>
385 public XmlRpcResponse GetUUI(XmlRpcRequest request, IPEndPoint remoteClient)
386 {
387 Hashtable hash = new Hashtable();
388
389 Hashtable requestData = (Hashtable)request.Params[0];
390 //string host = (string)requestData["host"];
391 //string portstr = (string)requestData["port"];
392 if (requestData.ContainsKey("userID") && requestData.ContainsKey("targetUserID"))
393 {
394 string userID_str = (string)requestData["userID"];
395 UUID userID = UUID.Zero;
396 UUID.TryParse(userID_str, out userID);
397
398 string tuserID_str = (string)requestData["targetUserID"];
399 UUID targetUserID = UUID.Zero;
400 UUID.TryParse(tuserID_str, out targetUserID);
401 string uui = m_HomeUsersService.GetUUI(userID, targetUserID);
402 if (uui != string.Empty)
403 hash["UUI"] = uui;
404 else
405 hash["result"] = "User unknown";
406 }
407
408 XmlRpcResponse response = new XmlRpcResponse();
409 response.Value = hash;
410 return response;
411
412 }
413
197 } 414 }
198} 415}