aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/Connectors
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/Connectors')
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs4
-rw-r--r--OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs10
-rw-r--r--OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs317
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs241
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs167
-rw-r--r--OpenSim/Services/Connectors/Grid/GridServiceConnector.cs147
-rw-r--r--OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs254
-rw-r--r--OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs38
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs272
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs397
-rw-r--r--OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs20
-rw-r--r--OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs423
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs418
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs246
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs262
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs240
-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/Simulation/SimulationServiceConnector.cs601
-rw-r--r--OpenSim/Services/Connectors/User/UserServiceConnector.cs114
-rw-r--r--OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs278
25 files changed, 6687 insertions, 382 deletions
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
index 84fbcd3..65b3537 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Services.Connectors
68 IConfig assetConfig = source.Configs["AssetService"]; 68 IConfig assetConfig = source.Configs["AssetService"];
69 if (assetConfig == null) 69 if (assetConfig == null)
70 { 70 {
71 m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpanSim.ini"); 71 m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini");
72 throw new Exception("Asset connector init error"); 72 throw new Exception("Asset connector init error");
73 } 73 }
74 74
@@ -251,7 +251,7 @@ namespace OpenSim.Services.Connectors
251 if (metadata == null) 251 if (metadata == null)
252 return false; 252 return false;
253 253
254 asset = new AssetBase(metadata.FullID, metadata.Name, metadata.Type); 254 asset = new AssetBase(metadata.FullID, metadata.Name, metadata.Type, UUID.Zero.ToString());
255 asset.Metadata = metadata; 255 asset.Metadata = metadata;
256 } 256 }
257 asset.Data = data; 257 asset.Data = data;
diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
index 19bb3e2..6f77a2d 100644
--- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Services.Connectors
67 IConfig assetConfig = source.Configs["AuthenticationService"]; 67 IConfig assetConfig = source.Configs["AuthenticationService"];
68 if (assetConfig == null) 68 if (assetConfig == null)
69 { 69 {
70 m_log.Error("[USER CONNECTOR]: AuthenticationService missing from OpanSim.ini"); 70 m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini");
71 throw new Exception("Authentication connector init error"); 71 throw new Exception("Authentication connector init error");
72 } 72 }
73 73
@@ -76,7 +76,7 @@ namespace OpenSim.Services.Connectors
76 76
77 if (serviceURI == String.Empty) 77 if (serviceURI == String.Empty)
78 { 78 {
79 m_log.Error("[USER CONNECTOR]: No Server URI named in section AuthenticationService"); 79 m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService");
80 throw new Exception("Authentication connector init error"); 80 throw new Exception("Authentication connector init error");
81 } 81 }
82 m_ServerURI = serviceURI; 82 m_ServerURI = serviceURI;
@@ -146,5 +146,11 @@ namespace OpenSim.Services.Connectors
146 146
147 return true; 147 return true;
148 } 148 }
149
150 public bool SetPassword(UUID principalID, string passwd)
151 {
152 // nope, we don't do this
153 return false;
154 }
149 } 155 }
150} 156}
diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
new file mode 100644
index 0000000..96c05a9
--- /dev/null
+++ b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
@@ -0,0 +1,317 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using IAvatarService = OpenSim.Services.Interfaces.IAvatarService;
40using OpenSim.Server.Base;
41using OpenMetaverse;
42
43namespace OpenSim.Services.Connectors
44{
45 public class AvatarServicesConnector : IAvatarService
46 {
47 private static readonly ILog m_log =
48 LogManager.GetLogger(
49 MethodBase.GetCurrentMethod().DeclaringType);
50
51 private string m_ServerURI = String.Empty;
52
53 public AvatarServicesConnector()
54 {
55 }
56
57 public AvatarServicesConnector(string serverURI)
58 {
59 m_ServerURI = serverURI.TrimEnd('/');
60 }
61
62 public AvatarServicesConnector(IConfigSource source)
63 {
64 Initialise(source);
65 }
66
67 public virtual void Initialise(IConfigSource source)
68 {
69 IConfig gridConfig = source.Configs["AvatarService"];
70 if (gridConfig == null)
71 {
72 m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini");
73 throw new Exception("Avatar connector init error");
74 }
75
76 string serviceURI = gridConfig.GetString("AvatarServerURI",
77 String.Empty);
78
79 if (serviceURI == String.Empty)
80 {
81 m_log.Error("[AVATAR CONNECTOR]: No Server URI named in section AvatarService");
82 throw new Exception("Avatar connector init error");
83 }
84 m_ServerURI = serviceURI;
85 }
86
87
88 #region IAvatarService
89
90 public AvatarData GetAvatar(UUID userID)
91 {
92 Dictionary<string, object> sendData = new Dictionary<string, object>();
93 //sendData["SCOPEID"] = scopeID.ToString();
94 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
95 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
96 sendData["METHOD"] = "getavatar";
97
98 sendData["UserID"] = userID;
99
100 string reply = string.Empty;
101 string reqString = ServerUtils.BuildQueryString(sendData);
102 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
103 try
104 {
105 reply = SynchronousRestFormsRequester.MakeRequest("POST",
106 m_ServerURI + "/avatar",
107 reqString);
108 if (reply == null || (reply != null && reply == string.Empty))
109 {
110 m_log.DebugFormat("[AVATAR CONNECTOR]: GetAgent received null or empty reply");
111 return null;
112 }
113 }
114 catch (Exception e)
115 {
116 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
117 }
118
119 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
120 AvatarData avatar = null;
121
122 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
123 {
124 if (replyData["result"] is Dictionary<string, object>)
125 {
126 avatar = new AvatarData((Dictionary<string, object>)replyData["result"]);
127 }
128 }
129
130 return avatar;
131
132 }
133
134 public bool SetAvatar(UUID userID, AvatarData avatar)
135 {
136 Dictionary<string, object> sendData = new Dictionary<string, object>();
137 //sendData["SCOPEID"] = scopeID.ToString();
138 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
139 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
140 sendData["METHOD"] = "setavatar";
141
142 sendData["UserID"] = userID.ToString();
143
144 Dictionary<string, object> structData = avatar.ToKeyValuePairs();
145
146 foreach (KeyValuePair<string, object> kvp in structData)
147 sendData[kvp.Key] = kvp.Value.ToString();
148
149
150 string reqString = ServerUtils.BuildQueryString(sendData);
151 //m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
152 try
153 {
154 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
155 m_ServerURI + "/avatar",
156 reqString);
157 if (reply != string.Empty)
158 {
159 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
160
161 if (replyData.ContainsKey("result"))
162 {
163 if (replyData["result"].ToString().ToLower() == "success")
164 return true;
165 else
166 return false;
167 }
168 else
169 m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar reply data does not contain result field");
170
171 }
172 else
173 m_log.DebugFormat("[AVATAR CONNECTOR]: SetAvatar received empty reply");
174 }
175 catch (Exception e)
176 {
177 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
178 }
179
180 return false;
181 }
182
183 public bool ResetAvatar(UUID userID)
184 {
185 Dictionary<string, object> sendData = new Dictionary<string, object>();
186 //sendData["SCOPEID"] = scopeID.ToString();
187 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
188 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
189 sendData["METHOD"] = "resetavatar";
190
191 sendData["UserID"] = userID.ToString();
192
193 string reqString = ServerUtils.BuildQueryString(sendData);
194 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
195 try
196 {
197 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
198 m_ServerURI + "/avatar",
199 reqString);
200 if (reply != string.Empty)
201 {
202 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
203
204 if (replyData.ContainsKey("result"))
205 {
206 if (replyData["result"].ToString().ToLower() == "success")
207 return true;
208 else
209 return false;
210 }
211 else
212 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field");
213
214 }
215 else
216 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply");
217 }
218 catch (Exception e)
219 {
220 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
221 }
222
223 return false;
224 }
225
226 public bool SetItems(UUID userID, string[] names, string[] values)
227 {
228 Dictionary<string, object> sendData = new Dictionary<string, object>();
229 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
230 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
231 sendData["METHOD"] = "setitems";
232
233 sendData["UserID"] = userID.ToString();
234 sendData["Names"] = new List<string>(names);
235 sendData["Values"] = new List<string>(values);
236
237 string reqString = ServerUtils.BuildQueryString(sendData);
238 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
239 try
240 {
241 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
242 m_ServerURI + "/avatar",
243 reqString);
244 if (reply != string.Empty)
245 {
246 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
247
248 if (replyData.ContainsKey("result"))
249 {
250 if (replyData["result"].ToString().ToLower() == "success")
251 return true;
252 else
253 return false;
254 }
255 else
256 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems reply data does not contain result field");
257
258 }
259 else
260 m_log.DebugFormat("[AVATAR CONNECTOR]: SetItems received empty reply");
261 }
262 catch (Exception e)
263 {
264 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
265 }
266
267 return false;
268 }
269
270 public bool RemoveItems(UUID userID, string[] names)
271 {
272 Dictionary<string, object> sendData = new Dictionary<string, object>();
273 //sendData["SCOPEID"] = scopeID.ToString();
274 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
275 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
276 sendData["METHOD"] = "removeitems";
277
278 sendData["UserID"] = userID.ToString();
279 sendData["Names"] = new List<string>(names);
280
281 string reqString = ServerUtils.BuildQueryString(sendData);
282 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
283 try
284 {
285 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
286 m_ServerURI + "/avatar",
287 reqString);
288 if (reply != string.Empty)
289 {
290 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
291
292 if (replyData.ContainsKey("result"))
293 {
294 if (replyData["result"].ToString().ToLower() == "success")
295 return true;
296 else
297 return false;
298 }
299 else
300 m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems reply data does not contain result field");
301
302 }
303 else
304 m_log.DebugFormat("[AVATAR CONNECTOR]: RemoveItems received empty reply");
305 }
306 catch (Exception e)
307 {
308 m_log.DebugFormat("[AVATAR CONNECTOR]: Exception when contacting avatar server: {0}", e.Message);
309 }
310
311 return false;
312 }
313
314 #endregion
315
316 }
317}
diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
new file mode 100644
index 0000000..baefebd
--- /dev/null
+++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
@@ -0,0 +1,241 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
39using OpenSim.Server.Base;
40using OpenMetaverse;
41
42namespace OpenSim.Services.Connectors
43{
44 public class FriendsServicesConnector : IFriendsService
45 {
46 private static readonly ILog m_log =
47 LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType);
49
50 private string m_ServerURI = String.Empty;
51
52 public FriendsServicesConnector()
53 {
54 }
55
56 public FriendsServicesConnector(string serverURI)
57 {
58 m_ServerURI = serverURI.TrimEnd('/');
59 }
60
61 public FriendsServicesConnector(IConfigSource source)
62 {
63 Initialise(source);
64 }
65
66 public virtual void Initialise(IConfigSource source)
67 {
68 IConfig gridConfig = source.Configs["FriendsService"];
69 if (gridConfig == null)
70 {
71 m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini");
72 throw new Exception("Friends connector init error");
73 }
74
75 string serviceURI = gridConfig.GetString("FriendsServerURI",
76 String.Empty);
77
78 if (serviceURI == String.Empty)
79 {
80 m_log.Error("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService");
81 throw new Exception("Friends connector init error");
82 }
83 m_ServerURI = serviceURI;
84 }
85
86
87 #region IFriendsService
88
89 public FriendInfo[] GetFriends(UUID PrincipalID)
90 {
91 Dictionary<string, object> sendData = new Dictionary<string, object>();
92
93 sendData["PRINCIPALID"] = PrincipalID.ToString();
94 sendData["METHOD"] = "getfriends";
95
96 string reqString = ServerUtils.BuildQueryString(sendData);
97
98 try
99 {
100 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
101 m_ServerURI + "/friends",
102 reqString);
103 if (reply != string.Empty)
104 {
105 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
106
107 if (replyData != null)
108 {
109 if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null"))
110 {
111 return new FriendInfo[0];
112 }
113
114 List<FriendInfo> finfos = new List<FriendInfo>();
115 Dictionary<string, object>.ValueCollection finfosList = replyData.Values;
116 //m_log.DebugFormat("[FRIENDS CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count);
117 foreach (object f in finfosList)
118 {
119 if (f is Dictionary<string, object>)
120 {
121 FriendInfo finfo = new FriendInfo((Dictionary<string, object>)f);
122 finfos.Add(finfo);
123 }
124 else
125 m_log.DebugFormat("[FRIENDS CONNECTOR]: GetFriends {0} received invalid response type {1}",
126 PrincipalID, f.GetType());
127 }
128
129 // Success
130 return finfos.ToArray();
131 }
132
133 else
134 m_log.DebugFormat("[FRIENDS CONNECTOR]: GetFriends {0} received null response",
135 PrincipalID);
136
137 }
138 }
139 catch (Exception e)
140 {
141 m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
142 }
143
144 return new FriendInfo[0];
145
146 }
147
148 public bool StoreFriend(UUID PrincipalID, string Friend, int flags)
149 {
150 FriendInfo finfo = new FriendInfo();
151 finfo.PrincipalID = PrincipalID;
152 finfo.Friend = Friend;
153 finfo.MyFlags = flags;
154
155 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
156
157 sendData["METHOD"] = "storefriend";
158
159 string reqString = ServerUtils.BuildQueryString(sendData);
160
161 string reply = string.Empty;
162 try
163 {
164 reply = SynchronousRestFormsRequester.MakeRequest("POST",
165 m_ServerURI + "/friends",
166 ServerUtils.BuildQueryString(sendData));
167 }
168 catch (Exception e)
169 {
170 m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
171 return false;
172 }
173
174 if (reply != string.Empty)
175 {
176 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
177
178 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
179 {
180 bool success = false;
181 Boolean.TryParse(replyData["Result"].ToString(), out success);
182 return success;
183 }
184 else
185 m_log.DebugFormat("[FRIENDS CONNECTOR]: StoreFriend {0} {1} received null response",
186 PrincipalID, Friend);
187 }
188 else
189 m_log.DebugFormat("[FRIENDS CONNECTOR]: StoreFriend received null reply");
190
191 return false;
192
193 }
194
195 public bool Delete(UUID PrincipalID, string Friend)
196 {
197 Dictionary<string, object> sendData = new Dictionary<string, object>();
198 sendData["PRINCIPALID"] = PrincipalID.ToString();
199 sendData["FRIENDS"] = Friend;
200 sendData["METHOD"] = "deletefriend";
201
202 string reqString = ServerUtils.BuildQueryString(sendData);
203
204 string reply = string.Empty;
205 try
206 {
207 reply = SynchronousRestFormsRequester.MakeRequest("POST",
208 m_ServerURI + "/friends",
209 ServerUtils.BuildQueryString(sendData));
210 }
211 catch (Exception e)
212 {
213 m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
214 return false;
215 }
216
217 if (reply != string.Empty)
218 {
219 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
220
221 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
222 {
223 bool success = false;
224 Boolean.TryParse(replyData["Result"].ToString(), out success);
225 return success;
226 }
227 else
228 m_log.DebugFormat("[FRIENDS CONNECTOR]: DeleteFriend {0} {1} received null response",
229 PrincipalID, Friend);
230 }
231 else
232 m_log.DebugFormat("[FRIENDS CONNECTOR]: DeleteFriend received null reply");
233
234 return false;
235
236 }
237
238 #endregion
239
240 }
241}
diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
new file mode 100644
index 0000000..a29ac28
--- /dev/null
+++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
@@ -0,0 +1,167 @@
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.Reflection;
31
32using OpenSim.Services.Interfaces;
33using GridRegion = OpenSim.Services.Interfaces.GridRegion;
34using OpenSim.Server.Base;
35using OpenSim.Framework.Servers.HttpServer;
36
37using OpenMetaverse;
38using log4net;
39
40namespace OpenSim.Services.Connectors.Friends
41{
42 public class FriendsSimConnector
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 public bool FriendshipOffered(GridRegion region, UUID userID, UUID friendID, string message)
47 {
48 Dictionary<string, object> sendData = new Dictionary<string, object>();
49 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
50 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
51 sendData["METHOD"] = "friendship_offered";
52
53 sendData["FromID"] = userID.ToString();
54 sendData["ToID"] = friendID.ToString();
55 sendData["Message"] = message;
56
57 return Call(region, sendData);
58
59 }
60
61 public bool FriendshipApproved(GridRegion region, UUID userID, string userName, UUID friendID)
62 {
63 Dictionary<string, object> sendData = new Dictionary<string, object>();
64 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
65 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
66 sendData["METHOD"] = "friendship_approved";
67
68 sendData["FromID"] = userID.ToString();
69 sendData["FromName"] = userName;
70 sendData["ToID"] = friendID.ToString();
71
72 return Call(region, sendData);
73 }
74
75 public bool FriendshipDenied(GridRegion region, UUID userID, string userName, UUID friendID)
76 {
77 Dictionary<string, object> sendData = new Dictionary<string, object>();
78 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
79 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
80 sendData["METHOD"] = "friendship_denied";
81
82 sendData["FromID"] = userID.ToString();
83 sendData["FromName"] = userName;
84 sendData["ToID"] = friendID.ToString();
85
86 return Call(region, sendData);
87 }
88
89 public bool FriendshipTerminated(GridRegion region, UUID userID, UUID friendID)
90 {
91 Dictionary<string, object> sendData = new Dictionary<string, object>();
92 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
93 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
94 sendData["METHOD"] = "friendship_terminated";
95
96 sendData["FromID"] = userID.ToString();
97 sendData["ToID"] = friendID.ToString();
98
99 return Call(region, sendData);
100 }
101
102 public bool GrantRights(GridRegion region, UUID userID, UUID friendID, int userFlags, int rights)
103 {
104 Dictionary<string, object> sendData = new Dictionary<string, object>();
105 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
106 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
107 sendData["METHOD"] = "grant_rights";
108
109 sendData["FromID"] = userID.ToString();
110 sendData["ToID"] = friendID.ToString();
111 sendData["UserFlags"] = userFlags.ToString();
112 sendData["Rights"] = rights.ToString();
113
114 return Call(region, sendData);
115 }
116
117 public bool StatusNotify(GridRegion region, UUID userID, UUID friendID, bool online)
118 {
119 Dictionary<string, object> sendData = new Dictionary<string, object>();
120 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
121 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
122 sendData["METHOD"] = "status";
123
124 sendData["FromID"] = userID.ToString();
125 sendData["ToID"] = friendID.ToString();
126 sendData["Online"] = online.ToString();
127
128 return Call(region, sendData);
129 }
130
131 private bool Call(GridRegion region, Dictionary<string, object> sendData)
132 {
133 string reqString = ServerUtils.BuildQueryString(sendData);
134 // m_log.DebugFormat("[FRIENDS CONNECTOR]: queryString = {0}", reqString);
135 try
136 {
137 string url = "http://" + region.ExternalHostName + ":" + region.HttpPort;
138 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
139 url + "/friends",
140 reqString);
141 if (reply != string.Empty)
142 {
143 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
144
145 if (replyData.ContainsKey("RESULT"))
146 {
147 if (replyData["RESULT"].ToString().ToLower() == "true")
148 return true;
149 else
150 return false;
151 }
152 else
153 m_log.DebugFormat("[FRIENDS CONNECTOR]: reply data does not contain result field");
154
155 }
156 else
157 m_log.DebugFormat("[FRIENDS CONNECTOR]: received empty reply");
158 }
159 catch (Exception e)
160 {
161 m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting remote sim: {0}", e.Message);
162 }
163
164 return false;
165 }
166 }
167}
diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
index 04c7c53..a453d99 100644
--- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs
@@ -460,6 +460,153 @@ namespace OpenSim.Services.Connectors
460 return rinfos; 460 return rinfos;
461 } 461 }
462 462
463 public List<GridRegion> GetDefaultRegions(UUID scopeID)
464 {
465 Dictionary<string, object> sendData = new Dictionary<string, object>();
466
467 sendData["SCOPEID"] = scopeID.ToString();
468
469 sendData["METHOD"] = "get_default_regions";
470
471 List<GridRegion> rinfos = new List<GridRegion>();
472 string reply = string.Empty;
473 try
474 {
475 reply = SynchronousRestFormsRequester.MakeRequest("POST",
476 m_ServerURI + "/grid",
477 ServerUtils.BuildQueryString(sendData));
478
479 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
480 }
481 catch (Exception e)
482 {
483 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
484 return rinfos;
485 }
486
487 if (reply != string.Empty)
488 {
489 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
490
491 if (replyData != null)
492 {
493 Dictionary<string, object>.ValueCollection rinfosList = replyData.Values;
494 foreach (object r in rinfosList)
495 {
496 if (r is Dictionary<string, object>)
497 {
498 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
499 rinfos.Add(rinfo);
500 }
501 }
502 }
503 else
504 m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions {0} received null response",
505 scopeID);
506 }
507 else
508 m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultRegions received null reply");
509
510 return rinfos;
511 }
512
513 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
514 {
515 Dictionary<string, object> sendData = new Dictionary<string, object>();
516
517 sendData["SCOPEID"] = scopeID.ToString();
518 sendData["X"] = x.ToString();
519 sendData["Y"] = y.ToString();
520
521 sendData["METHOD"] = "get_fallback_regions";
522
523 List<GridRegion> rinfos = new List<GridRegion>();
524 string reply = string.Empty;
525 try
526 {
527 reply = SynchronousRestFormsRequester.MakeRequest("POST",
528 m_ServerURI + "/grid",
529 ServerUtils.BuildQueryString(sendData));
530
531 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
532 }
533 catch (Exception e)
534 {
535 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
536 return rinfos;
537 }
538
539 if (reply != string.Empty)
540 {
541 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
542
543 if (replyData != null)
544 {
545 Dictionary<string, object>.ValueCollection rinfosList = replyData.Values;
546 foreach (object r in rinfosList)
547 {
548 if (r is Dictionary<string, object>)
549 {
550 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
551 rinfos.Add(rinfo);
552 }
553 }
554 }
555 else
556 m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions {0}, {1}-{2} received null response",
557 scopeID, x, y);
558 }
559 else
560 m_log.DebugFormat("[GRID CONNECTOR]: GetFallbackRegions received null reply");
561
562 return rinfos;
563 }
564
565 public virtual int GetRegionFlags(UUID scopeID, UUID regionID)
566 {
567 Dictionary<string, object> sendData = new Dictionary<string, object>();
568
569 sendData["SCOPEID"] = scopeID.ToString();
570 sendData["REGIONID"] = regionID.ToString();
571
572 sendData["METHOD"] = "get_region_flags";
573
574 string reply = string.Empty;
575 try
576 {
577 reply = SynchronousRestFormsRequester.MakeRequest("POST",
578 m_ServerURI + "/grid",
579 ServerUtils.BuildQueryString(sendData));
580 }
581 catch (Exception e)
582 {
583 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
584 return -1;
585 }
586
587 int flags = -1;
588
589 if (reply != string.Empty)
590 {
591 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
592
593 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
594 {
595 Int32.TryParse((string)replyData["result"], out flags);
596 //else
597 // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags {0}, {1} received wrong type {2}",
598 // scopeID, regionID, replyData["result"].GetType());
599 }
600 else
601 m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags {0}, {1} received null response",
602 scopeID, regionID);
603 }
604 else
605 m_log.DebugFormat("[GRID CONNECTOR]: GetRegionFlags received null reply");
606
607 return flags;
608 }
609
463 #endregion 610 #endregion
464 611
465 } 612 }
diff --git a/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs
deleted file mode 100644
index 7098b07..0000000
--- a/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs
+++ /dev/null
@@ -1,254 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Text;
32using System.Drawing;
33using System.Net;
34using System.Reflection;
35using OpenSim.Services.Interfaces;
36using GridRegion = OpenSim.Services.Interfaces.GridRegion;
37
38using OpenSim.Framework;
39
40using OpenMetaverse;
41using OpenMetaverse.Imaging;
42using log4net;
43using Nwc.XmlRpc;
44
45namespace OpenSim.Services.Connectors.Grid
46{
47 public class HypergridServiceConnector
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private IAssetService m_AssetService;
52
53 public HypergridServiceConnector(IAssetService assService)
54 {
55 m_AssetService = assService;
56 }
57
58 public UUID LinkRegion(GridRegion info, out ulong realHandle)
59 {
60 UUID uuid = UUID.Zero;
61 realHandle = 0;
62
63 Hashtable hash = new Hashtable();
64 hash["region_name"] = info.RegionName;
65
66 IList paramList = new ArrayList();
67 paramList.Add(hash);
68
69 XmlRpcRequest request = new XmlRpcRequest("link_region", paramList);
70 string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/";
71 m_log.Debug("[HGrid]: Linking to " + uri);
72 XmlRpcResponse response = null;
73 try
74 {
75 response = request.Send(uri, 10000);
76 }
77 catch (Exception e)
78 {
79 m_log.Debug("[HGrid]: Exception " + e.Message);
80 return uuid;
81 }
82
83 if (response.IsFault)
84 {
85 m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
86 }
87 else
88 {
89 hash = (Hashtable)response.Value;
90 //foreach (Object o in hash)
91 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
92 try
93 {
94 UUID.TryParse((string)hash["uuid"], out uuid);
95 //m_log.Debug(">> HERE, uuid: " + uuid);
96 info.RegionID = uuid;
97 if ((string)hash["handle"] != null)
98 {
99 realHandle = Convert.ToUInt64((string)hash["handle"]);
100 //m_log.Debug(">> HERE, realHandle: " + realHandle);
101 }
102 //if (hash["region_image"] != null)
103 //{
104 // UUID img = UUID.Zero;
105 // UUID.TryParse((string)hash["region_image"], out img);
106 // info.RegionSettings.TerrainImageID = img;
107 //}
108 if (hash["region_name"] != null)
109 {
110 info.RegionName = (string)hash["region_name"];
111 //m_log.Debug(">> " + info.RegionName);
112 }
113 if (hash["internal_port"] != null)
114 {
115 int port = Convert.ToInt32((string)hash["internal_port"]);
116 info.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port);
117 //m_log.Debug(">> " + info.InternalEndPoint.ToString());
118 }
119
120 }
121 catch (Exception e)
122 {
123 m_log.Error("[HGrid]: Got exception while parsing hyperlink response " + e.StackTrace);
124 }
125 }
126 return uuid;
127 }
128
129 public void GetMapImage(GridRegion info)
130 {
131 try
132 {
133 string regionimage = "regionImage" + info.RegionID.ToString();
134 regionimage = regionimage.Replace("-", "");
135
136 WebClient c = new WebClient();
137 string uri = "http://" + info.ExternalHostName + ":" + info.HttpPort + "/index.php?method=" + regionimage;
138 //m_log.Debug("JPEG: " + uri);
139 c.DownloadFile(uri, info.RegionID.ToString() + ".jpg");
140 Bitmap m = new Bitmap(info.RegionID.ToString() + ".jpg");
141 //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width);
142 byte[] imageData = OpenJPEG.EncodeFromImage(m, true);
143 AssetBase ass = new AssetBase(UUID.Random(), "region " + info.RegionID.ToString(), (sbyte)AssetType.Texture);
144
145 // !!! for now
146 //info.RegionSettings.TerrainImageID = ass.FullID;
147
148 ass.Temporary = true;
149 ass.Local = true;
150 ass.Data = imageData;
151
152 m_AssetService.Store(ass);
153
154 // finally
155 info.TerrainImage = ass.FullID;
156
157 }
158 catch // LEGIT: Catching problems caused by OpenJPEG p/invoke
159 {
160 m_log.Warn("[HGrid]: Failed getting/storing map image, because it is probably already in the cache");
161 }
162 }
163
164 public bool InformRegionOfUser(GridRegion regInfo, AgentCircuitData agentData, GridRegion home, string userServer, string assetServer, string inventoryServer)
165 {
166 string capsPath = agentData.CapsPath;
167 Hashtable loginParams = new Hashtable();
168 loginParams["session_id"] = agentData.SessionID.ToString();
169
170 loginParams["firstname"] = agentData.firstname;
171 loginParams["lastname"] = agentData.lastname;
172
173 loginParams["agent_id"] = agentData.AgentID.ToString();
174 loginParams["circuit_code"] = agentData.circuitcode.ToString();
175 loginParams["startpos_x"] = agentData.startpos.X.ToString();
176 loginParams["startpos_y"] = agentData.startpos.Y.ToString();
177 loginParams["startpos_z"] = agentData.startpos.Z.ToString();
178 loginParams["caps_path"] = capsPath;
179
180 if (home != null)
181 {
182 loginParams["region_uuid"] = home.RegionID.ToString();
183 loginParams["regionhandle"] = home.RegionHandle.ToString();
184 loginParams["home_address"] = home.ExternalHostName;
185 loginParams["home_port"] = home.HttpPort.ToString();
186 loginParams["internal_port"] = home.InternalEndPoint.Port.ToString();
187
188 m_log.Debug(" --------- Home -------");
189 m_log.Debug(" >> " + loginParams["home_address"] + " <<");
190 m_log.Debug(" >> " + loginParams["region_uuid"] + " <<");
191 m_log.Debug(" >> " + loginParams["regionhandle"] + " <<");
192 m_log.Debug(" >> " + loginParams["home_port"] + " <<");
193 m_log.Debug(" --------- ------------ -------");
194 }
195 else
196 m_log.WarnFormat("[HGrid]: Home region not found for {0} {1}", agentData.firstname, agentData.lastname);
197
198 loginParams["userserver_id"] = userServer;
199 loginParams["assetserver_id"] = assetServer;
200 loginParams["inventoryserver_id"] = inventoryServer;
201
202
203 ArrayList SendParams = new ArrayList();
204 SendParams.Add(loginParams);
205
206 // Send
207 string uri = "http://" + regInfo.ExternalHostName + ":" + regInfo.HttpPort + "/";
208 //m_log.Debug("XXX uri: " + uri);
209 XmlRpcRequest request = new XmlRpcRequest("expect_hg_user", SendParams);
210 XmlRpcResponse reply;
211 try
212 {
213 reply = request.Send(uri, 6000);
214 }
215 catch (Exception e)
216 {
217 m_log.Warn("[HGrid]: Failed to notify region about user. Reason: " + e.Message);
218 return false;
219 }
220
221 if (!reply.IsFault)
222 {
223 bool responseSuccess = true;
224 if (reply.Value != null)
225 {
226 Hashtable resp = (Hashtable)reply.Value;
227 if (resp.ContainsKey("success"))
228 {
229 if ((string)resp["success"] == "FALSE")
230 {
231 responseSuccess = false;
232 }
233 }
234 }
235 if (responseSuccess)
236 {
237 m_log.Info("[HGrid]: Successfully informed remote region about user " + agentData.AgentID);
238 return true;
239 }
240 else
241 {
242 m_log.ErrorFormat("[HGrid]: Region responded that it is not available to receive clients");
243 return false;
244 }
245 }
246 else
247 {
248 m_log.ErrorFormat("[HGrid]: XmlRpc request to region failed with message {0}, code {1} ", reply.FaultString, reply.FaultCode);
249 return false;
250 }
251 }
252
253 }
254}
diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
new file mode 100644
index 0000000..0e85067
--- /dev/null
+++ b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs
@@ -0,0 +1,38 @@
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;
29
30namespace OpenSim.Services.Connectors
31{
32 public class GridUserServiceConnector
33 {
34 public GridUserServiceConnector()
35 {
36 }
37 }
38}
diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
new file mode 100644
index 0000000..c426bba
--- /dev/null
+++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
@@ -0,0 +1,272 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Drawing;
32using System.Net;
33using System.Reflection;
34
35using OpenSim.Framework;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38
39using OpenMetaverse;
40using OpenMetaverse.Imaging;
41using Nwc.XmlRpc;
42using log4net;
43
44using OpenSim.Services.Connectors.Simulation;
45
46namespace OpenSim.Services.Connectors.Hypergrid
47{
48 public class GatekeeperServiceConnector : SimulationServiceConnector
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private static UUID m_HGMapImage = new UUID("00000000-0000-1111-9999-000000000013");
53
54 private IAssetService m_AssetService;
55
56 public GatekeeperServiceConnector() : base()
57 {
58 }
59
60 public GatekeeperServiceConnector(IAssetService assService)
61 {
62 m_AssetService = assService;
63 }
64
65 protected override string AgentPath()
66 {
67 return "/foreignagent/";
68 }
69
70 protected override string ObjectPath()
71 {
72 return "/foreignobject/";
73 }
74
75 public bool LinkRegion(GridRegion info, out UUID regionID, out ulong realHandle, out string externalName, out string imageURL, out string reason)
76 {
77 regionID = UUID.Zero;
78 imageURL = string.Empty;
79 realHandle = 0;
80 externalName = string.Empty;
81 reason = string.Empty;
82
83 Hashtable hash = new Hashtable();
84 hash["region_name"] = info.RegionName;
85
86 IList paramList = new ArrayList();
87 paramList.Add(hash);
88
89 XmlRpcRequest request = new XmlRpcRequest("link_region", paramList);
90 string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/";
91 //m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Linking to " + uri);
92 XmlRpcResponse response = null;
93 try
94 {
95 response = request.Send(uri, 10000);
96 }
97 catch (Exception e)
98 {
99 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Exception " + e.Message);
100 reason = "Error contacting remote server";
101 return false;
102 }
103
104 if (response.IsFault)
105 {
106 reason = response.FaultString;
107 m_log.ErrorFormat("[GATEKEEPER SERVICE CONNECTOR]: remote call returned an error: {0}", response.FaultString);
108 return false;
109 }
110
111 hash = (Hashtable)response.Value;
112 //foreach (Object o in hash)
113 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
114 try
115 {
116 bool success = false;
117 Boolean.TryParse((string)hash["result"], out success);
118 if (success)
119 {
120 UUID.TryParse((string)hash["uuid"], out regionID);
121 //m_log.Debug(">> HERE, uuid: " + uuid);
122 if ((string)hash["handle"] != null)
123 {
124 realHandle = Convert.ToUInt64((string)hash["handle"]);
125 //m_log.Debug(">> HERE, realHandle: " + realHandle);
126 }
127 if (hash["region_image"] != null)
128 imageURL = (string)hash["region_image"];
129 if (hash["external_name"] != null)
130 externalName = (string)hash["external_name"];
131 }
132
133 }
134 catch (Exception e)
135 {
136 reason = "Error parsing return arguments";
137 m_log.Error("[GATEKEEPER SERVICE CONNECTOR]: Got exception while parsing hyperlink response " + e.StackTrace);
138 return false;
139 }
140
141 return true;
142 }
143
144 UUID m_MissingTexture = new UUID("5748decc-f629-461c-9a36-a35a221fe21f");
145
146 public UUID GetMapImage(UUID regionID, string imageURL)
147 {
148 if (m_AssetService == null)
149 return m_MissingTexture;
150
151 try
152 {
153
154 WebClient c = new WebClient();
155 //m_log.Debug("JPEG: " + imageURL);
156 string filename = regionID.ToString();
157 c.DownloadFile(imageURL, filename + ".jpg");
158 Bitmap m = new Bitmap(filename + ".jpg");
159 //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width);
160 byte[] imageData = OpenJPEG.EncodeFromImage(m, true);
161 AssetBase ass = new AssetBase(UUID.Random(), "region " + filename, (sbyte)AssetType.Texture, regionID.ToString());
162
163 // !!! for now
164 //info.RegionSettings.TerrainImageID = ass.FullID;
165
166 ass.Temporary = true;
167 ass.Local = true;
168 ass.Data = imageData;
169
170 m_AssetService.Store(ass);
171
172 // finally
173 return ass.FullID;
174
175 }
176 catch // LEGIT: Catching problems caused by OpenJPEG p/invoke
177 {
178 m_log.Warn("[GATEKEEPER SERVICE CONNECTOR]: Failed getting/storing map image, because it is probably already in the cache");
179 }
180 return UUID.Zero;
181 }
182
183 public GridRegion GetHyperlinkRegion(GridRegion gatekeeper, UUID regionID)
184 {
185 Hashtable hash = new Hashtable();
186 hash["region_uuid"] = regionID.ToString();
187
188 IList paramList = new ArrayList();
189 paramList.Add(hash);
190
191 XmlRpcRequest request = new XmlRpcRequest("get_region", paramList);
192 string uri = "http://" + gatekeeper.ExternalEndPoint.Address + ":" + gatekeeper.HttpPort + "/";
193 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: contacting " + uri);
194 XmlRpcResponse response = null;
195 try
196 {
197 response = request.Send(uri, 10000);
198 }
199 catch (Exception e)
200 {
201 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Exception " + e.Message);
202 return null;
203 }
204
205 if (response.IsFault)
206 {
207 m_log.ErrorFormat("[GATEKEEPER SERVICE CONNECTOR]: remote call returned an error: {0}", response.FaultString);
208 return null;
209 }
210
211 hash = (Hashtable)response.Value;
212 //foreach (Object o in hash)
213 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
214 try
215 {
216 bool success = false;
217 Boolean.TryParse((string)hash["result"], out success);
218 if (success)
219 {
220 GridRegion region = new GridRegion();
221
222 UUID.TryParse((string)hash["uuid"], out region.RegionID);
223 //m_log.Debug(">> HERE, uuid: " + region.RegionID);
224 int n = 0;
225 if (hash["x"] != null)
226 {
227 Int32.TryParse((string)hash["x"], out n);
228 region.RegionLocX = n;
229 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
230 }
231 if (hash["y"] != null)
232 {
233 Int32.TryParse((string)hash["y"], out n);
234 region.RegionLocY = n;
235 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
236 }
237 if (hash["region_name"] != null)
238 {
239 region.RegionName = (string)hash["region_name"];
240 //m_log.Debug(">> HERE, name: " + region.RegionName);
241 }
242 if (hash["hostname"] != null)
243 region.ExternalHostName = (string)hash["hostname"];
244 if (hash["http_port"] != null)
245 {
246 uint p = 0;
247 UInt32.TryParse((string)hash["http_port"], out p);
248 region.HttpPort = p;
249 }
250 if (hash["internal_port"] != null)
251 {
252 int p = 0;
253 Int32.TryParse((string)hash["internal_port"], out p);
254 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
255 }
256
257 // Successful return
258 return region;
259 }
260
261 }
262 catch (Exception e)
263 {
264 m_log.Error("[GATEKEEPER SERVICE CONNECTOR]: Got exception while parsing hyperlink response " + e.StackTrace);
265 return null;
266 }
267
268 return null;
269 }
270
271 }
272}
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
new file mode 100644
index 0000000..3e91e3a
--- /dev/null
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -0,0 +1,397 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Net;
33using System.Reflection;
34using System.Text;
35
36using OpenSim.Framework;
37using OpenSim.Services.Interfaces;
38using OpenSim.Services.Connectors.Simulation;
39using GridRegion = OpenSim.Services.Interfaces.GridRegion;
40
41using OpenMetaverse;
42using OpenMetaverse.StructuredData;
43using log4net;
44using Nwc.XmlRpc;
45using Nini.Config;
46
47namespace OpenSim.Services.Connectors.Hypergrid
48{
49 public class UserAgentServiceConnector : IUserAgentService
50 {
51 private static readonly ILog m_log =
52 LogManager.GetLogger(
53 MethodBase.GetCurrentMethod().DeclaringType);
54
55 string m_ServerURL;
56 public UserAgentServiceConnector(string url)
57 {
58 m_ServerURL = url;
59 }
60
61 public UserAgentServiceConnector(IConfigSource config)
62 {
63 }
64
65 public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason)
66 {
67 reason = String.Empty;
68
69 if (destination == null)
70 {
71 reason = "Destination is null";
72 m_log.Debug("[USER AGENT CONNECTOR]: Given destination is null");
73 return false;
74 }
75
76 string uri = m_ServerURL + "/homeagent/" + aCircuit.AgentID + "/";
77
78 Console.WriteLine(" >>> LoginAgentToGrid <<< " + uri);
79
80 HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
81 AgentCreateRequest.Method = "POST";
82 AgentCreateRequest.ContentType = "application/json";
83 AgentCreateRequest.Timeout = 10000;
84 //AgentCreateRequest.KeepAlive = false;
85 //AgentCreateRequest.Headers.Add("Authorization", authKey);
86
87 // Fill it in
88 OSDMap args = PackCreateAgentArguments(aCircuit, gatekeeper, destination);
89
90 string strBuffer = "";
91 byte[] buffer = new byte[1];
92 try
93 {
94 strBuffer = OSDParser.SerializeJsonString(args);
95 Encoding str = Util.UTF8;
96 buffer = str.GetBytes(strBuffer);
97
98 }
99 catch (Exception e)
100 {
101 m_log.WarnFormat("[USER AGENT CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
102 // ignore. buffer will be empty, caller should check.
103 }
104
105 Stream os = null;
106 try
107 { // send the Post
108 AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
109 os = AgentCreateRequest.GetRequestStream();
110 os.Write(buffer, 0, strBuffer.Length); //Send it
111 m_log.InfoFormat("[USER AGENT CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}",
112 uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY);
113 }
114 //catch (WebException ex)
115 catch
116 {
117 //m_log.InfoFormat("[USER AGENT CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message);
118 reason = "cannot contact remote region";
119 return false;
120 }
121 finally
122 {
123 if (os != null)
124 os.Close();
125 }
126
127 // Let's wait for the response
128 //m_log.Info("[USER AGENT CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
129
130 WebResponse webResponse = null;
131 StreamReader sr = null;
132 try
133 {
134 webResponse = AgentCreateRequest.GetResponse();
135 if (webResponse == null)
136 {
137 m_log.Info("[USER AGENT CONNECTOR]: Null reply on DoCreateChildAgentCall post");
138 }
139 else
140 {
141
142 sr = new StreamReader(webResponse.GetResponseStream());
143 string response = sr.ReadToEnd().Trim();
144 m_log.InfoFormat("[USER AGENT CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response);
145
146 if (!String.IsNullOrEmpty(response))
147 {
148 try
149 {
150 // we assume we got an OSDMap back
151 OSDMap r = Util.GetOSDMap(response);
152 bool success = r["success"].AsBoolean();
153 reason = r["reason"].AsString();
154 return success;
155 }
156 catch (NullReferenceException e)
157 {
158 m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
159
160 // check for old style response
161 if (response.ToLower().StartsWith("true"))
162 return true;
163
164 return false;
165 }
166 }
167 }
168 }
169 catch (WebException ex)
170 {
171 m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
172 reason = "Destination did not reply";
173 return false;
174 }
175 finally
176 {
177 if (sr != null)
178 sr.Close();
179 }
180
181 return true;
182
183 }
184
185 protected OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination)
186 {
187 OSDMap args = null;
188 try
189 {
190 args = aCircuit.PackAgentCircuitData();
191 }
192 catch (Exception e)
193 {
194 m_log.Debug("[USER AGENT CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message);
195 }
196 // Add the input arguments
197 args["gatekeeper_host"] = OSD.FromString(gatekeeper.ExternalHostName);
198 args["gatekeeper_port"] = OSD.FromString(gatekeeper.HttpPort.ToString());
199 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
200 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
201 args["destination_name"] = OSD.FromString(destination.RegionName);
202 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
203
204 return args;
205 }
206
207 public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
208 {
209 position = Vector3.UnitY; lookAt = Vector3.UnitY;
210
211 Hashtable hash = new Hashtable();
212 hash["userID"] = userID.ToString();
213
214 IList paramList = new ArrayList();
215 paramList.Add(hash);
216
217 XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList);
218 XmlRpcResponse response = null;
219 try
220 {
221 response = request.Send(m_ServerURL, 10000);
222 }
223 catch (Exception e)
224 {
225 return null;
226 }
227
228 if (response.IsFault)
229 {
230 return null;
231 }
232
233 hash = (Hashtable)response.Value;
234 //foreach (Object o in hash)
235 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
236 try
237 {
238 bool success = false;
239 Boolean.TryParse((string)hash["result"], out success);
240 if (success)
241 {
242 GridRegion region = new GridRegion();
243
244 UUID.TryParse((string)hash["uuid"], out region.RegionID);
245 //m_log.Debug(">> HERE, uuid: " + region.RegionID);
246 int n = 0;
247 if (hash["x"] != null)
248 {
249 Int32.TryParse((string)hash["x"], out n);
250 region.RegionLocX = n;
251 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
252 }
253 if (hash["y"] != null)
254 {
255 Int32.TryParse((string)hash["y"], out n);
256 region.RegionLocY = n;
257 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
258 }
259 if (hash["region_name"] != null)
260 {
261 region.RegionName = (string)hash["region_name"];
262 //m_log.Debug(">> HERE, name: " + region.RegionName);
263 }
264 if (hash["hostname"] != null)
265 region.ExternalHostName = (string)hash["hostname"];
266 if (hash["http_port"] != null)
267 {
268 uint p = 0;
269 UInt32.TryParse((string)hash["http_port"], out p);
270 region.HttpPort = p;
271 }
272 if (hash["internal_port"] != null)
273 {
274 int p = 0;
275 Int32.TryParse((string)hash["internal_port"], out p);
276 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
277 }
278 if (hash["position"] != null)
279 Vector3.TryParse((string)hash["position"], out position);
280 if (hash["lookAt"] != null)
281 Vector3.TryParse((string)hash["lookAt"], out lookAt);
282
283 // Successful return
284 return region;
285 }
286
287 }
288 catch (Exception e)
289 {
290 return null;
291 }
292
293 return null;
294
295 }
296
297 public bool AgentIsComingHome(UUID sessionID, string thisGridExternalName)
298 {
299 Hashtable hash = new Hashtable();
300 hash["sessionID"] = sessionID.ToString();
301 hash["externalName"] = thisGridExternalName;
302
303 IList paramList = new ArrayList();
304 paramList.Add(hash);
305
306 XmlRpcRequest request = new XmlRpcRequest("agent_is_coming_home", paramList);
307 string reason = string.Empty;
308 return GetBoolResponse(request, out reason);
309 }
310
311 public bool VerifyAgent(UUID sessionID, string token)
312 {
313 Hashtable hash = new Hashtable();
314 hash["sessionID"] = sessionID.ToString();
315 hash["token"] = token;
316
317 IList paramList = new ArrayList();
318 paramList.Add(hash);
319
320 XmlRpcRequest request = new XmlRpcRequest("verify_agent", paramList);
321 string reason = string.Empty;
322 return GetBoolResponse(request, out reason);
323 }
324
325 public bool VerifyClient(UUID sessionID, string token)
326 {
327 Hashtable hash = new Hashtable();
328 hash["sessionID"] = sessionID.ToString();
329 hash["token"] = token;
330
331 IList paramList = new ArrayList();
332 paramList.Add(hash);
333
334 XmlRpcRequest request = new XmlRpcRequest("verify_client", paramList);
335 string reason = string.Empty;
336 return GetBoolResponse(request, out reason);
337 }
338
339 public void LogoutAgent(UUID userID, UUID sessionID)
340 {
341 Hashtable hash = new Hashtable();
342 hash["sessionID"] = sessionID.ToString();
343 hash["userID"] = userID.ToString();
344
345 IList paramList = new ArrayList();
346 paramList.Add(hash);
347
348 XmlRpcRequest request = new XmlRpcRequest("logout_agent", paramList);
349 string reason = string.Empty;
350 GetBoolResponse(request, out reason);
351 }
352
353
354 private bool GetBoolResponse(XmlRpcRequest request, out string reason)
355 {
356 //m_log.Debug("[HGrid]: Linking to " + uri);
357 XmlRpcResponse response = null;
358 try
359 {
360 response = request.Send(m_ServerURL, 10000);
361 }
362 catch (Exception e)
363 {
364 m_log.Debug("[USER AGENT CONNECTOR]: Unable to contact remote server ");
365 reason = "Exception: " + e.Message;
366 return false;
367 }
368
369 if (response.IsFault)
370 {
371 m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString);
372 reason = "XMLRPC Fault";
373 return false;
374 }
375
376 Hashtable hash = (Hashtable)response.Value;
377 //foreach (Object o in hash)
378 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
379 try
380 {
381 bool success = false;
382 reason = string.Empty;
383 Boolean.TryParse((string)hash["result"], out success);
384
385 return success;
386 }
387 catch (Exception e)
388 {
389 m_log.Error("[HGrid]: Got exception while parsing GetEndPoint response " + e.StackTrace);
390 reason = "Exception: " + e.Message;
391 return false;
392 }
393
394 }
395
396 }
397}
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
index b9ccd7e..0cc1978 100644
--- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Services.Connectors
68 IConfig assetConfig = source.Configs["InventoryService"]; 68 IConfig assetConfig = source.Configs["InventoryService"];
69 if (assetConfig == null) 69 if (assetConfig == null)
70 { 70 {
71 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpanSim.ini"); 71 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
72 throw new Exception("Inventory connector init error"); 72 throw new Exception("Inventory connector init error");
73 } 73 }
74 74
@@ -92,6 +92,8 @@ namespace OpenSim.Services.Connectors
92 92
93 if (ret == null) 93 if (ret == null)
94 return false; 94 return false;
95 if (ret.Count == 0)
96 return false;
95 97
96 return bool.Parse(ret["RESULT"].ToString()); 98 return bool.Parse(ret["RESULT"].ToString());
97 } 99 }
@@ -105,6 +107,8 @@ namespace OpenSim.Services.Connectors
105 107
106 if (ret == null) 108 if (ret == null)
107 return null; 109 return null;
110 if (ret.Count == 0)
111 return null;
108 112
109 List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); 113 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
110 114
@@ -123,7 +127,6 @@ namespace OpenSim.Services.Connectors
123 127
124 if (ret == null) 128 if (ret == null)
125 return null; 129 return null;
126
127 if (ret.Count == 0) 130 if (ret.Count == 0)
128 return null; 131 return null;
129 132
@@ -140,7 +143,6 @@ namespace OpenSim.Services.Connectors
140 143
141 if (ret == null) 144 if (ret == null)
142 return null; 145 return null;
143
144 if (ret.Count == 0) 146 if (ret.Count == 0)
145 return null; 147 return null;
146 148
@@ -157,7 +159,6 @@ namespace OpenSim.Services.Connectors
157 159
158 if (ret == null) 160 if (ret == null)
159 return null; 161 return null;
160
161 if (ret.Count == 0) 162 if (ret.Count == 0)
162 return null; 163 return null;
163 164
@@ -182,7 +183,7 @@ namespace OpenSim.Services.Connectors
182 183
183 public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) 184 public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
184 { 185 {
185 Dictionary<string,object> ret = MakeRequest("GETFOLDERCONTENT", 186 Dictionary<string,object> ret = MakeRequest("GETFOLDERITEMS",
186 new Dictionary<string,object> { 187 new Dictionary<string,object> {
187 { "PRINCIPAL", principalID.ToString() }, 188 { "PRINCIPAL", principalID.ToString() },
188 { "FOLDER", folderID.ToString() } 189 { "FOLDER", folderID.ToString() }
@@ -190,7 +191,6 @@ namespace OpenSim.Services.Connectors
190 191
191 if (ret == null) 192 if (ret == null)
192 return null; 193 return null;
193
194 if (ret.Count == 0) 194 if (ret.Count == 0)
195 return null; 195 return null;
196 196
@@ -244,7 +244,8 @@ namespace OpenSim.Services.Connectors
244 Dictionary<string,object> ret = MakeRequest("MOVEFOLDER", 244 Dictionary<string,object> ret = MakeRequest("MOVEFOLDER",
245 new Dictionary<string,object> { 245 new Dictionary<string,object> {
246 { "ParentID", folder.ParentID.ToString() }, 246 { "ParentID", folder.ParentID.ToString() },
247 { "ID", folder.ID.ToString() } 247 { "ID", folder.ID.ToString() },
248 { "PRINCIPAL", folder.Owner.ToString() }
248 }); 249 });
249 250
250 if (ret == null) 251 if (ret == null)
@@ -362,7 +363,7 @@ namespace OpenSim.Services.Connectors
362 363
363 Dictionary<string,object> ret = MakeRequest("MOVEITEMS", 364 Dictionary<string,object> ret = MakeRequest("MOVEITEMS",
364 new Dictionary<string,object> { 365 new Dictionary<string,object> {
365 { "PrincipalID", principalID.ToString() }, 366 { "PRINCIPAL", principalID.ToString() },
366 { "IDLIST", idlist }, 367 { "IDLIST", idlist },
367 { "DESTLIST", destlist } 368 { "DESTLIST", destlist }
368 }); 369 });
@@ -401,7 +402,6 @@ namespace OpenSim.Services.Connectors
401 402
402 if (ret == null) 403 if (ret == null)
403 return null; 404 return null;
404
405 if (ret.Count == 0) 405 if (ret.Count == 0)
406 return null; 406 return null;
407 407
@@ -417,7 +417,6 @@ namespace OpenSim.Services.Connectors
417 417
418 if (ret == null) 418 if (ret == null)
419 return null; 419 return null;
420
421 if (ret.Count == 0) 420 if (ret.Count == 0)
422 return null; 421 return null;
423 422
@@ -531,5 +530,6 @@ namespace OpenSim.Services.Connectors
531 530
532 return item; 531 return item;
533 } 532 }
533
534 } 534 }
535} 535}
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
new file mode 100644
index 0000000..4dadd9e
--- /dev/null
+++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
@@ -0,0 +1,423 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using OpenSim.Server.Base;
40using OpenMetaverse;
41
42namespace OpenSim.Services.Connectors
43{
44 public class PresenceServicesConnector : IPresenceService
45 {
46 private static readonly ILog m_log =
47 LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType);
49
50 private string m_ServerURI = String.Empty;
51
52 public PresenceServicesConnector()
53 {
54 }
55
56 public PresenceServicesConnector(string serverURI)
57 {
58 m_ServerURI = serverURI.TrimEnd('/');
59 }
60
61 public PresenceServicesConnector(IConfigSource source)
62 {
63 Initialise(source);
64 }
65
66 public virtual void Initialise(IConfigSource source)
67 {
68 IConfig gridConfig = source.Configs["PresenceService"];
69 if (gridConfig == null)
70 {
71 m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini");
72 throw new Exception("Presence connector init error");
73 }
74
75 string serviceURI = gridConfig.GetString("PresenceServerURI",
76 String.Empty);
77
78 if (serviceURI == String.Empty)
79 {
80 m_log.Error("[PRESENCE CONNECTOR]: No Server URI named in section PresenceService");
81 throw new Exception("Presence connector init error");
82 }
83 m_ServerURI = serviceURI;
84 }
85
86
87 #region IPresenceService
88
89 public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
90 {
91 Dictionary<string, object> sendData = new Dictionary<string, object>();
92 //sendData["SCOPEID"] = scopeID.ToString();
93 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
94 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
95 sendData["METHOD"] = "login";
96
97 sendData["UserID"] = userID;
98 sendData["SessionID"] = sessionID.ToString();
99 sendData["SecureSessionID"] = secureSessionID.ToString();
100
101 string reqString = ServerUtils.BuildQueryString(sendData);
102 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
103 try
104 {
105 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
106 m_ServerURI + "/presence",
107 reqString);
108 if (reply != string.Empty)
109 {
110 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
111
112 if (replyData.ContainsKey("result"))
113 {
114 if (replyData["result"].ToString().ToLower() == "success")
115 return true;
116 else
117 return false;
118 }
119 else
120 m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent reply data does not contain result field");
121
122 }
123 else
124 m_log.DebugFormat("[PRESENCE CONNECTOR]: LoginAgent received empty reply");
125 }
126 catch (Exception e)
127 {
128 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
129 }
130
131 return false;
132
133 }
134
135 public bool LogoutAgent(UUID sessionID, Vector3 position, Vector3 lookat)
136 {
137 Dictionary<string, object> sendData = new Dictionary<string, object>();
138 //sendData["SCOPEID"] = scopeID.ToString();
139 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
140 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
141 sendData["METHOD"] = "logout";
142
143 sendData["SessionID"] = sessionID.ToString();
144 sendData["Position"] = position.ToString();
145 sendData["LookAt"] = lookat.ToString();
146
147 string reqString = ServerUtils.BuildQueryString(sendData);
148 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
149 try
150 {
151 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
152 m_ServerURI + "/presence",
153 reqString);
154 if (reply != string.Empty)
155 {
156 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
157
158 if (replyData.ContainsKey("result"))
159 {
160 if (replyData["result"].ToString().ToLower() == "success")
161 return true;
162 else
163 return false;
164 }
165 else
166 m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent reply data does not contain result field");
167
168 }
169 else
170 m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutAgent received empty reply");
171 }
172 catch (Exception e)
173 {
174 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
175 }
176
177 return false;
178 }
179
180 public bool LogoutRegionAgents(UUID regionID)
181 {
182 Dictionary<string, object> sendData = new Dictionary<string, object>();
183 //sendData["SCOPEID"] = scopeID.ToString();
184 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
185 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
186 sendData["METHOD"] = "logoutregion";
187
188 sendData["RegionID"] = regionID.ToString();
189
190 string reqString = ServerUtils.BuildQueryString(sendData);
191 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
192 try
193 {
194 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
195 m_ServerURI + "/presence",
196 reqString);
197 if (reply != string.Empty)
198 {
199 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
200
201 if (replyData.ContainsKey("result"))
202 {
203 if (replyData["result"].ToString().ToLower() == "success")
204 return true;
205 else
206 return false;
207 }
208 else
209 m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents reply data does not contain result field");
210
211 }
212 else
213 m_log.DebugFormat("[PRESENCE CONNECTOR]: LogoutRegionAgents received empty reply");
214 }
215 catch (Exception e)
216 {
217 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
218 }
219
220 return false;
221 }
222
223 public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
224 {
225 Dictionary<string, object> sendData = new Dictionary<string, object>();
226 //sendData["SCOPEID"] = scopeID.ToString();
227 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
228 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
229 sendData["METHOD"] = "report";
230
231 sendData["SessionID"] = sessionID.ToString();
232 sendData["RegionID"] = regionID.ToString();
233 sendData["position"] = position.ToString();
234 sendData["lookAt"] = lookAt.ToString();
235
236 string reqString = ServerUtils.BuildQueryString(sendData);
237 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
238 try
239 {
240 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
241 m_ServerURI + "/presence",
242 reqString);
243 if (reply != string.Empty)
244 {
245 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
246
247 if (replyData.ContainsKey("result"))
248 {
249 if (replyData["result"].ToString().ToLower() == "success")
250 return true;
251 else
252 return false;
253 }
254 else
255 m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent reply data does not contain result field");
256
257 }
258 else
259 m_log.DebugFormat("[PRESENCE CONNECTOR]: ReportAgent received empty reply");
260 }
261 catch (Exception e)
262 {
263 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
264 }
265
266 return false;
267 }
268
269 public PresenceInfo GetAgent(UUID sessionID)
270 {
271 Dictionary<string, object> sendData = new Dictionary<string, object>();
272 //sendData["SCOPEID"] = scopeID.ToString();
273 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
274 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
275 sendData["METHOD"] = "getagent";
276
277 sendData["SessionID"] = sessionID.ToString();
278
279 string reply = string.Empty;
280 string reqString = ServerUtils.BuildQueryString(sendData);
281 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
282 try
283 {
284 reply = SynchronousRestFormsRequester.MakeRequest("POST",
285 m_ServerURI + "/presence",
286 reqString);
287 if (reply == null || (reply != null && reply == string.Empty))
288 {
289 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply");
290 return null;
291 }
292 }
293 catch (Exception e)
294 {
295 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
296 }
297
298 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
299 PresenceInfo pinfo = null;
300
301 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
302 {
303 if (replyData["result"] is Dictionary<string, object>)
304 {
305 pinfo = new PresenceInfo((Dictionary<string, object>)replyData["result"]);
306 }
307 }
308
309 return pinfo;
310 }
311
312 public PresenceInfo[] GetAgents(string[] userIDs)
313 {
314 Dictionary<string, object> sendData = new Dictionary<string, object>();
315 //sendData["SCOPEID"] = scopeID.ToString();
316 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
317 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
318 sendData["METHOD"] = "getagents";
319
320 sendData["uuids"] = new List<string>(userIDs);
321
322 string reply = string.Empty;
323 string reqString = ServerUtils.BuildQueryString(sendData);
324 //m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
325 try
326 {
327 reply = SynchronousRestFormsRequester.MakeRequest("POST",
328 m_ServerURI + "/presence",
329 reqString);
330 if (reply == null || (reply != null && reply == string.Empty))
331 {
332 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply");
333 return null;
334 }
335 }
336 catch (Exception e)
337 {
338 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
339 }
340
341 List<PresenceInfo> rinfos = new List<PresenceInfo>();
342
343 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
344
345 if (replyData != null)
346 {
347 if (replyData.ContainsKey("result") &&
348 (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure"))
349 {
350 return new PresenceInfo[0];
351 }
352
353 Dictionary<string, object>.ValueCollection pinfosList = replyData.Values;
354 //m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count);
355 foreach (object presence in pinfosList)
356 {
357 if (presence is Dictionary<string, object>)
358 {
359 PresenceInfo pinfo = new PresenceInfo((Dictionary<string, object>)presence);
360 rinfos.Add(pinfo);
361 }
362 else
363 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received invalid response type {0}",
364 presence.GetType());
365 }
366 }
367 else
368 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null response");
369
370 return rinfos.ToArray();
371 }
372
373
374 public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
375 {
376 Dictionary<string, object> sendData = new Dictionary<string, object>();
377 //sendData["SCOPEID"] = scopeID.ToString();
378 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
379 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
380 sendData["METHOD"] = "sethome";
381
382 sendData["UserID"] = userID;
383 sendData["RegionID"] = regionID.ToString();
384 sendData["position"] = position.ToString();
385 sendData["lookAt"] = lookAt.ToString();
386
387 string reqString = ServerUtils.BuildQueryString(sendData);
388 // m_log.DebugFormat("[PRESENCE CONNECTOR]: queryString = {0}", reqString);
389 try
390 {
391 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
392 m_ServerURI + "/presence",
393 reqString);
394 if (reply != string.Empty)
395 {
396 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
397
398 if (replyData.ContainsKey("result"))
399 {
400 if (replyData["result"].ToString().ToLower() == "success")
401 return true;
402 else
403 return false;
404 }
405 else
406 m_log.DebugFormat("[PRESENCE CONNECTOR]: SetHomeLocation reply data does not contain result field");
407
408 }
409 else
410 m_log.DebugFormat("[PRESENCE CONNECTOR]: SetHomeLocation received empty reply");
411 }
412 catch (Exception e)
413 {
414 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server: {0}", e.Message);
415 }
416
417 return false;
418 }
419
420 #endregion
421
422 }
423}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
new file mode 100644
index 0000000..17febf9
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
@@ -0,0 +1,418 @@
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", this.Name))
89 {
90 IConfig gridConfig = source.Configs["AssetService"];
91 if (gridConfig == null)
92 {
93 m_log.Error("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN ASSET CONNECTOR]: Failed to delete asset " + id + " from the asset service");
404
405 return false;
406 }
407
408 #endregion IAssetService
409
410 public AssetBase GetCached(string id)
411 {
412 if (m_cache != null)
413 return m_cache.Get(id);
414
415 return null;
416 }
417 }
418}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
new file mode 100644
index 0000000..b19135e
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
@@ -0,0 +1,246 @@
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", this.Name))
77 {
78 IConfig assetConfig = source.Configs["AuthenticationService"];
79 if (assetConfig == null)
80 {
81 m_log.Error("[SIMIAN 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("[SIMIAN 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 bool md5hashFound = false;
108
109 OSDArray identities = (OSDArray)response["Identities"];
110 for (int i = 0; i < identities.Count; i++)
111 {
112 OSDMap identity = identities[i] as OSDMap;
113 if (identity != null)
114 {
115 if (identity["Type"].AsString() == "md5hash")
116 {
117 string credential = identity["Credential"].AsString();
118
119 if (password == credential || "$1$" + Utils.MD5String(password) == credential || Utils.MD5String(password) == credential)
120 return Authorize(principalID);
121
122 md5hashFound = true;
123 break;
124 }
125 }
126 }
127
128 if (md5hashFound)
129 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Authentication failed for " + principalID + " using md5hash $1$" + Utils.MD5String(password));
130 else
131 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Authentication failed for " + principalID + ", no md5hash identity found");
132 }
133 else
134 {
135 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Failed to retrieve identities for " + principalID + ": " +
136 response["Message"].AsString());
137 }
138
139 return String.Empty;
140 }
141
142 public bool Verify(UUID principalID, string token, int lifetime)
143 {
144 NameValueCollection requestArgs = new NameValueCollection
145 {
146 { "RequestMethod", "GetSession" },
147 { "SessionID", token }
148 };
149
150 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
151 if (response["Success"].AsBoolean())
152 {
153 return true;
154 }
155 else
156 {
157 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Could not verify session for " + principalID + ": " +
158 response["Message"].AsString());
159 }
160
161 return false;
162 }
163
164 public bool Release(UUID principalID, string token)
165 {
166 NameValueCollection requestArgs = new NameValueCollection
167 {
168 { "RequestMethod", "RemoveSession" },
169 { "UserID", principalID.ToString() }
170 };
171
172 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
173 if (response["Success"].AsBoolean())
174 {
175 return true;
176 }
177 else
178 {
179 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Failed to remove session for " + principalID + ": " +
180 response["Message"].AsString());
181 }
182
183 return false;
184 }
185
186 public bool SetPassword(UUID principalID, string passwd)
187 {
188 // Fetch the user name first
189 NameValueCollection requestArgs = new NameValueCollection
190 {
191 { "RequestMethod", "GetUser" },
192 { "UserID", principalID.ToString() }
193 };
194
195 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
196 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
197 {
198 OSDMap userMap = (OSDMap)response["User"];
199 string identifier = userMap["Name"].AsString();
200
201 if (!String.IsNullOrEmpty(identifier))
202 {
203 // Add/update the md5hash identity
204 requestArgs = new NameValueCollection
205 {
206 { "RequestMethod", "AddIdentity" },
207 { "Identifier", identifier },
208 { "Credential", "$1$" + Utils.MD5String(passwd) },
209 { "Type", "md5hash" },
210 { "UserID", principalID.ToString() }
211 };
212
213 response = WebUtil.PostToService(m_serverUrl, requestArgs);
214 bool success = response["Success"].AsBoolean();
215
216 if (!success)
217 m_log.WarnFormat("[SIMIAN AUTH CONNECTOR]: Failed to set password for {0} ({1})", identifier, principalID);
218
219 return success;
220 }
221 }
222 else
223 {
224 m_log.Warn("[SIMIAN AUTH CONNECTOR]: Failed to retrieve identities for " + principalID + ": " +
225 response["Message"].AsString());
226 }
227
228 return false;
229 }
230
231 private string Authorize(UUID userID)
232 {
233 NameValueCollection requestArgs = new NameValueCollection
234 {
235 { "RequestMethod", "AddSession" },
236 { "UserID", userID.ToString() }
237 };
238
239 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
240 if (response["Success"].AsBoolean())
241 return response["SessionID"].AsUUID().ToString();
242 else
243 return String.Empty;
244 }
245 }
246}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
new file mode 100644
index 0000000..a47f32c
--- /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", this.Name))
82 {
83 IConfig gridConfig = source.Configs["AvatarService"];
84 if (gridConfig == null)
85 {
86 m_log.Error("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN AVATAR CONNECTOR]: Failed saving appearance for " + userID + ": " + response["Message"].AsString());
232
233 return success;
234 }
235 else
236 {
237 m_log.Error("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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..89f3594
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
@@ -0,0 +1,240 @@
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 bool isSimianEnabled = false;
80
81 if (source.Configs["Friends"] != null)
82 {
83 string module = source.Configs["Friends"].GetString("Connector");
84 isSimianEnabled = !String.IsNullOrEmpty(module) && module.EndsWith(this.Name);
85 }
86
87 if (isSimianEnabled)
88 {
89 IConfig assetConfig = source.Configs["FriendsService"];
90 if (assetConfig == null)
91 {
92 m_log.Error("[SIMIAN FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini");
93 throw new Exception("Friends connector init error");
94 }
95
96 string serviceURI = assetConfig.GetString("FriendsServerURI");
97 if (String.IsNullOrEmpty(serviceURI))
98 {
99 m_log.Error("[SIMIAN FRIENDS CONNECTOR]: No Server URI named in section FriendsService");
100 throw new Exception("Friends connector init error");
101 }
102
103 m_serverUrl = serviceURI;
104 }
105 }
106
107 #region IFriendsService
108
109 public FriendInfo[] GetFriends(UUID principalID)
110 {
111 Dictionary<UUID, FriendInfo> friends = new Dictionary<UUID, FriendInfo>();
112
113 OSDArray friendsArray = GetFriended(principalID);
114 OSDArray friendedMeArray = GetFriendedBy(principalID);
115
116 // Load the list of friends and their granted permissions
117 for (int i = 0; i < friendsArray.Count; i++)
118 {
119 OSDMap friendEntry = friendsArray[i] as OSDMap;
120 if (friendEntry != null)
121 {
122 UUID friendID = friendEntry["Key"].AsUUID();
123
124 FriendInfo friend = new FriendInfo();
125 friend.PrincipalID = principalID;
126 friend.Friend = friendID.ToString();
127 friend.MyFlags = friendEntry["Value"].AsInteger();
128 friend.TheirFlags = -1;
129
130 friends[friendID] = friend;
131 }
132 }
133
134 // Load the permissions those friends have granted to this user
135 for (int i = 0; i < friendedMeArray.Count; i++)
136 {
137 OSDMap friendedMeEntry = friendedMeArray[i] as OSDMap;
138 if (friendedMeEntry != null)
139 {
140 UUID friendID = friendedMeEntry["OwnerID"].AsUUID();
141
142 FriendInfo friend;
143 if (friends.TryGetValue(friendID, out friend))
144 friend.TheirFlags = friendedMeEntry["Value"].AsInteger();
145 }
146 }
147
148 // Convert the dictionary of friends to an array and return it
149 FriendInfo[] array = new FriendInfo[friends.Count];
150 int j = 0;
151 foreach (FriendInfo friend in friends.Values)
152 array[j++] = friend;
153
154 return array;
155 }
156
157 public bool StoreFriend(UUID principalID, string friend, int flags)
158 {
159 NameValueCollection requestArgs = new NameValueCollection
160 {
161 { "RequestMethod", "AddGeneric" },
162 { "OwnerID", principalID.ToString() },
163 { "Type", "Friend" },
164 { "Key", friend },
165 { "Value", flags.ToString() }
166 };
167
168 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
169 bool success = response["Success"].AsBoolean();
170
171 if (!success)
172 m_log.Error("[SIMIAN FRIENDS CONNECTOR]: Failed to store friend " + friend + " for user " + principalID + ": " + response["Message"].AsString());
173
174 return success;
175 }
176
177 public bool Delete(UUID principalID, string friend)
178 {
179 NameValueCollection requestArgs = new NameValueCollection
180 {
181 { "RequestMethod", "RemoveGeneric" },
182 { "OwnerID", principalID.ToString() },
183 { "Type", "Friend" },
184 { "Key", friend }
185 };
186
187 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
188 bool success = response["Success"].AsBoolean();
189
190 if (!success)
191 m_log.Error("[SIMIAN FRIENDS CONNECTOR]: Failed to remove friend " + friend + " for user " + principalID + ": " + response["Message"].AsString());
192
193 return success;
194 }
195
196 #endregion IFriendsService
197
198 private OSDArray GetFriended(UUID ownerID)
199 {
200 NameValueCollection requestArgs = new NameValueCollection
201 {
202 { "RequestMethod", "GetGenerics" },
203 { "OwnerID", ownerID.ToString() },
204 { "Type", "Friend" }
205 };
206
207 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
208 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
209 {
210 return (OSDArray)response["Entries"];
211 }
212 else
213 {
214 m_log.Warn("[SIMIAN FRIENDS CONNECTOR]: Failed to retrieve friends for user " + ownerID + ": " + response["Message"].AsString());
215 return new OSDArray(0);
216 }
217 }
218
219 private OSDArray GetFriendedBy(UUID ownerID)
220 {
221 NameValueCollection requestArgs = new NameValueCollection
222 {
223 { "RequestMethod", "GetGenerics" },
224 { "Key", ownerID.ToString() },
225 { "Type", "Friend" }
226 };
227
228 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
229 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
230 {
231 return (OSDArray)response["Entries"];
232 }
233 else
234 {
235 m_log.Warn("[SIMIAN FRIENDS CONNECTOR]: Failed to retrieve reverse friends for user " + ownerID + ": " + response["Message"].AsString());
236 return new OSDArray(0);
237 }
238 }
239 }
240}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
new file mode 100644
index 0000000..7d97aaa
--- /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, string connectorName)
38 {
39 if (config.Configs["Modules"] != null)
40 {
41 string module = config.Configs["Modules"].GetString(moduleName);
42 return !String.IsNullOrEmpty(module) && module.EndsWith(connectorName);
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..3a61226
--- /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", this.Name))
84 {
85 IConfig gridConfig = source.Configs["GridService"];
86 if (gridConfig == null)
87 {
88 m_log.Error("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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..56e7475
--- /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", this.Name))
96 {
97 IConfig gridConfig = source.Configs["InventoryService"];
98 if (gridConfig == null)
99 {
100 m_log.Error("[SIMIAN 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("[SIMIAN 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("[SIMIAN INVENTORY CONNECTOR]: No Server URI named in section UserAccountService");
121 }
122 else
123 {
124 m_log.Warn("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN INVENTORY CONNECTOR]: Default folder not found for content type " + contentType + ": " + response["Message"].AsString());
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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID);
867 }
868 }
869 else
870 {
871 m_log.Warn("[SIMIAN 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("[SIMIAN 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..c324272
--- /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", this.Name))
108 {
109 IConfig gridConfig = source.Configs["PresenceService"];
110 if (gridConfig == null)
111 {
112 m_log.Error("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
241 }
242 else
243 {
244 m_log.Warn("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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).TryGetScenePresence(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.TryGetScenePresence(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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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.Debug("[SIMIAN PRESENCE CONNECTOR]: No session returned 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("[SIMIAN 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("[SIMIAN 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..fbf4648
--- /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", this.Name))
92 {
93 IConfig gridConfig = source.Configs["UserAccountService"];
94 if (gridConfig == null)
95 {
96 m_log.Error("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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..874f1a2
--- /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", this.Name))
81 {
82 IConfig assetConfig = source.Configs["UserAccountService"];
83 if (assetConfig == null)
84 {
85 m_log.Error("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format");
167 }
168 }
169 else
170 {
171 m_log.Warn("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN 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("[SIMIAN ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format");
246 }
247 else
248 {
249 m_log.Warn("[SIMIAN 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/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
new file mode 100644
index 0000000..ff0dd7e
--- /dev/null
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -0,0 +1,601 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34
35using OpenSim.Framework;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using log4net;
42using Nini.Config;
43
44namespace OpenSim.Services.Connectors.Simulation
45{
46 public class SimulationServiceConnector : ISimulationService
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 //private GridRegion m_Region;
51
52 public SimulationServiceConnector()
53 {
54 }
55
56 public SimulationServiceConnector(IConfigSource config)
57 {
58 //m_Region = region;
59 }
60
61 public IScene GetScene(ulong regionHandle)
62 {
63 return null;
64 }
65
66 public ISimulationService GetInnerService()
67 {
68 return null;
69 }
70
71 #region Agents
72
73 protected virtual string AgentPath()
74 {
75 return "/agent/";
76 }
77
78 public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason)
79 {
80 reason = String.Empty;
81
82 if (destination == null)
83 {
84 reason = "Destination is null";
85 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Given destination is null");
86 return false;
87 }
88
89 // Eventually, we want to use a caps url instead of the agentID
90 string uri = string.Empty;
91 try
92 {
93 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + aCircuit.AgentID + "/";
94 }
95 catch (Exception e)
96 {
97 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent create. Reason: " + e.Message);
98 reason = e.Message;
99 return false;
100 }
101
102 //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri);
103
104 HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
105 AgentCreateRequest.Method = "POST";
106 AgentCreateRequest.ContentType = "application/json";
107 AgentCreateRequest.Timeout = 10000;
108 //AgentCreateRequest.KeepAlive = false;
109 //AgentCreateRequest.Headers.Add("Authorization", authKey);
110
111 // Fill it in
112 OSDMap args = PackCreateAgentArguments(aCircuit, destination, flags);
113 if (args == null)
114 return false;
115
116 string strBuffer = "";
117 byte[] buffer = new byte[1];
118 try
119 {
120 strBuffer = OSDParser.SerializeJsonString(args);
121 Encoding str = Util.UTF8;
122 buffer = str.GetBytes(strBuffer);
123
124 }
125 catch (Exception e)
126 {
127 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
128 // ignore. buffer will be empty, caller should check.
129 }
130
131 Stream os = null;
132 try
133 { // send the Post
134 AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
135 os = AgentCreateRequest.GetRequestStream();
136 os.Write(buffer, 0, strBuffer.Length); //Send it
137 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}",
138 uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY);
139 }
140 //catch (WebException ex)
141 catch
142 {
143 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message);
144 reason = "cannot contact remote region";
145 return false;
146 }
147 finally
148 {
149 if (os != null)
150 os.Close();
151 }
152
153 // Let's wait for the response
154 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
155
156 WebResponse webResponse = null;
157 StreamReader sr = null;
158 try
159 {
160 webResponse = AgentCreateRequest.GetResponse();
161 if (webResponse == null)
162 {
163 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on DoCreateChildAgentCall post");
164 }
165 else
166 {
167
168 sr = new StreamReader(webResponse.GetResponseStream());
169 string response = sr.ReadToEnd().Trim();
170 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response);
171
172 if (!String.IsNullOrEmpty(response))
173 {
174 try
175 {
176 // we assume we got an OSDMap back
177 OSDMap r = Util.GetOSDMap(response);
178 bool success = r["success"].AsBoolean();
179 reason = r["reason"].AsString();
180 return success;
181 }
182 catch (NullReferenceException e)
183 {
184 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
185
186 // check for old style response
187 if (response.ToLower().StartsWith("true"))
188 return true;
189
190 return false;
191 }
192 }
193 }
194 }
195 catch (WebException ex)
196 {
197 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
198 reason = "Destination did not reply";
199 return false;
200 }
201 finally
202 {
203 if (sr != null)
204 sr.Close();
205 }
206
207 return true;
208 }
209
210 protected virtual OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion destination, uint flags)
211 {
212 OSDMap args = null;
213 try
214 {
215 args = aCircuit.PackAgentCircuitData();
216 }
217 catch (Exception e)
218 {
219 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message);
220 return null;
221 }
222 // Add the input arguments
223 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
224 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
225 args["destination_name"] = OSD.FromString(destination.RegionName);
226 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
227 args["teleport_flags"] = OSD.FromString(flags.ToString());
228
229 return args;
230 }
231
232 public bool UpdateAgent(GridRegion destination, AgentData data)
233 {
234 return UpdateAgent(destination, (IAgentData)data);
235 }
236
237 public bool UpdateAgent(GridRegion destination, AgentPosition data)
238 {
239 return UpdateAgent(destination, (IAgentData)data);
240 }
241
242 private bool UpdateAgent(GridRegion destination, IAgentData cAgentData)
243 {
244 // Eventually, we want to use a caps url instead of the agentID
245 string uri = string.Empty;
246 try
247 {
248 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + cAgentData.AgentID + "/";
249 }
250 catch (Exception e)
251 {
252 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent update. Reason: " + e.Message);
253 return false;
254 }
255 //Console.WriteLine(" >>> DoAgentUpdateCall <<< " + uri);
256
257 HttpWebRequest ChildUpdateRequest = (HttpWebRequest)WebRequest.Create(uri);
258 ChildUpdateRequest.Method = "PUT";
259 ChildUpdateRequest.ContentType = "application/json";
260 ChildUpdateRequest.Timeout = 10000;
261 //ChildUpdateRequest.KeepAlive = false;
262
263 // Fill it in
264 OSDMap args = null;
265 try
266 {
267 args = cAgentData.Pack();
268 }
269 catch (Exception e)
270 {
271 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: PackUpdateMessage failed with exception: " + e.Message);
272 }
273 // Add the input arguments
274 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
275 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
276 args["destination_name"] = OSD.FromString(destination.RegionName);
277 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
278
279 string strBuffer = "";
280 byte[] buffer = new byte[1];
281 try
282 {
283 strBuffer = OSDParser.SerializeJsonString(args);
284 Encoding str = Util.UTF8;
285 buffer = str.GetBytes(strBuffer);
286
287 }
288 catch (Exception e)
289 {
290 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of ChildUpdate: {0}", e.Message);
291 // ignore. buffer will be empty, caller should check.
292 }
293
294 Stream os = null;
295 try
296 { // send the Post
297 ChildUpdateRequest.ContentLength = buffer.Length; //Count bytes to send
298 os = ChildUpdateRequest.GetRequestStream();
299 os.Write(buffer, 0, strBuffer.Length); //Send it
300 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted AgentUpdate request to remote sim {0}", uri);
301 }
302 catch (WebException ex)
303 //catch
304 {
305 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on AgentUpdate {0}", ex.Message);
306
307 return false;
308 }
309 finally
310 {
311 if (os != null)
312 os.Close();
313 }
314
315 // Let's wait for the response
316 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after ChildAgentUpdate");
317
318 WebResponse webResponse = null;
319 StreamReader sr = null;
320 try
321 {
322 webResponse = ChildUpdateRequest.GetResponse();
323 if (webResponse == null)
324 {
325 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on ChilAgentUpdate post");
326 }
327
328 sr = new StreamReader(webResponse.GetResponseStream());
329 //reply = sr.ReadToEnd().Trim();
330 sr.ReadToEnd().Trim();
331 sr.Close();
332 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
333
334 }
335 catch (WebException ex)
336 {
337 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of ChilAgentUpdate {0}", ex.Message);
338 // ignore, really
339 }
340 finally
341 {
342 if (sr != null)
343 sr.Close();
344 }
345
346 return true;
347 }
348
349 public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
350 {
351 agent = null;
352 // Eventually, we want to use a caps url instead of the agentID
353 string uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + id + "/" + destination.RegionID.ToString() + "/";
354 //Console.WriteLine(" >>> DoRetrieveRootAgentCall <<< " + uri);
355
356 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
357 request.Method = "GET";
358 request.Timeout = 10000;
359 //request.Headers.Add("authorization", ""); // coming soon
360
361 HttpWebResponse webResponse = null;
362 string reply = string.Empty;
363 StreamReader sr = null;
364 try
365 {
366 webResponse = (HttpWebResponse)request.GetResponse();
367 if (webResponse == null)
368 {
369 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on agent get ");
370 }
371
372 sr = new StreamReader(webResponse.GetResponseStream());
373 reply = sr.ReadToEnd().Trim();
374
375 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was " + reply);
376
377 }
378 catch (WebException ex)
379 {
380 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of agent get {0}", ex.Message);
381 // ignore, really
382 return false;
383 }
384 finally
385 {
386 if (sr != null)
387 sr.Close();
388 }
389
390 if (webResponse.StatusCode == HttpStatusCode.OK)
391 {
392 // we know it's jason
393 OSDMap args = Util.GetOSDMap(reply);
394 if (args == null)
395 {
396 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: Error getting OSDMap from reply");
397 return false;
398 }
399
400 agent = new CompleteAgentData();
401 agent.Unpack(args);
402 return true;
403 }
404
405 //Console.WriteLine("[REMOTE SIMULATION CONNECTOR]: DoRetrieveRootAgentCall returned status " + webResponse.StatusCode);
406 return false;
407 }
408
409 public bool ReleaseAgent(UUID origin, UUID id, string uri)
410 {
411 WebRequest request = WebRequest.Create(uri);
412 request.Method = "DELETE";
413 request.Timeout = 10000;
414
415 StreamReader sr = null;
416 try
417 {
418 WebResponse webResponse = request.GetResponse();
419 if (webResponse == null)
420 {
421 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on ReleaseAgent");
422 }
423
424 sr = new StreamReader(webResponse.GetResponseStream());
425 //reply = sr.ReadToEnd().Trim();
426 sr.ReadToEnd().Trim();
427 sr.Close();
428 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
429
430 }
431 catch (WebException ex)
432 {
433 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of ReleaseAgent {0}", ex.Message);
434 return false;
435 }
436 finally
437 {
438 if (sr != null)
439 sr.Close();
440 }
441
442 return true;
443 }
444
445 public bool CloseAgent(GridRegion destination, UUID id)
446 {
447 string uri = string.Empty;
448 try
449 {
450 uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + id + "/" + destination.RegionID.ToString() + "/";
451 }
452 catch (Exception e)
453 {
454 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Unable to resolve external endpoint on agent close. Reason: " + e.Message);
455 return false;
456 }
457
458 //Console.WriteLine(" >>> DoCloseAgentCall <<< " + uri);
459
460 WebRequest request = WebRequest.Create(uri);
461 request.Method = "DELETE";
462 request.Timeout = 10000;
463
464 StreamReader sr = null;
465 try
466 {
467 WebResponse webResponse = request.GetResponse();
468 if (webResponse == null)
469 {
470 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on agent delete ");
471 }
472
473 sr = new StreamReader(webResponse.GetResponseStream());
474 //reply = sr.ReadToEnd().Trim();
475 sr.ReadToEnd().Trim();
476 sr.Close();
477 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: ChilAgentUpdate reply was {0} ", reply);
478
479 }
480 catch (WebException ex)
481 {
482 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of agent delete {0}", ex.Message);
483 return false;
484 }
485 finally
486 {
487 if (sr != null)
488 sr.Close();
489 }
490
491 return true;
492 }
493
494 #endregion Agents
495
496 #region Objects
497
498 protected virtual string ObjectPath()
499 {
500 return "/object/";
501 }
502
503 public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
504 {
505 string uri
506 = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + ObjectPath() + sog.UUID + "/";
507 //m_log.Debug(" >>> DoCreateObjectCall <<< " + uri);
508
509 WebRequest ObjectCreateRequest = WebRequest.Create(uri);
510 ObjectCreateRequest.Method = "POST";
511 ObjectCreateRequest.ContentType = "application/json";
512 ObjectCreateRequest.Timeout = 10000;
513
514 OSDMap args = new OSDMap(2);
515 args["sog"] = OSD.FromString(sog.ToXml2());
516 args["extra"] = OSD.FromString(sog.ExtraToXmlString());
517 string state = sog.GetStateSnapshot();
518 if (state.Length > 0)
519 args["state"] = OSD.FromString(state);
520 // Add the input general arguments
521 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
522 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
523 args["destination_name"] = OSD.FromString(destination.RegionName);
524 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
525
526 string strBuffer = "";
527 byte[] buffer = new byte[1];
528 try
529 {
530 strBuffer = OSDParser.SerializeJsonString(args);
531 Encoding str = Util.UTF8;
532 buffer = str.GetBytes(strBuffer);
533
534 }
535 catch (Exception e)
536 {
537 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR]: Exception thrown on serialization of CreateObject: {0}", e.Message);
538 // ignore. buffer will be empty, caller should check.
539 }
540
541 Stream os = null;
542 try
543 { // send the Post
544 ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send
545 os = ObjectCreateRequest.GetRequestStream();
546 os.Write(buffer, 0, strBuffer.Length); //Send it
547 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Posted CreateObject request to remote sim {0}", uri);
548 }
549 catch (WebException ex)
550 {
551 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: Bad send on CreateObject {0}", ex.Message);
552 return false;
553 }
554 finally
555 {
556 if (os != null)
557 os.Close();
558 }
559
560 // Let's wait for the response
561 //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
562
563 StreamReader sr = null;
564 try
565 {
566 WebResponse webResponse = ObjectCreateRequest.GetResponse();
567 if (webResponse == null)
568 {
569 m_log.Info("[REMOTE SIMULATION CONNECTOR]: Null reply on CreateObject post");
570 return false;
571 }
572
573 sr = new StreamReader(webResponse.GetResponseStream());
574 //reply = sr.ReadToEnd().Trim();
575 sr.ReadToEnd().Trim();
576 //m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", reply);
577
578 }
579 catch (WebException ex)
580 {
581 m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of CreateObject {0}", ex.Message);
582 return false;
583 }
584 finally
585 {
586 if (sr != null)
587 sr.Close();
588 }
589
590 return true;
591 }
592
593 public bool CreateObject(GridRegion destination, UUID userID, UUID itemID)
594 {
595 // TODO, not that urgent
596 return false;
597 }
598
599 #endregion Objects
600 }
601}
diff --git a/OpenSim/Services/Connectors/User/UserServiceConnector.cs b/OpenSim/Services/Connectors/User/UserServiceConnector.cs
deleted file mode 100644
index 683990f..0000000
--- a/OpenSim/Services/Connectors/User/UserServiceConnector.cs
+++ /dev/null
@@ -1,114 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Services.Interfaces;
38using OpenMetaverse;
39
40namespace OpenSim.Services.Connectors
41{
42 public class UserServicesConnector : IUserAccountService
43 {
44 private static readonly ILog m_log =
45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType);
47
48// private string m_ServerURI = String.Empty;
49
50 public UserServicesConnector()
51 {
52 }
53
54 public UserServicesConnector(string serverURI)
55 {
56// m_ServerURI = serverURI.TrimEnd('/');
57 }
58
59 public UserServicesConnector(IConfigSource source)
60 {
61 Initialise(source);
62 }
63
64 public virtual void Initialise(IConfigSource source)
65 {
66 IConfig assetConfig = source.Configs["UserService"];
67 if (assetConfig == null)
68 {
69 m_log.Error("[USER CONNECTOR]: UserService missing from OpanSim.ini");
70 throw new Exception("User connector init error");
71 }
72
73 string serviceURI = assetConfig.GetString("UserServerURI",
74 String.Empty);
75
76 if (serviceURI == String.Empty)
77 {
78 m_log.Error("[USER CONNECTOR]: No Server URI named in section UserService");
79 throw new Exception("User connector init error");
80 }
81 //m_ServerURI = serviceURI;
82 }
83
84 public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
85 {
86 return null;
87 }
88
89 public UserAccount GetUserAccount(UUID scopeID, UUID userID)
90 {
91 return null;
92 }
93
94 public bool SetHomePosition(UserAccount data, UUID regionID, UUID regionSecret)
95 {
96 return false;
97 }
98
99 public bool SetUserAccount(UserAccount data, UUID principalID, string token)
100 {
101 return false;
102 }
103
104 public bool CreateUserAccount(UserAccount data, UUID principalID, string token)
105 {
106 return false;
107 }
108
109 public List<UserAccount> GetUserAccount(UUID scopeID, string query)
110 {
111 return null;
112 }
113 }
114}
diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs
new file mode 100644
index 0000000..1527db2
--- /dev/null
+++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs
@@ -0,0 +1,278 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Server.Base;
38using OpenSim.Services.Interfaces;
39using OpenMetaverse;
40
41namespace OpenSim.Services.Connectors
42{
43 public class UserAccountServicesConnector : IUserAccountService
44 {
45 private static readonly ILog m_log =
46 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType);
48
49 private string m_ServerURI = String.Empty;
50
51 public UserAccountServicesConnector()
52 {
53 }
54
55 public UserAccountServicesConnector(string serverURI)
56 {
57 m_ServerURI = serverURI.TrimEnd('/');
58 }
59
60 public UserAccountServicesConnector(IConfigSource source)
61 {
62 Initialise(source);
63 }
64
65 public virtual void Initialise(IConfigSource source)
66 {
67 IConfig assetConfig = source.Configs["UserAccountService"];
68 if (assetConfig == null)
69 {
70 m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini");
71 throw new Exception("User account connector init error");
72 }
73
74 string serviceURI = assetConfig.GetString("UserAccountServerURI",
75 String.Empty);
76
77 if (serviceURI == String.Empty)
78 {
79 m_log.Error("[ACCOUNT CONNECTOR]: No Server URI named in section UserAccountService");
80 throw new Exception("User account connector init error");
81 }
82 m_ServerURI = serviceURI;
83 }
84
85 public virtual UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
86 {
87 Dictionary<string, object> sendData = new Dictionary<string, object>();
88 //sendData["SCOPEID"] = scopeID.ToString();
89 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
90 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
91 sendData["METHOD"] = "getaccount";
92
93 sendData["ScopeID"] = scopeID;
94 sendData["FirstName"] = firstName.ToString();
95 sendData["LastName"] = lastName.ToString();
96
97 return SendAndGetReply(sendData);
98 }
99
100 public virtual UserAccount GetUserAccount(UUID scopeID, string email)
101 {
102 Dictionary<string, object> sendData = new Dictionary<string, object>();
103 //sendData["SCOPEID"] = scopeID.ToString();
104 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
105 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
106 sendData["METHOD"] = "getaccount";
107
108 sendData["ScopeID"] = scopeID;
109 sendData["Email"] = email;
110
111 return SendAndGetReply(sendData);
112 }
113
114 public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID)
115 {
116 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUSerAccount {0}", userID);
117 Dictionary<string, object> sendData = new Dictionary<string, object>();
118 //sendData["SCOPEID"] = scopeID.ToString();
119 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
120 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
121 sendData["METHOD"] = "getaccount";
122
123 sendData["ScopeID"] = scopeID;
124 sendData["UserID"] = userID.ToString();
125
126 return SendAndGetReply(sendData);
127 }
128
129 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
130 {
131 Dictionary<string, object> sendData = new Dictionary<string, object>();
132 //sendData["SCOPEID"] = scopeID.ToString();
133 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
134 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
135 sendData["METHOD"] = "getaccounts";
136
137 sendData["ScopeID"] = scopeID.ToString();
138 sendData["query"] = query;
139
140 string reply = string.Empty;
141 string reqString = ServerUtils.BuildQueryString(sendData);
142 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
143 try
144 {
145 reply = SynchronousRestFormsRequester.MakeRequest("POST",
146 m_ServerURI + "/accounts",
147 reqString);
148 if (reply == null || (reply != null && reply == string.Empty))
149 {
150 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received null or empty reply");
151 return null;
152 }
153 }
154 catch (Exception e)
155 {
156 m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting accounts server: {0}", e.Message);
157 }
158
159 List<UserAccount> accounts = new List<UserAccount>();
160
161 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
162
163 if (replyData != null)
164 {
165 if (replyData.ContainsKey("result") && replyData.ContainsKey("result").ToString() == "null")
166 {
167 return accounts;
168 }
169
170 Dictionary<string, object>.ValueCollection accountList = replyData.Values;
171 //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetAgents returned {0} elements", pinfosList.Count);
172 foreach (object acc in accountList)
173 {
174 if (acc is Dictionary<string, object>)
175 {
176 UserAccount pinfo = new UserAccount((Dictionary<string, object>)acc);
177 accounts.Add(pinfo);
178 }
179 else
180 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received invalid response type {0}",
181 acc.GetType());
182 }
183 }
184 else
185 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccounts received null response");
186
187 return accounts;
188 }
189
190 public virtual bool StoreUserAccount(UserAccount data)
191 {
192 Dictionary<string, object> sendData = new Dictionary<string, object>();
193 //sendData["SCOPEID"] = scopeID.ToString();
194 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
195 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
196 sendData["METHOD"] = "setaccount";
197
198 Dictionary<string, object> structData = data.ToKeyValuePairs();
199
200 foreach (KeyValuePair<string,object> kvp in structData)
201 sendData[kvp.Key] = kvp.Value.ToString();
202
203 return SendAndGetBoolReply(sendData);
204 }
205
206 private UserAccount SendAndGetReply(Dictionary<string, object> sendData)
207 {
208 string reply = string.Empty;
209 string reqString = ServerUtils.BuildQueryString(sendData);
210 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
211 try
212 {
213 reply = SynchronousRestFormsRequester.MakeRequest("POST",
214 m_ServerURI + "/accounts",
215 reqString);
216 if (reply == null || (reply != null && reply == string.Empty))
217 {
218 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccount received null or empty reply");
219 return null;
220 }
221 }
222 catch (Exception e)
223 {
224 m_log.DebugFormat("[ACCOUNT CONNECTOR]: Exception when contacting user account server: {0}", e.Message);
225 }
226
227 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
228 UserAccount account = null;
229
230 if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null))
231 {
232 if (replyData["result"] is Dictionary<string, object>)
233 {
234 account = new UserAccount((Dictionary<string, object>)replyData["result"]);
235 }
236 }
237
238 return account;
239
240 }
241
242 private bool SendAndGetBoolReply(Dictionary<string, object> sendData)
243 {
244 string reqString = ServerUtils.BuildQueryString(sendData);
245 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
246 try
247 {
248 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
249 m_ServerURI + "/accounts",
250 reqString);
251 if (reply != string.Empty)
252 {
253 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
254
255 if (replyData.ContainsKey("result"))
256 {
257 if (replyData["result"].ToString().ToLower() == "success")
258 return true;
259 else
260 return false;
261 }
262 else
263 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount reply data does not contain result field");
264
265 }
266 else
267 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Set or Create UserAccount received empty reply");
268 }
269 catch (Exception e)
270 {
271 m_log.DebugFormat("[ACCOUNTS CONNECTOR]: Exception when contacting user account server: {0}", e.Message);
272 }
273
274 return false;
275 }
276
277 }
278}