diff options
author | Homer Horwitz | 2009-03-15 21:34:28 +0000 |
---|---|---|
committer | Homer Horwitz | 2009-03-15 21:34:28 +0000 |
commit | abc5df12c883ab14bf7926fc047431249ba52cb5 (patch) | |
tree | ff9042dde59b02e97b1ed2ebe6e39c7db855c615 /OpenSim/Client/MXP/PacketHandler | |
parent | regionInfo isn't defined here yet, which leads to a NRE. Grid-server (diff) | |
download | opensim-SC_OLD-abc5df12c883ab14bf7926fc047431249ba52cb5.zip opensim-SC_OLD-abc5df12c883ab14bf7926fc047431249ba52cb5.tar.gz opensim-SC_OLD-abc5df12c883ab14bf7926fc047431249ba52cb5.tar.bz2 opensim-SC_OLD-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/MXP/PacketHandler')
-rw-r--r-- | OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs | 271 |
1 files changed, 182 insertions, 89 deletions
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; | |||
40 | using OpenSim.Framework; | 40 | using OpenSim.Framework; |
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Framework.Communications; | 42 | using OpenSim.Framework.Communications; |
43 | using System.Security.Cryptography; | ||
43 | 44 | ||
44 | namespace OpenSim.Client.MXP.PacketHandler | 45 | namespace 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 | } |