aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/Connectors
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/Connectors')
-rw-r--r--OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs10
-rw-r--r--OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs317
-rw-r--r--OpenSim/Services/Connectors/Grid/GridServiceConnector.cs107
-rw-r--r--OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs423
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs575
-rw-r--r--OpenSim/Services/Connectors/User/UserServiceConnector.cs114
-rw-r--r--OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs277
7 files changed, 1707 insertions, 116 deletions
diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
index 19bb3e2..f36fe5b 100644
--- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Services.Connectors
67 IConfig assetConfig = source.Configs["AuthenticationService"]; 67 IConfig assetConfig = source.Configs["AuthenticationService"];
68 if (assetConfig == null) 68 if (assetConfig == null)
69 { 69 {
70 m_log.Error("[USER CONNECTOR]: AuthenticationService missing from OpanSim.ini"); 70 m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpanSim.ini");
71 throw new Exception("Authentication connector init error"); 71 throw new Exception("Authentication connector init error");
72 } 72 }
73 73
@@ -76,7 +76,7 @@ namespace OpenSim.Services.Connectors
76 76
77 if (serviceURI == String.Empty) 77 if (serviceURI == String.Empty)
78 { 78 {
79 m_log.Error("[USER CONNECTOR]: No Server URI named in section AuthenticationService"); 79 m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService");
80 throw new Exception("Authentication connector init error"); 80 throw new Exception("Authentication connector init error");
81 } 81 }
82 m_ServerURI = serviceURI; 82 m_ServerURI = serviceURI;
@@ -146,5 +146,11 @@ namespace OpenSim.Services.Connectors
146 146
147 return true; 147 return true;
148 } 148 }
149
150 public bool SetPassword(UUID principalID, string passwd)
151 {
152 // nope, we don't do this
153 return false;
154 }
149 } 155 }
150} 156}
diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
new file mode 100644
index 0000000..96c05a9
--- /dev/null
+++ b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
@@ -0,0 +1,317 @@
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 log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using IAvatarService = OpenSim.Services.Interfaces.IAvatarService;
40using OpenSim.Server.Base;
41using OpenMetaverse;
42
43namespace OpenSim.Services.Connectors
44{
45 public class AvatarServicesConnector : IAvatarService
46 {
47 private static readonly ILog m_log =
48 LogManager.GetLogger(
49 MethodBase.GetCurrentMethod().DeclaringType);
50
51 private string m_ServerURI = String.Empty;
52
53 public AvatarServicesConnector()
54 {
55 }
56
57 public AvatarServicesConnector(string serverURI)
58 {
59 m_ServerURI = serverURI.TrimEnd('/');
60 }
61
62 public AvatarServicesConnector(IConfigSource source)
63 {
64 Initialise(source);
65 }
66
67 public virtual void Initialise(IConfigSource source)
68 {
69 IConfig gridConfig = source.Configs["AvatarService"];
70 if (gridConfig == null)
71 {
72 m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini");
73 throw new Exception("Avatar connector init error");
74 }
75
76 string serviceURI = gridConfig.GetString("AvatarServerURI",
77 String.Empty);
78
79 if (serviceURI == String.Empty)
80 {
81 m_log.Error("[AVATAR CONNECTOR]: No Server URI named in section AvatarService");
82 throw new Exception("Avatar connector init error");
83 }
84 m_ServerURI = serviceURI;
85 }
86
87
88 #region IAvatarService
89
90 public AvatarData GetAvatar(UUID userID)
91 {
92 Dictionary<string, object> sendData = new Dictionary<string, object>();
93 //sendData["SCOPEID"] = scopeID.ToString();
94 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
95 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
96 sendData["METHOD"] = "getavatar";
97
98 sendData["UserID"] = userID;
99
100 string reply = string.Empty;
101 string reqString = ServerUtils.BuildQueryString(sendData);
102 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
103 try
104 {
105 reply = SynchronousRestFormsRequester.MakeRequest("POST",
106 m_ServerURI + "/avatar",
107 reqString);
108 if (reply == null || (reply != null && reply == string.Empty))
109 {
110 m_log.DebugFormat("[AVATAR CONNECTOR]: GetAgent received null or empty reply");
111 return null;
112 }
113 }
114 catch (Exception e)
115 {
116 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
117 }
118
119 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
120 AvatarData avatar = null;
121
122 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
123 {
124 if (replyData["result"] is Dictionary<string, object>)
125 {
126 avatar = new AvatarData((Dictionary<string, object>)replyData["result"]);
127 }
128 }
129
130 return avatar;
131
132 }
133
134 public bool SetAvatar(UUID userID, AvatarData avatar)
135 {
136 Dictionary<string, object> sendData = new Dictionary<string, object>();
137 //sendData["SCOPEID"] = scopeID.ToString();
138 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
139 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
140 sendData["METHOD"] = "setavatar";
141
142 sendData["UserID"] = userID.ToString();
143
144 Dictionary<string, object> structData = avatar.ToKeyValuePairs();
145
146 foreach (KeyValuePair<string, object> kvp in structData)
147 sendData[kvp.Key] = kvp.Value.ToString();
148
149
150 string reqString = ServerUtils.BuildQueryString(sendData);
151 //m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
152 try
153 {
154 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
155 m_ServerURI + "/avatar",
156 reqString);
157 if (reply != string.Empty)
158 {
159 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
160
161 if (replyData.ContainsKey("result"))
162 {
163 if (replyData["result"].ToString().ToLower() == "success")
164 return true;
165 else
166 return false;
167 }
168 else
169 m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar reply data does not contain result field");
170
171 }
172 else
173 m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar received empty reply");
174 }
175 catch (Exception e)
176 {
177 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
178 }
179
180 return false;
181 }
182
183 public bool ResetAvatar(UUID userID)
184 {
185 Dictionary<string, object> sendData = new Dictionary<string, object>();
186 //sendData["SCOPEID"] = scopeID.ToString();
187 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
188 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
189 sendData["METHOD"] = "resetavatar";
190
191 sendData["UserID"] = userID.ToString();
192
193 string reqString = ServerUtils.BuildQueryString(sendData);
194 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
195 try
196 {
197 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
198 m_ServerURI + "/avatar",
199 reqString);
200 if (reply != string.Empty)
201 {
202 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
203
204 if (replyData.ContainsKey("result"))
205 {
206 if (replyData["result"].ToString().ToLower() == "success")
207 return true;
208 else
209 return false;
210 }
211 else
212 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field");
213
214 }
215 else
216 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply");
217 }
218 catch (Exception e)
219 {
220 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
221 }
222
223 return false;
224 }
225
226 public bool SetItems(UUID userID, string[] names, string[] values)
227 {
228 Dictionary<string, object> sendData = new Dictionary<string, object>();
229 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
230 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
231 sendData["METHOD"] = "setitems";
232
233 sendData["UserID"] = userID.ToString();
234 sendData["Names"] = new List<string>(names);
235 sendData["Values"] = new List<string>(values);
236
237 string reqString = ServerUtils.BuildQueryString(sendData);
238 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
239 try
240 {
241 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
242 m_ServerURI + "/avatar",
243 reqString);
244 if (reply != string.Empty)
245 {
246 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
247
248 if (replyData.ContainsKey("result"))
249 {
250 if (replyData["result"].ToString().ToLower() == "success")
251 return true;
252 else
253 return false;
254 }
255 else
256 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field");
257
258 }
259 else
260 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply");
261 }
262 catch (Exception e)
263 {
264 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
265 }
266
267 return false;
268 }
269
270 public bool RemoveItems(UUID userID, string[] names)
271 {
272 Dictionary<string, object> sendData = new Dictionary<string, object>();
273 //sendData["SCOPEID"] = scopeID.ToString();
274 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
275 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
276 sendData["METHOD"] = "removeitems";
277
278 sendData["UserID"] = userID.ToString();
279 sendData["Names"] = new List<string>(names);
280
281 string reqString = ServerUtils.BuildQueryString(sendData);
282 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
283 try
284 {
285 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
286 m_ServerURI + "/avatar",
287 reqString);
288 if (reply != string.Empty)
289 {
290 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
291
292 if (replyData.ContainsKey("result"))
293 {
294 if (replyData["result"].ToString().ToLower() == "success")
295 return true;
296 else
297 return false;
298 }
299 else
300 m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems reply data does not contain result field");
301
302 }
303 else
304 m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems received empty reply");
305 }
306 catch (Exception e)
307 {
308 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
309 }
310
311 return false;
312 }
313
314 #endregion
315
316 }
317}
diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
index 04c7c53..a1ca58e 100644
--- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
@@ -460,6 +460,113 @@ namespace OpenSim.Services.Connectors
460 return rinfos; 460 return rinfos;
461 } 461 }
462 462
463 public List<GridRegion> GetDefaultRegions(UUID scopeID)
464 {
465 Dictionary<string, object> sendData = new Dictionary<string, object>();
466
467 sendData["SCOPEID"] = scopeID.ToString();
468
469 sendData["METHOD"] = "get_default_regions";
470
471 List<GridRegion> rinfos = new List<GridRegion>();
472 string reply = string.Empty;
473 try
474 {
475 reply = SynchronousRestFormsRequester.MakeRequest("POST",
476 m_ServerURI + "/grid",
477 ServerUtils.BuildQueryString(sendData));
478
479 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
480 }
481 catch (Exception e)
482 {
483 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
484 return rinfos;
485 }
486
487 if (reply != string.Empty)
488 {
489 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
490
491 if (replyData != null)
492 {
493 Dictionary<string, object>.ValueCollection rinfosList = replyData.Values;
494 foreach (object r in rinfosList)
495 {
496 if (r is Dictionary<string, object>)
497 {
498 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
499 rinfos.Add(rinfo);
500 }
501 }
502 }
503 else
504 m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions {0} received null response",
505 scopeID);
506 }
507 else
508 m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions received null reply");
509
510 return rinfos;
511 }
512
513 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
514 {
515 Dictionary<string, object> sendData = new Dictionary<string, object>();
516
517 sendData["SCOPEID"] = scopeID.ToString();
518 sendData["X"] = x.ToString();
519 sendData["Y"] = y.ToString();
520
521 sendData["METHOD"] = "get_fallback_regions";
522
523 List<GridRegion> rinfos = new List<GridRegion>();
524 string reply = string.Empty;
525 try
526 {
527 reply = SynchronousRestFormsRequester.MakeRequest("POST",
528 m_ServerURI + "/grid",
529 ServerUtils.BuildQueryString(sendData));
530
531 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
532 }
533 catch (Exception e)
534 {
535 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
536 return rinfos;
537 }
538
539 if (reply != string.Empty)
540 {
541 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
542
543 if (replyData != null)
544 {
545 Dictionary<string, object>.ValueCollection rinfosList = replyData.Values;
546 foreach (object r in rinfosList)
547 {
548 if (r is Dictionary<string, object>)
549 {
550 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
551 rinfos.Add(rinfo);
552 }
553 }
554 }
555 else
556 m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions {0}, {1}-{2} received null response",
557 scopeID, x, y);
558 }
559 else
560 m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions received null reply");
561
562 return rinfos;
563 }
564
565 public int GetRegionFlags(UUID scopeID, UUID regionID)
566 {
567 return 0;
568 }
569
463 #endregion 570 #endregion
464 571
465 } 572 }
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
new file mode 100644
index 0000000..fac3d1f
--- /dev/null
+++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
@@ -0,0 +1,423 @@
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 log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenSim.Server.Base;
40using OpenMetaverse;
41
42namespace OpenSim.Services.Connectors
43{
44 public class PresenceServicesConnector : IPresenceService
45 {
46 private static readonly ILog m_log =
47 LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType);
49
50 private string m_ServerURI = String.Empty;
51
52 public PresenceServicesConnector()
53 {
54 }
55
56 public PresenceServicesConnector(string serverURI)
57 {
58 m_ServerURI = serverURI.TrimEnd('/');
59 }
60
61 public PresenceServicesConnector(IConfigSource source)
62 {
63 Initialise(source);
64 }
65
66 public virtual void Initialise(IConfigSource source)
67 {
68 IConfig gridConfig = source.Configs["PresenceService"];
69 if (gridConfig == null)
70 {
71 m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini");
72 throw new Exception("Presence connector init error");
73 }
74
75 string serviceURI = gridConfig.GetString("PresenceServerURI",
76 String.Empty);
77
78 if (serviceURI == String.Empty)
79 {
80 m_log.Error("[PRESENCE CONNECTOR]: No Server URI named in section PresenceService");
81 throw new Exception("Presence connector init error");
82 }
83 m_ServerURI = serviceURI;
84 }
85
86
87 #region IPresenceService
88
89 public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
90 {
91 Dictionary<string, object> sendData = new Dictionary<string, object>();
92 //sendData["SCOPEID"] = scopeID.ToString();
93 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
94 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
95 sendData["METHOD"] = "login";
96
97 sendData["UserID"] = userID;
98 sendData["SessionID"] = sessionID.ToString();
99 sendData["SecureSessionID"] = secureSessionID.ToString();
100
101 string reqString = ServerUtils.BuildQueryString(sendData);
102 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
103 try
104 {
105 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
106 m_ServerURI + "/presence",
107 reqString);
108 if (reply != string.Empty)
109 {
110 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
111
112 if (replyData.ContainsKey("result"))
113 {
114 if (replyData["result"].ToString().ToLower() == "success")
115 return true;
116 else
117 return false;
118 }
119 else
120 m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent reply data does not contain result field");
121
122 }
123 else
124 m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent received empty reply");
125 }
126 catch (Exception e)
127 {
128 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
129 }
130
131 return false;
132
133 }
134
135 public bool LogoutAgent(UUID sessionID, Vector3 position, Vector3 lookat)
136 {
137 Dictionary<string, object> sendData = new Dictionary<string, object>();
138 //sendData["SCOPEID"] = scopeID.ToString();
139 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
140 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
141 sendData["METHOD"] = "logout";
142
143 sendData["SessionID"] = sessionID.ToString();
144 sendData["Position"] = position.ToString();
145 sendData["LookAt"] = lookat.ToString();
146
147 string reqString = ServerUtils.BuildQueryString(sendData);
148 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
149 try
150 {
151 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
152 m_ServerURI + "/presence",
153 reqString);
154 if (reply != string.Empty)
155 {
156 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
157
158 if (replyData.ContainsKey("result"))
159 {
160 if (replyData["result"].ToString().ToLower() == "success")
161 return true;
162 else
163 return false;
164 }
165 else
166 m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent reply data does not contain result field");
167
168 }
169 else
170 m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent received empty reply");
171 }
172 catch (Exception e)
173 {
174 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
175 }
176
177 return false;
178 }
179
180 public bool LogoutRegionAgents(UUID regionID)
181 {
182 Dictionary<string, object> sendData = new Dictionary<string, object>();
183 //sendData["SCOPEID"] = scopeID.ToString();
184 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
185 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
186 sendData["METHOD"] = "logoutregion";
187
188 sendData["RegionID"] = regionID.ToString();
189
190 string reqString = ServerUtils.BuildQueryString(sendData);
191 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
192 try
193 {
194 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
195 m_ServerURI + "/presence",
196 reqString);
197 if (reply != string.Empty)
198 {
199 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
200
201 if (replyData.ContainsKey("result"))
202 {
203 if (replyData["result"].ToString().ToLower() == "success")
204 return true;
205 else
206 return false;
207 }
208 else
209 m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents reply data does not contain result field");
210
211 }
212 else
213 m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents received empty reply");
214 }
215 catch (Exception e)
216 {
217 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
218 }
219
220 return false;
221 }
222
223 public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
224 {
225 Dictionary<string, object> sendData = new Dictionary<string, object>();
226 //sendData["SCOPEID"] = scopeID.ToString();
227 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
228 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
229 sendData["METHOD"] = "report";
230
231 sendData["SessionID"] = sessionID.ToString();
232 sendData["RegionID"] = regionID.ToString();
233 sendData["position"] = position.ToString();
234 sendData["lookAt"] = lookAt.ToString();
235
236 string reqString = ServerUtils.BuildQueryString(sendData);
237 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
238 try
239 {
240 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
241 m_ServerURI + "/presence",
242 reqString);
243 if (reply != string.Empty)
244 {
245 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
246
247 if (replyData.ContainsKey("result"))
248 {
249 if (replyData["result"].ToString().ToLower() == "success")
250 return true;
251 else
252 return false;
253 }
254 else
255 m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent reply data does not contain result field");
256
257 }
258 else
259 m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent received empty reply");
260 }
261 catch (Exception e)
262 {
263 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
264 }
265
266 return false;
267 }
268
269 public PresenceInfo GetAgent(UUID sessionID)
270 {
271 Dictionary<string, object> sendData = new Dictionary<string, object>();
272 //sendData["SCOPEID"] = scopeID.ToString();
273 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
274 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
275 sendData["METHOD"] = "getagent";
276
277 sendData["SessionID"] = sessionID.ToString();
278
279 string reply = string.Empty;
280 string reqString = ServerUtils.BuildQueryString(sendData);
281 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
282 try
283 {
284 reply = SynchronousRestFormsRequester.MakeRequest("POST",
285 m_ServerURI + "/presence",
286 reqString);
287 if (reply == null || (reply != null && reply == string.Empty))
288 {
289 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply");
290 return null;
291 }
292 }
293 catch (Exception e)
294 {
295 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
296 }
297
298 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
299 PresenceInfo pinfo = null;
300
301 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
302 {
303 if (replyData["result"] is Dictionary<string, object>)
304 {
305 pinfo = new PresenceInfo((Dictionary<string, object>)replyData["result"]);
306 }
307 }
308
309 return pinfo;
310 }
311
312 public PresenceInfo[] GetAgents(string[] userIDs)
313 {
314 Dictionary<string, object> sendData = new Dictionary<string, object>();
315 //sendData["SCOPEID"] = scopeID.ToString();
316 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
317 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
318 sendData["METHOD"] = "getagents";
319
320 sendData["uuids"] = new List<string>(userIDs);
321
322 string reply = string.Empty;
323 string reqString = ServerUtils.BuildQueryString(sendData);
324 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
325 try
326 {
327 reply = SynchronousRestFormsRequester.MakeRequest("POST",
328 m_ServerURI + "/presence",
329 reqString);
330 if (reply == null || (reply != null && reply == string.Empty))
331 {
332 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply");
333 return null;
334 }
335 }
336 catch (Exception e)
337 {
338 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
339 }
340
341 List<PresenceInfo> rinfos = new List<PresenceInfo>();
342
343 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
344
345 if (replyData != null)
346 {
347 if (replyData.ContainsKey("result") &&
348 (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure"))
349 {
350 return new PresenceInfo[0];
351 }
352
353 Dictionary<string, object>.ValueCollection pinfosList = replyData.Values;
354 //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count);
355 foreach (object presence in pinfosList)
356 {
357 if (presence is Dictionary<string, object>)
358 {
359 PresenceInfo pinfo = new PresenceInfo((Dictionary<string, object>)presence);
360 rinfos.Add(pinfo);
361 }
362 else
363 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received invalid response type {0}",
364 presence.GetType());
365 }
366 }
367 else
368 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null response");
369
370 return rinfos.ToArray();
371 }
372
373
374 public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
375 {
376 Dictionary<string, object> sendData = new Dictionary<string, object>();
377 //sendData["SCOPEID"] = scopeID.ToString();
378 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
379 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
380 sendData["METHOD"] = "sethome";
381
382 sendData["UserID"] = userID;
383 sendData["RegionID"] = regionID.ToString();
384 sendData["position"] = position.ToString();
385 sendData["lookAt"] = lookAt.ToString();
386
387 string reqString = ServerUtils.BuildQueryString(sendData);
388 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
389 try
390 {
391 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
392 m_ServerURI + "/presence",
393 reqString);
394 if (reply != string.Empty)
395 {
396 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
397
398 if (replyData.ContainsKey("result"))
399 {
400 if (replyData["result"].ToString().ToLower() == "success")
401 return true;
402 else
403 return false;
404 }
405 else
406 m_log.DebugFormat("[PRESENCE CONNECTOR]: SetHomeLocation reply data does not contain result field");
407
408 }
409 else
410 m_log.DebugFormat("[PRESENCE CONNECTOR]: SetHomeLocation received empty reply");
411 }
412 catch (Exception e)
413 {
414 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
415 }
416
417 return false;
418 }
419
420 #endregion
421
422 }
423}
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
new file mode 100644
index 0000000..b1b2a30
--- /dev/null
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -0,0 +1,575 @@
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.Generic;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34
35using OpenSim.Framework;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using log4net;
42using Nini.Config;
43
44namespace OpenSim.Services.Connectors.Simulation
45{
46 public class SimulationServiceConnector : ISimulationService
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 //private GridRegion m_Region;
51
52 public SimulationServiceConnector()
53 {
54 }
55
56 public SimulationServiceConnector(IConfigSource config)
57 {
58 //m_Region = region;
59 }
60
61 public IScene GetScene(ulong regionHandle)
62 {
63 return null;
64 }
65
66 #region Agents
67
68 public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason)
69 {
70 reason = String.Empty;
71
72 if (destination == null)
73 {
74 reason = "Destination is null";
75 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Given destination is null");
76 return false;
77 }
78
79 // Eventually, we want to use a caps url instead of the agentID
80 string uri = string.Empty;
81 try
82 {
83 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + "/agent/" + aCircuit.AgentID + "/";
84 }
85 catch (Exception e)
86 {
87 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent create. Reason: " + e.Message);
88 reason = e.Message;
89 return false;
90 }
91
92 //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri);
93
94 HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
95 AgentCreateRequest.Method = "POST";
96 AgentCreateRequest.ContentType = "application/json";
97 AgentCreateRequest.Timeout = 10000;
98 //AgentCreateRequest.KeepAlive = false;
99 //AgentCreateRequest.Headers.Add("Authorization", authKey);
100
101 // Fill it in
102 OSDMap args = null;
103 try
104 {
105 args = aCircuit.PackAgentCircuitData();
106 }
107 catch (Exception e)
108 {
109 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message);
110 }
111 // Add the input arguments
112 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
113 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
114 args["destination_name"] = OSD.FromString(destination.RegionName);
115 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
116 args["teleport_flags"] = OSD.FromString(flags.ToString());
117
118 string strBuffer = "";
119 byte[] buffer = new byte[1];
120 try
121 {
122 strBuffer = OSDParser.SerializeJsonString(args);
123 Encoding str = Util.UTF8;
124 buffer = str.GetBytes(strBuffer);
125
126 }
127 catch (Exception e)
128 {
129 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
130 // ignore. buffer will be empty, caller should check.
131 }
132
133 Stream os = null;
134 try
135 { // send the Post
136 AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
137 os = AgentCreateRequest.GetRequestStream();
138 os.Write(buffer, 0, strBuffer.Length); //Send it
139 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}",
140 uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY);
141 }
142 //catch (WebException ex)
143 catch
144 {
145 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message);
146 reason = "cannot contact remote region";
147 return false;
148 }
149 finally
150 {
151 if (os != null)
152 os.Close();
153 }
154
155 // Let's wait for the response
156 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
157
158 WebResponse webResponse = null;
159 StreamReader sr = null;
160 try
161 {
162 webResponse = AgentCreateRequest.GetResponse();
163 if (webResponse == null)
164 {
165 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on DoCreateChildAgentCall post");
166 }
167 else
168 {
169
170 sr = new StreamReader(webResponse.GetResponseStream());
171 string response = sr.ReadToEnd().Trim();
172 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response);
173
174 if (!String.IsNullOrEmpty(response))
175 {
176 try
177 {
178 // we assume we got an OSDMap back
179 OSDMap r = Util.GetOSDMap(response);
180 bool success = r["success"].AsBoolean();
181 reason = r["reason"].AsString();
182 return success;
183 }
184 catch (NullReferenceException e)
185 {
186 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
187
188 // check for old style response
189 if (response.ToLower().StartsWith("true"))
190 return true;
191
192 return false;
193 }
194 }
195 }
196 }
197 catch (WebException ex)
198 {
199 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
200 // ignore, really
201 }
202 finally
203 {
204 if (sr != null)
205 sr.Close();
206 }
207
208 return true;
209 }
210
211 public bool UpdateAgent(GridRegion destination, AgentData data)
212 {
213 return UpdateAgent(destination, (IAgentData)data);
214 }
215
216 public bool UpdateAgent(GridRegion destination, AgentPosition data)
217 {
218 return UpdateAgent(destination, (IAgentData)data);
219 }
220
221 private bool UpdateAgent(GridRegion destination, IAgentData cAgentData)
222 {
223 // Eventually, we want to use a caps url instead of the agentID
224 string uri = string.Empty;
225 try
226 {
227 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + "/agent/" + cAgentData.AgentID + "/";
228 }
229 catch (Exception e)
230 {
231 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent update. Reason: " + e.Message);
232 return false;
233 }
234 //Console.WriteLine(" >>> DoAgentUpdateCall <<< " + uri);
235
236 HttpWebRequest ChildUpdateRequest = (HttpWebRequest)WebRequest.Create(uri);
237 ChildUpdateRequest.Method = "PUT";
238 ChildUpdateRequest.ContentType = "application/json";
239 ChildUpdateRequest.Timeout = 10000;
240 //ChildUpdateRequest.KeepAlive = false;
241
242 // Fill it in
243 OSDMap args = null;
244 try
245 {
246 args = cAgentData.Pack();
247 }
248 catch (Exception e)
249 {
250 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: PackUpdateMessage failed with exception: " + e.Message);
251 }
252 // Add the input arguments
253 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
254 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
255 args["destination_name"] = OSD.FromString(destination.RegionName);
256 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
257
258 string strBuffer = "";
259 byte[] buffer = new byte[1];
260 try
261 {
262 strBuffer = OSDParser.SerializeJsonString(args);
263 Encoding str = Util.UTF8;
264 buffer = str.GetBytes(strBuffer);
265
266 }
267 catch (Exception e)
268 {
269 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of ChildUpdate: {0}", e.Message);
270 // ignore. buffer will be empty, caller should check.
271 }
272
273 Stream os = null;
274 try
275 { // send the Post
276 ChildUpdateRequest.ContentLength = buffer.Length; //Count bytes to send
277 os = ChildUpdateRequest.GetRequestStream();
278 os.Write(buffer, 0, strBuffer.Length); //Send it
279 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted AgentUpdate request to remote sim {0}", uri);
280 }
281 catch (WebException ex)
282 //catch
283 {
284 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on AgentUpdate {0}", ex.Message);
285
286 return false;
287 }
288 finally
289 {
290 if (os != null)
291 os.Close();
292 }
293
294 // Let's wait for the response
295 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after ChildAgentUpdate");
296
297 WebResponse webResponse = null;
298 StreamReader sr = null;
299 try
300 {
301 webResponse = ChildUpdateRequest.GetResponse();
302 if (webResponse == null)
303 {
304 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on ChilAgentUpdate post");
305 }
306
307 sr = new StreamReader(webResponse.GetResponseStream());
308 //reply = sr.ReadToEnd().Trim();
309 sr.ReadToEnd().Trim();
310 sr.Close();
311 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
312
313 }
314 catch (WebException ex)
315 {
316 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of ChilAgentUpdate {0}", ex.Message);
317 // ignore, really
318 }
319 finally
320 {
321 if (sr != null)
322 sr.Close();
323 }
324
325 return true;
326 }
327
328 public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
329 {
330 agent = null;
331 // Eventually, we want to use a caps url instead of the agentID
332 string uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + "/agent/" + id + "/" + destination.RegionID.ToString() + "/";
333 //Console.WriteLine(" >>> DoRetrieveRootAgentCall <<< " + uri);
334
335 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
336 request.Method = "GET";
337 request.Timeout = 10000;
338 //request.Headers.Add("authorization", ""); // coming soon
339
340 HttpWebResponse webResponse = null;
341 string reply = string.Empty;
342 StreamReader sr = null;
343 try
344 {
345 webResponse = (HttpWebResponse)request.GetResponse();
346 if (webResponse == null)
347 {
348 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on agent get ");
349 }
350
351 sr = new StreamReader(webResponse.GetResponseStream());
352 reply = sr.ReadToEnd().Trim();
353
354 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was " + reply);
355
356 }
357 catch (WebException ex)
358 {
359 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of agent get {0}", ex.Message);
360 // ignore, really
361 return false;
362 }
363 finally
364 {
365 if (sr != null)
366 sr.Close();
367 }
368
369 if (webResponse.StatusCode == HttpStatusCode.OK)
370 {
371 // we know it's jason
372 OSDMap args = Util.GetOSDMap(reply);
373 if (args == null)
374 {
375 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: Error getting OSDMap from reply");
376 return false;
377 }
378
379 agent = new CompleteAgentData();
380 agent.Unpack(args);
381 return true;
382 }
383
384 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: DoRetrieveRootAgentCall returned status " + webResponse.StatusCode);
385 return false;
386 }
387
388 public bool ReleaseAgent(UUID origin, UUID id, string uri)
389 {
390 WebRequest request = WebRequest.Create(uri);
391 request.Method = "DELETE";
392 request.Timeout = 10000;
393
394 StreamReader sr = null;
395 try
396 {
397 WebResponse webResponse = request.GetResponse();
398 if (webResponse == null)
399 {
400 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on ReleaseAgent");
401 }
402
403 sr = new StreamReader(webResponse.GetResponseStream());
404 //reply = sr.ReadToEnd().Trim();
405 sr.ReadToEnd().Trim();
406 sr.Close();
407 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
408
409 }
410 catch (WebException ex)
411 {
412 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of ReleaseAgent {0}", ex.Message);
413 return false;
414 }
415 finally
416 {
417 if (sr != null)
418 sr.Close();
419 }
420
421 return true;
422 }
423
424 public bool CloseAgent(GridRegion destination, UUID id)
425 {
426 string uri = string.Empty;
427 try
428 {
429 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + "/agent/" + id + "/" + destination.RegionID.ToString() + "/";
430 }
431 catch (Exception e)
432 {
433 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent close. Reason: " + e.Message);
434 return false;
435 }
436
437 //Console.WriteLine(" >>> DoCloseAgentCall <<< " + uri);
438
439 WebRequest request = WebRequest.Create(uri);
440 request.Method = "DELETE";
441 request.Timeout = 10000;
442
443 StreamReader sr = null;
444 try
445 {
446 WebResponse webResponse = request.GetResponse();
447 if (webResponse == null)
448 {
449 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on agent delete ");
450 }
451
452 sr = new StreamReader(webResponse.GetResponseStream());
453 //reply = sr.ReadToEnd().Trim();
454 sr.ReadToEnd().Trim();
455 sr.Close();
456 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
457
458 }
459 catch (WebException ex)
460 {
461 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of agent delete {0}", ex.Message);
462 return false;
463 }
464 finally
465 {
466 if (sr != null)
467 sr.Close();
468 }
469
470 return true;
471 }
472
473 #endregion Agents
474
475 #region Objects
476
477 public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
478 {
479 string uri
480 = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + "/object/" + sog.UUID + "/";
481 //m_log.Debug(" >>> DoCreateObjectCall <<< " + uri);
482
483 WebRequest ObjectCreateRequest = WebRequest.Create(uri);
484 ObjectCreateRequest.Method = "POST";
485 ObjectCreateRequest.ContentType = "application/json";
486 ObjectCreateRequest.Timeout = 10000;
487
488 OSDMap args = new OSDMap(2);
489 args["sog"] = OSD.FromString(sog.ToXml2());
490 args["extra"] = OSD.FromString(sog.ExtraToXmlString());
491 string state = sog.GetStateSnapshot();
492 if (state.Length > 0)
493 args["state"] = OSD.FromString(state);
494 // Add the input general arguments
495 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
496 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
497 args["destination_name"] = OSD.FromString(destination.RegionName);
498 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
499
500 string strBuffer = "";
501 byte[] buffer = new byte[1];
502 try
503 {
504 strBuffer = OSDParser.SerializeJsonString(args);
505 Encoding str = Util.UTF8;
506 buffer = str.GetBytes(strBuffer);
507
508 }
509 catch (Exception e)
510 {
511 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of CreateObject: {0}", e.Message);
512 // ignore. buffer will be empty, caller should check.
513 }
514
515 Stream os = null;
516 try
517 { // send the Post
518 ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send
519 os = ObjectCreateRequest.GetRequestStream();
520 os.Write(buffer, 0, strBuffer.Length); //Send it
521 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted CreateObject request to remote sim {0}", uri);
522 }
523 catch (WebException ex)
524 {
525 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on CreateObject {0}", ex.Message);
526 return false;
527 }
528 finally
529 {
530 if (os != null)
531 os.Close();
532 }
533
534 // Let's wait for the response
535 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
536
537 StreamReader sr = null;
538 try
539 {
540 WebResponse webResponse = ObjectCreateRequest.GetResponse();
541 if (webResponse == null)
542 {
543 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on CreateObject post");
544 return false;
545 }
546
547 sr = new StreamReader(webResponse.GetResponseStream());
548 //reply = sr.ReadToEnd().Trim();
549 sr.ReadToEnd().Trim();
550 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", reply);
551
552 }
553 catch (WebException ex)
554 {
555 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of CreateObject {0}", ex.Message);
556 return false;
557 }
558 finally
559 {
560 if (sr != null)
561 sr.Close();
562 }
563
564 return true;
565 }
566
567 public bool CreateObject(GridRegion destination, UUID userID, UUID itemID)
568 {
569 // TODO, not that urgent
570 return false;
571 }
572
573 #endregion Objects
574 }
575}
diff --git a/OpenSim/Services/Connectors/User/UserServiceConnector.cs b/OpenSim/Services/Connectors/User/UserServiceConnector.cs
deleted file mode 100644
index 683990f..0000000
--- a/OpenSim/Services/Connectors/User/UserServiceConnector.cs
+++ /dev/null
@@ -1,114 +0,0 @@
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 log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using OpenMetaverse;
39
40namespace OpenSim.Services.Connectors
41{
42 public class UserServicesConnector : IUserAccountService
43 {
44 private static readonly ILog m_log =
45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType);
47
48// private string m_ServerURI = String.Empty;
49
50 public UserServicesConnector()
51 {
52 }
53
54 public UserServicesConnector(string serverURI)
55 {
56// m_ServerURI = serverURI.TrimEnd('/');
57 }
58
59 public UserServicesConnector(IConfigSource source)
60 {
61 Initialise(source);
62 }
63
64 public virtual void Initialise(IConfigSource source)
65 {
66 IConfig assetConfig = source.Configs["UserService"];
67 if (assetConfig == null)
68 {
69 m_log.Error("[USER CONNECTOR]: UserService missing from OpanSim.ini");
70 throw new Exception("User connector init error");
71 }
72
73 string serviceURI = assetConfig.GetString("UserServerURI",
74 String.Empty);
75
76 if (serviceURI == String.Empty)
77 {
78 m_log.Error("[USER CONNECTOR]: No Server URI named in section UserService");
79 throw new Exception("User connector init error");
80 }
81 //m_ServerURI = serviceURI;
82 }
83
84 public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
85 {
86 return null;
87 }
88
89 public UserAccount GetUserAccount(UUID scopeID, UUID userID)
90 {
91 return null;
92 }
93
94 public bool SetHomePosition(UserAccount data, UUID regionID, UUID regionSecret)
95 {
96 return false;
97 }
98
99 public bool SetUserAccount(UserAccount data, UUID principalID, string token)
100 {
101 return false;
102 }
103
104 public bool CreateUserAccount(UserAccount data, UUID principalID, string token)
105 {
106 return false;
107 }
108
109 public List<UserAccount> GetUserAccount(UUID scopeID, string query)
110 {
111 return null;
112 }
113 }
114}
diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs
new file mode 100644
index 0000000..e1621b8
--- /dev/null
+++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs
@@ -0,0 +1,277 @@
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 log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Server.Base;
38using OpenSim.Services.Interfaces;
39using OpenMetaverse;
40
41namespace OpenSim.Services.Connectors
42{
43 public class UserAccountServicesConnector : IUserAccountService
44 {
45 private static readonly ILog m_log =
46 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType);
48
49 private string m_ServerURI = String.Empty;
50
51 public UserAccountServicesConnector()
52 {
53 }
54
55 public UserAccountServicesConnector(string serverURI)
56 {
57 m_ServerURI = serverURI.TrimEnd('/');
58 }
59
60 public UserAccountServicesConnector(IConfigSource source)
61 {
62 Initialise(source);
63 }
64
65 public virtual void Initialise(IConfigSource source)
66 {
67 IConfig assetConfig = source.Configs["UserAccountService"];
68 if (assetConfig == null)
69 {
70 m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini");
71 throw new Exception("User account connector init error");
72 }
73
74 string serviceURI = assetConfig.GetString("UserAccountServerURI",
75 String.Empty);
76
77 if (serviceURI == String.Empty)
78 {
79 m_log.Error("[ACCOUNT CONNECTOR]: No Server URI named in section UserAccountService");
80 throw new Exception("User account connector init error");
81 }
82 m_ServerURI = serviceURI;
83 }
84
85 public virtual UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
86 {
87 Dictionary<string, object> sendData = new Dictionary<string, object>();
88 //sendData["SCOPEID"] = scopeID.ToString();
89 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
90 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
91 sendData["METHOD"] = "getaccount";
92
93 sendData["ScopeID"] = scopeID;
94 sendData["FirstName"] = firstName.ToString();
95 sendData["LastName"] = lastName.ToString();
96
97 return SendAndGetReply(sendData);
98 }
99
100 public virtual UserAccount GetUserAccount(UUID scopeID, string email)
101 {
102 Dictionary<string, object> sendData = new Dictionary<string, object>();
103 //sendData["SCOPEID"] = scopeID.ToString();
104 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
105 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
106 sendData["METHOD"] = "getaccount";
107
108 sendData["ScopeID"] = scopeID;
109 sendData["Email"] = email;
110
111 return SendAndGetReply(sendData);
112 }
113
114 public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID)
115 {
116 Dictionary<string, object> sendData = new Dictionary<string, object>();
117 //sendData["SCOPEID"] = scopeID.ToString();
118 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
119 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
120 sendData["METHOD"] = "getaccount";
121
122 sendData["ScopeID"] = scopeID;
123 sendData["UserID"] = userID.ToString();
124
125 return SendAndGetReply(sendData);
126 }
127
128 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
129 {
130 Dictionary<string, object> sendData = new Dictionary<string, object>();
131 //sendData["SCOPEID"] = scopeID.ToString();
132 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
133 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
134 sendData["METHOD"] = "getagents";
135
136 sendData["ScopeID"] = scopeID.ToString();
137 sendData["query"] = query;
138
139 string reply = string.Empty;
140 string reqString = ServerUtils.BuildQueryString(sendData);
141 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
142 try
143 {
144 reply = SynchronousRestFormsRequester.MakeRequest("POST",
145 m_ServerURI + "/accounts",
146 reqString);
147 if (reply == null || (reply != null && reply == string.Empty))
148 {
149 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received null or empty reply");
150 return null;
151 }
152 }
153 catch (Exception e)
154 {
155 m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting accounts server: {0}", e.Message);
156 }
157
158 List<UserAccount> accounts = new List<UserAccount>();
159
160 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
161
162 if (replyData != null)
163 {
164 if (replyData.ContainsKey("result") && replyData.ContainsKey("result").ToString() == "null")
165 {
166 return accounts;
167 }
168
169 Dictionary<string, object>.ValueCollection accountList = replyData.Values;
170 //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count);
171 foreach (object acc in accountList)
172 {
173 if (acc is Dictionary<string, object>)
174 {
175 UserAccount pinfo = new UserAccount((Dictionary<string, object>)acc);
176 accounts.Add(pinfo);
177 }
178 else
179 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received invalid response type {0}",
180 acc.GetType());
181 }
182 }
183 else
184 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccounts received null response");
185
186 return accounts;
187 }
188
189 public bool StoreUserAccount(UserAccount data)
190 {
191 Dictionary<string, object> sendData = new Dictionary<string, object>();
192 //sendData["SCOPEID"] = scopeID.ToString();
193 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
194 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
195 sendData["METHOD"] = "setaccount";
196
197 Dictionary<string, object> structData = data.ToKeyValuePairs();
198
199 foreach (KeyValuePair<string,object> kvp in structData)
200 sendData[kvp.Key] = kvp.Value.ToString();
201
202 return SendAndGetBoolReply(sendData);
203 }
204
205 private UserAccount SendAndGetReply(Dictionary<string, object> sendData)
206 {
207 string reply = string.Empty;
208 string reqString = ServerUtils.BuildQueryString(sendData);
209 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
210 try
211 {
212 reply = SynchronousRestFormsRequester.MakeRequest("POST",
213 m_ServerURI + "/accounts",
214 reqString);
215 if (reply == null || (reply != null && reply == string.Empty))
216 {
217 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccount received null or empty reply");
218 return null;
219 }
220 }
221 catch (Exception e)
222 {
223 m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user account server: {0}", e.Message);
224 }
225
226 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
227 UserAccount account = null;
228
229 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
230 {
231 if (replyData["result"] is Dictionary<string, object>)
232 {
233 account = new UserAccount((Dictionary<string, object>)replyData["result"]);
234 }
235 }
236
237 return account;
238
239 }
240
241 private bool SendAndGetBoolReply(Dictionary<string, object> sendData)
242 {
243 string reqString = ServerUtils.BuildQueryString(sendData);
244 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
245 try
246 {
247 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
248 m_ServerURI + "/accounts",
249 reqString);
250 if (reply != string.Empty)
251 {
252 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
253
254 if (replyData.ContainsKey("result"))
255 {
256 if (replyData["result"].ToString().ToLower() == "success")
257 return true;
258 else
259 return false;
260 }
261 else
262 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount reply data does not contain result field");
263
264 }
265 else
266 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount received empty reply");
267 }
268 catch (Exception e)
269 {
270 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Exception when contacting user account server: {0}", e.Message);
271 }
272
273 return false;
274 }
275
276 }
277}