aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Client
diff options
context:
space:
mode:
authorHomer Horwitz2009-03-15 21:34:28 +0000
committerHomer Horwitz2009-03-15 21:34:28 +0000
commitabc5df12c883ab14bf7926fc047431249ba52cb5 (patch)
treeff9042dde59b02e97b1ed2ebe6e39c7db855c615 /OpenSim/Client
parentregionInfo isn't defined here yet, which leads to a NRE. Grid-server (diff)
downloadopensim-SC-abc5df12c883ab14bf7926fc047431249ba52cb5.zip
opensim-SC-abc5df12c883ab14bf7926fc047431249ba52cb5.tar.gz
opensim-SC-abc5df12c883ab14bf7926fc047431249ba52cb5.tar.bz2
opensim-SC-abc5df12c883ab14bf7926fc047431249ba52cb5.tar.xz
This patch improves MXP connect and disconnect functionality.
- Avatars are now properly on top of terrain. - ScenePresence is now removed from Scene only once. Fixes Mantis #3302. Thanks tlaukkan.
Diffstat (limited to 'OpenSim/Client')
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs34
-rw-r--r--OpenSim/Client/MXP/MXPModule.cs18
-rw-r--r--OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs271
3 files changed, 208 insertions, 115 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index 9052443..5a7accf 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -189,8 +189,6 @@ namespace OpenSim.Client.MXP.ClientStack
189 189
190 private void MXPProcessModifyRequest(ModifyRequestMessage modifyRequest) 190 private void MXPProcessModifyRequest(ModifyRequestMessage modifyRequest)
191 { 191 {
192 m_log.Debug("Received modify request for: " + modifyRequest.ObjectFragment.ObjectName);
193
194 ObjectFragment objectFragment=modifyRequest.ObjectFragment; 192 ObjectFragment objectFragment=modifyRequest.ObjectFragment;
195 if (objectFragment.ObjectId == m_userID.Guid) 193 if (objectFragment.ObjectId == m_userID.Guid)
196 { 194 {
@@ -448,7 +446,7 @@ namespace OpenSim.Client.MXP.ClientStack
448 Session.Send(pe); 446 Session.Send(pe);
449 } 447 }
450 448
451 public void MXPSentSynchronizationBegin(int objectCount) 449 public void MXPSendSynchronizationBegin(int objectCount)
452 { 450 {
453 m_objectsToSynchronize = objectCount; 451 m_objectsToSynchronize = objectCount;
454 m_objectsSynchronized = 0; 452 m_objectsSynchronized = 0;
@@ -767,6 +765,15 @@ namespace OpenSim.Client.MXP.ClientStack
767 //throw new System.NotImplementedException(); 765 //throw new System.NotImplementedException();
768 } 766 }
769 767
768 public void OnClean()
769 {
770 if (OnLogout != null)
771 OnLogout(this);
772
773 if (OnConnectionClosed != null)
774 OnConnectionClosed(this);
775 }
776
770 public void Close(bool ShutdownCircuit) 777 public void Close(bool ShutdownCircuit)
771 { 778 {
772 m_log.Info("[MXP ClientStack] Close Called with SC=" + ShutdownCircuit); 779 m_log.Info("[MXP ClientStack] Close Called with SC=" + ShutdownCircuit);
@@ -780,16 +787,6 @@ namespace OpenSim.Client.MXP.ClientStack
780 Session.SetStateDisconnected(); 787 Session.SetStateDisconnected();
781 } 788 }
782 789
783 // Handle OpenSim cleanup
784 if (ShutdownCircuit)
785 {
786 if (OnConnectionClosed != null)
787 OnConnectionClosed(this);
788 }
789 else
790 {
791 Scene.RemoveClient(AgentId);
792 }
793 } 790 }
794 791
795 public void Kick(string message) 792 public void Kick(string message)
@@ -800,6 +797,17 @@ namespace OpenSim.Client.MXP.ClientStack
800 public void Start() 797 public void Start()
801 { 798 {
802 Scene.AddNewClient(this); 799 Scene.AddNewClient(this);
800
801 // Mimicking LLClientView which gets always set appearance from client.
802 OpenSim.Region.Framework.Scenes.Scene scene=(OpenSim.Region.Framework.Scenes.Scene)Scene;
803 AvatarAppearance appearance;
804 scene.GetAvatarAppearance(this,out appearance);
805 List<byte> visualParams = new List<byte>();
806 foreach (byte visualParam in appearance.VisualParams)
807 {
808 visualParams.Add(visualParam);
809 }
810 OnSetAppearance(appearance.Texture.ToBytes(), visualParams);
803 } 811 }
804 812
805 public void Stop() 813 public void Stop()
diff --git a/OpenSim/Client/MXP/MXPModule.cs b/OpenSim/Client/MXP/MXPModule.cs
index 6ec7744..4eb0058 100644
--- a/OpenSim/Client/MXP/MXPModule.cs
+++ b/OpenSim/Client/MXP/MXPModule.cs
@@ -38,21 +38,20 @@ using OpenSim.Region.Framework.Scenes;
38 38
39namespace OpenSim.Client.MXP 39namespace OpenSim.Client.MXP
40{ 40{
41
41 /** 42 /**
42 * MXP Client Module which adds MXP support to client / region communication. 43 * MXP Client Module which adds MXP support to client / region communication.
43 */ 44 */
44 public class MXPModule : IRegionModule 45 public class MXPModule : IRegionModule
45 { 46 {
47 private MXPPacketServer m_server;
46 48
49 private IConfigSource m_config;
47 private int m_port = 1253; 50 private int m_port = 1253;
48 //private int m_ticks = 0;
49 private bool m_shutdown = false;
50 51
51 private IConfigSource m_config;
52 private readonly Timer m_ticker = new Timer(100);
53 private readonly Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); 52 private readonly Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
54 53 private readonly Timer m_ticker = new Timer(100);
55 private MXPPacketServer m_server; 54 private bool m_shutdown = false;
56 55
57 public void Initialise(Scene scene, IConfigSource source) 56 public void Initialise(Scene scene, IConfigSource source)
58 { 57 {
@@ -88,13 +87,6 @@ namespace OpenSim.Client.MXP
88 87
89 if (!m_shutdown) 88 if (!m_shutdown)
90 m_ticker.Start(); 89 m_ticker.Start();
91
92 // Commenting this at because of the excess flood to log.
93 // TODO: Add ini file option.
94 /*if (++ticks % 100 == 0)
95 {
96 server.PrintDebugInformation();
97 }*/
98 } 90 }
99 91
100 public void Close() 92 public void Close()
diff --git a/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs b/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs
index ba7bd00..bb04955 100644
--- a/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs
+++ b/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs
@@ -40,6 +40,7 @@ using OpenSim.Client.MXP.ClientStack;
40using OpenSim.Framework; 40using OpenSim.Framework;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Framework.Communications; 42using OpenSim.Framework.Communications;
43using System.Security.Cryptography;
43 44
44namespace OpenSim.Client.MXP.PacketHandler 45namespace OpenSim.Client.MXP.PacketHandler
45{ 46{
@@ -214,17 +215,6 @@ namespace OpenSim.Client.MXP.PacketHandler
214 215
215 #region Processing 216 #region Processing
216 217
217 public void PrintDebugInformation()
218 {
219 m_log.Info("[MXP ClientStack] Statistics report");
220 m_log.Info("Pending Sessions: " + PendingSessionCount);
221 m_log.Info("Sessions: " + SessionCount + " (Clients: " + m_clients.Count + " )");
222 m_log.Info("Transmitter Alive?: " + IsTransmitterAlive);
223 m_log.Info("Packets Sent/Received: " + PacketsSent + " / " + PacketsReceived);
224 m_log.Info("Bytes Sent/Received: " + BytesSent + " / " + BytesReceived);
225 m_log.Info("Send/Receive Rate (bps): " + SendRate + " / " + ReceiveRate);
226 }
227
228 public void Process() 218 public void Process()
229 { 219 {
230 ProcessMessages(); 220 ProcessMessages();
@@ -243,7 +233,7 @@ namespace OpenSim.Client.MXP.PacketHandler
243 233
244 foreach (MXPClientView clientView in m_sessionsToRemove) 234 foreach (MXPClientView clientView in m_sessionsToRemove)
245 { 235 {
246 clientView.Scene.RemoveClient(clientView.AgentId); 236 clientView.OnClean();
247 m_clients.Remove(clientView); 237 m_clients.Remove(clientView);
248 m_sessions.Remove(clientView.Session); 238 m_sessions.Remove(clientView.Session);
249 } 239 }
@@ -251,59 +241,6 @@ namespace OpenSim.Client.MXP.PacketHandler
251 m_sessionsToRemove.Clear(); 241 m_sessionsToRemove.Clear();
252 } 242 }
253 243
254 public bool AuthoriseUser(string participantName, string password, UUID sceneId, out UUID userId, out string firstName, out string lastName)
255 {
256 userId = UUID.Zero;
257 firstName = "";
258 lastName = "";
259
260 if (!m_scenes.ContainsKey(sceneId))
261 {
262 m_log.Info("Login failed as region was not found: " + sceneId);
263 return false;
264 }
265
266 string[] nameParts=participantName.Split(' ');
267 if (nameParts.Length != 2)
268 {
269 m_log.Info("Login failed as user name is not formed of first and last name separated by space: " + participantName);
270 return false;
271 }
272 firstName = nameParts[0];
273 lastName = nameParts[1];
274
275 UserProfileData userProfile = m_scenes[sceneId].CommsManager.UserService.GetUserProfile(firstName, lastName);
276 if (userProfile == null && !m_accountsAuthenticate)
277 {
278 userId = ((UserManagerBase)m_scenes[sceneId].CommsManager.UserService).AddUser(firstName, lastName, "test", "", 1000, 1000);
279 }
280 else
281 {
282 if (userProfile == null)
283 {
284 m_log.Info("Login failed as user was not found: " + participantName);
285 return false;
286 }
287 userId = userProfile.ID;
288 }
289
290 if (m_accountsAuthenticate)
291 {
292 if (!password.StartsWith("$1$"))
293 {
294 password = "$1$" + Util.Md5Hash(password);
295 }
296 password = password.Remove(0, 3); //remove $1$
297 string s = Util.Md5Hash(password + ":" + userProfile.PasswordSalt);
298 return (userProfile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
299 || userProfile.PasswordHash.Equals(password, StringComparison.InvariantCultureIgnoreCase));
300 }
301 else
302 {
303 return true;
304 }
305 }
306
307 public void ProcessMessages() 244 public void ProcessMessages()
308 { 245 {
309 if (m_transmitter.PendingSessionCount > 0) 246 if (m_transmitter.PendingSessionCount > 0)
@@ -327,9 +264,9 @@ namespace OpenSim.Client.MXP.PacketHandler
327 264
328 JoinRequestMessage joinRequestMessage = (JoinRequestMessage) message; 265 JoinRequestMessage joinRequestMessage = (JoinRequestMessage) message;
329 266
330 UUID userId; 267 m_log.Info("[MXP ClientStack] Session join request: " + session.SessionId + " (" +
331 string firstName; 268 (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
332 string lastName; 269 session.RemoteEndPoint.Port + ")");
333 270
334 if (joinRequestMessage.BubbleId == Guid.Empty) 271 if (joinRequestMessage.BubbleId == Guid.Empty)
335 { 272 {
@@ -337,7 +274,7 @@ namespace OpenSim.Client.MXP.PacketHandler
337 { 274 {
338 if (scene.RegionInfo.RegionName == joinRequestMessage.BubbleName) 275 if (scene.RegionInfo.RegionName == joinRequestMessage.BubbleName)
339 { 276 {
340 m_log.Info("Resolved region by name: " + joinRequestMessage.BubbleName + " (" + scene.RegionInfo.RegionID+")"); 277 m_log.Info("[MXP ClientStack] Resolved region by name: " + joinRequestMessage.BubbleName + " (" + scene.RegionInfo.RegionID + ")");
341 joinRequestMessage.BubbleId = scene.RegionInfo.RegionID.Guid; 278 joinRequestMessage.BubbleId = scene.RegionInfo.RegionID.Guid;
342 } 279 }
343 } 280 }
@@ -345,47 +282,71 @@ namespace OpenSim.Client.MXP.PacketHandler
345 282
346 if (joinRequestMessage.BubbleId == Guid.Empty) 283 if (joinRequestMessage.BubbleId == Guid.Empty)
347 { 284 {
348 m_log.Warn("Failed to resolve region by name: "+joinRequestMessage.BubbleName); 285 m_log.Warn("[MXP ClientStack] Failed to resolve region by name: " + joinRequestMessage.BubbleName);
286 }
287
288 UUID sceneId = new UUID(joinRequestMessage.BubbleId);
289
290 bool regionExists = true;
291 if (!m_scenes.ContainsKey(sceneId))
292 {
293 m_log.Info("[MXP ClientStack] No such region: " + sceneId);
294 regionExists=false;
349 } 295 }
350 296
351 bool authorized = AuthoriseUser(joinRequestMessage.ParticipantName, 297 UserProfileData user=null;
298 UUID userId=UUID.Zero;
299 string firstName=null;
300 string lastName=null;
301 bool authorized = regionExists?AuthoriseUser(joinRequestMessage.ParticipantName,
352 joinRequestMessage.ParticipantPassphrase, 302 joinRequestMessage.ParticipantPassphrase,
353 new UUID(joinRequestMessage.BubbleId), out userId, out firstName, out lastName); 303 new UUID(joinRequestMessage.BubbleId), out userId, out firstName, out lastName, out user)
304 :false;
354 305
355 if (authorized) 306 if (authorized)
356 { 307 {
357 Scene target = m_scenes[new UUID(joinRequestMessage.BubbleId)]; 308 Scene scene = m_scenes[sceneId];
358
359 UUID mxpSessionID = UUID.Random(); 309 UUID mxpSessionID = UUID.Random();
360 310
361 m_log.Info("[MXP ClientStack] Session join request success: " + session.SessionId + " (" + 311 m_log.Info("[MXP ClientStack] Session join request success: " + session.SessionId + " (" +
362 (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + 312 (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
363 session.RemoteEndPoint.Port + ")"); 313 session.RemoteEndPoint.Port + ")");
364 314
365 AcceptConnection(session, joinRequestMessage, mxpSessionID,userId); 315 m_log.Info("[MXP ClientStack] Attaching UserAgent to UserProfile...");
366 316 AttachUserAgentToUserProfile(session, mxpSessionID, sceneId, user);
367 MXPClientView client = new MXPClientView(session, mxpSessionID,userId, target, 317 m_log.Info("[MXP ClientStack] Attached UserAgent to UserProfile.");
368 firstName, lastName); 318 m_log.Info("[MXP ClientStack] Preparing Scene to Connection...");
369 m_log.Info("[MXP ClientStack] Created Client"); 319 PrepareSceneForConnection(mxpSessionID, sceneId, user);
320 m_log.Info("[MXP ClientStack] Prepared Scene to Connection.");
321 m_log.Info("[MXP ClientStack] Accepting connection...");
322 AcceptConnection(session, joinRequestMessage, mxpSessionID, userId);
323 m_log.Info("[MXP ClientStack] Accepted connection.");
324
325 m_log.Info("[MXP ClientStack] Creating ClientView....");
326 MXPClientView client = new MXPClientView(session, mxpSessionID, userId, scene, firstName, lastName);
370 m_clients.Add(client); 327 m_clients.Add(client);
328 m_log.Info("[MXP ClientStack] Created ClientView.");
371 329
372 m_log.Info("[MXP ClientStack] Adding to Scene");
373 target.ClientManager.Add(client.CircuitCode, client);
374 330
375 m_log.Info("[MXP ClientStack] Initialising..."); 331 m_log.Info("[MXP ClientStack] Adding ClientView to Scene...");
332 scene.ClientManager.Add(client.CircuitCode, client);
333 m_log.Info("[MXP ClientStack] Added ClientView to Scene.");
376 334
377 client.MXPSentSynchronizationBegin(m_scenes[new UUID(joinRequestMessage.BubbleId)].SceneContents.GetTotalObjectsCount()); 335
336 client.MXPSendSynchronizationBegin(m_scenes[new UUID(joinRequestMessage.BubbleId)].SceneContents.GetTotalObjectsCount());
378 337
338 m_log.Info("[MXP ClientStack] Starting ClientView...");
379 try 339 try
380 { 340 {
381 client.Start(); 341 client.Start();
382 } catch( Exception e) 342 m_log.Info("[MXP ClientStack] Started ClientView.");
343 }
344 catch (Exception e)
383 { 345 {
384 m_log.Info(e); 346 m_log.Info(e);
385 } 347 }
386 348
387 m_log.Info("[MXP ClientStack] Connected"); 349 m_log.Info("[MXP ClientStack] Connected");
388 //target.EventManager.TriggerOnNewClient(client);
389 } 350 }
390 else 351 else
391 { 352 {
@@ -512,6 +473,138 @@ namespace OpenSim.Client.MXP.PacketHandler
512 session.SetStateDisconnected(); 473 session.SetStateDisconnected();
513 } 474 }
514 475
476 public bool AuthoriseUser(string participantName, string password, UUID sceneId, out UUID userId, out string firstName, out string lastName, out UserProfileData userProfile)
477 {
478 userId = UUID.Zero;
479 firstName = "";
480 lastName = "";
481 userProfile = null;
482
483 string[] nameParts = participantName.Split(' ');
484 if (nameParts.Length != 2)
485 {
486 m_log.Info("[MXP ClientStack] Login failed as user name is not formed of first and last name separated by space: " + participantName);
487 return false;
488 }
489 firstName = nameParts[0];
490 lastName = nameParts[1];
491
492 userProfile = m_scenes[sceneId].CommsManager.UserService.GetUserProfile(firstName, lastName);
493 if (userProfile == null && !m_accountsAuthenticate)
494 {
495 userId = ((UserManagerBase)m_scenes[sceneId].CommsManager.UserService).AddUser(firstName, lastName, "test", "", 1000, 1000);
496 }
497 else
498 {
499 if (userProfile == null)
500 {
501 m_log.Info("Login failed as user was not found: " + participantName);
502 return false;
503 }
504 userId = userProfile.ID;
505 }
506
507 if (m_accountsAuthenticate)
508 {
509 if (!password.StartsWith("$1$"))
510 {
511 password = "$1$" + Util.Md5Hash(password);
512 }
513 password = password.Remove(0, 3); //remove $1$
514 string s = Util.Md5Hash(password + ":" + userProfile.PasswordSalt);
515 return (userProfile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
516 || userProfile.PasswordHash.Equals(password, StringComparison.InvariantCultureIgnoreCase));
517 }
518 else
519 {
520 return true;
521 }
522 }
523
524 private void AttachUserAgentToUserProfile(Session session, UUID sessionId, UUID sceneId, UserProfileData userProfile)
525 {
526 Scene scene = m_scenes[sceneId];
527 CommunicationsManager commsManager = m_scenes[sceneId].CommsManager;
528 UserManagerBase userService = (UserManagerBase)commsManager.UserService;
529
530 UserAgentData agent = new UserAgentData();
531
532 // User connection
533 agent.AgentOnline = true;
534 agent.AgentIP = session.RemoteEndPoint.Address.ToString();
535 agent.AgentPort = (uint)session.RemoteEndPoint.Port;
536
537 agent.SecureSessionID = UUID.Random();
538 agent.SessionID = sessionId;
539
540 // Profile UUID
541 agent.ProfileID = userProfile.ID;
542
543 // Current location/position/alignment
544 if (userProfile.CurrentAgent != null)
545 {
546 agent.Region = userProfile.CurrentAgent.Region;
547 agent.Handle = userProfile.CurrentAgent.Handle;
548 agent.Position = userProfile.CurrentAgent.Position;
549 agent.LookAt = userProfile.CurrentAgent.LookAt;
550 }
551 else
552 {
553 agent.Region = userProfile.HomeRegionID;
554 agent.Handle = userProfile.HomeRegion;
555 agent.Position = userProfile.HomeLocation;
556 agent.LookAt = userProfile.HomeLookAt;
557 }
558
559 // What time did the user login?
560 agent.LoginTime = Util.UnixTimeSinceEpoch();
561 agent.LogoutTime = 0;
562
563 userProfile.CurrentAgent = agent;
564
565 userService.CommitAgent(ref userProfile);
566 }
567
568 private void PrepareSceneForConnection(UUID sessionId, UUID sceneId, UserProfileData userProfile)
569 {
570 Scene scene = m_scenes[sceneId];
571 CommunicationsManager commsManager = m_scenes[sceneId].CommsManager;
572 UserManagerBase userService = (UserManagerBase)commsManager.UserService;
573
574 AgentCircuitData agent = new AgentCircuitData();
575 agent.AgentID = userProfile.ID;
576 agent.firstname = userProfile.FirstName;
577 agent.lastname = userProfile.SurName;
578 agent.SessionID = sessionId;
579 agent.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
580 agent.circuitcode = sessionId.CRC();
581 agent.BaseFolder = UUID.Zero;
582 agent.InventoryFolder = UUID.Zero;
583 agent.startpos = new Vector3(0, 0, 0); // TODO Fill in region start position
584 agent.CapsPath = "http://localhost/";
585 agent.Appearance = userService.GetUserAppearance(userProfile.ID);
586
587 if (agent.Appearance == null)
588 {
589 m_log.WarnFormat("[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname);
590 agent.Appearance = new AvatarAppearance();
591 }
592
593 scene.NewUserConnection(agent);
594
595 }
596
597 public void PrintDebugInformation()
598 {
599 m_log.Info("[MXP ClientStack] Statistics report");
600 m_log.Info("Pending Sessions: " + PendingSessionCount);
601 m_log.Info("Sessions: " + SessionCount + " (Clients: " + m_clients.Count + " )");
602 m_log.Info("Transmitter Alive?: " + IsTransmitterAlive);
603 m_log.Info("Packets Sent/Received: " + PacketsSent + " / " + PacketsReceived);
604 m_log.Info("Bytes Sent/Received: " + BytesSent + " / " + BytesReceived);
605 m_log.Info("Send/Receive Rate (bps): " + SendRate + " / " + ReceiveRate);
606 }
607
515 #endregion 608 #endregion
516 609
517 } 610 }