MXPPacketServer.cs 26 KB

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