aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Services/Base/ServiceBase.cs2
-rw-r--r--OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs4
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs29
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs31
-rw-r--r--OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs2
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs410
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs201
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs262
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs232
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs47
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs421
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs895
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs511
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs435
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs311
-rw-r--r--OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs1
-rw-r--r--OpenSim/Services/GridService/GridService.cs6
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs5
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs29
-rw-r--r--OpenSim/Services/Interfaces/IUserAccountService.cs20
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs8
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs53
-rw-r--r--OpenSim/Services/PresenceService/PresenceService.cs4
-rw-r--r--OpenSim/Services/UserAccountService/GridUserService.cs2
-rw-r--r--OpenSim/Services/UserAccountService/UserAccountService.cs2
25 files changed, 3884 insertions, 39 deletions
diff --git a/OpenSim/Services/Base/ServiceBase.cs b/OpenSim/Services/Base/ServiceBase.cs
index 91d5c56..ef30cba 100644
--- a/OpenSim/Services/Base/ServiceBase.cs
+++ b/OpenSim/Services/Base/ServiceBase.cs
@@ -72,7 +72,7 @@ namespace OpenSim.Services.Base
72// m_log.DebugFormat("[SERVICE BASE]: Found type {0}", pluginType); 72// m_log.DebugFormat("[SERVICE BASE]: Found type {0}", pluginType);
73 73
74 if (pluginType.IsPublic) 74 if (pluginType.IsPublic)
75 { 75 {
76 if (className != String.Empty && 76 if (className != String.Empty &&
77 pluginType.ToString() != 77 pluginType.ToString() !=
78 pluginType.Namespace + "." + className) 78 pluginType.Namespace + "." + className)
diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
index ce88236..0e85067 100644
--- a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
+++ b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
@@ -28,9 +28,9 @@
28using System; 28using System;
29 29
30namespace OpenSim.Services.Connectors 30namespace OpenSim.Services.Connectors
31{ 31{
32 public class GridUserServiceConnector 32 public class GridUserServiceConnector
33 { 33 {
34 public GridUserServiceConnector() 34 public GridUserServiceConnector()
35 { 35 {
36 } 36 }
diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
index 9f73b38..c426bba 100644
--- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
@@ -1,4 +1,31 @@
1using System; 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;
2using System.Collections; 29using System.Collections;
3using System.Collections.Generic; 30using System.Collections.Generic;
4using System.Drawing; 31using System.Drawing;
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index 83d3449..3e91e3a 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -1,4 +1,31 @@
1using System; 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;
2using System.Collections; 29using System.Collections;
3using System.Collections.Generic; 30using System.Collections.Generic;
4using System.IO; 31using System.IO;
@@ -334,7 +361,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
334 } 361 }
335 catch (Exception e) 362 catch (Exception e)
336 { 363 {
337 m_log.Debug("[HGrid]: Exception " + e.Message); 364 m_log.Debug("[USER AGENT CONNECTOR]: Unable to contact remote server ");
338 reason = "Exception: " + e.Message; 365 reason = "Exception: " + e.Message;
339 return false; 366 return false;
340 } 367 }
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
index 9821dd4..0cc1978 100644
--- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
@@ -126,7 +126,7 @@ namespace OpenSim.Services.Connectors
126 }); 126 });
127 127
128 if (ret == null) 128 if (ret == null)
129 return null; 129 return null;
130 if (ret.Count == 0) 130 if (ret.Count == 0)
131 return null; 131 return null;
132 132
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
new file mode 100644
index 0000000..1c22a72
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
@@ -0,0 +1,410 @@
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 log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40using OpenMetaverse;
41using OpenMetaverse.StructuredData;
42
43namespace OpenSim.Services.Connectors.SimianGrid
44{
45 /// <summary>
46 /// Connects to the SimianGrid asset service
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class SimianAssetServiceConnector : IAssetService, ISharedRegionModule
50 {
51 private static readonly ILog m_log =
52 LogManager.GetLogger(
53 MethodBase.GetCurrentMethod().DeclaringType);
54 private static string ZeroID = UUID.Zero.ToString();
55
56 private string m_serverUrl = String.Empty;
57 private IImprovedAssetCache m_cache;
58
59 #region ISharedRegionModule
60
61 public Type ReplaceableInterface { get { return null; } }
62 public void RegionLoaded(Scene scene)
63 {
64 if (m_cache == null)
65 {
66 IImprovedAssetCache cache = scene.RequestModuleInterface<IImprovedAssetCache>();
67 if (cache is ISharedRegionModule)
68 m_cache = cache;
69 }
70 }
71 public void PostInitialise() { }
72 public void Close() { }
73
74 public SimianAssetServiceConnector() { }
75 public string Name { get { return "SimianAssetServiceConnector"; } }
76 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAssetService>(this); } }
77 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAssetService>(this); } }
78
79 #endregion ISharedRegionModule
80
81 public SimianAssetServiceConnector(IConfigSource source)
82 {
83 Initialise(source);
84 }
85
86 public void Initialise(IConfigSource source)
87 {
88 if (Simian.IsSimianEnabled(source, "AssetServices"))
89 {
90 IConfig gridConfig = source.Configs["AssetService"];
91 if (gridConfig == null)
92 {
93 m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini");
94 throw new Exception("Asset connector init error");
95 }
96
97 string serviceUrl = gridConfig.GetString("AssetServerURI");
98 if (String.IsNullOrEmpty(serviceUrl))
99 {
100 m_log.Error("[ASSET CONNECTOR]: No AssetServerURI in section AssetService");
101 throw new Exception("Asset connector init error");
102 }
103
104 if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("="))
105 serviceUrl = serviceUrl + '/';
106
107 m_serverUrl = serviceUrl;
108 }
109 }
110
111 #region IAssetService
112
113 public AssetBase Get(string id)
114 {
115 AssetBase asset = null;
116
117 // Cache fetch
118 if (m_cache != null)
119 {
120 asset = m_cache.Get(id);
121 if (asset != null)
122 return asset;
123 }
124
125 Uri url;
126
127 // Determine if id is an absolute URL or a grid-relative UUID
128 if (!Uri.TryCreate(id, UriKind.Absolute, out url))
129 url = new Uri(m_serverUrl + id);
130
131 try
132 {
133 HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
134
135 using (WebResponse response = request.GetResponse())
136 {
137 using (Stream responseStream = response.GetResponseStream())
138 {
139 string creatorID = response.Headers.GetOne("X-Asset-Creator-Id") ?? String.Empty;
140
141 // Create the asset object
142 asset = new AssetBase(id, String.Empty, SLUtil.ContentTypeToSLAssetType(response.ContentType), creatorID);
143
144 UUID assetID;
145 if (UUID.TryParse(id, out assetID))
146 asset.FullID = assetID;
147
148 // Grab the asset data from the response stream
149 using (MemoryStream stream = new MemoryStream())
150 {
151 responseStream.CopyTo(stream, Int32.MaxValue);
152 asset.Data = stream.ToArray();
153 }
154 }
155 }
156
157 // Cache store
158 if (m_cache != null && asset != null)
159 m_cache.Cache(asset);
160
161 return asset;
162 }
163 catch (Exception ex)
164 {
165 m_log.Warn("[ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message);
166 return null;
167 }
168 }
169
170 /// <summary>
171 /// Get an asset's metadata
172 /// </summary>
173 /// <param name="id"></param>
174 /// <returns></returns>
175 public AssetMetadata GetMetadata(string id)
176 {
177 AssetMetadata metadata = null;
178
179 // Cache fetch
180 if (m_cache != null)
181 {
182 AssetBase asset = m_cache.Get(id);
183 if (asset != null)
184 return asset.Metadata;
185 }
186
187 Uri url;
188
189 // Determine if id is an absolute URL or a grid-relative UUID
190 if (!Uri.TryCreate(id, UriKind.Absolute, out url))
191 url = new Uri(m_serverUrl + id);
192
193 try
194 {
195 HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
196 request.Method = "HEAD";
197
198 using (WebResponse response = request.GetResponse())
199 {
200 using (Stream responseStream = response.GetResponseStream())
201 {
202 // Create the metadata object
203 metadata = new AssetMetadata();
204 metadata.ContentType = response.ContentType;
205 metadata.ID = id;
206
207 UUID uuid;
208 if (UUID.TryParse(id, out uuid))
209 metadata.FullID = uuid;
210
211 string lastModifiedStr = response.Headers.Get("Last-Modified");
212 if (!String.IsNullOrEmpty(lastModifiedStr))
213 {
214 DateTime lastModified;
215 if (DateTime.TryParse(lastModifiedStr, out lastModified))
216 metadata.CreationDate = lastModified;
217 }
218 }
219 }
220 }
221 catch (Exception ex)
222 {
223 m_log.Warn("[ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message);
224 }
225
226 return metadata;
227 }
228
229 public byte[] GetData(string id)
230 {
231 AssetBase asset = Get(id);
232
233 if (asset != null)
234 return asset.Data;
235
236 return null;
237 }
238
239 /// <summary>
240 /// Get an asset asynchronously
241 /// </summary>
242 /// <param name="id">The asset id</param>
243 /// <param name="sender">Represents the requester. Passed back via the handler</param>
244 /// <param name="handler">The handler to call back once the asset has been retrieved</param>
245 /// <returns>True if the id was parseable, false otherwise</returns>
246 public bool Get(string id, Object sender, AssetRetrieved handler)
247 {
248 Util.FireAndForget(
249 delegate(object o)
250 {
251 AssetBase asset = Get(id);
252 handler(id, sender, asset);
253 }
254 );
255
256 return true;
257 }
258
259 /// <summary>
260 /// Creates a new asset
261 /// </summary>
262 /// Returns a random ID if none is passed into it
263 /// <param name="asset"></param>
264 /// <returns></returns>
265 public string Store(AssetBase asset)
266 {
267 bool storedInCache = false;
268 string errorMessage = null;
269
270 // AssetID handling
271 if (String.IsNullOrEmpty(asset.ID) || asset.ID == ZeroID)
272 {
273 asset.FullID = UUID.Random();
274 asset.ID = asset.FullID.ToString();
275 }
276
277 // Cache handling
278 if (m_cache != null)
279 {
280 m_cache.Cache(asset);
281 storedInCache = true;
282 }
283
284 // Local asset handling
285 if (asset.Local)
286 {
287 if (!storedInCache)
288 {
289 m_log.Error("Cannot store local " + asset.Metadata.ContentType + " asset without an asset cache");
290 asset.ID = null;
291 asset.FullID = UUID.Zero;
292 }
293
294 return asset.ID;
295 }
296
297 // Distinguish public and private assets
298 bool isPublic = true;
299 switch ((AssetType)asset.Type)
300 {
301 case AssetType.CallingCard:
302 case AssetType.Gesture:
303 case AssetType.LSLBytecode:
304 case AssetType.LSLText:
305 isPublic = false;
306 break;
307 }
308
309 // Make sure ContentType is set
310 if (String.IsNullOrEmpty(asset.Metadata.ContentType))
311 asset.Metadata.ContentType = SLUtil.SLAssetTypeToContentType(asset.Type);
312
313 // Build the remote storage request
314 List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
315 {
316 new MultipartForm.Parameter("AssetID", asset.FullID.ToString()),
317 new MultipartForm.Parameter("CreatorID", asset.Metadata.CreatorID),
318 new MultipartForm.Parameter("Temporary", asset.Temporary ? "1" : "0"),
319 new MultipartForm.Parameter("Public", isPublic ? "1" : "0"),
320 new MultipartForm.File("Asset", asset.Name, asset.Metadata.ContentType, asset.Data)
321 };
322
323 // Make the remote storage request
324 try
325 {
326 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
327
328 HttpWebResponse response = MultipartForm.Post(request, postParameters);
329 using (Stream responseStream = response.GetResponseStream())
330 {
331 try
332 {
333 string responseStr = responseStream.GetStreamString();
334 OSD responseOSD = OSDParser.Deserialize(responseStr);
335 if (responseOSD.Type == OSDType.Map)
336 {
337 OSDMap responseMap = (OSDMap)responseOSD;
338 if (responseMap["Success"].AsBoolean())
339 return asset.ID;
340 else
341 errorMessage = "Upload failed: " + responseMap["Message"].AsString();
342 }
343 else
344 {
345 errorMessage = "Response format was invalid.";
346 }
347 }
348 catch
349 {
350 errorMessage = "Failed to parse the response.";
351 }
352 }
353 }
354 catch (WebException ex)
355 {
356 errorMessage = ex.Message;
357 }
358
359 m_log.WarnFormat("[ASSET CONNECTOR]: Failed to store asset \"{0}\" ({1}, {2}): {3}",
360 asset.Name, asset.ID, asset.Metadata.ContentType, errorMessage);
361 return null;
362 }
363
364 /// <summary>
365 /// Update an asset's content
366 /// </summary>
367 /// Attachments and bare scripts need this!!
368 /// <param name="id"> </param>
369 /// <param name="data"></param>
370 /// <returns></returns>
371 public bool UpdateContent(string id, byte[] data)
372 {
373 AssetBase asset = Get(id);
374
375 if (asset == null)
376 {
377 m_log.Warn("[ASSET CONNECTOR]: Failed to fetch asset " + id + " for updating");
378 return false;
379 }
380
381 asset.Data = data;
382
383 string result = Store(asset);
384 return !String.IsNullOrEmpty(result);
385 }
386
387 /// <summary>
388 /// Delete an asset
389 /// </summary>
390 /// <param name="id"></param>
391 /// <returns></returns>
392 public bool Delete(string id)
393 {
394 if (m_cache != null)
395 m_cache.Expire(id);
396
397 string url = m_serverUrl + id;
398
399 OSDMap response = WebUtil.ServiceRequest(url, "DELETE");
400 if (response["Success"].AsBoolean())
401 return true;
402 else
403 m_log.Warn("[ASSET CONNECTOR]: Failed to delete asset " + id + " from the asset service");
404
405 return false;
406 }
407
408 #endregion IAssetService
409 }
410}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
new file mode 100644
index 0000000..6317b87
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
@@ -0,0 +1,201 @@
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.Specialized;
30using System.Reflection;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40
41namespace OpenSim.Services.Connectors.SimianGrid
42{
43 /// <summary>
44 /// Connects authentication/authorization to the SimianGrid backend
45 /// </summary>
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
47 public class SimianAuthenticationServiceConnector : IAuthenticationService, ISharedRegionModule
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(
51 MethodBase.GetCurrentMethod().DeclaringType);
52
53 private string m_serverUrl = String.Empty;
54
55 #region ISharedRegionModule
56
57 public Type ReplaceableInterface { get { return null; } }
58 public void RegionLoaded(Scene scene) { }
59 public void PostInitialise() { }
60 public void Close() { }
61
62 public SimianAuthenticationServiceConnector() { }
63 public string Name { get { return "SimianAuthenticationServiceConnector"; } }
64 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAuthenticationService>(this); } }
65 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAuthenticationService>(this); } }
66
67 #endregion ISharedRegionModule
68
69 public SimianAuthenticationServiceConnector(IConfigSource source)
70 {
71 Initialise(source);
72 }
73
74 public void Initialise(IConfigSource source)
75 {
76 if (Simian.IsSimianEnabled(source, "AuthenticationServices"))
77 {
78 IConfig assetConfig = source.Configs["AuthenticationService"];
79 if (assetConfig == null)
80 {
81 m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini");
82 throw new Exception("Authentication connector init error");
83 }
84
85 string serviceURI = assetConfig.GetString("AuthenticationServerURI");
86 if (String.IsNullOrEmpty(serviceURI))
87 {
88 m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService");
89 throw new Exception("Authentication connector init error");
90 }
91
92 m_serverUrl = serviceURI;
93 }
94 }
95
96 public string Authenticate(UUID principalID, string password, int lifetime)
97 {
98 NameValueCollection requestArgs = new NameValueCollection
99 {
100 { "RequestMethod", "GetIdentities" },
101 { "UserID", principalID.ToString() }
102 };
103
104 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
105 if (response["Success"].AsBoolean() && response["Identities"] is OSDArray)
106 {
107 OSDArray identities = (OSDArray)response["Identities"];
108 for (int i = 0; i < identities.Count; i++)
109 {
110 OSDMap identity = identities[i] as OSDMap;
111 if (identity != null)
112 {
113 if (identity["Type"].AsString() == "md5hash")
114 {
115 string credential = identity["Credential"].AsString();
116
117 if (password == credential || Utils.MD5String(password) == credential)
118 return Authorize(principalID);
119 }
120 }
121 }
122
123 m_log.Warn("[AUTH CONNECTOR]: Authentication failed for " + principalID);
124 }
125 else
126 {
127 m_log.Warn("[AUTH CONNECTOR]: Failed to retrieve identities for " + principalID + ": " +
128 response["Message"].AsString());
129 }
130
131 return String.Empty;
132 }
133
134 public bool Verify(UUID principalID, string token, int lifetime)
135 {
136 NameValueCollection requestArgs = new NameValueCollection
137 {
138 { "RequestMethod", "GetSession" },
139 { "SessionID", token }
140 };
141
142 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
143 if (response["Success"].AsBoolean())
144 {
145 return true;
146 }
147 else
148 {
149 m_log.Warn("[AUTH CONNECTOR]: Could not verify session for " + principalID + ": " +
150 response["Message"].AsString());
151 }
152
153 return false;
154 }
155
156 public bool Release(UUID principalID, string token)
157 {
158 NameValueCollection requestArgs = new NameValueCollection
159 {
160 { "RequestMethod", "RemoveSession" },
161 { "UserID", principalID.ToString() }
162 };
163
164 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
165 if (response["Success"].AsBoolean())
166 {
167 return true;
168 }
169 else
170 {
171 m_log.Warn("[AUTH CONNECTOR]: Failed to remove session for " + principalID + ": " +
172 response["Message"].AsString());
173 }
174
175 return false;
176 }
177
178 public bool SetPassword(UUID principalID, string passwd)
179 {
180 // TODO: Use GetIdentities to find the md5hash identity for principalID
181 // and then update it with AddIdentity
182 m_log.Error("[AUTH CONNECTOR]: Changing passwords is not implemented yet");
183 return false;
184 }
185
186 private string Authorize(UUID userID)
187 {
188 NameValueCollection requestArgs = new NameValueCollection
189 {
190 { "RequestMethod", "AddSession" },
191 { "UserID", userID.ToString() }
192 };
193
194 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
195 if (response["Success"].AsBoolean())
196 return response["SessionID"].AsUUID().ToString();
197 else
198 return String.Empty;
199 }
200 }
201}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
new file mode 100644
index 0000000..a18cb22
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
@@ -0,0 +1,262 @@
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.Collections.Specialized;
31using System.IO;
32using System.Net;
33using System.Reflection;
34using log4net;
35using Mono.Addins;
36using Nini.Config;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Server.Base;
41using OpenSim.Services.Interfaces;
42using OpenMetaverse;
43using OpenMetaverse.StructuredData;
44
45namespace OpenSim.Services.Connectors.SimianGrid
46{
47 /// <summary>
48 /// Connects avatar appearance data to the SimianGrid backend
49 /// </summary>
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
51 public class SimianAvatarServiceConnector : IAvatarService, ISharedRegionModule
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56 private static string ZeroID = UUID.Zero.ToString();
57
58 private string m_serverUrl = String.Empty;
59
60 #region ISharedRegionModule
61
62 public Type ReplaceableInterface { get { return null; } }
63 public void RegionLoaded(Scene scene) { }
64 public void PostInitialise() { }
65 public void Close() { }
66
67 public SimianAvatarServiceConnector() { }
68 public string Name { get { return "SimianAvatarServiceConnector"; } }
69 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAvatarService>(this); } }
70 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAvatarService>(this); } }
71
72 #endregion ISharedRegionModule
73
74 public SimianAvatarServiceConnector(IConfigSource source)
75 {
76 Initialise(source);
77 }
78
79 public void Initialise(IConfigSource source)
80 {
81 if (Simian.IsSimianEnabled(source, "AvatarServices"))
82 {
83 IConfig gridConfig = source.Configs["AvatarService"];
84 if (gridConfig == null)
85 {
86 m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini");
87 throw new Exception("Avatar connector init error");
88 }
89
90 string serviceUrl = gridConfig.GetString("AvatarServerURI");
91 if (String.IsNullOrEmpty(serviceUrl))
92 {
93 m_log.Error("[AVATAR CONNECTOR]: No AvatarServerURI in section AvatarService");
94 throw new Exception("Avatar connector init error");
95 }
96
97 if (!serviceUrl.EndsWith("/"))
98 serviceUrl = serviceUrl + '/';
99
100 m_serverUrl = serviceUrl;
101 }
102 }
103
104 #region IAvatarService
105
106 public AvatarData GetAvatar(UUID userID)
107 {
108 NameValueCollection requestArgs = new NameValueCollection
109 {
110 { "RequestMethod", "GetUser" },
111 { "UserID", userID.ToString() }
112 };
113
114 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
115 if (response["Success"].AsBoolean())
116 {
117 OSDMap map = null;
118 try { map = OSDParser.DeserializeJson(response["LLAppearance"].AsString()) as OSDMap; }
119 catch { }
120
121 if (map != null)
122 {
123 AvatarWearable[] wearables = new AvatarWearable[13];
124 wearables[0] = new AvatarWearable(map["ShapeItem"].AsUUID(), map["ShapeAsset"].AsUUID());
125 wearables[1] = new AvatarWearable(map["SkinItem"].AsUUID(), map["SkinAsset"].AsUUID());
126 wearables[2] = new AvatarWearable(map["HairItem"].AsUUID(), map["HairAsset"].AsUUID());
127 wearables[3] = new AvatarWearable(map["EyesItem"].AsUUID(), map["EyesAsset"].AsUUID());
128 wearables[4] = new AvatarWearable(map["ShirtItem"].AsUUID(), map["ShirtAsset"].AsUUID());
129 wearables[5] = new AvatarWearable(map["PantsItem"].AsUUID(), map["PantsAsset"].AsUUID());
130 wearables[6] = new AvatarWearable(map["ShoesItem"].AsUUID(), map["ShoesAsset"].AsUUID());
131 wearables[7] = new AvatarWearable(map["SocksItem"].AsUUID(), map["SocksAsset"].AsUUID());
132 wearables[8] = new AvatarWearable(map["JacketItem"].AsUUID(), map["JacketAsset"].AsUUID());
133 wearables[9] = new AvatarWearable(map["GlovesItem"].AsUUID(), map["GlovesAsset"].AsUUID());
134 wearables[10] = new AvatarWearable(map["UndershirtItem"].AsUUID(), map["UndershirtAsset"].AsUUID());
135 wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID());
136 wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID());
137
138 AvatarAppearance appearance = new AvatarAppearance(userID);
139 appearance.Wearables = wearables;
140 appearance.AvatarHeight = (float)map["Height"].AsReal();
141
142 AvatarData avatar = new AvatarData(appearance);
143
144 // Get attachments
145 map = null;
146 try { map = OSDParser.DeserializeJson(response["LLAttachments"].AsString()) as OSDMap; }
147 catch { }
148
149 if (map != null)
150 {
151 foreach (KeyValuePair<string, OSD> kvp in map)
152 avatar.Data[kvp.Key] = kvp.Value.AsString();
153 }
154
155 return avatar;
156 }
157 else
158 {
159 m_log.Warn("[AVATAR CONNECTOR]: Failed to get user appearance for " + userID +
160 ", LLAppearance is missing or invalid");
161 return null;
162 }
163 }
164 else
165 {
166 m_log.Warn("[AVATAR CONNECTOR]: Failed to get user appearance for " + userID + ": " +
167 response["Message"].AsString());
168 }
169
170 return null;
171 }
172
173 public bool SetAvatar(UUID userID, AvatarData avatar)
174 {
175 m_log.Debug("[AVATAR CONNECTOR]: SetAvatar called for " + userID);
176
177 if (avatar.AvatarType == 1) // LLAvatar
178 {
179 AvatarAppearance appearance = avatar.ToAvatarAppearance(userID);
180
181 OSDMap map = new OSDMap();
182
183 map["Height"] = OSD.FromReal(appearance.AvatarHeight);
184
185 map["ShapeItem"] = OSD.FromUUID(appearance.BodyItem);
186 map["ShapeAsset"] = OSD.FromUUID(appearance.BodyAsset);
187 map["SkinItem"] = OSD.FromUUID(appearance.SkinItem);
188 map["SkinAsset"] = OSD.FromUUID(appearance.SkinAsset);
189 map["HairItem"] = OSD.FromUUID(appearance.HairItem);
190 map["HairAsset"] = OSD.FromUUID(appearance.HairAsset);
191 map["EyesItem"] = OSD.FromUUID(appearance.EyesItem);
192 map["EyesAsset"] = OSD.FromUUID(appearance.EyesAsset);
193 map["ShirtItem"] = OSD.FromUUID(appearance.ShirtItem);
194 map["ShirtAsset"] = OSD.FromUUID(appearance.ShirtAsset);
195 map["PantsItem"] = OSD.FromUUID(appearance.PantsItem);
196 map["PantsAsset"] = OSD.FromUUID(appearance.PantsAsset);
197 map["ShoesItem"] = OSD.FromUUID(appearance.ShoesItem);
198 map["ShoesAsset"] = OSD.FromUUID(appearance.ShoesAsset);
199 map["SocksItem"] = OSD.FromUUID(appearance.SocksItem);
200 map["SocksAsset"] = OSD.FromUUID(appearance.SocksAsset);
201 map["JacketItem"] = OSD.FromUUID(appearance.JacketItem);
202 map["JacketAsset"] = OSD.FromUUID(appearance.JacketAsset);
203 map["GlovesItem"] = OSD.FromUUID(appearance.GlovesItem);
204 map["GlovesAsset"] = OSD.FromUUID(appearance.GlovesAsset);
205 map["UndershirtItem"] = OSD.FromUUID(appearance.UnderShirtItem);
206 map["UndershirtAsset"] = OSD.FromUUID(appearance.UnderShirtAsset);
207 map["UnderpantsItem"] = OSD.FromUUID(appearance.UnderPantsItem);
208 map["UnderpantsAsset"] = OSD.FromUUID(appearance.UnderPantsAsset);
209 map["SkirtItem"] = OSD.FromUUID(appearance.SkirtItem);
210 map["SkirtAsset"] = OSD.FromUUID(appearance.SkirtAsset);
211
212 OSDMap items = new OSDMap();
213 foreach (KeyValuePair<string, string> kvp in avatar.Data)
214 {
215 if (kvp.Key.StartsWith("_ap_"))
216 items.Add(kvp.Key, OSD.FromString(kvp.Value));
217 }
218
219 NameValueCollection requestArgs = new NameValueCollection
220 {
221 { "RequestMethod", "AddUserData" },
222 { "UserID", userID.ToString() },
223 { "LLAppearance", OSDParser.SerializeJsonString(map) },
224 { "LLAttachments", OSDParser.SerializeJsonString(items) }
225 };
226
227 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
228 bool success = response["Success"].AsBoolean();
229
230 if (!success)
231 m_log.Warn("[AVATAR CONNECTOR]: Failed saving appearance for " + userID + ": " + response["Message"].AsString());
232
233 return success;
234 }
235 else
236 {
237 m_log.Error("[AVATAR CONNECTOR]: Can't save appearance for " + userID + ". Unhandled avatar type " + avatar.AvatarType);
238 return false;
239 }
240 }
241
242 public bool ResetAvatar(UUID userID)
243 {
244 m_log.Error("[AVATAR CONNECTOR]: ResetAvatar called for " + userID + ", implement this");
245 return false;
246 }
247
248 public bool SetItems(UUID userID, string[] names, string[] values)
249 {
250 m_log.Error("[AVATAR CONNECTOR]: SetItems called for " + userID + " with " + names.Length + " names and " + values.Length + " values, implement this");
251 return false;
252 }
253
254 public bool RemoveItems(UUID userID, string[] names)
255 {
256 m_log.Error("[AVATAR CONNECTOR]: RemoveItems called for " + userID + " with " + names.Length + " names, implement this");
257 return false;
258 }
259
260 #endregion IAvatarService
261 }
262}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
new file mode 100644
index 0000000..b3ecc7e
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
@@ -0,0 +1,232 @@
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.Collections.Specialized;
31using System.Reflection;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41
42using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
43
44namespace OpenSim.Services.Connectors.SimianGrid
45{
46 /// <summary>
47 /// Stores and retrieves friend lists from the SimianGrid backend
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
50 public class SimianFriendsServiceConnector : IFriendsService, ISharedRegionModule
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 private string m_serverUrl = String.Empty;
57
58 #region ISharedRegionModule
59
60 public Type ReplaceableInterface { get { return null; } }
61 public void RegionLoaded(Scene scene) { }
62 public void PostInitialise() { }
63 public void Close() { }
64
65 public SimianFriendsServiceConnector() { }
66 public string Name { get { return "SimianFriendsServiceConnector"; } }
67 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IFriendsService>(this); } }
68 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IFriendsService>(this); } }
69
70 #endregion ISharedRegionModule
71
72 public SimianFriendsServiceConnector(IConfigSource source)
73 {
74 Initialise(source);
75 }
76
77 public void Initialise(IConfigSource source)
78 {
79 if (Simian.IsSimianEnabled(source, "FriendsServices"))
80 {
81 IConfig assetConfig = source.Configs["FriendsService"];
82 if (assetConfig == null)
83 {
84 m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini");
85 throw new Exception("Friends connector init error");
86 }
87
88 string serviceURI = assetConfig.GetString("FriendsServerURI");
89 if (String.IsNullOrEmpty(serviceURI))
90 {
91 m_log.Error("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService");
92 throw new Exception("Friends connector init error");
93 }
94
95 m_serverUrl = serviceURI;
96 }
97 }
98
99 #region IFriendsService
100
101 public FriendInfo[] GetFriends(UUID principalID)
102 {
103 Dictionary<UUID, FriendInfo> friends = new Dictionary<UUID, FriendInfo>();
104
105 OSDArray friendsArray = GetFriended(principalID);
106 OSDArray friendedMeArray = GetFriendedBy(principalID);
107
108 // Load the list of friends and their granted permissions
109 for (int i = 0; i < friendsArray.Count; i++)
110 {
111 OSDMap friendEntry = friendsArray[i] as OSDMap;
112 if (friendEntry != null)
113 {
114 UUID friendID = friendEntry["Key"].AsUUID();
115
116 FriendInfo friend = new FriendInfo();
117 friend.PrincipalID = principalID;
118 friend.Friend = friendID.ToString();
119 friend.MyFlags = friendEntry["Value"].AsInteger();
120 friend.TheirFlags = -1;
121
122 friends[friendID] = friend;
123 }
124 }
125
126 // Load the permissions those friends have granted to this user
127 for (int i = 0; i < friendedMeArray.Count; i++)
128 {
129 OSDMap friendedMeEntry = friendedMeArray[i] as OSDMap;
130 if (friendedMeEntry != null)
131 {
132 UUID friendID = friendedMeEntry["OwnerID"].AsUUID();
133
134 FriendInfo friend;
135 if (friends.TryGetValue(friendID, out friend))
136 friend.TheirFlags = friendedMeEntry["Value"].AsInteger();
137 }
138 }
139
140 // Convert the dictionary of friends to an array and return it
141 FriendInfo[] array = new FriendInfo[friends.Count];
142 int j = 0;
143 foreach (FriendInfo friend in friends.Values)
144 array[j++] = friend;
145
146 return array;
147 }
148
149 public bool StoreFriend(UUID principalID, string friend, int flags)
150 {
151 NameValueCollection requestArgs = new NameValueCollection
152 {
153 { "RequestMethod", "AddGeneric" },
154 { "OwnerID", principalID.ToString() },
155 { "Type", "Friend" },
156 { "Key", friend },
157 { "Value", flags.ToString() }
158 };
159
160 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
161 bool success = response["Success"].AsBoolean();
162
163 if (!success)
164 m_log.Error("[FRIENDS CONNECTOR]: Failed to store friend " + friend + " for user " + principalID + ": " + response["Message"].AsString());
165
166 return success;
167 }
168
169 public bool Delete(UUID principalID, string friend)
170 {
171 NameValueCollection requestArgs = new NameValueCollection
172 {
173 { "RequestMethod", "RemoveGeneric" },
174 { "OwnerID", principalID.ToString() },
175 { "Type", "Friend" },
176 { "Key", friend }
177 };
178
179 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
180 bool success = response["Success"].AsBoolean();
181
182 if (!success)
183 m_log.Error("[FRIENDS CONNECTOR]: Failed to remove friend " + friend + " for user " + principalID + ": " + response["Message"].AsString());
184
185 return success;
186 }
187
188 #endregion IFriendsService
189
190 private OSDArray GetFriended(UUID ownerID)
191 {
192 NameValueCollection requestArgs = new NameValueCollection
193 {
194 { "RequestMethod", "GetGenerics" },
195 { "OwnerID", ownerID.ToString() },
196 { "Type", "Friend" }
197 };
198
199 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
200 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
201 {
202 return (OSDArray)response["Entries"];
203 }
204 else
205 {
206 m_log.Warn("[FRIENDS CONNECTOR]: Failed to retrieve friends for user " + ownerID + ": " + response["Message"].AsString());
207 return new OSDArray(0);
208 }
209 }
210
211 private OSDArray GetFriendedBy(UUID ownerID)
212 {
213 NameValueCollection requestArgs = new NameValueCollection
214 {
215 { "RequestMethod", "GetGenerics" },
216 { "Key", ownerID.ToString() },
217 { "Type", "Friend" }
218 };
219
220 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
221 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
222 {
223 return (OSDArray)response["Entries"];
224 }
225 else
226 {
227 m_log.Warn("[FRIENDS CONNECTOR]: Failed to retrieve reverse friends for user " + ownerID + ": " + response["Message"].AsString());
228 return new OSDArray(0);
229 }
230 }
231 }
232}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
new file mode 100644
index 0000000..c3de98e
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
@@ -0,0 +1,47 @@
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 Mono.Addins;
30using Nini.Config;
31
32[assembly: Addin("SimianGrid", "1.0")]
33[assembly: AddinDependency("OpenSim", "0.5")]
34
35public static class Simian
36{
37 public static bool IsSimianEnabled(IConfigSource config, string moduleName)
38 {
39 if (config.Configs["Modules"] != null)
40 {
41 string module = config.Configs["Modules"].GetString("AuthenticationServices");
42 return !String.IsNullOrEmpty(module) && module.Contains("Simian");
43 }
44
45 return false;
46 }
47} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
new file mode 100644
index 0000000..eebdf14
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
@@ -0,0 +1,421 @@
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.Collections.Specialized;
31using System.Net;
32using System.Reflection;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Server.Base;
42using OpenMetaverse;
43using OpenMetaverse.StructuredData;
44
45using GridRegion = OpenSim.Services.Interfaces.GridRegion;
46
47namespace OpenSim.Services.Connectors.SimianGrid
48{
49 /// <summary>
50 /// Connects region registration and neighbor lookups to the SimianGrid
51 /// backend
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
54 public class SimianGridServiceConnector : IGridService, ISharedRegionModule
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(
58 MethodBase.GetCurrentMethod().DeclaringType);
59
60 private string m_serverUrl = String.Empty;
61
62 #region ISharedRegionModule
63
64 public Type ReplaceableInterface { get { return null; } }
65 public void RegionLoaded(Scene scene) { }
66 public void PostInitialise() { }
67 public void Close() { }
68
69 public SimianGridServiceConnector() { }
70 public string Name { get { return "SimianGridServiceConnector"; } }
71 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IGridService>(this); } }
72 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IGridService>(this); } }
73
74 #endregion ISharedRegionModule
75
76 public SimianGridServiceConnector(IConfigSource source)
77 {
78 Initialise(source);
79 }
80
81 public void Initialise(IConfigSource source)
82 {
83 if (Simian.IsSimianEnabled(source, "GridServices"))
84 {
85 IConfig gridConfig = source.Configs["GridService"];
86 if (gridConfig == null)
87 {
88 m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini");
89 throw new Exception("Grid connector init error");
90 }
91
92 string serviceUrl = gridConfig.GetString("GridServerURI");
93 if (String.IsNullOrEmpty(serviceUrl))
94 {
95 m_log.Error("[GRID CONNECTOR]: No Server URI named in section GridService");
96 throw new Exception("Grid connector init error");
97 }
98
99 m_serverUrl = serviceUrl;
100 }
101 }
102
103 #region IGridService
104
105 public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
106 {
107 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0);
108 Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, 4096.0);
109
110 string httpAddress = "http://" + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort + "/";
111
112 OSDMap extraData = new OSDMap
113 {
114 { "ServerURI", OSD.FromString(regionInfo.ServerURI) },
115 { "InternalAddress", OSD.FromString(regionInfo.InternalEndPoint.Address.ToString()) },
116 { "InternalPort", OSD.FromInteger(regionInfo.InternalEndPoint.Port) },
117 { "ExternalAddress", OSD.FromString(regionInfo.ExternalEndPoint.Address.ToString()) },
118 { "ExternalPort", OSD.FromInteger(regionInfo.ExternalEndPoint.Port) },
119 { "MapTexture", OSD.FromUUID(regionInfo.TerrainImage) },
120 { "Access", OSD.FromInteger(regionInfo.Access) },
121 { "RegionSecret", OSD.FromString(regionInfo.RegionSecret) },
122 { "EstateOwner", OSD.FromUUID(regionInfo.EstateOwner) },
123 { "Token", OSD.FromString(regionInfo.Token) }
124 };
125
126 NameValueCollection requestArgs = new NameValueCollection
127 {
128 { "RequestMethod", "AddScene" },
129 { "SceneID", regionInfo.RegionID.ToString() },
130 { "Name", regionInfo.RegionName },
131 { "MinPosition", minPosition.ToString() },
132 { "MaxPosition", maxPosition.ToString() },
133 { "Address", httpAddress },
134 { "Enabled", "1" },
135 { "ExtraData", OSDParser.SerializeJsonString(extraData) }
136 };
137
138 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
139 if (response["Success"].AsBoolean())
140 return String.Empty;
141 else
142 return "Region registration for " + regionInfo.RegionName + " failed: " + response["Message"].AsString();
143 }
144
145 public bool DeregisterRegion(UUID regionID)
146 {
147 NameValueCollection requestArgs = new NameValueCollection
148 {
149 { "RequestMethod", "AddScene" },
150 { "SceneID", regionID.ToString() },
151 { "Enabled", "0" }
152 };
153
154 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
155 bool success = response["Success"].AsBoolean();
156
157 if (!success)
158 m_log.Warn("[GRID CONNECTOR]: Region deregistration for " + regionID + " failed: " + response["Message"].AsString());
159
160 return success;
161 }
162
163 public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID)
164 {
165 const int NEIGHBOR_RADIUS = 128;
166
167 GridRegion region = GetRegionByUUID(scopeID, regionID);
168
169 if (region != null)
170 {
171 List<GridRegion> regions = GetRegionRange(scopeID,
172 region.RegionLocX - NEIGHBOR_RADIUS, region.RegionLocX + (int)Constants.RegionSize + NEIGHBOR_RADIUS,
173 region.RegionLocY - NEIGHBOR_RADIUS, region.RegionLocY + (int)Constants.RegionSize + NEIGHBOR_RADIUS);
174
175 for (int i = 0; i < regions.Count; i++)
176 {
177 if (regions[i].RegionID == regionID)
178 {
179 regions.RemoveAt(i);
180 break;
181 }
182 }
183
184 m_log.Debug("[GRID CONNECTOR]: Found " + regions.Count + " neighbors for region " + regionID);
185 return regions;
186 }
187
188 return new List<GridRegion>(0);
189 }
190
191 public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
192 {
193 NameValueCollection requestArgs = new NameValueCollection
194 {
195 { "RequestMethod", "GetScene" },
196 { "SceneID", regionID.ToString() }
197 };
198
199 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
200 if (response["Success"].AsBoolean())
201 {
202 return ResponseToGridRegion(response);
203 }
204 else
205 {
206 m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region " + regionID);
207 return null;
208 }
209 }
210
211 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
212 {
213 // Go one meter in from the requested x/y coords to avoid requesting a position
214 // that falls on the border of two sims
215 Vector3d position = new Vector3d(x + 1, y + 1, 0.0);
216
217 NameValueCollection requestArgs = new NameValueCollection
218 {
219 { "RequestMethod", "GetScene" },
220 { "Position", position.ToString() },
221 { "Enabled", "1" }
222 };
223
224 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
225 if (response["Success"].AsBoolean())
226 {
227 return ResponseToGridRegion(response);
228 }
229 else
230 {
231 //m_log.InfoFormat("[GRID CONNECTOR]: Grid service did not find a match for region at {0},{1}",
232 // x / Constants.RegionSize, y / Constants.RegionSize);
233 return null;
234 }
235 }
236
237 public GridRegion GetRegionByName(UUID scopeID, string regionName)
238 {
239 List<GridRegion> regions = GetRegionsByName(scopeID, regionName, 1);
240
241 m_log.Debug("[GRID CONNECTOR]: Got " + regions.Count + " matches for region name " + regionName);
242
243 if (regions.Count > 0)
244 return regions[0];
245
246 return null;
247 }
248
249 public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
250 {
251 List<GridRegion> foundRegions = new List<GridRegion>();
252
253 NameValueCollection requestArgs = new NameValueCollection
254 {
255 { "RequestMethod", "GetScenes" },
256 { "NameQuery", name },
257 { "Enabled", "1" }
258 };
259 if (maxNumber > 0)
260 requestArgs["MaxNumber"] = maxNumber.ToString();
261
262 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
263 if (response["Success"].AsBoolean())
264 {
265 OSDArray array = response["Scenes"] as OSDArray;
266 if (array != null)
267 {
268 for (int i = 0; i < array.Count; i++)
269 {
270 GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
271 if (region != null)
272 foundRegions.Add(region);
273 }
274 }
275 }
276
277 return foundRegions;
278 }
279
280 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
281 {
282 List<GridRegion> foundRegions = new List<GridRegion>();
283
284 Vector3d minPosition = new Vector3d(xmin, ymin, 0.0);
285 Vector3d maxPosition = new Vector3d(xmax, ymax, 4096.0);
286
287 NameValueCollection requestArgs = new NameValueCollection
288 {
289 { "RequestMethod", "GetScenes" },
290 { "MinPosition", minPosition.ToString() },
291 { "MaxPosition", maxPosition.ToString() },
292 { "Enabled", "1" }
293 };
294
295 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
296 if (response["Success"].AsBoolean())
297 {
298 OSDArray array = response["Scenes"] as OSDArray;
299 if (array != null)
300 {
301 for (int i = 0; i < array.Count; i++)
302 {
303 GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
304 if (region != null)
305 foundRegions.Add(region);
306 }
307 }
308 }
309
310 return foundRegions;
311 }
312
313 public List<GridRegion> GetDefaultRegions(UUID scopeID)
314 {
315 // TODO: Allow specifying the default grid location
316 const int DEFAULT_X = 1000 * 256;
317 const int DEFAULT_Y = 1000 * 256;
318
319 GridRegion defRegion = GetNearestRegion(new Vector3d(DEFAULT_X, DEFAULT_Y, 0.0), true);
320 if (defRegion != null)
321 return new List<GridRegion>(1) { defRegion };
322 else
323 return new List<GridRegion>(0);
324 }
325
326 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
327 {
328 GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true);
329 if (defRegion != null)
330 return new List<GridRegion>(1) { defRegion };
331 else
332 return new List<GridRegion>(0);
333 }
334
335 public int GetRegionFlags(UUID scopeID, UUID regionID)
336 {
337 const int REGION_ONLINE = 4;
338
339 NameValueCollection requestArgs = new NameValueCollection
340 {
341 { "RequestMethod", "GetScene" },
342 { "SceneID", regionID.ToString() }
343 };
344
345 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
346 if (response["Success"].AsBoolean())
347 {
348 return response["Enabled"].AsBoolean() ? REGION_ONLINE : 0;
349 }
350 else
351 {
352 m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region " + regionID + " during region flags check");
353 return -1;
354 }
355 }
356
357 #endregion IGridService
358
359 private GridRegion GetNearestRegion(Vector3d position, bool onlyEnabled)
360 {
361 NameValueCollection requestArgs = new NameValueCollection
362 {
363 { "RequestMethod", "GetScene" },
364 { "Position", position.ToString() },
365 { "FindClosest", "1" }
366 };
367 if (onlyEnabled)
368 requestArgs["Enabled"] = "1";
369
370 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
371 if (response["Success"].AsBoolean())
372 {
373 return ResponseToGridRegion(response);
374 }
375 else
376 {
377 m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region at " + position);
378 return null;
379 }
380 }
381
382 private GridRegion ResponseToGridRegion(OSDMap response)
383 {
384 if (response == null)
385 return null;
386
387 OSDMap extraData = response["ExtraData"] as OSDMap;
388 if (extraData == null)
389 return null;
390
391 GridRegion region = new GridRegion();
392
393 region.RegionID = response["SceneID"].AsUUID();
394 region.RegionName = response["Name"].AsString();
395
396 Vector3d minPosition = response["MinPosition"].AsVector3d();
397 region.RegionLocX = (int)minPosition.X;
398 region.RegionLocY = (int)minPosition.Y;
399
400 Uri httpAddress = response["Address"].AsUri();
401 region.ExternalHostName = httpAddress.Host;
402 region.HttpPort = (uint)httpAddress.Port;
403
404 region.ServerURI = extraData["ServerURI"].AsString();
405
406 IPAddress internalAddress;
407 IPAddress.TryParse(extraData["InternalAddress"].AsString(), out internalAddress);
408 if (internalAddress == null)
409 internalAddress = IPAddress.Any;
410
411 region.InternalEndPoint = new IPEndPoint(internalAddress, extraData["InternalPort"].AsInteger());
412 region.TerrainImage = extraData["MapTexture"].AsUUID();
413 region.Access = (byte)extraData["Access"].AsInteger();
414 region.RegionSecret = extraData["RegionSecret"].AsString();
415 region.EstateOwner = extraData["EstateOwner"].AsUUID();
416 region.Token = extraData["Token"].AsString();
417
418 return region;
419 }
420 }
421}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
new file mode 100644
index 0000000..891782f
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
@@ -0,0 +1,895 @@
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.Collections.Specialized;
31using System.Reflection;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Server.Base;
41using OpenSim.Services.Interfaces;
42
43namespace OpenSim.Services.Connectors.SimianGrid
44{
45 /// <summary>
46 /// Permissions bitflags
47 /// </summary>
48 [Flags]
49 public enum PermissionMask : uint
50 {
51 None = 0,
52 Transfer = 1 << 13,
53 Modify = 1 << 14,
54 Copy = 1 << 15,
55 Move = 1 << 19,
56 Damage = 1 << 20,
57 All = 0x7FFFFFFF
58 }
59
60 /// <summary>
61 /// Connects avatar inventories to the SimianGrid backend
62 /// </summary>
63 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
64 public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule
65 {
66 private static readonly ILog m_log =
67 LogManager.GetLogger(
68 MethodBase.GetCurrentMethod().DeclaringType);
69
70 private string m_serverUrl = String.Empty;
71 private string m_userServerUrl = String.Empty;
72 private object m_gestureSyncRoot = new object();
73
74 #region ISharedRegionModule
75
76 public Type ReplaceableInterface { get { return null; } }
77 public void RegionLoaded(Scene scene) { }
78 public void PostInitialise() { }
79 public void Close() { }
80
81 public SimianInventoryServiceConnector() { }
82 public string Name { get { return "SimianInventoryServiceConnector"; } }
83 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IInventoryService>(this); } }
84 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IInventoryService>(this); } }
85
86 #endregion ISharedRegionModule
87
88 public SimianInventoryServiceConnector(IConfigSource source)
89 {
90 Initialise(source);
91 }
92
93 public void Initialise(IConfigSource source)
94 {
95 if (Simian.IsSimianEnabled(source, "InventoryServices"))
96 {
97 IConfig gridConfig = source.Configs["InventoryService"];
98 if (gridConfig == null)
99 {
100 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
101 throw new Exception("Inventory connector init error");
102 }
103
104 string serviceUrl = gridConfig.GetString("InventoryServerURI");
105 if (String.IsNullOrEmpty(serviceUrl))
106 {
107 m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService");
108 throw new Exception("Inventory connector init error");
109 }
110
111 m_serverUrl = serviceUrl;
112
113 gridConfig = source.Configs["UserAccountService"];
114 if (gridConfig != null)
115 {
116 serviceUrl = gridConfig.GetString("UserAccountServerURI");
117 if (!String.IsNullOrEmpty(serviceUrl))
118 m_userServerUrl = serviceUrl;
119 else
120 m_log.Info("[INVENTORY CONNECTOR]: No Server URI named in section UserAccountService");
121 }
122 else
123 {
124 m_log.Warn("[INVENTORY CONNECTOR]: UserAccountService missing from OpenSim.ini");
125 }
126 }
127 }
128
129 /// <summary>
130 /// Create the entire inventory for a given user
131 /// </summary>
132 /// <param name="user"></param>
133 /// <returns></returns>
134 public bool CreateUserInventory(UUID userID)
135 {
136 NameValueCollection requestArgs = new NameValueCollection
137 {
138 { "RequestMethod", "AddInventory" },
139 { "OwnerID", userID.ToString() }
140 };
141
142 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
143 bool success = response["Success"].AsBoolean();
144
145 if (!success)
146 m_log.Warn("[INVENTORY CONNECTOR]: Inventory creation for " + userID + " failed: " + response["Message"].AsString());
147
148 return success;
149 }
150
151 /// <summary>
152 /// Gets the skeleton of the inventory -- folders only
153 /// </summary>
154 /// <param name="userID"></param>
155 /// <returns></returns>
156 public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
157 {
158 NameValueCollection requestArgs = new NameValueCollection
159 {
160 { "RequestMethod", "GetInventoryNode" },
161 { "ItemID", userID.ToString() },
162 { "OwnerID", userID.ToString() },
163 { "IncludeFolders", "1" },
164 { "IncludeItems", "0" },
165 { "ChildrenOnly", "0" }
166 };
167
168 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
169 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
170 {
171 OSDArray items = (OSDArray)response["Items"];
172 return GetFoldersFromResponse(items, userID, true);
173 }
174 else
175 {
176 m_log.Warn("[INVENTORY CONNECTOR]: Failed to retrieve inventory skeleton for " + userID + ": " +
177 response["Message"].AsString());
178 return new List<InventoryFolderBase>(0);
179 }
180 }
181
182 /// <summary>
183 /// Synchronous inventory fetch.
184 /// </summary>
185 /// <param name="userID"></param>
186 /// <returns></returns>
187 [Obsolete]
188 public InventoryCollection GetUserInventory(UUID userID)
189 {
190 m_log.Error("[INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID);
191
192 InventoryCollection inventory = new InventoryCollection();
193 inventory.UserID = userID;
194 inventory.Folders = new List<InventoryFolderBase>();
195 inventory.Items = new List<InventoryItemBase>();
196
197 return inventory;
198 }
199
200 /// <summary>
201 /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the
202 /// inventory has been received
203 /// </summary>
204 /// <param name="userID"></param>
205 /// <param name="callback"></param>
206 [Obsolete]
207 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
208 {
209 m_log.Error("[INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID);
210 callback(new List<InventoryFolderImpl>(0), new List<InventoryItemBase>(0));
211 }
212
213 /// <summary>
214 /// Retrieve the root inventory folder for the given user.
215 /// </summary>
216 /// <param name="userID"></param>
217 /// <returns>null if no root folder was found</returns>
218 public InventoryFolderBase GetRootFolder(UUID userID)
219 {
220 NameValueCollection requestArgs = new NameValueCollection
221 {
222 { "RequestMethod", "GetInventoryNode" },
223 { "ItemID", userID.ToString() },
224 { "OwnerID", userID.ToString() },
225 { "IncludeFolders", "1" },
226 { "IncludeItems", "0" },
227 { "ChildrenOnly", "1" }
228 };
229
230 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
231 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
232 {
233 OSDArray items = (OSDArray)response["Items"];
234 List<InventoryFolderBase> folders = GetFoldersFromResponse(items, userID, true);
235
236 if (folders.Count > 0)
237 return folders[0];
238 }
239
240 return null;
241 }
242
243 /// <summary>
244 /// Gets the user folder for the given folder-type
245 /// </summary>
246 /// <param name="userID"></param>
247 /// <param name="type"></param>
248 /// <returns></returns>
249 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
250 {
251 string contentType = SLUtil.SLAssetTypeToContentType((int)type);
252
253 NameValueCollection requestArgs = new NameValueCollection
254 {
255 { "RequestMethod", "GetFolderForType" },
256 { "ContentType", contentType },
257 { "OwnerID", userID.ToString() }
258 };
259
260 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
261 if (response["Success"].AsBoolean() && response["Folder"] is OSDMap)
262 {
263 OSDMap folder = (OSDMap)response["Folder"];
264
265 return new InventoryFolderBase(
266 folder["ID"].AsUUID(),
267 folder["Name"].AsString(),
268 folder["OwnerID"].AsUUID(),
269 (short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()),
270 folder["ParentID"].AsUUID(),
271 (ushort)folder["Version"].AsInteger()
272 );
273 }
274 else
275 {
276 m_log.Warn("[INVENTORY CONNECTOR]: Default folder not found for content type " + contentType);
277 return GetRootFolder(userID);
278 }
279 }
280
281 /// <summary>
282 /// Get an item, given by its UUID
283 /// </summary>
284 /// <param name="item"></param>
285 /// <returns></returns>
286 public InventoryItemBase GetItem(InventoryItemBase item)
287 {
288 NameValueCollection requestArgs = new NameValueCollection
289 {
290 { "RequestMethod", "GetInventoryNode" },
291 { "ItemID", item.ID.ToString() },
292 { "OwnerID", item.Owner.ToString() },
293 { "IncludeFolders", "1" },
294 { "IncludeItems", "1" },
295 { "ChildrenOnly", "1" }
296 };
297
298 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
299 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
300 {
301 List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]);
302 if (items.Count > 0)
303 {
304 // The requested item should be the first in this list, but loop through
305 // and sanity check just in case
306 for (int i = 0; i < items.Count; i++)
307 {
308 if (items[i].ID == item.ID)
309 return items[i];
310 }
311 }
312 }
313
314 m_log.Warn("[INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found");
315 return null;
316 }
317
318 /// <summary>
319 /// Get a folder, given by its UUID
320 /// </summary>
321 /// <param name="folder"></param>
322 /// <returns></returns>
323 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
324 {
325 NameValueCollection requestArgs = new NameValueCollection
326 {
327 { "RequestMethod", "GetInventoryNode" },
328 { "ItemID", folder.ID.ToString() },
329 { "OwnerID", folder.Owner.ToString() },
330 { "IncludeFolders", "1" },
331 { "IncludeItems", "0" },
332 { "ChildrenOnly", "1" }
333 };
334
335 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
336 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
337 {
338 OSDArray items = (OSDArray)response["Items"];
339 List<InventoryFolderBase> folders = GetFoldersFromResponse(items, folder.ID, true);
340
341 if (folders.Count > 0)
342 return folders[0];
343 }
344
345 return null;
346 }
347
348 /// <summary>
349 /// Gets everything (folders and items) inside a folder
350 /// </summary>
351 /// <param name="userID"></param>
352 /// <param name="folderID"></param>
353 /// <returns></returns>
354 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
355 {
356 InventoryCollection inventory = new InventoryCollection();
357 inventory.UserID = userID;
358
359 NameValueCollection requestArgs = new NameValueCollection
360 {
361 { "RequestMethod", "GetInventoryNode" },
362 { "ItemID", folderID.ToString() },
363 { "OwnerID", userID.ToString() },
364 { "IncludeFolders", "1" },
365 { "IncludeItems", "1" },
366 { "ChildrenOnly", "1" }
367 };
368
369 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
370 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
371 {
372 OSDArray items = (OSDArray)response["Items"];
373
374 inventory.Folders = GetFoldersFromResponse(items, folderID, false);
375 inventory.Items = GetItemsFromResponse(items);
376 }
377 else
378 {
379 m_log.Warn("[INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " +
380 response["Message"].AsString());
381 inventory.Folders = new List<InventoryFolderBase>(0);
382 inventory.Items = new List<InventoryItemBase>(0);
383 }
384
385 return inventory;
386 }
387
388 /// <summary>
389 /// Gets the items inside a folder
390 /// </summary>
391 /// <param name="userID"></param>
392 /// <param name="folderID"></param>
393 /// <returns></returns>
394 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
395 {
396 InventoryCollection inventory = new InventoryCollection();
397 inventory.UserID = userID;
398
399 NameValueCollection requestArgs = new NameValueCollection
400 {
401 { "RequestMethod", "GetInventoryNode" },
402 { "ItemID", folderID.ToString() },
403 { "OwnerID", userID.ToString() },
404 { "IncludeFolders", "0" },
405 { "IncludeItems", "1" },
406 { "ChildrenOnly", "1" }
407 };
408
409 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
410 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
411 {
412 OSDArray items = (OSDArray)response["Items"];
413 return GetItemsFromResponse(items);
414 }
415 else
416 {
417 m_log.Warn("[INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " +
418 response["Message"].AsString());
419 return new List<InventoryItemBase>(0);
420 }
421 }
422
423 /// <summary>
424 /// Add a new folder to the user's inventory
425 /// </summary>
426 /// <param name="folder"></param>
427 /// <returns>true if the folder was successfully added</returns>
428 public bool AddFolder(InventoryFolderBase folder)
429 {
430 NameValueCollection requestArgs = new NameValueCollection
431 {
432 { "RequestMethod", "AddInventoryFolder" },
433 { "FolderID", folder.ID.ToString() },
434 { "ParentID", folder.ParentID.ToString() },
435 { "OwnerID", folder.Owner.ToString() },
436 { "Name", folder.Name },
437 { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) }
438 };
439
440 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
441 bool success = response["Success"].AsBoolean();
442
443 if (!success)
444 {
445 m_log.Warn("[INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " +
446 response["Message"].AsString());
447 }
448
449 return success;
450 }
451
452 /// <summary>
453 /// Update a folder in the user's inventory
454 /// </summary>
455 /// <param name="folder"></param>
456 /// <returns>true if the folder was successfully updated</returns>
457 public bool UpdateFolder(InventoryFolderBase folder)
458 {
459 return AddFolder(folder);
460 }
461
462 /// <summary>
463 /// Move an inventory folder to a new location
464 /// </summary>
465 /// <param name="folder">A folder containing the details of the new location</param>
466 /// <returns>true if the folder was successfully moved</returns>
467 public bool MoveFolder(InventoryFolderBase folder)
468 {
469 return AddFolder(folder);
470 }
471
472 /// <summary>
473 /// Delete an item from the user's inventory
474 /// </summary>
475 /// <param name="item"></param>
476 /// <returns>true if the item was successfully deleted</returns>
477 //bool DeleteItem(InventoryItemBase item);
478 public bool DeleteFolders(UUID userID, List<UUID> folderIDs)
479 {
480 return DeleteItems(userID, folderIDs);
481 }
482
483 /// <summary>
484 /// Delete an item from the user's inventory
485 /// </summary>
486 /// <param name="item"></param>
487 /// <returns>true if the item was successfully deleted</returns>
488 public bool DeleteItems(UUID userID, List<UUID> itemIDs)
489 {
490 // TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes
491 bool allSuccess = true;
492
493 for (int i = 0; i < itemIDs.Count; i++)
494 {
495 UUID itemID = itemIDs[i];
496
497 NameValueCollection requestArgs = new NameValueCollection
498 {
499 { "RequestMethod", "RemoveInventoryNode" },
500 { "OwnerID", userID.ToString() },
501 { "ItemID", itemID.ToString() }
502 };
503
504 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
505 bool success = response["Success"].AsBoolean();
506
507 if (!success)
508 {
509 m_log.Warn("[INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " +
510 response["Message"].AsString());
511 allSuccess = false;
512 }
513 }
514
515 return allSuccess;
516 }
517
518 /// <summary>
519 /// Purge an inventory folder of all its items and subfolders.
520 /// </summary>
521 /// <param name="folder"></param>
522 /// <returns>true if the folder was successfully purged</returns>
523 public bool PurgeFolder(InventoryFolderBase folder)
524 {
525 NameValueCollection requestArgs = new NameValueCollection
526 {
527 { "RequestMethod", "PurgeInventoryFolder" },
528 { "OwnerID", folder.Owner.ToString() },
529 { "FolderID", folder.ID.ToString() }
530 };
531
532 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
533 bool success = response["Success"].AsBoolean();
534
535 if (!success)
536 {
537 m_log.Warn("[INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " +
538 response["Message"].AsString());
539 }
540
541 return success;
542 }
543
544 /// <summary>
545 /// Add a new item to the user's inventory
546 /// </summary>
547 /// <param name="item"></param>
548 /// <returns>true if the item was successfully added</returns>
549 public bool AddItem(InventoryItemBase item)
550 {
551 // A folder of UUID.Zero means we need to find the most appropriate home for this item
552 if (item.Folder == UUID.Zero)
553 {
554 InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType);
555 if (folder != null && folder.ID != UUID.Zero)
556 item.Folder = folder.ID;
557 else
558 item.Folder = item.Owner; // Root folder
559 }
560
561 if ((AssetType)item.AssetType == AssetType.Gesture)
562 UpdateGesture(item.Owner, item.ID, item.Flags == 1);
563
564 if (item.BasePermissions == 0)
565 m_log.WarnFormat("[INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID);
566
567 OSDMap permissions = new OSDMap
568 {
569 { "BaseMask", OSD.FromInteger(item.BasePermissions) },
570 { "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) },
571 { "GroupMask", OSD.FromInteger(item.GroupPermissions) },
572 { "NextOwnerMask", OSD.FromInteger(item.NextPermissions) },
573 { "OwnerMask", OSD.FromInteger(item.CurrentPermissions) }
574 };
575
576 OSDMap extraData = new OSDMap()
577 {
578 { "Flags", OSD.FromInteger(item.Flags) },
579 { "GroupID", OSD.FromUUID(item.GroupID) },
580 { "GroupOwned", OSD.FromBoolean(item.GroupOwned) },
581 { "SalePrice", OSD.FromInteger(item.SalePrice) },
582 { "SaleType", OSD.FromInteger(item.SaleType) },
583 { "Permissions", permissions }
584 };
585
586 NameValueCollection requestArgs = new NameValueCollection
587 {
588 { "RequestMethod", "AddInventoryItem" },
589 { "ItemID", item.ID.ToString() },
590 { "AssetID", item.AssetID.ToString() },
591 { "ParentID", item.Folder.ToString() },
592 { "OwnerID", item.Owner.ToString() },
593 { "Name", item.Name },
594 { "Description", item.Description },
595 { "CreatorID", item.CreatorId },
596 { "ExtraData", OSDParser.SerializeJsonString(extraData) }
597 };
598
599 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
600 bool success = response["Success"].AsBoolean();
601
602 if (!success)
603 {
604 m_log.Warn("[INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " +
605 response["Message"].AsString());
606 }
607
608 return success;
609 }
610
611 /// <summary>
612 /// Update an item in the user's inventory
613 /// </summary>
614 /// <param name="item"></param>
615 /// <returns>true if the item was successfully updated</returns>
616 public bool UpdateItem(InventoryItemBase item)
617 {
618 if (item.AssetID != UUID.Zero)
619 {
620 return AddItem(item);
621 }
622 else
623 {
624 // This is actually a folder update
625 InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0);
626 return UpdateFolder(folder);
627 }
628 }
629
630 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
631 {
632 bool success = true;
633
634 while (items.Count > 0)
635 {
636 List<InventoryItemBase> currentItems = new List<InventoryItemBase>();
637 UUID destFolderID = items[0].Folder;
638
639 // Find all of the items being moved to the current destination folder
640 for (int i = 0; i < items.Count; i++)
641 {
642 InventoryItemBase item = items[i];
643 if (item.Folder == destFolderID)
644 currentItems.Add(item);
645 }
646
647 // Do the inventory move for the current items
648 success &= MoveItems(ownerID, items, destFolderID);
649
650 // Remove the processed items from the list
651 for (int i = 0; i < currentItems.Count; i++)
652 items.Remove(currentItems[i]);
653 }
654
655 return success;
656 }
657
658 /// <summary>
659 /// Does the given user have an inventory structure?
660 /// </summary>
661 /// <param name="userID"></param>
662 /// <returns></returns>
663 public bool HasInventoryForUser(UUID userID)
664 {
665 return GetRootFolder(userID) != null;
666 }
667
668 /// <summary>
669 /// Get the active gestures of the agent.
670 /// </summary>
671 /// <param name="userID"></param>
672 /// <returns></returns>
673 public List<InventoryItemBase> GetActiveGestures(UUID userID)
674 {
675 OSDArray items = FetchGestures(userID);
676
677 string[] itemIDs = new string[items.Count];
678 for (int i = 0; i < items.Count; i++)
679 itemIDs[i] = items[i].AsUUID().ToString();
680
681 NameValueCollection requestArgs = new NameValueCollection
682 {
683 { "RequestMethod", "GetInventoryNodes" },
684 { "OwnerID", userID.ToString() },
685 { "Items", String.Join(",", itemIDs) }
686 };
687
688 // FIXME: Implement this in SimianGrid
689 return new List<InventoryItemBase>(0);
690 }
691
692 /// <summary>
693 /// Get the union of permissions of all inventory items
694 /// that hold the given assetID.
695 /// </summary>
696 /// <param name="userID"></param>
697 /// <param name="assetID"></param>
698 /// <returns>The permissions or 0 if no such asset is found in
699 /// the user's inventory</returns>
700 public int GetAssetPermissions(UUID userID, UUID assetID)
701 {
702 NameValueCollection requestArgs = new NameValueCollection
703 {
704 { "RequestMethod", "GetInventoryNodes" },
705 { "OwnerID", userID.ToString() },
706 { "AssetID", assetID.ToString() }
707 };
708
709 // FIXME: Implement this in SimianGrid
710 return (int)PermissionMask.All;
711 }
712
713 private List<InventoryFolderBase> GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder)
714 {
715 List<InventoryFolderBase> invFolders = new List<InventoryFolderBase>(items.Count);
716
717 for (int i = 0; i < items.Count; i++)
718 {
719 OSDMap item = items[i] as OSDMap;
720
721 if (item != null && item["Type"].AsString() == "Folder")
722 {
723 UUID folderID = item["ID"].AsUUID();
724
725 if (folderID == baseFolder && !includeBaseFolder)
726 continue;
727
728 invFolders.Add(new InventoryFolderBase(
729 folderID,
730 item["Name"].AsString(),
731 item["OwnerID"].AsUUID(),
732 (short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()),
733 item["ParentID"].AsUUID(),
734 (ushort)item["Version"].AsInteger()
735 ));
736 }
737 }
738
739 return invFolders;
740 }
741
742 private List<InventoryItemBase> GetItemsFromResponse(OSDArray items)
743 {
744 List<InventoryItemBase> invItems = new List<InventoryItemBase>(items.Count);
745
746 for (int i = 0; i < items.Count; i++)
747 {
748 OSDMap item = items[i] as OSDMap;
749
750 if (item != null && item["Type"].AsString() == "Item")
751 {
752 InventoryItemBase invItem = new InventoryItemBase();
753
754 invItem.AssetID = item["AssetID"].AsUUID();
755 invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString());
756 invItem.CreationDate = item["CreationDate"].AsInteger();
757 invItem.CreatorId = item["CreatorID"].AsString();
758 invItem.CreatorIdAsUuid = item["CreatorID"].AsUUID();
759 invItem.Description = item["Description"].AsString();
760 invItem.Folder = item["ParentID"].AsUUID();
761 invItem.ID = item["ID"].AsUUID();
762 invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString());
763 invItem.Name = item["Name"].AsString();
764 invItem.Owner = item["OwnerID"].AsUUID();
765
766 OSDMap extraData = item["ExtraData"] as OSDMap;
767 if (extraData != null && extraData.Count > 0)
768 {
769 invItem.Flags = extraData["Flags"].AsUInteger();
770 invItem.GroupID = extraData["GroupID"].AsUUID();
771 invItem.GroupOwned = extraData["GroupOwned"].AsBoolean();
772 invItem.SalePrice = extraData["SalePrice"].AsInteger();
773 invItem.SaleType = (byte)extraData["SaleType"].AsInteger();
774
775 OSDMap perms = extraData["Permissions"] as OSDMap;
776 if (perms != null)
777 {
778 invItem.BasePermissions = perms["BaseMask"].AsUInteger();
779 invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger();
780 invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger();
781 invItem.GroupPermissions = perms["GroupMask"].AsUInteger();
782 invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger();
783 }
784 }
785
786 if (invItem.BasePermissions == 0)
787 {
788 m_log.InfoFormat("[INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})",
789 invItem.Name, invItem.ID);
790 invItem.BasePermissions = (uint)PermissionMask.All;
791 invItem.CurrentPermissions = (uint)PermissionMask.All;
792 invItem.EveryOnePermissions = (uint)PermissionMask.All;
793 invItem.GroupPermissions = (uint)PermissionMask.All;
794 invItem.NextPermissions = (uint)PermissionMask.All;
795 }
796
797 invItems.Add(invItem);
798 }
799 }
800
801 return invItems;
802 }
803
804 private bool MoveItems(UUID ownerID, List<InventoryItemBase> items, UUID destFolderID)
805 {
806 string[] itemIDs = new string[items.Count];
807 for (int i = 0; i < items.Count; i++)
808 itemIDs[i] = items[i].ID.ToString();
809
810 NameValueCollection requestArgs = new NameValueCollection
811 {
812 { "RequestMethod", "MoveInventoryNodes" },
813 { "OwnerID", ownerID.ToString() },
814 { "FolderID", destFolderID.ToString() },
815 { "Items", String.Join(",", itemIDs) }
816 };
817
818 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
819 bool success = response["Success"].AsBoolean();
820
821 if (!success)
822 {
823 m_log.Warn("[INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " +
824 destFolderID + ": " + response["Message"].AsString());
825 }
826
827 return success;
828 }
829
830 private void UpdateGesture(UUID userID, UUID itemID, bool enabled)
831 {
832 OSDArray gestures = FetchGestures(userID);
833 OSDArray newGestures = new OSDArray();
834
835 for (int i = 0; i < gestures.Count; i++)
836 {
837 UUID gesture = gestures[i].AsUUID();
838 if (gesture != itemID)
839 newGestures.Add(OSD.FromUUID(gesture));
840 }
841
842 if (enabled)
843 newGestures.Add(OSD.FromUUID(itemID));
844
845 SaveGestures(userID, newGestures);
846 }
847
848 private OSDArray FetchGestures(UUID userID)
849 {
850 NameValueCollection requestArgs = new NameValueCollection
851 {
852 { "RequestMethod", "GetUser" },
853 { "UserID", userID.ToString() }
854 };
855
856 OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs);
857 if (response["Success"].AsBoolean())
858 {
859 OSDMap user = response["User"] as OSDMap;
860 if (user != null && response.ContainsKey("Gestures"))
861 {
862 OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString());
863 if (gestures != null && gestures is OSDArray)
864 return (OSDArray)gestures;
865 else
866 m_log.Error("[INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID);
867 }
868 }
869 else
870 {
871 m_log.Warn("[INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " +
872 response["Message"].AsString());
873 }
874
875 return new OSDArray();
876 }
877
878 private void SaveGestures(UUID userID, OSDArray gestures)
879 {
880 NameValueCollection requestArgs = new NameValueCollection
881 {
882 { "RequestMethod", "AddUserData" },
883 { "UserID", userID.ToString() },
884 { "Gestures", OSDParser.SerializeJsonString(gestures) }
885 };
886
887 OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs);
888 if (!response["Success"].AsBoolean())
889 {
890 m_log.Warn("[INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " +
891 response["Message"].AsString());
892 }
893 }
894 }
895}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
new file mode 100644
index 0000000..1b5edf4
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
@@ -0,0 +1,511 @@
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.Collections.Specialized;
31using System.Net;
32using System.Reflection;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenSim.Framework;
37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Server.Base;
42using OpenMetaverse;
43using OpenMetaverse.StructuredData;
44
45using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
46
47namespace OpenSim.Services.Connectors.SimianGrid
48{
49 /// <summary>
50 /// Connects avatar presence information (for tracking current location and
51 /// message routing) to the SimianGrid backend
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
54 public class SimianPresenceServiceConnector : IPresenceService, ISharedRegionModule
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(
58 MethodBase.GetCurrentMethod().DeclaringType);
59
60 private string m_serverUrl = String.Empty;
61
62 #region ISharedRegionModule
63
64 public Type ReplaceableInterface { get { return null; } }
65 public void RegionLoaded(Scene scene) { }
66 public void PostInitialise() { }
67 public void Close() { }
68
69 public SimianPresenceServiceConnector() { }
70 public string Name { get { return "SimianPresenceServiceConnector"; } }
71 public void AddRegion(Scene scene)
72 {
73 if (!String.IsNullOrEmpty(m_serverUrl))
74 {
75 scene.RegisterModuleInterface<IPresenceService>(this);
76
77 scene.EventManager.OnMakeRootAgent += MakeRootAgentHandler;
78 scene.EventManager.OnNewClient += NewClientHandler;
79 scene.EventManager.OnSignificantClientMovement += SignificantClientMovementHandler;
80
81 LogoutRegionAgents(scene.RegionInfo.RegionID);
82 }
83 }
84 public void RemoveRegion(Scene scene)
85 {
86 if (!String.IsNullOrEmpty(m_serverUrl))
87 {
88 scene.UnregisterModuleInterface<IPresenceService>(this);
89
90 scene.EventManager.OnMakeRootAgent -= MakeRootAgentHandler;
91 scene.EventManager.OnNewClient -= NewClientHandler;
92 scene.EventManager.OnSignificantClientMovement -= SignificantClientMovementHandler;
93
94 LogoutRegionAgents(scene.RegionInfo.RegionID);
95 }
96 }
97
98 #endregion ISharedRegionModule
99
100 public SimianPresenceServiceConnector(IConfigSource source)
101 {
102 Initialise(source);
103 }
104
105 public void Initialise(IConfigSource source)
106 {
107 if (Simian.IsSimianEnabled(source, "PresenceServices"))
108 {
109 IConfig gridConfig = source.Configs["PresenceService"];
110 if (gridConfig == null)
111 {
112 m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini");
113 throw new Exception("Presence connector init error");
114 }
115
116 string serviceUrl = gridConfig.GetString("PresenceServerURI");
117 if (String.IsNullOrEmpty(serviceUrl))
118 {
119 m_log.Error("[PRESENCE CONNECTOR]: No PresenceServerURI in section PresenceService");
120 throw new Exception("Presence connector init error");
121 }
122
123 m_serverUrl = serviceUrl;
124 }
125 }
126
127 #region IPresenceService
128
129 public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
130 {
131 m_log.ErrorFormat("[PRESENCE CONNECTOR]: Login requested, UserID={0}, SessionID={1}, SecureSessionID={2}",
132 userID, sessionID, secureSessionID);
133
134 NameValueCollection requestArgs = new NameValueCollection
135 {
136 { "RequestMethod", "AddSession" },
137 { "UserID", userID.ToString() }
138 };
139 if (sessionID != UUID.Zero)
140 {
141 requestArgs["SessionID"] = sessionID.ToString();
142 requestArgs["SecureSessionID"] = secureSessionID.ToString();
143 }
144
145 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
146 bool success = response["Success"].AsBoolean();
147
148 if (!success)
149 m_log.Warn("[PRESENCE CONNECTOR]: Failed to login agent " + userID + ": " + response["Message"].AsString());
150
151 return success;
152 }
153
154 public bool LogoutAgent(UUID sessionID, Vector3 position, Vector3 lookAt)
155 {
156 m_log.InfoFormat("[PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID);
157
158 NameValueCollection requestArgs = new NameValueCollection
159 {
160 { "RequestMethod", "RemoveSession" },
161 { "SessionID", sessionID.ToString() }
162 };
163
164 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
165 bool success = response["Success"].AsBoolean();
166
167 if (!success)
168 m_log.Warn("[PRESENCE CONNECTOR]: Failed to logout agent with sessionID " + sessionID + ": " + response["Message"].AsString());
169
170 return success;
171 }
172
173 public bool LogoutRegionAgents(UUID regionID)
174 {
175 m_log.InfoFormat("[PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID);
176
177 NameValueCollection requestArgs = new NameValueCollection
178 {
179 { "RequestMethod", "RemoveSessions" },
180 { "SceneID", regionID.ToString() }
181 };
182
183 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
184 bool success = response["Success"].AsBoolean();
185
186 if (!success)
187 m_log.Warn("[PRESENCE CONNECTOR]: Failed to logout agents from region " + regionID + ": " + response["Message"].AsString());
188
189 return success;
190 }
191
192 public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
193 {
194 //m_log.DebugFormat("[PRESENCE CONNECTOR]: Updating session data for agent with sessionID " + sessionID);
195
196 NameValueCollection requestArgs = new NameValueCollection
197 {
198 { "RequestMethod", "UpdateSession" },
199 { "SessionID", sessionID.ToString() },
200 { "SceneID", regionID.ToString() },
201 { "ScenePosition", position.ToString() },
202 { "SceneLookAt", lookAt.ToString() }
203 };
204
205 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
206 bool success = response["Success"].AsBoolean();
207
208 if (!success)
209 m_log.Warn("[PRESENCE CONNECTOR]: Failed to update agent session " + sessionID + ": " + response["Message"].AsString());
210
211 return success;
212 }
213
214 public PresenceInfo GetAgent(UUID sessionID)
215 {
216 m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting session data for agent with sessionID " + sessionID);
217
218 NameValueCollection requestArgs = new NameValueCollection
219 {
220 { "RequestMethod", "GetSession" },
221 { "SessionID", sessionID.ToString() }
222 };
223
224 OSDMap sessionResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
225 if (sessionResponse["Success"].AsBoolean())
226 {
227 UUID userID = sessionResponse["UserID"].AsUUID();
228 m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting user data for " + userID);
229
230 requestArgs = new NameValueCollection
231 {
232 { "RequestMethod", "GetUser" },
233 { "UserID", userID.ToString() }
234 };
235
236 OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
237 if (userResponse["Success"].AsBoolean())
238 return ResponseToPresenceInfo(sessionResponse, userResponse);
239 else
240 m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
241 }
242 else
243 {
244 m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve session " + sessionID + ": " + sessionResponse["Message"].AsString());
245 }
246
247 return null;
248 }
249
250 public PresenceInfo[] GetAgents(string[] userIDs)
251 {
252 List<PresenceInfo> presences = new List<PresenceInfo>(userIDs.Length);
253
254 for (int i = 0; i < userIDs.Length; i++)
255 {
256 UUID userID;
257 if (UUID.TryParse(userIDs[i], out userID) && userID != UUID.Zero)
258 presences.AddRange(GetSessions(userID));
259 }
260
261 return presences.ToArray();
262 }
263
264 public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
265 {
266 m_log.DebugFormat("[PRESENCE CONNECTOR]: Setting home location for user " + userID);
267
268 NameValueCollection requestArgs = new NameValueCollection
269 {
270 { "RequestMethod", "AddUserData" },
271 { "UserID", userID.ToString() },
272 { "HomeLocation", SerializeLocation(regionID, position, lookAt) }
273 };
274
275 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
276 bool success = response["Success"].AsBoolean();
277
278 if (!success)
279 m_log.Warn("[PRESENCE CONNECTOR]: Failed to set home location for " + userID + ": " + response["Message"].AsString());
280
281 return success;
282 }
283
284 #endregion IPresenceService
285
286 #region Presence Detection
287
288 private void MakeRootAgentHandler(ScenePresence sp)
289 {
290 m_log.DebugFormat("[PRESENCE DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
291
292 ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
293 SetLastLocation(sp.UUID, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
294 }
295
296 private void NewClientHandler(IClientAPI client)
297 {
298 client.OnConnectionClosed += LogoutHandler;
299 }
300
301 private void SignificantClientMovementHandler(IClientAPI client)
302 {
303 ScenePresence sp;
304 if (client.Scene is Scene && ((Scene)client.Scene).TryGetAvatar(client.AgentId, out sp))
305 ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
306 }
307
308 private void LogoutHandler(IClientAPI client)
309 {
310 if (client.IsLoggingOut)
311 {
312 client.OnConnectionClosed -= LogoutHandler;
313
314 object obj;
315 if (client.Scene.TryGetAvatar(client.AgentId, out obj) && obj is ScenePresence)
316 {
317 // The avatar is still in the scene, we can get the exact logout position
318 ScenePresence sp = (ScenePresence)obj;
319 SetLastLocation(client.AgentId, client.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
320 }
321 else
322 {
323 // The avatar was already removed from the scene, store LastLocation using the most recent session data
324 m_log.Warn("[PRESENCE]: " + client.Name + " has already been removed from the scene, storing approximate LastLocation");
325 SetLastLocation(client.SessionId);
326 }
327
328 LogoutAgent(client.SessionId, Vector3.Zero, Vector3.UnitX);
329 }
330 }
331
332 #endregion Presence Detection
333
334 #region Helpers
335
336 private OSDMap GetUserData(UUID userID)
337 {
338 m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting user data for " + userID);
339
340 NameValueCollection requestArgs = new NameValueCollection
341 {
342 { "RequestMethod", "GetUser" },
343 { "UserID", userID.ToString() }
344 };
345
346 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
347 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
348 return response;
349 else
350 m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + response["Message"].AsString());
351
352 return null;
353 }
354
355 private OSDMap GetSessionData(UUID sessionID)
356 {
357 m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting session data for session " + sessionID);
358
359 NameValueCollection requestArgs = new NameValueCollection
360 {
361 { "RequestMethod", "GetSession" },
362 { "SessionID", sessionID.ToString() }
363 };
364
365 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
366 if (response["Success"].AsBoolean())
367 return response;
368 else
369 m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve session data for session " + sessionID);
370
371 return null;
372 }
373
374 private List<PresenceInfo> GetSessions(UUID userID)
375 {
376 List<PresenceInfo> presences = new List<PresenceInfo>(1);
377
378 OSDMap userResponse = GetUserData(userID);
379 if (userResponse != null)
380 {
381 m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting sessions for " + userID);
382
383 NameValueCollection requestArgs = new NameValueCollection
384 {
385 { "RequestMethod", "GetSession" },
386 { "UserID", userID.ToString() }
387 };
388
389 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
390 if (response["Success"].AsBoolean())
391 {
392 PresenceInfo presence = ResponseToPresenceInfo(response, userResponse);
393 if (presence != null)
394 presences.Add(presence);
395 }
396 else
397 {
398 m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve sessions for " + userID + ": " + response["Message"].AsString());
399 }
400 }
401
402 return presences;
403 }
404
405 /// <summary>
406 /// Fetch the last known avatar location with GetSession and persist it
407 /// as user data with AddUserData
408 /// </summary>
409 private bool SetLastLocation(UUID sessionID)
410 {
411 NameValueCollection requestArgs = new NameValueCollection
412 {
413 { "RequestMethod", "GetSession" },
414 { "SessionID", sessionID.ToString() }
415 };
416
417 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
418 bool success = response["Success"].AsBoolean();
419
420 if (success)
421 {
422 UUID userID = response["UserID"].AsUUID();
423 UUID sceneID = response["SceneID"].AsUUID();
424 Vector3 position = response["ScenePosition"].AsVector3();
425 Vector3 lookAt = response["SceneLookAt"].AsVector3();
426
427 return SetLastLocation(userID, sceneID, position, lookAt);
428 }
429 else
430 {
431 m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve presence information for session " + sessionID +
432 " while saving last location: " + response["Message"].AsString());
433 }
434
435 return success;
436 }
437
438 private bool SetLastLocation(UUID userID, UUID sceneID, Vector3 position, Vector3 lookAt)
439 {
440 NameValueCollection requestArgs = new NameValueCollection
441 {
442 { "RequestMethod", "AddUserData" },
443 { "UserID", userID.ToString() },
444 { "LastLocation", SerializeLocation(sceneID, position, lookAt) }
445 };
446
447 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
448 bool success = response["Success"].AsBoolean();
449
450 if (!success)
451 m_log.Warn("[PRESENCE CONNECTOR]: Failed to set last location for " + userID + ": " + response["Message"].AsString());
452
453 return success;
454 }
455
456 private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse)
457 {
458 if (sessionResponse == null)
459 return null;
460
461 PresenceInfo info = new PresenceInfo();
462
463 info.Online = true;
464 info.UserID = sessionResponse["UserID"].AsUUID().ToString();
465 info.RegionID = sessionResponse["SceneID"].AsUUID();
466 info.Position = sessionResponse["ScenePosition"].AsVector3();
467 info.LookAt = sessionResponse["SceneLookAt"].AsVector3();
468
469 if (userResponse != null && userResponse["User"] is OSDMap)
470 {
471 OSDMap user = (OSDMap)userResponse["User"];
472
473 info.Login = user["LastLoginDate"].AsDate();
474 info.Logout = user["LastLogoutDate"].AsDate();
475 DeserializeLocation(user["HomeLocation"].AsString(), out info.HomeRegionID, out info.HomePosition, out info.HomeLookAt);
476 }
477
478 return info;
479 }
480
481 private string SerializeLocation(UUID regionID, Vector3 position, Vector3 lookAt)
482 {
483 return "{" + String.Format("\"SceneID\":\"{0}\",\"Position\":\"{1}\",\"LookAt\":\"{2}\"", regionID, position, lookAt) + "}";
484 }
485
486 private bool DeserializeLocation(string location, out UUID regionID, out Vector3 position, out Vector3 lookAt)
487 {
488 OSDMap map = null;
489
490 try { map = OSDParser.DeserializeJson(location) as OSDMap; }
491 catch { }
492
493 if (map != null)
494 {
495 regionID = map["SceneID"].AsUUID();
496 if (Vector3.TryParse(map["Position"].AsString(), out position) &&
497 Vector3.TryParse(map["LookAt"].AsString(), out lookAt))
498 {
499 return true;
500 }
501 }
502
503 regionID = UUID.Zero;
504 position = Vector3.Zero;
505 lookAt = Vector3.Zero;
506 return false;
507 }
508
509 #endregion Helpers
510 }
511}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs
new file mode 100644
index 0000000..9c226fb
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs
@@ -0,0 +1,435 @@
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.Collections.Specialized;
31using System.Reflection;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Framework.Client;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces;
42
43namespace OpenSim.Services.Connectors.SimianGrid
44{
45 /// <summary>
46 /// Avatar profile flags
47 /// </summary>
48 [Flags]
49 public enum ProfileFlags : uint
50 {
51 AllowPublish = 1,
52 MaturePublish = 2,
53 Identified = 4,
54 Transacted = 8,
55 Online = 16
56 }
57
58 /// <summary>
59 /// Connects avatar profile and classified queries to the SimianGrid
60 /// backend
61 /// </summary>
62 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
63 public class SimianProfiles : INonSharedRegionModule
64 {
65 private static readonly ILog m_log =
66 LogManager.GetLogger(
67 MethodBase.GetCurrentMethod().DeclaringType);
68
69 private string m_serverUrl = String.Empty;
70
71 #region INonSharedRegionModule
72
73 public Type ReplaceableInterface { get { return null; } }
74 public void RegionLoaded(Scene scene) { }
75 public void Close() { }
76
77 public SimianProfiles() { }
78 public string Name { get { return "SimianProfiles"; } }
79 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { CheckEstateManager(scene); scene.EventManager.OnClientConnect += ClientConnectHandler; } }
80 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.EventManager.OnClientConnect -= ClientConnectHandler; } }
81
82 #endregion INonSharedRegionModule
83
84 public SimianProfiles(IConfigSource source)
85 {
86 Initialise(source);
87 }
88
89 public void Initialise(IConfigSource source)
90 {
91 if (Simian.IsSimianEnabled(source, "UserAccountServices"))
92 {
93 IConfig gridConfig = source.Configs["UserAccountService"];
94 if (gridConfig == null)
95 {
96 m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini");
97 throw new Exception("Profiles init error");
98 }
99
100 string serviceUrl = gridConfig.GetString("UserAccountServerURI");
101 if (String.IsNullOrEmpty(serviceUrl))
102 {
103 m_log.Error("[PROFILES]: No UserAccountServerURI in section UserAccountService");
104 throw new Exception("Profiles init error");
105 }
106
107 if (!serviceUrl.EndsWith("/"))
108 serviceUrl = serviceUrl + '/';
109
110 m_serverUrl = serviceUrl;
111 }
112 }
113
114 private void ClientConnectHandler(IClientCore clientCore)
115 {
116 if (clientCore is IClientAPI)
117 {
118 IClientAPI client = (IClientAPI)clientCore;
119
120 // Classifieds
121 client.AddGenericPacketHandler("avatarclassifiedsrequest", AvatarClassifiedsRequestHandler);
122 client.OnClassifiedInfoRequest += ClassifiedInfoRequestHandler;
123 client.OnClassifiedInfoUpdate += ClassifiedInfoUpdateHandler;
124 client.OnClassifiedDelete += ClassifiedDeleteHandler;
125
126 // Picks
127 client.AddGenericPacketHandler("avatarpicksrequest", HandleAvatarPicksRequest);
128 client.AddGenericPacketHandler("pickinforequest", HandlePickInfoRequest);
129 client.OnPickInfoUpdate += PickInfoUpdateHandler;
130 client.OnPickDelete += PickDeleteHandler;
131
132 // Notes
133 client.AddGenericPacketHandler("avatarnotesrequest", HandleAvatarNotesRequest);
134 client.OnAvatarNotesUpdate += AvatarNotesUpdateHandler;
135
136 // Profiles
137 client.OnRequestAvatarProperties += RequestAvatarPropertiesHandler;
138 client.OnUpdateAvatarProperties += UpdateAvatarPropertiesHandler;
139 client.OnAvatarInterestUpdate += AvatarInterestUpdateHandler;
140 client.OnUserInfoRequest += UserInfoRequestHandler;
141 client.OnUpdateUserInfo += UpdateUserInfoHandler;
142 }
143 }
144
145 #region Classifieds
146
147 private void AvatarClassifiedsRequestHandler(Object sender, string method, List<String> args)
148 {
149 if (!(sender is IClientAPI))
150 return;
151 IClientAPI client = (IClientAPI)sender;
152
153 UUID targetAvatarID;
154 if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
155 {
156 m_log.Error("[PROFILES]: Unrecognized arguments for " + method);
157 return;
158 }
159
160 // FIXME: Query the generic key/value store for classifieds
161 client.SendAvatarClassifiedReply(targetAvatarID, new Dictionary<UUID, string>(0));
162 }
163
164 private void ClassifiedInfoRequestHandler(UUID classifiedID, IClientAPI client)
165 {
166 // FIXME: Fetch this info
167 client.SendClassifiedInfoReply(classifiedID, UUID.Zero, 0, Utils.DateTimeToUnixTime(DateTime.UtcNow + TimeSpan.FromDays(1)),
168 0, String.Empty, String.Empty, UUID.Zero, 0, UUID.Zero, String.Empty, Vector3.Zero, String.Empty, 0, 0);
169 }
170
171 private void ClassifiedInfoUpdateHandler(UUID classifiedID, uint category, string name, string description,
172 UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price,
173 IClientAPI client)
174 {
175 // FIXME: Save this info
176 }
177
178 private void ClassifiedDeleteHandler(UUID classifiedID, IClientAPI client)
179 {
180 // FIXME: Delete the specified classified ad
181 }
182
183 #endregion Classifieds
184
185 #region Picks
186
187 private void HandleAvatarPicksRequest(Object sender, string method, List<String> args)
188 {
189 if (!(sender is IClientAPI))
190 return;
191 IClientAPI client = (IClientAPI)sender;
192
193 UUID targetAvatarID;
194 if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
195 {
196 m_log.Error("[PROFILES]: Unrecognized arguments for " + method);
197 return;
198 }
199
200 // FIXME: Fetch these
201 client.SendAvatarPicksReply(targetAvatarID, new Dictionary<UUID, string>(0));
202 }
203
204 private void HandlePickInfoRequest(Object sender, string method, List<String> args)
205 {
206 if (!(sender is IClientAPI))
207 return;
208 IClientAPI client = (IClientAPI)sender;
209
210 UUID avatarID;
211 UUID pickID;
212 if (args.Count < 2 || !UUID.TryParse(args[0], out avatarID) || !UUID.TryParse(args[1], out pickID))
213 {
214 m_log.Error("[PROFILES]: Unrecognized arguments for " + method);
215 return;
216 }
217
218 // FIXME: Fetch this
219 client.SendPickInfoReply(pickID, avatarID, false, UUID.Zero, String.Empty, String.Empty, UUID.Zero, String.Empty,
220 String.Empty, String.Empty, Vector3.Zero, 0, false);
221 }
222
223 private void PickInfoUpdateHandler(IClientAPI client, UUID pickID, UUID creatorID, bool topPick, string name,
224 string desc, UUID snapshotID, int sortOrder, bool enabled)
225 {
226 // FIXME: Save this
227 }
228
229 private void PickDeleteHandler(IClientAPI client, UUID pickID)
230 {
231 // FIXME: Delete
232 }
233
234 #endregion Picks
235
236 #region Notes
237
238 private void HandleAvatarNotesRequest(Object sender, string method, List<String> args)
239 {
240 if (!(sender is IClientAPI))
241 return;
242 IClientAPI client = (IClientAPI)sender;
243
244 UUID targetAvatarID;
245 if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
246 {
247 m_log.Error("[PROFILES]: Unrecognized arguments for " + method);
248 return;
249 }
250
251 // FIXME: Fetch this
252 client.SendAvatarNotesReply(targetAvatarID, String.Empty);
253 }
254
255 private void AvatarNotesUpdateHandler(IClientAPI client, UUID targetID, string notes)
256 {
257 // FIXME: Save this
258 }
259
260 #endregion Notes
261
262 #region Profiles
263
264 private void RequestAvatarPropertiesHandler(IClientAPI client, UUID avatarID)
265 {
266 OSDMap user = FetchUserData(avatarID);
267
268 ProfileFlags flags = ProfileFlags.AllowPublish | ProfileFlags.MaturePublish;
269
270 if (user != null)
271 {
272 OSDMap about = null;
273 if (user.ContainsKey("LLAbout"))
274 {
275 try { about = OSDParser.DeserializeJson(user["LLAbout"].AsString()) as OSDMap; }
276 catch { }
277 }
278
279 if (about == null)
280 about = new OSDMap(0);
281
282 // Check if this user is a grid operator
283 byte[] charterMember;
284 if (user["AccessLevel"].AsInteger() >= 200)
285 charterMember = Utils.StringToBytes("Operator");
286 else
287 charterMember = Utils.EmptyBytes;
288
289 // Check if the user is online
290 if (client.Scene is Scene)
291 {
292 OpenSim.Services.Interfaces.PresenceInfo[] presences = ((Scene)client.Scene).PresenceService.GetAgents(new string[] { avatarID.ToString() });
293 if (presences != null && presences.Length > 0)
294 flags |= ProfileFlags.Online;
295 }
296
297 // Check if the user is identified
298 if (user["Identified"].AsBoolean())
299 flags |= ProfileFlags.Identified;
300
301 client.SendAvatarProperties(avatarID, about["About"].AsString(), user["CreationDate"].AsDate().ToString("M/d/yyyy",
302 System.Globalization.CultureInfo.InvariantCulture), charterMember, about["FLAbout"].AsString(), (uint)flags,
303 about["FLImage"].AsUUID(), about["Image"].AsUUID(), about["URL"].AsString(), user["Partner"].AsUUID());
304
305 }
306 else
307 {
308 m_log.Warn("[PROFILES]: Failed to fetch profile information for " + client.Name + ", returning default values");
309 client.SendAvatarProperties(avatarID, String.Empty, "1/1/1970", Utils.EmptyBytes,
310 String.Empty, (uint)flags, UUID.Zero, UUID.Zero, String.Empty, UUID.Zero);
311 }
312 }
313
314 private void UpdateAvatarPropertiesHandler(IClientAPI client, UserProfileData profileData)
315 {
316 OSDMap map = new OSDMap
317 {
318 { "About", OSD.FromString(profileData.AboutText) },
319 { "Image", OSD.FromUUID(profileData.Image) },
320 { "FLAbout", OSD.FromString(profileData.FirstLifeAboutText) },
321 { "FLImage", OSD.FromUUID(profileData.FirstLifeImage) },
322 { "URL", OSD.FromString(profileData.ProfileUrl) }
323 };
324
325 AddUserData(client.AgentId, "LLAbout", map);
326 }
327
328 private void AvatarInterestUpdateHandler(IClientAPI client, uint wantmask, string wanttext, uint skillsmask,
329 string skillstext, string languages)
330 {
331 OSDMap map = new OSDMap
332 {
333 { "WantMask", OSD.FromInteger(wantmask) },
334 { "WantText", OSD.FromString(wanttext) },
335 { "SkillsMask", OSD.FromInteger(skillsmask) },
336 { "SkillsText", OSD.FromString(skillstext) },
337 { "Languages", OSD.FromString(languages) }
338 };
339
340 AddUserData(client.AgentId, "LLInterests", map);
341 }
342
343 private void UserInfoRequestHandler(IClientAPI client)
344 {
345 m_log.Error("[PROFILES]: UserInfoRequestHandler");
346
347 // Fetch this user's e-mail address
348 NameValueCollection requestArgs = new NameValueCollection
349 {
350 { "RequestMethod", "GetUser" },
351 { "UserID", client.AgentId.ToString() }
352 };
353
354 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
355 string email = response["Email"].AsString();
356
357 if (!response["Success"].AsBoolean())
358 m_log.Warn("[PROFILES]: GetUser failed during a user info request for " + client.Name);
359
360 client.SendUserInfoReply(false, true, email);
361 }
362
363 private void UpdateUserInfoHandler(bool imViaEmail, bool visible, IClientAPI client)
364 {
365 m_log.Info("[PROFILES]: Ignoring user info update from " + client.Name);
366 }
367
368 #endregion Profiles
369
370 /// <summary>
371 /// Sanity checks regions for a valid estate owner at startup
372 /// </summary>
373 private void CheckEstateManager(Scene scene)
374 {
375 EstateSettings estate = scene.RegionInfo.EstateSettings;
376
377 if (estate.EstateOwner == UUID.Zero)
378 {
379 // Attempt to lookup the grid admin
380 UserAccount admin = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, UUID.Zero);
381 if (admin != null)
382 {
383 m_log.InfoFormat("[PROFILES]: Setting estate {0} (ID: {1}) owner to {2}", estate.EstateName,
384 estate.EstateID, admin.Name);
385
386 estate.EstateOwner = admin.PrincipalID;
387 estate.Save();
388 }
389 else
390 {
391 m_log.WarnFormat("[PROFILES]: Estate {0} (ID: {1}) does not have an owner", estate.EstateName, estate.EstateID);
392 }
393 }
394 }
395
396 private bool AddUserData(UUID userID, string key, OSDMap value)
397 {
398 NameValueCollection requestArgs = new NameValueCollection
399 {
400 { "RequestMethod", "AddUserData" },
401 { "UserID", userID.ToString() },
402 { key, OSDParser.SerializeJsonString(value) }
403 };
404
405 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
406 bool success = response["Success"].AsBoolean();
407
408 if (!success)
409 m_log.WarnFormat("[PROFILES]: Failed to add user data with key {0} for {1}: {2}", key, userID, response["Message"].AsString());
410
411 return success;
412 }
413
414 private OSDMap FetchUserData(UUID userID)
415 {
416 NameValueCollection requestArgs = new NameValueCollection
417 {
418 { "RequestMethod", "GetUser" },
419 { "UserID", userID.ToString() }
420 };
421
422 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
423 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
424 {
425 return (OSDMap)response["User"];
426 }
427 else
428 {
429 m_log.Error("[PROFILES]: Failed to fetch user data for " + userID + ": " + response["Message"].AsString());
430 }
431
432 return null;
433 }
434 }
435}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs
new file mode 100644
index 0000000..bb0ac57
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs
@@ -0,0 +1,311 @@
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.Collections.Specialized;
31using System.IO;
32using System.Reflection;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Services.Interfaces;
37using log4net;
38using Mono.Addins;
39using Nini.Config;
40using OpenMetaverse;
41using OpenMetaverse.StructuredData;
42
43namespace OpenSim.Services.Connectors.SimianGrid
44{
45 /// <summary>
46 /// Connects user account data (creating new users, looking up existing
47 /// users) to the SimianGrid backend
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
50 public class SimianUserAccountServiceConnector : IUserAccountService, ISharedRegionModule
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 private string m_serverUrl = String.Empty;
57 private ExpiringCache<UUID, UserAccount> m_accountCache;
58
59 #region ISharedRegionModule
60
61 public Type ReplaceableInterface { get { return null; } }
62 public void RegionLoaded(Scene scene) { }
63 public void PostInitialise() { }
64 public void Close() { }
65
66 public SimianUserAccountServiceConnector() { }
67 public string Name { get { return "SimianUserAccountServiceConnector"; } }
68 public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IUserAccountService>(this); } }
69 public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IUserAccountService>(this); } }
70
71 #endregion ISharedRegionModule
72
73 public SimianUserAccountServiceConnector(IConfigSource source)
74 {
75 Initialise(source);
76 }
77
78 public void Initialise(IConfigSource source)
79 {
80 if (Simian.IsSimianEnabled(source, "UserAccountServices"))
81 {
82 IConfig assetConfig = source.Configs["UserAccountService"];
83 if (assetConfig == null)
84 {
85 m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini");
86 throw new Exception("User account connector init error");
87 }
88
89 string serviceURI = assetConfig.GetString("UserAccountServerURI");
90 if (String.IsNullOrEmpty(serviceURI))
91 {
92 m_log.Error("[ACCOUNT CONNECTOR]: No UserAccountServerURI in section UserAccountService, skipping SimianUserAccountServiceConnector");
93 throw new Exception("User account connector init error");
94 }
95
96 m_accountCache = new ExpiringCache<UUID, UserAccount>();
97 m_serverUrl = serviceURI;
98 }
99 }
100
101 public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
102 {
103 NameValueCollection requestArgs = new NameValueCollection
104 {
105 { "RequestMethod", "GetUser" },
106 { "Name", firstName + ' ' + lastName }
107 };
108
109 return GetUser(requestArgs);
110 }
111
112 public UserAccount GetUserAccount(UUID scopeID, string email)
113 {
114 NameValueCollection requestArgs = new NameValueCollection
115 {
116 { "RequestMethod", "GetUser" },
117 { "Email", email }
118 };
119
120 return GetUser(requestArgs);
121 }
122
123 public UserAccount GetUserAccount(UUID scopeID, UUID userID)
124 {
125 // Cache check
126 UserAccount account;
127 if (m_accountCache.TryGetValue(userID, out account))
128 return account;
129
130 NameValueCollection requestArgs = new NameValueCollection
131 {
132 { "RequestMethod", "GetUser" },
133 { "UserID", userID.ToString() }
134 };
135
136 return GetUser(requestArgs);
137 }
138
139 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
140 {
141 List<UserAccount> accounts = new List<UserAccount>();
142
143 m_log.DebugFormat("[ACCOUNT CONNECTOR]: Searching for user accounts with name query " + query);
144
145 NameValueCollection requestArgs = new NameValueCollection
146 {
147 { "RequestMethod", "GetUsers" },
148 { "NameQuery", query }
149 };
150
151 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
152 if (response["Success"].AsBoolean())
153 {
154 OSDArray array = response["Users"] as OSDArray;
155 if (array != null && array.Count > 0)
156 {
157 for (int i = 0; i < array.Count; i++)
158 {
159 UserAccount account = ResponseToUserAccount(array[i] as OSDMap);
160 if (account != null)
161 accounts.Add(account);
162 }
163 }
164 else
165 {
166 m_log.Warn("[ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format");
167 }
168 }
169 else
170 {
171 m_log.Warn("[ACCOUNT CONNECTOR]: Failed to search for account data by name " + query);
172 }
173
174 return accounts;
175 }
176
177 public bool StoreUserAccount(UserAccount data)
178 {
179 m_log.InfoFormat("[ACCOUNT CONNECTOR]: Storing user account for " + data.Name);
180
181 NameValueCollection requestArgs = new NameValueCollection
182 {
183 { "RequestMethod", "AddUser" },
184 { "UserID", data.PrincipalID.ToString() },
185 { "Name", data.Name },
186 { "Email", data.Email },
187 { "AccessLevel", data.UserLevel.ToString() }
188 };
189
190 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
191
192 if (response["Success"].AsBoolean())
193 {
194 m_log.InfoFormat("[ACCOUNT CONNECTOR]: Storing user account data for " + data.Name);
195
196 requestArgs = new NameValueCollection
197 {
198 { "RequestMethod", "AddUserData" },
199 { "UserID", data.PrincipalID.ToString() },
200 { "CreationDate", data.Created.ToString() },
201 { "UserFlags", data.UserFlags.ToString() },
202 { "UserTitle", data.UserTitle }
203 };
204
205 response = WebUtil.PostToService(m_serverUrl, requestArgs);
206 bool success = response["Success"].AsBoolean();
207
208 if (success)
209 {
210 // Cache the user account info
211 m_accountCache.AddOrUpdate(data.PrincipalID, data, DateTime.Now + TimeSpan.FromMinutes(2.0d));
212 }
213 else
214 {
215 m_log.Warn("[ACCOUNT CONNECTOR]: Failed to store user account data for " + data.Name + ": " + response["Message"].AsString());
216 }
217
218 return success;
219 }
220 else
221 {
222 m_log.Warn("[ACCOUNT CONNECTOR]: Failed to store user account for " + data.Name + ": " + response["Message"].AsString());
223 }
224
225 return false;
226 }
227
228 /// <summary>
229 /// Helper method for the various ways of retrieving a user account
230 /// </summary>
231 /// <param name="requestArgs">Service query parameters</param>
232 /// <returns>A UserAccount object on success, null on failure</returns>
233 private UserAccount GetUser(NameValueCollection requestArgs)
234 {
235 string lookupValue = (requestArgs.Count > 1) ? requestArgs[1] : "(Unknown)";
236 m_log.DebugFormat("[ACCOUNT CONNECTOR]: Looking up user account with query: " + lookupValue);
237
238 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
239 if (response["Success"].AsBoolean())
240 {
241 OSDMap user = response["User"] as OSDMap;
242 if (user != null)
243 return ResponseToUserAccount(user);
244 else
245 m_log.Warn("[ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format");
246 }
247 else
248 {
249 m_log.Warn("[ACCOUNT CONNECTOR]: Failed to lookup user account with query: " + lookupValue);
250 }
251
252 return null;
253 }
254
255 /// <summary>
256 /// Convert a User object in LLSD format to a UserAccount
257 /// </summary>
258 /// <param name="response">LLSD containing user account data</param>
259 /// <returns>A UserAccount object on success, null on failure</returns>
260 private UserAccount ResponseToUserAccount(OSDMap response)
261 {
262 if (response == null)
263 return null;
264
265 UserAccount account = new UserAccount();
266 account.PrincipalID = response["UserID"].AsUUID();
267 account.Created = response["CreationDate"].AsInteger();
268 account.Email = response["Email"].AsString();
269 account.ServiceURLs = new Dictionary<string, object>(0);
270 account.UserFlags = response["UserFlags"].AsInteger();
271 account.UserLevel = response["AccessLevel"].AsInteger();
272 account.UserTitle = response["UserTitle"].AsString();
273 GetFirstLastName(response["Name"].AsString(), out account.FirstName, out account.LastName);
274
275 // Cache the user account info
276 m_accountCache.AddOrUpdate(account.PrincipalID, account, DateTime.Now + TimeSpan.FromMinutes(2.0d));
277
278 return account;
279 }
280
281 /// <summary>
282 /// Convert a name with a single space in it to a first and last name
283 /// </summary>
284 /// <param name="name">A full name such as "John Doe"</param>
285 /// <param name="firstName">First name</param>
286 /// <param name="lastName">Last name (surname)</param>
287 private static void GetFirstLastName(string name, out string firstName, out string lastName)
288 {
289 if (String.IsNullOrEmpty(name))
290 {
291 firstName = String.Empty;
292 lastName = String.Empty;
293 }
294 else
295 {
296 string[] names = name.Split(' ');
297
298 if (names.Length == 2)
299 {
300 firstName = names[0];
301 lastName = names[1];
302 }
303 else
304 {
305 firstName = String.Empty;
306 lastName = name;
307 }
308 }
309 }
310 }
311}
diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs
index 8e7c92b..2f9b520 100644
--- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs
+++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs
@@ -113,6 +113,7 @@ namespace OpenSim.Services.Connectors
113 113
114 public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID) 114 public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID)
115 { 115 {
116 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUSerAccount {0}", userID);
116 Dictionary<string, object> sendData = new Dictionary<string, object>(); 117 Dictionary<string, object> sendData = new Dictionary<string, object>();
117 //sendData["SCOPEID"] = scopeID.ToString(); 118 //sendData["SCOPEID"] = scopeID.ToString();
118 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); 119 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index 1368e46..2faf018 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -123,8 +123,7 @@ namespace OpenSim.Services.GridService
123 if ((rflags & OpenSim.Data.RegionFlags.Reservation) != 0) 123 if ((rflags & OpenSim.Data.RegionFlags.Reservation) != 0)
124 { 124 {
125 // Regions reserved for the null key cannot be taken. 125 // Regions reserved for the null key cannot be taken.
126 // 126 if ((string)region.Data["PrincipalID"] == UUID.Zero.ToString())
127 if (region.Data["PrincipalID"] == UUID.Zero.ToString())
128 return "Region location us reserved"; 127 return "Region location us reserved";
129 128
130 // Treat it as an auth request 129 // Treat it as an auth request
@@ -132,7 +131,6 @@ namespace OpenSim.Services.GridService
132 // NOTE: Fudging the flags value here, so these flags 131 // NOTE: Fudging the flags value here, so these flags
133 // should not be used elsewhere. Don't optimize 132 // should not be used elsewhere. Don't optimize
134 // this with the later retrieval of the same flags! 133 // this with the later retrieval of the same flags!
135 //
136 rflags |= OpenSim.Data.RegionFlags.Authenticate; 134 rflags |= OpenSim.Data.RegionFlags.Authenticate;
137 } 135 }
138 136
@@ -489,7 +487,7 @@ namespace OpenSim.Services.GridService
489 f |= (OpenSim.Data.RegionFlags)val; 487 f |= (OpenSim.Data.RegionFlags)val;
490 } 488 }
491 } 489 }
492 catch (Exception e) 490 catch (Exception)
493 { 491 {
494 MainConsole.Instance.Output("Error in flag specification: " + p); 492 MainConsole.Instance.Output("Error in flag specification: " + p);
495 } 493 }
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
index de5df9d..58746d0 100644
--- a/OpenSim/Services/GridService/HypergridLinker.cs
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -168,10 +168,11 @@ namespace OpenSim.Services.GridService
168 } 168 }
169 169
170 // Sanity check. 170 // Sanity check.
171 IPAddress ipaddr = null; 171 //IPAddress ipaddr = null;
172 try 172 try
173 { 173 {
174 ipaddr = Util.GetHostFromDNS(host); 174 //ipaddr = Util.GetHostFromDNS(host);
175 Util.GetHostFromDNS(host);
175 } 176 }
176 catch 177 catch
177 { 178 {
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index 15379b5..26f211b 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -1,4 +1,31 @@
1using System; 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;
2using System.Collections.Generic; 29using System.Collections.Generic;
3using System.Net; 30using System.Net;
4using System.Reflection; 31using System.Reflection;
diff --git a/OpenSim/Services/Interfaces/IUserAccountService.cs b/OpenSim/Services/Interfaces/IUserAccountService.cs
index 3dacf53..a45bf8c 100644
--- a/OpenSim/Services/Interfaces/IUserAccountService.cs
+++ b/OpenSim/Services/Interfaces/IUserAccountService.cs
@@ -140,14 +140,20 @@ namespace OpenSim.Services.Interfaces
140 UserAccount GetUserAccount(UUID scopeID, UUID userID); 140 UserAccount GetUserAccount(UUID scopeID, UUID userID);
141 UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName); 141 UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName);
142 UserAccount GetUserAccount(UUID scopeID, string Email); 142 UserAccount GetUserAccount(UUID scopeID, string Email);
143 // Returns the list of avatars that matches both the search 143
144 // criterion and the scope ID passed 144 /// <summary>
145 // 145 /// Returns the list of avatars that matches both the search criterion and the scope ID passed
146 /// </summary>
147 /// <param name="scopeID"></param>
148 /// <param name="query"></param>
149 /// <returns></returns>
146 List<UserAccount> GetUserAccounts(UUID scopeID, string query); 150 List<UserAccount> GetUserAccounts(UUID scopeID, string query);
147 151
148 // Store the data given, wich replaces the sotred data, therefore 152 /// <summary>
149 // must be complete. 153 /// Store the data given, wich replaces the sotred data, therefore must be complete.
150 // 154 /// </summary>
155 /// <param name="data"></param>
156 /// <returns></returns>
151 bool StoreUserAccount(UserAccount data); 157 bool StoreUserAccount(UserAccount data);
152 } 158 }
153} 159} \ No newline at end of file
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index 05f5b4c..ee30fa3 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -47,9 +47,9 @@ namespace OpenSim.Services.LLLoginService
47{ 47{
48 public class LLFailedLoginResponse : OpenSim.Services.Interfaces.FailedLoginResponse 48 public class LLFailedLoginResponse : OpenSim.Services.Interfaces.FailedLoginResponse
49 { 49 {
50 string m_key; 50 protected string m_key;
51 string m_value; 51 protected string m_value;
52 string m_login; 52 protected string m_login;
53 53
54 public static LLFailedLoginResponse UserProblem; 54 public static LLFailedLoginResponse UserProblem;
55 public static LLFailedLoginResponse AuthorizationProblem; 55 public static LLFailedLoginResponse AuthorizationProblem;
@@ -623,7 +623,7 @@ namespace OpenSim.Services.LLLoginService
623 } 623 }
624 624
625 private InventoryData GetInventorySkeleton(List<InventoryFolderBase> folders) 625 private InventoryData GetInventorySkeleton(List<InventoryFolderBase> folders)
626 { 626 {
627 UUID rootID = UUID.Zero; 627 UUID rootID = UUID.Zero;
628 ArrayList AgentInventoryArray = new ArrayList(); 628 ArrayList AgentInventoryArray = new ArrayList();
629 Hashtable TempHash; 629 Hashtable TempHash;
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index ae729f8..1eaf4d4 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -1,4 +1,31 @@
1using System; 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;
2using System.Collections.Generic; 29using System.Collections.Generic;
3using System.Net; 30using System.Net;
4using System.Reflection; 31using System.Reflection;
@@ -24,24 +51,24 @@ namespace OpenSim.Services.LLLoginService
24 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
25 private static bool Initialized = false; 52 private static bool Initialized = false;
26 53
27 private IUserAccountService m_UserAccountService; 54 protected IUserAccountService m_UserAccountService;
28 private IAuthenticationService m_AuthenticationService; 55 protected IAuthenticationService m_AuthenticationService;
29 private IInventoryService m_InventoryService; 56 protected IInventoryService m_InventoryService;
30 private IGridService m_GridService; 57 protected IGridService m_GridService;
31 private IPresenceService m_PresenceService; 58 protected IPresenceService m_PresenceService;
32 private ISimulationService m_LocalSimulationService; 59 private ISimulationService m_LocalSimulationService;
33 private ISimulationService m_RemoteSimulationService; 60 private ISimulationService m_RemoteSimulationService;
34 private ILibraryService m_LibraryService; 61 protected ILibraryService m_LibraryService;
35 private IFriendsService m_FriendsService; 62 protected IFriendsService m_FriendsService;
36 private IAvatarService m_AvatarService; 63 protected IAvatarService m_AvatarService;
37 private IUserAgentService m_UserAgentService; 64 private IUserAgentService m_UserAgentService;
38 65
39 private GatekeeperServiceConnector m_GatekeeperConnector; 66 private GatekeeperServiceConnector m_GatekeeperConnector;
40 67
41 private string m_DefaultRegionName; 68 private string m_DefaultRegionName;
42 private string m_WelcomeMessage; 69 protected string m_WelcomeMessage;
43 private bool m_RequireInventory; 70 private bool m_RequireInventory;
44 private int m_MinLoginLevel; 71 protected int m_MinLoginLevel;
45 private string m_GatekeeperURL; 72 private string m_GatekeeperURL;
46 73
47 IConfig m_LoginServerConfig; 74 IConfig m_LoginServerConfig;
@@ -259,7 +286,7 @@ namespace OpenSim.Services.LLLoginService
259 } 286 }
260 } 287 }
261 288
262 private GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt) 289 protected GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt)
263 { 290 {
264 m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation); 291 m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation);
265 292
@@ -470,7 +497,7 @@ namespace OpenSim.Services.LLLoginService
470 } 497 }
471 } 498 }
472 499
473 private AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar, 500 protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar,
474 UUID session, UUID secureSession, Vector3 position, string currentWhere, out string where, out string reason) 501 UUID session, UUID secureSession, Vector3 position, string currentWhere, out string where, out string reason)
475 { 502 {
476 where = currentWhere; 503 where = currentWhere;
diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs
index 304538a..ea8d673 100644
--- a/OpenSim/Services/PresenceService/PresenceService.cs
+++ b/OpenSim/Services/PresenceService/PresenceService.cs
@@ -72,6 +72,10 @@ namespace OpenSim.Services.PresenceService
72 data.Data["HomeRegionID"] = d[0].Data["HomeRegionID"]; 72 data.Data["HomeRegionID"] = d[0].Data["HomeRegionID"];
73 data.Data["HomePosition"] = d[0].Data["HomePosition"]; 73 data.Data["HomePosition"] = d[0].Data["HomePosition"];
74 data.Data["HomeLookAt"] = d[0].Data["HomeLookAt"]; 74 data.Data["HomeLookAt"] = d[0].Data["HomeLookAt"];
75 data.Data["Position"] = d[0].Data["Position"];
76 data.Data["LookAt"] = d[0].Data["LookAt"];
77
78 data.RegionID = d[0].RegionID;
75 } 79 }
76 else 80 else
77 { 81 {
diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs
index 36cce75..c6e33bb 100644
--- a/OpenSim/Services/UserAccountService/GridUserService.cs
+++ b/OpenSim/Services/UserAccountService/GridUserService.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Services.UserAccountService
58 info.HomePosition = Vector3.Parse(d.Data["HomePosition"]); 58 info.HomePosition = Vector3.Parse(d.Data["HomePosition"]);
59 info.HomeLookAt = Vector3.Parse(d.Data["HomeLookAt"]); 59 info.HomeLookAt = Vector3.Parse(d.Data["HomeLookAt"]);
60 60
61 return info; 61 return info;
62 } 62 }
63 63
64 public bool StoreGridUserInfo(GridUserInfo info) 64 public bool StoreGridUserInfo(GridUserInfo info)
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs
index 82c34e7..38caf74 100644
--- a/OpenSim/Services/UserAccountService/UserAccountService.cs
+++ b/OpenSim/Services/UserAccountService/UserAccountService.cs
@@ -200,7 +200,9 @@ namespace OpenSim.Services.UserAccountService
200 } 200 }
201 201
202 if (d.Length < 1) 202 if (d.Length < 1)
203 {
203 return null; 204 return null;
205 }
204 206
205 return MakeUserAccount(d[0]); 207 return MakeUserAccount(d[0]);
206 } 208 }