/// <summary> /// Main service start method. /// </summary> internal static void Main() { Logger.Initialize(); AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); CacheServiceConnection.Initialize ( new IPEndPoint ( IPAddress.Parse ( Settings.Default.CacheServiceAddress), Settings.Default.CacheServicePort ), Settings.Default.CacheServiceReconnectInterval ); GameServiceConnection.Initialize ( new IPEndPoint ( IPAddress.Parse ( Settings.Default.GameServiceAddress), Settings.Default.GameServicePort), Settings.Default.GameServiceReconnectInterval ); while (Console.ReadKey(true) != null) { } }
/// <summary> /// Main service start method. /// </summary> internal static void Main() { // initializing logger Logger.Initialize(); // setting unhandled exceptions handler AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); // initializing user connections listener UserConnectionsListener.Initialize ( new IPEndPoint ( IPAddress.Parse(Settings.Default.LoginServiceAddress), Settings.Default.LoginServicePort ), Settings.Default.LoginServiceBacklog, Settings.Default.LoginServiceEnableFirewall ); // initializing cache server connection CacheServiceConnection.Initialize ( new IPEndPoint ( IPAddress.Parse(Settings.Default.CacheServiceAddress), Settings.Default.CacheServicePort ), Settings.Default.CacheServiceReconnectInterval); while (Console.ReadKey(true) != null) { } }
/// <summary> /// Removes provided <see cref="UserConnection"/> object from active connections list. /// </summary> /// <param name="connection"><see cref="UserConnection"/> object to remove from active connections list.</param> internal static void RemoveFromActiveConnections(UserConnection connection) { if (connection != null) { if (connection.Session.AccountID > 0) { CacheServiceConnection.Send(new UnCacheUser(connection.Session.ID).ToPacket()); } m_ActiveConnections.Remove(connection.Session.ID); connection = null; } }
/// <summary> /// Closes all active <see cref="UserConnection"/>s. /// </summary> internal static void CloseAllConnections() { foreach (UserConnection connection in m_ActiveConnections.Values) { connection.CloseConnection(); if (connection.Session.AccountID > 0) { CacheServiceConnection.Send(new UnCacheUser(connection.Session.ID).ToPacket()); } } m_ActiveConnections.Clear(); }
/// <summary> /// Closes active <see cref="UserConnection"/>. /// </summary> /// <param name="connection"><see cref="UserConnection"/> object, which network must be closed.</param> internal static void CloseActiveConnection(UserConnection connection) { if (connection != null) { connection.CloseConnection(); if (connection.Session.AccountID > 0) { CacheServiceConnection.Send(new UnCacheUser(connection.Session.ID).ToPacket()); } m_ActiveConnections.Remove(connection.Session.ID); Logger.WriteLine(Source.OuterNetwork, "Connection closed for session {0}.", connection.Session.ToString()); connection = null; } }
/// <summary> /// Initializes all needed world objects. /// </summary> internal static void StartUp() { if (m_Initialized) { Logger.WriteLine(Source.World, "Can't initialize already initialized world."); return; } Logger.WriteLine(Source.World, "Initializing world..."); #if WORLD_PREFOMANCE Logger.WriteLine(Source.World, "Working set: {0}", Environment.WorkingSet); Stopwatch sw = new Stopwatch(); sw.Start(); #endif if (!Geodata.Initialize()) { return; } else { Logger.WriteLine(Source.World, "Geodata files loaded."); } #if WORLD_PREFOMANCE sw.Stop(); Logger.WriteLine(Source.World, "Working set: {0}", Environment.WorkingSet); Logger.WriteLine(Source.World, "GLoading time: {0}", sw.GetSplitTimeInMicroseconds()); #endif if (!RegionsGrid.Initialize()) { return; } m_Initialized = true; Logger.WriteLine(Source.InnerNetwork, "Setting world as active..."); CacheServiceConnection.Send(new SetWorldActiveRequest().ToPacket()); }
/// <summary> /// Handles incoming packet. /// </summary> /// <param name="packet">Incoming packet.</param> protected override void Handle(Packet packet) { Logger.WriteLine(Source.OuterNetwork, "Received: {0}", packet.ToString()); if (!CacheServiceConnection.Active) // validate if login service is active { Send(LoginFailed.ToPacket(UserAuthenticationResponseType.ServerMaintenance)); UserConnectionsListener.CloseActiveConnection(this); return; } if (QueuedRequestsPool.HasRequest(this, true)) // validate if user is awaiting response from cache service { return; } switch (packet.FirstOpcode) { case 0x07: { Send(ResponseAuthGameGuard.Static); return; } case 0x00: { m_RSADecryptor = new RSAManaged(); m_RSADecryptor.ImportParameters(UserConnectionsListener.PrivateKey); // get login and password unsafe { byte[] bytes = new byte[0x80]; fixed(byte *buf = bytes, src = packet.GetBuffer()) L2Buffer.Copy(src, 0x01, buf, 0x00, 0x80); fixed(byte *buf = m_RSADecryptor.DecryptValue(bytes)) { L2Buffer.GetTrimmedString(buf, 0x03, ref Login, 0x0e); L2Buffer.GetTrimmedString(buf, 0x11, ref Password, 0x10); } } // validate user login if (!Utils.IsValidUserLogin(Login)) { Send(LoginFailed.ToPacket(UserAuthenticationResponseType.UserOrPasswordWrong)); return; } //Password = Utils.HashPassword(Password); Session.AccountName = Login; Logger.WriteLine(Session.ToString()); long requestId = long.MinValue; // request cache to auth user if (QueuedRequestsPool.Enqueue(this, ref requestId)) { CacheServiceConnection.Send(new UserAuthenticationRequest(requestId, Login, Password, Session.ID).ToPacket()); } else { Logger.WriteLine(Source.InnerNetwork, "Failed to send UserAuthenticationRequest to cache service, request was not enqueued by QueuedRequestsPool ?..."); Send(LoginFailed.ToPacket(UserAuthenticationResponseType.SystemError)); UserConnectionsListener.CloseActiveConnection(this); } return; } case 0x05: { int login1 = packet.ReadInt(); int login2 = packet.ReadInt(); if (login1 != Session.Login1 || login2 != Session.Login2) { Logger.WriteLine(Source.OuterNetwork, "Invalid UserSession data: {0}. BAN!", Session.ToString()); CacheServiceConnection.Send(new UnCacheUser(Session.ID).ToPacket()); UserConnectionsListener.CloseActiveConnection(this); } else { long requestID = long.MinValue; if (QueuedRequestsPool.Enqueue(this, ref requestID)) { CacheServiceConnection.Send(new WorldsListRequest(requestID).ToPacket()); } else { Logger.WriteLine(Source.InnerNetwork, "Failed to send WorldsListRequest to cache service, request was not enqueued by QueuedRequestsPool ?..."); UserConnectionsListener.CloseActiveConnection(this); } } return; } case 0x02: { // skip not needed data packet.MoveOffset(8); long requestID = long.MinValue; if (QueuedRequestsPool.Enqueue(this, ref requestID)) { CacheServiceConnection.Send(new JoinWorldRequest(requestID, Session.ID, packet.ReadByte()).ToPacket()); } else { Logger.WriteLine(Source.InnerNetwork, "Failed to send JionWorldRequest to cache service, request was not enqueued by QueuedRequestsPool ?..."); UserConnectionsListener.CloseActiveConnection(this); } return; } } Logger.WriteLine(Source.OuterNetwork, "Unknown packet received: {0}", packet.ToString()); UserConnectionsListener.CloseActiveConnection(this); }