diff options
Diffstat (limited to 'OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs')
-rw-r--r-- | OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs | 881 |
1 files changed, 881 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs new file mode 100644 index 0000000..f6f0e8f --- /dev/null +++ b/OpenSim/Region/Environment/Modules/InterGrid/OpenGridProtocolModule.cs | |||
@@ -0,0 +1,881 @@ | |||
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 OpenSim 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 | using System; | ||
28 | using System.Collections; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Net; | ||
32 | using System.Net.Security; | ||
33 | using System.Net.Sockets; | ||
34 | using System.Reflection; | ||
35 | using System.Text.RegularExpressions; | ||
36 | using System.Threading; | ||
37 | |||
38 | using libsecondlife; | ||
39 | using libsecondlife.StructuredData; | ||
40 | |||
41 | using log4net; | ||
42 | using Nini.Config; | ||
43 | using Nwc.XmlRpc; | ||
44 | |||
45 | using OpenSim.Framework; | ||
46 | using OpenSim.Region.Environment.Interfaces; | ||
47 | using OpenSim.Region.Environment.Scenes; | ||
48 | using OpenSim.Framework.Communications.Cache; | ||
49 | using OpenSim.Framework.Communications.Capabilities; | ||
50 | using OpenSim.Framework.Statistics; | ||
51 | using LLSD = libsecondlife.StructuredData.LLSD; | ||
52 | using LLSDMap = libsecondlife.StructuredData.LLSDMap; | ||
53 | using LLSDArray = libsecondlife.StructuredData.LLSDArray; | ||
54 | |||
55 | namespace OpenSim.Region.Environment.Modules.InterGrid | ||
56 | { | ||
57 | public struct OGPState | ||
58 | { | ||
59 | public string first_name; | ||
60 | public string last_name; | ||
61 | public LLUUID agent_id; | ||
62 | public LLUUID local_agent_id; | ||
63 | public LLUUID region_id; | ||
64 | public uint circuit_code; | ||
65 | public LLUUID secure_session_id; | ||
66 | public LLUUID session_id; | ||
67 | public bool agent_access; | ||
68 | public string sim_access; | ||
69 | public uint god_level; | ||
70 | public bool god_overide; | ||
71 | public bool identified; | ||
72 | public bool transacted; | ||
73 | public bool age_verified; | ||
74 | public bool allow_redirect; | ||
75 | public int limited_to_estate; | ||
76 | public string inventory_host; | ||
77 | public bool src_can_see_mainland; | ||
78 | public int src_estate_id; | ||
79 | } | ||
80 | |||
81 | |||
82 | public class OpenGridProtocolModule : IRegionModule | ||
83 | { | ||
84 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
85 | private List<Scene> m_scene = new List<Scene>(); | ||
86 | |||
87 | private Dictionary<string, AgentCircuitData> CapsLoginID = new Dictionary<string, AgentCircuitData>(); | ||
88 | private Dictionary<LLUUID, OGPState> m_OGPState = new Dictionary<LLUUID, OGPState>(); | ||
89 | |||
90 | |||
91 | |||
92 | #region IRegionModule Members | ||
93 | |||
94 | public void Initialise(Scene scene, IConfigSource config) | ||
95 | { | ||
96 | bool enabled = false; | ||
97 | IConfig cfg = null; | ||
98 | try | ||
99 | { | ||
100 | cfg = config.Configs["OpenGridProtocol"]; | ||
101 | } catch (NullReferenceException) | ||
102 | { | ||
103 | enabled = false; | ||
104 | } | ||
105 | if (cfg != null) | ||
106 | { | ||
107 | enabled = cfg.GetBoolean("ogp_enabled", false); | ||
108 | if (enabled) | ||
109 | { | ||
110 | m_log.Warn("[OGP]: Open Grid Protocol is on, Listening for Clients on /agent/"); | ||
111 | lock (m_scene) | ||
112 | { | ||
113 | if (m_scene.Count == 0) | ||
114 | { | ||
115 | scene.AddLLSDHandler("/agent/", ProcessAgentDomainMessage); | ||
116 | } | ||
117 | |||
118 | if (!m_scene.Contains(scene)) | ||
119 | m_scene.Add(scene); | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | // Of interest to this module potentially | ||
124 | //scene.EventManager.OnNewClient += OnNewClient; | ||
125 | //scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage; | ||
126 | //scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | ||
127 | //scene.EventManager.OnMakeChildAgent += MakeChildAgent; | ||
128 | //scene.EventManager.OnClientClosed += ClientLoggedOut; | ||
129 | } | ||
130 | |||
131 | public void PostInitialise() | ||
132 | { | ||
133 | } | ||
134 | |||
135 | public void Close() | ||
136 | { | ||
137 | } | ||
138 | |||
139 | public string Name | ||
140 | { | ||
141 | get { return "OpenGridProtocolModule"; } | ||
142 | } | ||
143 | |||
144 | public bool IsSharedModule | ||
145 | { | ||
146 | get { return true; } | ||
147 | } | ||
148 | |||
149 | #endregion | ||
150 | |||
151 | public LLSD ProcessAgentDomainMessage(string path, LLSD request, string endpoint) | ||
152 | { | ||
153 | // /agent/* | ||
154 | |||
155 | string[] pathSegments = path.Split('/'); | ||
156 | if (pathSegments.Length < 1) | ||
157 | { | ||
158 | return GenerateNoHandlerMessage(); | ||
159 | } | ||
160 | |||
161 | m_log.InfoFormat("[OGP]: path {0}, segments {1} segment[1] {2} Last segment {3}", | ||
162 | path, pathSegments.Length, pathSegments[1], pathSegments[pathSegments.Length - 1]); | ||
163 | |||
164 | switch (pathSegments[pathSegments.Length - 1]) | ||
165 | { | ||
166 | case "rez_avatar": | ||
167 | return RezAvatarMethod(path, request); | ||
168 | //break; | ||
169 | case "derez_avatar": | ||
170 | return DerezAvatarMethod(path, request); | ||
171 | //break; | ||
172 | |||
173 | } | ||
174 | if (path.Length < 2) | ||
175 | { | ||
176 | return GenerateNoHandlerMessage(); | ||
177 | } | ||
178 | |||
179 | switch (pathSegments[pathSegments.Length - 2] + "/" + pathSegments[pathSegments.Length - 1]) | ||
180 | { | ||
181 | case "rez_avatar/rez": | ||
182 | return RezAvatarMethod(path, request); | ||
183 | //break; | ||
184 | case "rez_avatar/request": | ||
185 | return RequestRezAvatarMethod(path, request); | ||
186 | //break; | ||
187 | default: | ||
188 | return GenerateNoHandlerMessage(); | ||
189 | } | ||
190 | //return null; | ||
191 | } | ||
192 | |||
193 | public LLSD RequestRezAvatarMethod(string path, LLSD request) | ||
194 | { | ||
195 | m_log.WarnFormat("[REQUESTREZAVATAR]: {0}", request.ToString()); | ||
196 | |||
197 | LLSDMap requestMap = (LLSDMap)request; | ||
198 | |||
199 | Scene homeScene = GetRootScene(); | ||
200 | |||
201 | |||
202 | |||
203 | if (homeScene == null) | ||
204 | return GenerateNoHandlerMessage(); | ||
205 | |||
206 | |||
207 | RegionInfo reg = homeScene.RegionInfo; | ||
208 | ulong regionhandle = GetOSCompatibleRegionHandle(reg); | ||
209 | string RegionURI = reg.ServerURI; | ||
210 | int RegionPort = (int)reg.HttpPort; | ||
211 | |||
212 | LLUUID RemoteAgentID = requestMap["agent_id"].AsUUID(); | ||
213 | |||
214 | // will be used in the future. The client always connects with the aditi agentid currently | ||
215 | LLUUID LocalAgentID = RemoteAgentID; | ||
216 | |||
217 | string FirstName = requestMap["first_name"].AsString(); | ||
218 | string LastName = requestMap["last_name"].AsString(); | ||
219 | |||
220 | |||
221 | OGPState userState = GetOGPState(LocalAgentID); | ||
222 | |||
223 | userState.first_name = requestMap["first_name"].AsString(); | ||
224 | userState.last_name = requestMap["last_name"].AsString(); | ||
225 | userState.age_verified = requestMap["age_verified"].AsBoolean(); | ||
226 | userState.transacted = requestMap["transacted"].AsBoolean(); | ||
227 | userState.agent_access = requestMap["agent_access"].AsBoolean(); | ||
228 | userState.allow_redirect = requestMap["allow_redirect"].AsBoolean(); | ||
229 | userState.identified = requestMap["identified"].AsBoolean(); | ||
230 | userState.god_level = (uint)requestMap["god_level"].AsInteger(); | ||
231 | userState.sim_access = requestMap["sim_access"].AsString(); | ||
232 | userState.agent_id = RemoteAgentID; | ||
233 | userState.limited_to_estate = requestMap["limited_to_estate"].AsInteger(); | ||
234 | userState.src_can_see_mainland = requestMap["src_can_see_mainland"].AsBoolean(); | ||
235 | userState.src_estate_id = requestMap["src_estate_id"].AsInteger(); | ||
236 | userState.local_agent_id = LocalAgentID; | ||
237 | |||
238 | UpdateOGPState(LocalAgentID, userState); | ||
239 | |||
240 | LLSDMap responseMap = new LLSDMap(); | ||
241 | responseMap["sim_host"] = LLSD.FromString(Util.GetHostFromDNS(reg.ExternalHostName).ToString()); | ||
242 | responseMap["sim_ip"] = LLSD.FromString(Util.GetHostFromDNS(reg.ExternalHostName).ToString()); | ||
243 | responseMap["connect"] = LLSD.FromBoolean(true); | ||
244 | responseMap["sim_port"] = LLSD.FromInteger(reg.InternalEndPoint.Port); | ||
245 | responseMap["region_x"] = LLSD.FromInteger(reg.RegionLocX * (uint)Constants.RegionSize); // LLX | ||
246 | responseMap["region_Y"] = LLSD.FromInteger(reg.RegionLocY * (uint)Constants.RegionSize); // LLY | ||
247 | responseMap["region_id"] = LLSD.FromUUID(reg.originRegionID); | ||
248 | responseMap["sim_access"] = LLSD.FromString((reg.RegionSettings.Maturity == 1) ? "Mature" : "PG"); | ||
249 | |||
250 | // Generate a dummy agent for the user so we can get back a CAPS path | ||
251 | AgentCircuitData agentData = new AgentCircuitData(); | ||
252 | agentData.AgentID = LocalAgentID; | ||
253 | agentData.BaseFolder=LLUUID.Zero; | ||
254 | agentData.CapsPath=Util.GetRandomCapsPath(); | ||
255 | agentData.child = false; | ||
256 | agentData.circuitcode = (uint)(Util.RandomClass.Next()); | ||
257 | agentData.firstname = FirstName; | ||
258 | agentData.lastname = LastName; | ||
259 | agentData.SecureSessionID=LLUUID.Random(); | ||
260 | agentData.SessionID=LLUUID.Random(); | ||
261 | agentData.startpos=LLVector3.Zero; | ||
262 | |||
263 | // Pre-Fill our region cache with information on the agent. | ||
264 | UserAgentData useragent = new UserAgentData(); | ||
265 | useragent.AgentIP="unknown"; | ||
266 | useragent.AgentOnline=true; | ||
267 | useragent.AgentPort = (uint)0; | ||
268 | useragent.Handle = regionhandle; | ||
269 | useragent.InitialRegion = reg.originRegionID; | ||
270 | useragent.LoginTime=Util.UnixTimeSinceEpoch(); | ||
271 | useragent.LogoutTime = 0; | ||
272 | useragent.Position=agentData.startpos; | ||
273 | useragent.PositionX=agentData.startpos.X; | ||
274 | useragent.PositionY=agentData.startpos.Y; | ||
275 | useragent.PositionZ=agentData.startpos.Z; | ||
276 | useragent.Region=reg.originRegionID; | ||
277 | useragent.SecureSessionID=agentData.SecureSessionID; | ||
278 | useragent.SessionID = agentData.SessionID; | ||
279 | |||
280 | |||
281 | UserProfileData userProfile = new UserProfileData(); | ||
282 | userProfile.AboutText = "OGP User"; | ||
283 | userProfile.CanDoMask = (uint)0; | ||
284 | userProfile.Created = Util.UnixTimeSinceEpoch(); | ||
285 | userProfile.CurrentAgent = useragent; | ||
286 | userProfile.CustomType = "OGP"; | ||
287 | userProfile.FirstLifeAboutText = "I'm testing OpenGrid Protocol"; | ||
288 | userProfile.FirstLifeImage = LLUUID.Zero; | ||
289 | userProfile.FirstName = agentData.firstname; | ||
290 | userProfile.GodLevel = 0; | ||
291 | userProfile.HomeLocation = agentData.startpos; | ||
292 | userProfile.HomeLocationX = agentData.startpos.X; | ||
293 | userProfile.HomeLocationY = agentData.startpos.Y; | ||
294 | userProfile.HomeLocationZ = agentData.startpos.Z; | ||
295 | userProfile.HomeLookAt = LLVector3.Zero; | ||
296 | userProfile.HomeLookAtX = userProfile.HomeLookAt.X; | ||
297 | userProfile.HomeLookAtY = userProfile.HomeLookAt.Y; | ||
298 | userProfile.HomeLookAtZ = userProfile.HomeLookAt.Z; | ||
299 | userProfile.HomeRegion = reg.RegionHandle; | ||
300 | userProfile.HomeRegionID = reg.originRegionID; | ||
301 | userProfile.HomeRegionX = reg.RegionLocX; | ||
302 | userProfile.HomeRegionY = reg.RegionLocY; | ||
303 | userProfile.ID = agentData.AgentID; | ||
304 | userProfile.Image = LLUUID.Zero; | ||
305 | userProfile.LastLogin = Util.UnixTimeSinceEpoch(); | ||
306 | userProfile.Partner = LLUUID.Zero; | ||
307 | userProfile.PasswordHash = "$1$"; | ||
308 | userProfile.PasswordSalt = ""; | ||
309 | userProfile.RootInventoryFolderID = LLUUID.Zero; | ||
310 | userProfile.SurName = agentData.lastname; | ||
311 | userProfile.UserAssetURI = homeScene.CommsManager.NetworkServersInfo.AssetURL; | ||
312 | userProfile.UserFlags = 0; | ||
313 | userProfile.UserInventoryURI = homeScene.CommsManager.NetworkServersInfo.InventoryURL; | ||
314 | userProfile.WantDoMask = 0; | ||
315 | userProfile.WebLoginKey = LLUUID.Random(); | ||
316 | |||
317 | // Do caps registration | ||
318 | // get seed cap | ||
319 | |||
320 | |||
321 | // Stick our data in the cache so the region will know something about us | ||
322 | homeScene.CommsManager.UserProfileCacheService.PreloadUserCache(agentData.AgentID, userProfile); | ||
323 | |||
324 | // Call 'new user' event handler | ||
325 | homeScene.NewUserConnection(reg.RegionHandle, agentData); | ||
326 | |||
327 | |||
328 | string raCap = string.Empty; | ||
329 | |||
330 | LLUUID AvatarRezCapUUID = LLUUID.Random(); | ||
331 | string rezAvatarPath = "/agent/" + AvatarRezCapUUID + "/rez_avatar"; | ||
332 | |||
333 | // Get a reference to the user's cap so we can pull out the Caps Object Path | ||
334 | OpenSim.Framework.Communications.Capabilities.Caps userCap = homeScene.GetCapsHandlerForUser(agentData.AgentID); | ||
335 | |||
336 | responseMap["seed_capability"] = LLSD.FromString("http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + userCap.CapsObjectPath + "0000/"); | ||
337 | |||
338 | responseMap["rez_avatar/rez"] = LLSD.FromString("http://" + reg.ExternalHostName + ":" + reg.HttpPort + rezAvatarPath); | ||
339 | |||
340 | // Add the user to the list of CAPS that are outstanding. | ||
341 | // well allow the caps hosts in this dictionary | ||
342 | lock (CapsLoginID) | ||
343 | { | ||
344 | if (CapsLoginID.ContainsKey(rezAvatarPath)) | ||
345 | { | ||
346 | m_log.Error("[OGP]: Holy anomoly batman! Caps path already existed! All the UUID Duplication worries were founded!"); | ||
347 | } | ||
348 | else | ||
349 | { | ||
350 | CapsLoginID.Add(rezAvatarPath, agentData); | ||
351 | } | ||
352 | } | ||
353 | |||
354 | return responseMap; | ||
355 | } | ||
356 | |||
357 | public LLSD RezAvatarMethod(string path, LLSD request) | ||
358 | { | ||
359 | m_log.WarnFormat("[REZAVATAR]: {0}", request.ToString()); | ||
360 | |||
361 | LLSDMap responseMap = new LLSDMap(); | ||
362 | |||
363 | AgentCircuitData userData = null; | ||
364 | |||
365 | // Only people we've issued a cap can go further | ||
366 | if (TryGetAgentCircuitData(path,out userData)) | ||
367 | { | ||
368 | LLSDMap requestMap = (LLSDMap)request; | ||
369 | |||
370 | // take these values to start. There's a few more | ||
371 | LLUUID SecureSessionID=requestMap["secure_session_id"].AsUUID(); | ||
372 | LLUUID SessionID = requestMap["session_id"].AsUUID(); | ||
373 | int circuitcode = requestMap["circuit_code"].AsInteger(); | ||
374 | |||
375 | //Update our Circuit data with the real values | ||
376 | userData.SecureSessionID = SecureSessionID; | ||
377 | userData.SessionID = SessionID; | ||
378 | |||
379 | // Locate a home scene suitable for the user. | ||
380 | Scene homeScene = GetRootScene(); | ||
381 | |||
382 | if (homeScene != null) | ||
383 | { | ||
384 | // Get a reference to their Cap object so we can pull out the capobjectroot | ||
385 | OpenSim.Framework.Communications.Capabilities.Caps userCap = | ||
386 | homeScene.GetCapsHandlerForUser(userData.AgentID); | ||
387 | |||
388 | //Update the circuit data in the region so this user is authorized | ||
389 | homeScene.UpdateCircuitData(userData); | ||
390 | homeScene.ChangeCircuitCode(userData.circuitcode,(uint)circuitcode); | ||
391 | |||
392 | // Load state | ||
393 | OGPState userState = GetOGPState(userData.AgentID); | ||
394 | |||
395 | // Keep state changes | ||
396 | userState.first_name = requestMap["first_name"].AsString(); | ||
397 | userState.secure_session_id = requestMap["secure_session_id"].AsUUID(); | ||
398 | userState.age_verified = requestMap["age_verified"].AsBoolean(); | ||
399 | userState.region_id = homeScene.RegionInfo.originRegionID; // replace 0000000 with our regionid | ||
400 | userState.transacted = requestMap["transacted"].AsBoolean(); | ||
401 | userState.agent_access = requestMap["agent_access"].AsBoolean(); | ||
402 | userState.inventory_host = requestMap["inventory_host"].AsString(); | ||
403 | userState.identified = requestMap["identified"].AsBoolean(); | ||
404 | userState.session_id = requestMap["session_id"].AsUUID(); | ||
405 | userState.god_level = (uint)requestMap["god_level"].AsInteger(); | ||
406 | userState.last_name = requestMap["last_name"].AsString(); | ||
407 | userState.god_overide = requestMap["god_override"].AsBoolean(); | ||
408 | userState.circuit_code = (uint)requestMap["circuit_code"].AsInteger(); | ||
409 | userState.limited_to_estate = requestMap["limited_to_estate"].AsInteger(); | ||
410 | |||
411 | // Save state changes | ||
412 | UpdateOGPState(userData.AgentID, userState); | ||
413 | |||
414 | // Get the region information for the home region. | ||
415 | RegionInfo reg = homeScene.RegionInfo; | ||
416 | |||
417 | // Dummy positional and look at info.. we don't have it. | ||
418 | LLSDArray PositionArray = new LLSDArray(); | ||
419 | PositionArray.Add(LLSD.FromInteger(128)); | ||
420 | PositionArray.Add(LLSD.FromInteger(128)); | ||
421 | PositionArray.Add(LLSD.FromInteger(40)); | ||
422 | |||
423 | LLSDArray LookAtArray = new LLSDArray(); | ||
424 | LookAtArray.Add(LLSD.FromInteger(1)); | ||
425 | LookAtArray.Add(LLSD.FromInteger(1)); | ||
426 | LookAtArray.Add(LLSD.FromInteger(1)); | ||
427 | |||
428 | // Our region's X and Y position in OpenSimulator space. | ||
429 | uint fooX = reg.RegionLocX; | ||
430 | uint fooY = reg.RegionLocY; | ||
431 | m_log.InfoFormat("[OGP]: region x({0}) region y({1})", fooX, fooY); | ||
432 | m_log.InfoFormat("[OGP]: region http {0} {1}", reg.ServerURI, reg.HttpPort); | ||
433 | m_log.InfoFormat("[OGO]: region UUID {0} ", reg.RegionID); | ||
434 | |||
435 | // Convert the X and Y position to LL space | ||
436 | responseMap["region_x"] = LLSD.FromInteger(fooX * (uint)Constants.RegionSize); // convert it to LL X | ||
437 | responseMap["region_y"] = LLSD.FromInteger(fooY * (uint)Constants.RegionSize); // convert it to LL Y | ||
438 | |||
439 | // Give em a new seed capability | ||
440 | responseMap["seed_capability"] = LLSD.FromString("http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + userCap.CapsObjectPath + "0000/"); | ||
441 | responseMap["region"] = LLSD.FromUUID(reg.originRegionID); | ||
442 | responseMap["look_at"] = LookAtArray; | ||
443 | |||
444 | responseMap["sim_port"] = LLSD.FromInteger(reg.InternalEndPoint.Port); | ||
445 | responseMap["sim_host"] = LLSD.FromString(Util.GetHostFromDNS(reg.ExternalHostName).ToString());// + ":" + reg.InternalEndPoint.Port.ToString()); | ||
446 | responseMap["sim_ip"] = LLSD.FromString(Util.GetHostFromDNS(reg.ExternalHostName).ToString()); | ||
447 | |||
448 | responseMap["session_id"] = LLSD.FromUUID(SessionID); | ||
449 | responseMap["secure_session_id"] = LLSD.FromUUID(SecureSessionID); | ||
450 | responseMap["circuit_code"] = LLSD.FromInteger(circuitcode); | ||
451 | |||
452 | responseMap["position"] = PositionArray; | ||
453 | |||
454 | responseMap["region_id"] = LLSD.FromUUID(reg.originRegionID); | ||
455 | |||
456 | responseMap["sim_access"] = LLSD.FromString("Mature"); | ||
457 | |||
458 | responseMap["connect"] = LLSD.FromBoolean(true); | ||
459 | |||
460 | m_log.InfoFormat("[OGP]: host: {0}, IP {1}", responseMap["sim_host"].ToString(), responseMap["sim_ip"].ToString()); | ||
461 | |||
462 | } | ||
463 | |||
464 | } | ||
465 | |||
466 | return responseMap; | ||
467 | } | ||
468 | |||
469 | |||
470 | |||
471 | public LLSD DerezAvatarMethod(string path, LLSD request) | ||
472 | { | ||
473 | |||
474 | |||
475 | m_log.ErrorFormat("DerezPath: {0}, Request: {1}", path, request.ToString()); | ||
476 | |||
477 | LLSD llsdResponse = null; | ||
478 | LLSDMap responseMap = new LLSDMap(); | ||
479 | |||
480 | |||
481 | |||
482 | string[] PathArray = path.Split('/'); | ||
483 | m_log.InfoFormat("[OGP]: prefix {0}, uuid {1}, suffix {2}", PathArray[1], PathArray[2], PathArray[3]); | ||
484 | string uuidString = PathArray[2]; | ||
485 | m_log.InfoFormat("[OGP]: Request to Derez avatar with UUID {0}", uuidString); | ||
486 | LLUUID userUUID = LLUUID.Zero; | ||
487 | if (Helpers.TryParse(uuidString, out userUUID)) | ||
488 | { | ||
489 | |||
490 | LLUUID RemoteID = uuidString; | ||
491 | LLUUID LocalID = RemoteID; | ||
492 | // FIXME: TODO: Routine to map RemoteUUIDs to LocalUUIds | ||
493 | // would be done already.. but the client connects with the Aditi UUID | ||
494 | // regardless over the UDP stack | ||
495 | |||
496 | OGPState userState = GetOGPState(LocalID); | ||
497 | if (userState.agent_id != LLUUID.Zero) | ||
498 | { | ||
499 | |||
500 | LLSDMap outboundRequestMap = new LLSDMap(); | ||
501 | LLSDMap inboundRequestMap = (LLSDMap)request; | ||
502 | string rezAvatarString = inboundRequestMap["rez_avatar"].AsString(); | ||
503 | |||
504 | LLSDArray LookAtArray = new LLSDArray(); | ||
505 | LookAtArray.Add(LLSD.FromInteger(1)); | ||
506 | LookAtArray.Add(LLSD.FromInteger(1)); | ||
507 | LookAtArray.Add(LLSD.FromInteger(1)); | ||
508 | |||
509 | |||
510 | LLSDArray PositionArray = new LLSDArray(); | ||
511 | PositionArray.Add(LLSD.FromInteger(128)); | ||
512 | PositionArray.Add(LLSD.FromInteger(128)); | ||
513 | PositionArray.Add(LLSD.FromInteger(40)); | ||
514 | |||
515 | LLSDArray lookArray = new LLSDArray(); | ||
516 | lookArray.Add(LLSD.FromInteger(128)); | ||
517 | lookArray.Add(LLSD.FromInteger(128)); | ||
518 | lookArray.Add(LLSD.FromInteger(40)); | ||
519 | |||
520 | responseMap["connect"] = LLSD.FromBoolean(true);// it's okay to give this user up | ||
521 | responseMap["look_at"] = LookAtArray; | ||
522 | |||
523 | m_log.WarnFormat("[OGP]: Invoking rez_avatar on host:{0} for avatar: {1} {2}", rezAvatarString, userState.first_name, userState.last_name); | ||
524 | |||
525 | LLSDMap rezResponseMap = invokeRezAvatarCap(responseMap, rezAvatarString,userState); | ||
526 | |||
527 | // If invoking it returned an error, parse and end | ||
528 | if (rezResponseMap.ContainsKey("connect")) | ||
529 | { | ||
530 | if (rezResponseMap["connect"].AsBoolean() == false) | ||
531 | { | ||
532 | return responseMap; | ||
533 | } | ||
534 | } | ||
535 | |||
536 | string rezRespSeedCap = rezResponseMap["seed_capability"].AsString(); | ||
537 | string rezRespSim_ip = rezResponseMap["sim_ip"].AsString(); | ||
538 | string rezRespSim_host = rezResponseMap["sim_host"].AsString(); | ||
539 | |||
540 | int rrPort = rezResponseMap["sim_port"].AsInteger(); | ||
541 | int rrX = rezResponseMap["region_x"].AsInteger(); | ||
542 | int rrY = rezResponseMap["region_y"].AsInteger(); | ||
543 | m_log.ErrorFormat("X:{0}, Y:{1}", rrX, rrY); | ||
544 | LLUUID rrRID = rezResponseMap["region_id"].AsUUID(); | ||
545 | |||
546 | string rrAccess = rezResponseMap["sim_access"].AsString(); | ||
547 | |||
548 | LLSDArray RezResponsePositionArray = (LLSDArray)rezResponseMap["position"]; | ||
549 | |||
550 | responseMap["seed_capability"] = LLSD.FromString(rezRespSeedCap); | ||
551 | responseMap["sim_ip"] = LLSD.FromString(Util.GetHostFromDNS(rezRespSim_ip).ToString()); | ||
552 | responseMap["sim_host"] = LLSD.FromString(Util.GetHostFromDNS(rezRespSim_host).ToString()); | ||
553 | responseMap["sim_port"] = LLSD.FromInteger(rrPort); | ||
554 | responseMap["region_x"] = LLSD.FromInteger(rrX * (int)Constants.RegionSize); | ||
555 | responseMap["region_y"] = LLSD.FromInteger(rrY * (int)Constants.RegionSize); | ||
556 | responseMap["region_id"] = LLSD.FromUUID(rrRID); | ||
557 | responseMap["sim_access"] = LLSD.FromString(rrAccess); | ||
558 | |||
559 | |||
560 | |||
561 | responseMap["position"] = RezResponsePositionArray; | ||
562 | responseMap["look_at"] = lookArray; | ||
563 | responseMap["connect"] = LLSD.FromBoolean(true); | ||
564 | |||
565 | ShutdownConnection(LocalID,this); | ||
566 | |||
567 | |||
568 | m_log.Warn("RESPONSEDEREZ: " + responseMap.ToString()); | ||
569 | return responseMap; | ||
570 | |||
571 | } | ||
572 | else | ||
573 | { | ||
574 | |||
575 | return GenerateNoHandlerMessage(); | ||
576 | } | ||
577 | } | ||
578 | else | ||
579 | { | ||
580 | return GenerateNoHandlerMessage(); | ||
581 | } | ||
582 | |||
583 | return responseMap; | ||
584 | } | ||
585 | |||
586 | private LLSDMap invokeRezAvatarCap(LLSDMap responseMap, string CapAddress, OGPState userState) | ||
587 | { | ||
588 | |||
589 | WebRequest DeRezRequest = WebRequest.Create(CapAddress); | ||
590 | DeRezRequest.Method = "POST"; | ||
591 | DeRezRequest.ContentType = "application/xml+llsd"; | ||
592 | |||
593 | LLSDMap RAMap = new LLSDMap(); | ||
594 | LLSDMap AgentParms = new LLSDMap(); | ||
595 | LLSDMap RegionParms = new LLSDMap(); | ||
596 | |||
597 | |||
598 | AgentParms["first_name"] = LLSD.FromString(userState.first_name); | ||
599 | AgentParms["last_name"] = LLSD.FromString(userState.last_name); | ||
600 | AgentParms["agent_id"] = LLSD.FromUUID(userState.agent_id); | ||
601 | RegionParms["region_id"] = LLSD.FromUUID(userState.region_id); | ||
602 | AgentParms["circuit_code"] = LLSD.FromInteger(userState.circuit_code); | ||
603 | AgentParms["secure_session_id"] = LLSD.FromUUID(userState.secure_session_id); | ||
604 | AgentParms["session_id"] = LLSD.FromUUID(userState.session_id); | ||
605 | AgentParms["agent_access"] = LLSD.FromBoolean(userState.agent_access); | ||
606 | AgentParms["god_level"] = LLSD.FromInteger(userState.god_level); | ||
607 | AgentParms["god_overide"] = LLSD.FromBoolean(userState.god_overide); | ||
608 | AgentParms["identified"] = LLSD.FromBoolean(userState.identified); | ||
609 | AgentParms["transacted"] = LLSD.FromBoolean(userState.transacted); | ||
610 | AgentParms["age_verified"] = LLSD.FromBoolean(userState.age_verified); | ||
611 | AgentParms["limited_to_estate"] = LLSD.FromInteger(userState.limited_to_estate); | ||
612 | AgentParms["inventory_host"] = LLSD.FromString(userState.inventory_host); | ||
613 | RAMap["agent_params"] = AgentParms; | ||
614 | RAMap["region_params"] = RegionParms; | ||
615 | |||
616 | string RAMapString = AgentParms.ToString(); | ||
617 | m_log.InfoFormat("[OGP] RAMap string {0}", RAMapString); | ||
618 | LLSD LLSDofRAMap = AgentParms; // RENAME if this works | ||
619 | |||
620 | m_log.InfoFormat("[OGP]: LLSD of map as string was {0}", LLSDofRAMap.ToString()); | ||
621 | byte[] buffer = LLSDParser.SerializeXmlBytes(LLSDofRAMap); | ||
622 | |||
623 | //string bufferDump = System.Text.Encoding.ASCII.GetString(buffer); | ||
624 | //m_log.InfoFormat("[OGP]: buffer form is {0}",bufferDump); | ||
625 | //m_log.InfoFormat("[OGP]: LLSD of map was {0}",buffer.Length); | ||
626 | |||
627 | Stream os = null; | ||
628 | try | ||
629 | { // send the Post | ||
630 | DeRezRequest.ContentLength = buffer.Length; //Count bytes to send | ||
631 | os = DeRezRequest.GetRequestStream(); | ||
632 | os.Write(buffer, 0, buffer.Length); //Send it | ||
633 | os.Close(); | ||
634 | m_log.InfoFormat("[OGP]: Derez Avatar Posted Rez Avatar request to remote sim {0}", CapAddress); | ||
635 | } | ||
636 | catch (WebException ex) | ||
637 | { | ||
638 | m_log.InfoFormat("[OGP] Bad send on de_rez_avatar {0}", ex.Message); | ||
639 | responseMap["connect"] = LLSD.FromBoolean(false); | ||
640 | |||
641 | return responseMap; | ||
642 | } | ||
643 | |||
644 | m_log.Info("[OGP] waiting for a reply after rez avatar send"); | ||
645 | string rez_avatar_reply = null; | ||
646 | { // get the response | ||
647 | try | ||
648 | { | ||
649 | WebResponse webResponse = DeRezRequest.GetResponse(); | ||
650 | if (webResponse == null) | ||
651 | { | ||
652 | m_log.Info("[OGP:] Null reply on rez_avatar post"); | ||
653 | } | ||
654 | |||
655 | StreamReader sr = new StreamReader(webResponse.GetResponseStream()); | ||
656 | rez_avatar_reply = sr.ReadToEnd().Trim(); | ||
657 | m_log.InfoFormat("[OGP]: rez_avatar reply was {0} ", rez_avatar_reply); | ||
658 | |||
659 | } | ||
660 | catch (WebException ex) | ||
661 | { | ||
662 | m_log.InfoFormat("[OGP]: exception on read after send of rez avatar {0}", ex.Message); | ||
663 | responseMap["connect"] = LLSD.FromBoolean(false); | ||
664 | |||
665 | return responseMap; | ||
666 | } | ||
667 | LLSD rezResponse = null; | ||
668 | try | ||
669 | { | ||
670 | rezResponse = LLSDParser.DeserializeXml(rez_avatar_reply); | ||
671 | |||
672 | responseMap = (LLSDMap)rezResponse; | ||
673 | } | ||
674 | catch (Exception ex) | ||
675 | { | ||
676 | m_log.InfoFormat("[OGP]: exception on parse of rez reply {0}", ex.Message); | ||
677 | responseMap["connect"] = LLSD.FromBoolean(false); | ||
678 | |||
679 | return responseMap; | ||
680 | } | ||
681 | } | ||
682 | return responseMap; | ||
683 | } | ||
684 | |||
685 | |||
686 | |||
687 | public LLSD GenerateNoHandlerMessage() | ||
688 | { | ||
689 | LLSDMap map = new LLSDMap(); | ||
690 | map["reason"] = LLSD.FromString("LLSDRequest"); | ||
691 | map["message"] = LLSD.FromString("No handler registered for LLSD Requests"); | ||
692 | map["login"] = LLSD.FromString("false"); | ||
693 | |||
694 | return map; | ||
695 | } | ||
696 | |||
697 | private bool TryGetAgentCircuitData(string path, out AgentCircuitData userdata) | ||
698 | { | ||
699 | userdata = null; | ||
700 | lock (CapsLoginID) | ||
701 | { | ||
702 | if (CapsLoginID.ContainsKey(path)) | ||
703 | { | ||
704 | userdata = CapsLoginID[path]; | ||
705 | DiscardUsedCap(path); | ||
706 | return true; | ||
707 | } | ||
708 | } | ||
709 | return false; | ||
710 | } | ||
711 | |||
712 | private void DiscardUsedCap(string path) | ||
713 | { | ||
714 | CapsLoginID.Remove(path); | ||
715 | } | ||
716 | |||
717 | |||
718 | private Scene GetRootScene() | ||
719 | { | ||
720 | Scene ReturnScene = null; | ||
721 | lock (m_scene) | ||
722 | { | ||
723 | if (m_scene.Count > 0) | ||
724 | { | ||
725 | ReturnScene = m_scene[0]; | ||
726 | } | ||
727 | } | ||
728 | |||
729 | return ReturnScene; | ||
730 | |||
731 | } | ||
732 | |||
733 | private ulong GetOSCompatibleRegionHandle(RegionInfo reg) | ||
734 | { | ||
735 | return Util.UIntsToLong(reg.RegionLocX, reg.RegionLocY); | ||
736 | } | ||
737 | |||
738 | private ulong GetOSCompatibleRegionHandle(uint x, uint y) | ||
739 | { | ||
740 | return Util.UIntsToLong(x, y); | ||
741 | } | ||
742 | |||
743 | private ulong GetOSCompatibleRegionHandle(ulong regionhandle) | ||
744 | { | ||
745 | uint x,y; | ||
746 | Helpers.LongToUInts(regionhandle,out x, out y); | ||
747 | return GetOSCompatibleRegionHandle(x,y); | ||
748 | } | ||
749 | |||
750 | |||
751 | private ulong GetOGPCompatibleRegionHandle(RegionInfo reg) | ||
752 | { | ||
753 | return Util.UIntsToLong((reg.RegionLocX * (uint)Constants.RegionSize), (reg.RegionLocY * (uint)Constants.RegionSize)); | ||
754 | } | ||
755 | |||
756 | private ulong GetOGPCompatibleRegionHandle(uint x, uint y) | ||
757 | { | ||
758 | return Util.UIntsToLong((x * (uint)Constants.RegionSize), (y * (uint)Constants.RegionSize)); | ||
759 | } | ||
760 | |||
761 | private ulong GetOGPCompatibleRegionHandle(ulong regionhandle) | ||
762 | { | ||
763 | uint x, y; | ||
764 | Helpers.LongToUInts(regionhandle, out x, out y); | ||
765 | return GetOGPCompatibleRegionHandle(x, y); | ||
766 | } | ||
767 | |||
768 | private OGPState InitializeNewState() | ||
769 | { | ||
770 | OGPState returnState = new OGPState(); | ||
771 | returnState.first_name = ""; | ||
772 | returnState.last_name = ""; | ||
773 | returnState.agent_id = LLUUID.Zero; | ||
774 | returnState.local_agent_id = LLUUID.Zero; | ||
775 | returnState.region_id = LLUUID.Zero; | ||
776 | returnState.circuit_code = 0; | ||
777 | returnState.secure_session_id = LLUUID.Zero; | ||
778 | returnState.session_id = LLUUID.Zero; | ||
779 | returnState.agent_access = true; | ||
780 | returnState.god_level = 0; | ||
781 | returnState.god_overide = false; | ||
782 | returnState.identified = false; | ||
783 | returnState.transacted = false; | ||
784 | returnState.age_verified = false; | ||
785 | returnState.limited_to_estate = 1; | ||
786 | returnState.inventory_host = "http://inv4.mysql.aditi.lindenlab.com"; | ||
787 | returnState.allow_redirect = true; | ||
788 | returnState.sim_access = ""; | ||
789 | returnState.src_can_see_mainland = true; | ||
790 | returnState.src_estate_id = 1; | ||
791 | |||
792 | return returnState; | ||
793 | } | ||
794 | |||
795 | private OGPState GetOGPState(LLUUID agentId) | ||
796 | { | ||
797 | lock (m_OGPState) | ||
798 | { | ||
799 | if (m_OGPState.ContainsKey(agentId)) | ||
800 | { | ||
801 | return m_OGPState[agentId]; | ||
802 | } | ||
803 | else | ||
804 | { | ||
805 | return InitializeNewState(); | ||
806 | } | ||
807 | } | ||
808 | } | ||
809 | |||
810 | public void DeleteOGPState(LLUUID agentId) | ||
811 | { | ||
812 | lock (m_OGPState) | ||
813 | if (m_OGPState.ContainsKey(agentId)) | ||
814 | m_OGPState.Remove(agentId); | ||
815 | |||
816 | } | ||
817 | |||
818 | private void UpdateOGPState(LLUUID agentId, OGPState state) | ||
819 | { | ||
820 | lock (m_OGPState) | ||
821 | { | ||
822 | if (m_OGPState.ContainsKey(agentId)) | ||
823 | { | ||
824 | m_OGPState[agentId] = state; | ||
825 | } | ||
826 | else | ||
827 | { | ||
828 | m_OGPState.Add(agentId,state); | ||
829 | } | ||
830 | } | ||
831 | } | ||
832 | public void ShutdownConnection(LLUUID avatarId, OpenGridProtocolModule mod) | ||
833 | { | ||
834 | Scene homeScene = GetRootScene(); | ||
835 | ScenePresence avatar = null; | ||
836 | if (homeScene.TryGetAvatar(avatarId,out avatar)) | ||
837 | { | ||
838 | KillAUser ku = new KillAUser(avatar,mod); | ||
839 | Thread ta = new Thread(ku.ShutdownNoLogout); | ||
840 | ta.IsBackground = true; | ||
841 | ta.Name = "ShutdownThread"; | ||
842 | ta.Start(); | ||
843 | } | ||
844 | } | ||
845 | } | ||
846 | |||
847 | public class KillAUser | ||
848 | { | ||
849 | private ScenePresence avToBeKilled = null; | ||
850 | private OpenGridProtocolModule m_mod = null; | ||
851 | |||
852 | public KillAUser(ScenePresence avatar, OpenGridProtocolModule mod) | ||
853 | { | ||
854 | avToBeKilled = avatar; | ||
855 | m_mod = mod; | ||
856 | } | ||
857 | |||
858 | public void ShutdownNoLogout() | ||
859 | { | ||
860 | LLUUID avUUID = LLUUID.Zero; | ||
861 | |||
862 | if (avToBeKilled != null) | ||
863 | { | ||
864 | avUUID = avToBeKilled.UUID; | ||
865 | avToBeKilled.MakeChildAgent(); | ||
866 | |||
867 | avToBeKilled.ControllingClient.SendLogoutPacketWhenClosing = false; | ||
868 | |||
869 | Thread.Sleep(30000); | ||
870 | |||
871 | // test for child agent because they might have come back | ||
872 | if (avToBeKilled.IsChildAgent) | ||
873 | { | ||
874 | m_mod.DeleteOGPState(avUUID); | ||
875 | avToBeKilled.ControllingClient.Close(true); | ||
876 | } | ||
877 | } | ||
878 | } | ||
879 | |||
880 | } | ||
881 | } | ||