MXPPacketServer.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  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. /* This file borrows heavily from MXPServer.cs - the reference MXPServer
  28. * See http://www.bubblecloud.org for a copy of the original file and
  29. * implementation details. */
  30. using System;
  31. using System.Collections.Generic;
  32. using System.Reflection;
  33. using System.Threading;
  34. using log4net;
  35. using MXP;
  36. using MXP.Messages;
  37. using OpenMetaverse;
  38. using OpenSim.Client.MXP.ClientStack;
  39. using OpenSim.Framework;
  40. using OpenSim.Region.Framework.Scenes;
  41. using OpenSim.Framework.Communications;
  42. using System.Security.Cryptography;
  43. namespace OpenSim.Client.MXP.PacketHandler
  44. {
  45. public class MXPPacketServer
  46. {
  47. internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  48. #region Fields
  49. private readonly List<MXPClientView> m_clients = new List<MXPClientView>();
  50. private readonly Dictionary<UUID, Scene> m_scenes;
  51. private readonly Transmitter m_transmitter;
  52. private readonly Thread m_clientThread;
  53. private readonly IList<Session> m_sessions = new List<Session>();
  54. private readonly IList<Session> m_sessionsToClient = new List<Session>();
  55. private readonly IList<MXPClientView> m_sessionsToRemove = new List<MXPClientView>();
  56. private readonly int m_port;
  57. private readonly bool m_accountsAuthenticate;
  58. private readonly String m_programName;
  59. private readonly byte m_programMajorVersion;
  60. private readonly byte m_programMinorVersion;
  61. #endregion
  62. #region Constructors
  63. public MXPPacketServer(int port, Dictionary<UUID, Scene> scenes, bool accountsAuthenticate)
  64. {
  65. m_port = port;
  66. m_accountsAuthenticate = accountsAuthenticate;
  67. m_scenes = scenes;
  68. m_programMinorVersion = 63;
  69. m_programMajorVersion = 0;
  70. m_programName = "OpenSimulator";
  71. m_transmitter = new Transmitter(port);
  72. m_clientThread = new Thread(StartListener);
  73. m_clientThread.Name = "MXPThread";
  74. m_clientThread.IsBackground = true;
  75. m_clientThread.Start();
  76. ThreadTracker.Add(m_clientThread);
  77. }
  78. public void StartListener()
  79. {
  80. m_log.Info("[MXP ClientStack] Transmitter starting on UDP server port: " + m_port);
  81. m_transmitter.Startup();
  82. m_log.Info("[MXP ClientStack] Transmitter started. MXP version: "+MxpConstants.ProtocolMajorVersion+"."+MxpConstants.ProtocolMinorVersion+" Source Revision: "+MxpConstants.ProtocolSourceRevision);
  83. }
  84. #endregion
  85. #region Properties
  86. /// <summary>
  87. /// Number of sessions pending. (Process() accepts pending sessions).
  88. /// </summary>
  89. public int PendingSessionCount
  90. {
  91. get
  92. {
  93. return m_transmitter.PendingSessionCount;
  94. }
  95. }
  96. /// <summary>
  97. /// Number of connected sessions.
  98. /// </summary>
  99. public int SessionCount
  100. {
  101. get
  102. {
  103. return m_sessions.Count;
  104. }
  105. }
  106. /// <summary>
  107. /// Property reflecting whether client transmitter threads are alive.
  108. /// </summary>
  109. public bool IsTransmitterAlive
  110. {
  111. get
  112. {
  113. return m_transmitter != null && m_transmitter.IsAlive;
  114. }
  115. }
  116. /// <summary>
  117. /// Number of packets sent.
  118. /// </summary>
  119. public ulong PacketsSent
  120. {
  121. get
  122. {
  123. return m_transmitter != null ? m_transmitter.PacketsSent : 0;
  124. }
  125. }
  126. /// <summary>
  127. /// Number of packets received.
  128. /// </summary>
  129. public ulong PacketsReceived
  130. {
  131. get
  132. {
  133. return m_transmitter != null ? m_transmitter.PacketsReceived : 0;
  134. }
  135. }
  136. /// <summary>
  137. /// Bytes client has received so far.
  138. /// </summary>
  139. public ulong BytesReceived
  140. {
  141. get
  142. {
  143. return m_transmitter != null ? m_transmitter.BytesReceived : 0;
  144. }
  145. }
  146. /// <summary>
  147. /// Bytes client has sent so far.
  148. /// </summary>
  149. public ulong BytesSent
  150. {
  151. get
  152. {
  153. return m_transmitter != null ? m_transmitter.BytesSent : 0;
  154. }
  155. }
  156. /// <summary>
  157. /// Number of bytes received (bytes per second) during past second.
  158. /// </summary>
  159. public double ReceiveRate
  160. {
  161. get
  162. {
  163. return m_transmitter != null ? m_transmitter.ReceiveRate : 0;
  164. }
  165. }
  166. /// <summary>
  167. /// Number of bytes sent (bytes per second) during past second.
  168. /// </summary>
  169. public double SendRate
  170. {
  171. get
  172. {
  173. return m_transmitter != null ? m_transmitter.SendRate : 0;
  174. }
  175. }
  176. #endregion
  177. #region Session Management
  178. public void Disconnect(Session session)
  179. {
  180. if (session.IsConnected)
  181. {
  182. Message message = MessageFactory.Current.ReserveMessage(typeof(LeaveRequestMessage));
  183. session.Send(message);
  184. MessageFactory.Current.ReleaseMessage(message);
  185. }
  186. else
  187. {
  188. throw new Exception("Not connected.");
  189. }
  190. }
  191. #endregion
  192. #region Processing
  193. public void Process()
  194. {
  195. ProcessMessages();
  196. Clean();
  197. }
  198. public void Clean()
  199. {
  200. foreach (MXPClientView clientView in m_clients)
  201. {
  202. if (clientView.Session.SessionState == SessionState.Disconnected)
  203. {
  204. m_sessionsToRemove.Add(clientView);
  205. }
  206. }
  207. foreach (MXPClientView clientView in m_sessionsToRemove)
  208. {
  209. clientView.Scene.RemoveClient(clientView.AgentId);
  210. clientView.OnClean();
  211. m_clients.Remove(clientView);
  212. m_sessions.Remove(clientView.Session);
  213. }
  214. m_sessionsToRemove.Clear();
  215. }
  216. public void ProcessMessages()
  217. {
  218. if (m_transmitter.PendingSessionCount > 0)
  219. {
  220. Session tmp = m_transmitter.AcceptPendingSession();
  221. m_sessions.Add(tmp);
  222. m_sessionsToClient.Add(tmp);
  223. }
  224. List<Session> tmpRemove = new List<Session>();
  225. foreach (Session session in m_sessionsToClient)
  226. {
  227. while (session.AvailableMessages > 0)
  228. {
  229. Message message = session.Receive();
  230. if (message.GetType() == typeof (JoinRequestMessage))
  231. {
  232. JoinRequestMessage joinRequestMessage = (JoinRequestMessage) message;
  233. m_log.Info("[MXP ClientStack]: Session join request: " + session.SessionId + " (" +
  234. (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
  235. session.RemoteEndPoint.Port + ")");
  236. try
  237. {
  238. if (joinRequestMessage.BubbleId == Guid.Empty)
  239. {
  240. foreach (Scene scene in m_scenes.Values)
  241. {
  242. if (scene.RegionInfo.RegionName == joinRequestMessage.BubbleName)
  243. {
  244. m_log.Info("[MXP ClientStack]: Resolved region by name: " + joinRequestMessage.BubbleName + " (" + scene.RegionInfo.RegionID + ")");
  245. joinRequestMessage.BubbleId = scene.RegionInfo.RegionID.Guid;
  246. }
  247. }
  248. }
  249. if (joinRequestMessage.BubbleId == Guid.Empty)
  250. {
  251. m_log.Warn("[MXP ClientStack]: Failed to resolve region by name: " + joinRequestMessage.BubbleName);
  252. }
  253. UUID sceneId = new UUID(joinRequestMessage.BubbleId);
  254. bool regionExists = true;
  255. if (!m_scenes.ContainsKey(sceneId))
  256. {
  257. m_log.Info("[MXP ClientStack]: No such region: " + sceneId);
  258. regionExists = false;
  259. }
  260. UserProfileData user = null;
  261. UUID userId = UUID.Zero;
  262. string firstName = null;
  263. string lastName = null;
  264. bool authorized = regionExists ? AuthoriseUser(joinRequestMessage.ParticipantName,
  265. joinRequestMessage.ParticipantPassphrase,
  266. new UUID(joinRequestMessage.BubbleId), out userId, out firstName, out lastName, out user)
  267. : false;
  268. if (authorized)
  269. {
  270. Scene scene = m_scenes[sceneId];
  271. UUID mxpSessionID = UUID.Random();
  272. string reason;
  273. m_log.Debug("[MXP ClientStack]: Session join request success: " + session.SessionId + " (" +
  274. (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
  275. session.RemoteEndPoint.Port + ")");
  276. m_log.Debug("[MXP ClientStack]: Attaching UserAgent to UserProfile...");
  277. AttachUserAgentToUserProfile(session, mxpSessionID, sceneId, user);
  278. m_log.Debug("[MXP ClientStack]: Attached UserAgent to UserProfile.");
  279. m_log.Debug("[MXP ClientStack]: Preparing Scene to Connection...");
  280. if (!PrepareSceneForConnection(mxpSessionID, sceneId, user, out reason))
  281. {
  282. m_log.DebugFormat("[MXP ClientStack]: Scene refused connection: {0}", reason);
  283. DeclineConnection(session, joinRequestMessage);
  284. tmpRemove.Add(session);
  285. continue;
  286. }
  287. m_log.Debug("[MXP ClientStack]: Prepared Scene to Connection.");
  288. m_log.Debug("[MXP ClientStack]: Accepting connection...");
  289. AcceptConnection(session, joinRequestMessage, mxpSessionID, userId);
  290. m_log.Info("[MXP ClientStack]: Accepted connection.");
  291. m_log.Debug("[MXP ClientStack]: Creating ClientView....");
  292. MXPClientView client = new MXPClientView(session, mxpSessionID, userId, scene, firstName, lastName);
  293. m_clients.Add(client);
  294. m_log.Debug("[MXP ClientStack]: Created ClientView.");
  295. m_log.Debug("[MXP ClientStack]: Adding ClientView to Scene...");
  296. scene.ClientManager.Add(client.CircuitCode, client);
  297. m_log.Debug("[MXP ClientStack]: Added ClientView to Scene.");
  298. client.MXPSendSynchronizationBegin(m_scenes[new UUID(joinRequestMessage.BubbleId)].SceneContents.GetTotalObjectsCount());
  299. m_log.Debug("[MXP ClientStack]: Starting ClientView...");
  300. try
  301. {
  302. client.Start();
  303. m_log.Debug("[MXP ClientStack]: Started ClientView.");
  304. }
  305. catch (Exception e)
  306. {
  307. m_log.Error(e);
  308. }
  309. m_log.Debug("[MXP ClientStack]: Connected");
  310. }
  311. else
  312. {
  313. m_log.Info("[MXP ClientStack]: Session join request failure: " + session.SessionId + " (" +
  314. (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
  315. session.RemoteEndPoint.Port + ")");
  316. DeclineConnection(session, joinRequestMessage);
  317. }
  318. }
  319. catch (Exception e)
  320. {
  321. m_log.Error("[MXP ClientStack]: Session join request failure: " + session.SessionId + " (" +
  322. (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" +
  323. session.RemoteEndPoint.Port + "): "+e.ToString()+" :"+e.StackTrace.ToString());
  324. }
  325. tmpRemove.Add(session);
  326. }
  327. }
  328. }
  329. foreach (Session session in tmpRemove)
  330. {
  331. m_sessionsToClient.Remove(session);
  332. }
  333. foreach (MXPClientView clientView in m_clients)
  334. {
  335. int messagesProcessedCount = 0;
  336. Session session = clientView.Session;
  337. while (session.AvailableMessages > 0)
  338. {
  339. Message message = session.Receive();
  340. if (message.GetType() == typeof(LeaveRequestMessage))
  341. {
  342. LeaveResponseMessage leaveResponseMessage = (LeaveResponseMessage)MessageFactory.Current.ReserveMessage(
  343. typeof(LeaveResponseMessage));
  344. m_log.Debug("[MXP ClientStack]: Session leave request: " + session.SessionId + " (" + (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + session.RemoteEndPoint.Port + ")");
  345. leaveResponseMessage.RequestMessageId = message.MessageId;
  346. leaveResponseMessage.FailureCode = 0;
  347. session.Send(leaveResponseMessage);
  348. if (session.SessionState != SessionState.Disconnected)
  349. {
  350. session.SetStateDisconnected();
  351. }
  352. m_log.Debug("[MXP ClientStack]: Removing Client from Scene");
  353. //clientView.Scene.RemoveClient(clientView.AgentId);
  354. }
  355. if (message.GetType() == typeof(LeaveResponseMessage))
  356. {
  357. LeaveResponseMessage leaveResponseMessage = (LeaveResponseMessage)message;
  358. m_log.Debug("[MXP ClientStack]: Session leave response: " + session.SessionId + " (" + (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + session.RemoteEndPoint.Port + ")");
  359. if (leaveResponseMessage.FailureCode == 0)
  360. {
  361. session.SetStateDisconnected();
  362. }
  363. m_log.Debug("[MXP ClientStack]: Removing Client from Scene");
  364. //clientView.Scene.RemoveClient(clientView.AgentId);
  365. }
  366. else
  367. {
  368. clientView.MXPPRocessMessage(message);
  369. }
  370. MessageFactory.Current.ReleaseMessage(message);
  371. messagesProcessedCount++;
  372. if (messagesProcessedCount > 1000)
  373. {
  374. break;
  375. }
  376. }
  377. }
  378. }
  379. private void AcceptConnection(Session session, JoinRequestMessage joinRequestMessage, UUID mxpSessionID, UUID userId)
  380. {
  381. JoinResponseMessage joinResponseMessage = (JoinResponseMessage)MessageFactory.Current.ReserveMessage(
  382. typeof(JoinResponseMessage));
  383. joinResponseMessage.RequestMessageId = joinRequestMessage.MessageId;
  384. joinResponseMessage.FailureCode = MxpResponseCodes.SUCCESS;
  385. joinResponseMessage.BubbleId = joinRequestMessage.BubbleId;
  386. joinResponseMessage.ParticipantId = userId.Guid;
  387. joinResponseMessage.AvatarId = userId.Guid;
  388. joinResponseMessage.BubbleAssetCacheUrl = "http://" +
  389. NetworkUtil.GetHostFor(session.RemoteEndPoint.Address,
  390. m_scenes[
  391. new UUID(joinRequestMessage.BubbleId)].
  392. RegionInfo.
  393. ExternalHostName) + ":" +
  394. m_scenes[new UUID(joinRequestMessage.BubbleId)].RegionInfo.
  395. HttpPort + "/assets/";
  396. joinResponseMessage.BubbleName = m_scenes[new UUID(joinRequestMessage.BubbleId)].RegionInfo.RegionName;
  397. joinResponseMessage.BubbleRange = 128;
  398. joinResponseMessage.BubblePerceptionRange = 128 + 256;
  399. joinResponseMessage.BubbleRealTime = 0;
  400. joinResponseMessage.ProgramName = m_programName;
  401. joinResponseMessage.ProgramMajorVersion = m_programMajorVersion;
  402. joinResponseMessage.ProgramMinorVersion = m_programMinorVersion;
  403. joinResponseMessage.ProtocolMajorVersion = MxpConstants.ProtocolMajorVersion;
  404. joinResponseMessage.ProtocolMinorVersion = MxpConstants.ProtocolMinorVersion;
  405. joinResponseMessage.ProtocolSourceRevision = MxpConstants.ProtocolSourceRevision;
  406. session.Send(joinResponseMessage);
  407. session.SetStateConnected();
  408. }
  409. private void DeclineConnection(Session session, Message joinRequestMessage)
  410. {
  411. JoinResponseMessage joinResponseMessage = (JoinResponseMessage)MessageFactory.Current.ReserveMessage(typeof(JoinResponseMessage));
  412. joinResponseMessage.RequestMessageId = joinRequestMessage.MessageId;
  413. joinResponseMessage.FailureCode = MxpResponseCodes.UNAUTHORIZED_OPERATION;
  414. joinResponseMessage.ProgramName = m_programName;
  415. joinResponseMessage.ProgramMajorVersion = m_programMajorVersion;
  416. joinResponseMessage.ProgramMinorVersion = m_programMinorVersion;
  417. joinResponseMessage.ProtocolMajorVersion = MxpConstants.ProtocolMajorVersion;
  418. joinResponseMessage.ProtocolMinorVersion = MxpConstants.ProtocolMinorVersion;
  419. joinResponseMessage.ProtocolSourceRevision = MxpConstants.ProtocolSourceRevision;
  420. session.Send(joinResponseMessage);
  421. session.SetStateDisconnected();
  422. }
  423. public bool AuthoriseUser(string participantName, string password, UUID sceneId, out UUID userId, out string firstName, out string lastName, out UserProfileData userProfile)
  424. {
  425. userId = UUID.Zero;
  426. firstName = "";
  427. lastName = "";
  428. userProfile = null;
  429. string[] nameParts = participantName.Split(' ');
  430. if (nameParts.Length != 2)
  431. {
  432. m_log.Error("[MXP ClientStack]: Login failed as user name is not formed of first and last name separated by space: " + participantName);
  433. return false;
  434. }
  435. firstName = nameParts[0];
  436. lastName = nameParts[1];
  437. userProfile = m_scenes[sceneId].CommsManager.UserService.GetUserProfile(firstName, lastName);
  438. if (userProfile == null && !m_accountsAuthenticate)
  439. {
  440. userId = ((UserManagerBase)m_scenes[sceneId].CommsManager.UserService).AddUser(firstName, lastName, "test", "", 1000, 1000);
  441. }
  442. else
  443. {
  444. if (userProfile == null)
  445. {
  446. m_log.Error("[MXP ClientStack]: Login failed as user was not found: " + participantName);
  447. return false;
  448. }
  449. userId = userProfile.ID;
  450. }
  451. if (m_accountsAuthenticate)
  452. {
  453. if (!password.StartsWith("$1$"))
  454. {
  455. password = "$1$" + Util.Md5Hash(password);
  456. }
  457. password = password.Remove(0, 3); //remove $1$
  458. string s = Util.Md5Hash(password + ":" + userProfile.PasswordSalt);
  459. return (userProfile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
  460. || userProfile.PasswordHash.Equals(password, StringComparison.InvariantCulture));
  461. }
  462. else
  463. {
  464. return true;
  465. }
  466. }
  467. private void AttachUserAgentToUserProfile(Session session, UUID sessionId, UUID sceneId, UserProfileData userProfile)
  468. {
  469. //Scene scene = m_scenes[sceneId];
  470. CommunicationsManager commsManager = m_scenes[sceneId].CommsManager;
  471. IUserService userService = (IUserService)commsManager.UserService;
  472. UserAgentData agent = new UserAgentData();
  473. // User connection
  474. agent.AgentOnline = true;
  475. agent.AgentIP = session.RemoteEndPoint.Address.ToString();
  476. agent.AgentPort = (uint)session.RemoteEndPoint.Port;
  477. agent.SecureSessionID = UUID.Random();
  478. agent.SessionID = sessionId;
  479. // Profile UUID
  480. agent.ProfileID = userProfile.ID;
  481. // Current location/position/alignment
  482. if (userProfile.CurrentAgent != null)
  483. {
  484. agent.Region = userProfile.CurrentAgent.Region;
  485. agent.Handle = userProfile.CurrentAgent.Handle;
  486. agent.Position = userProfile.CurrentAgent.Position;
  487. agent.LookAt = userProfile.CurrentAgent.LookAt;
  488. }
  489. else
  490. {
  491. agent.Region = userProfile.HomeRegionID;
  492. agent.Handle = userProfile.HomeRegion;
  493. agent.Position = userProfile.HomeLocation;
  494. agent.LookAt = userProfile.HomeLookAt;
  495. }
  496. // What time did the user login?
  497. agent.LoginTime = Util.UnixTimeSinceEpoch();
  498. agent.LogoutTime = 0;
  499. userProfile.CurrentAgent = agent;
  500. userService.UpdateUserProfile(userProfile);
  501. //userService.CommitAgent(ref userProfile);
  502. }
  503. private bool PrepareSceneForConnection(UUID sessionId, UUID sceneId, UserProfileData userProfile, out string reason)
  504. {
  505. Scene scene = m_scenes[sceneId];
  506. CommunicationsManager commsManager = m_scenes[sceneId].CommsManager;
  507. UserManagerBase userService = (UserManagerBase)commsManager.UserService;
  508. AgentCircuitData agent = new AgentCircuitData();
  509. agent.AgentID = userProfile.ID;
  510. agent.firstname = userProfile.FirstName;
  511. agent.lastname = userProfile.SurName;
  512. agent.SessionID = sessionId;
  513. agent.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
  514. agent.circuitcode = sessionId.CRC();
  515. agent.BaseFolder = UUID.Zero;
  516. agent.InventoryFolder = UUID.Zero;
  517. agent.startpos = new Vector3(0, 0, 0); // TODO Fill in region start position
  518. agent.CapsPath = "http://localhost/";
  519. agent.Appearance = userService.GetUserAppearance(userProfile.ID);
  520. if (agent.Appearance == null)
  521. {
  522. m_log.WarnFormat("[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname);
  523. agent.Appearance = new AvatarAppearance();
  524. }
  525. return scene.NewUserConnection(agent, out reason);
  526. }
  527. public void PrintDebugInformation()
  528. {
  529. m_log.Info("[MXP ClientStack]: Statistics report");
  530. m_log.Info("Pending Sessions: " + PendingSessionCount);
  531. m_log.Info("Sessions: " + SessionCount + " (Clients: " + m_clients.Count + " )");
  532. m_log.Info("Transmitter Alive?: " + IsTransmitterAlive);
  533. m_log.Info("Packets Sent/Received: " + PacketsSent + " / " + PacketsReceived);
  534. m_log.Info("Bytes Sent/Received: " + BytesSent + " / " + BytesReceived);
  535. m_log.Info("Send/Receive Rate (bps): " + SendRate + " / " + ReceiveRate);
  536. }
  537. #endregion
  538. }
  539. }