/// <summary>
        /// Handles incoming <see cref="Packet"/>.
        /// </summary>
        /// <param name="p"><see cref="Packet"/> to handle.</param>
        internal void Handle( Packet p )
        {
            switch ( p.FirstOpcode )
            {
                case ServiceLayer.Identity:
                    {
                        switch ( p.SecondOpcode )
                        {
                            case ServiceLayer.InitializeRequest:
                                {
                                    Logger.WriteLine(Source.InnerNetwork, "Connected service requests connection initialization.");
                                    return;
                                }
                            case ServiceLayer.SetSettingsRequest:
                                {
                                    LoginServiceSettings settings = ( LoginServiceSettings )SetSettingsRequest.FromPacket(p, ServiceType.LoginService);
                                    ConnectionsManager.SetServiceSettings(settings);
                                    return;
                                }
                        }

                        break;
                    }
                case UserDataLayer.Identity:
                    {
                        switch ( p.SecondOpcode )
                        {
                            case UserDataLayer.AuthenticateUser:
                                {
                                    UserAuthenticationRequest request = new UserAuthenticationRequest(p);

                                    if ( RealtimeManager.ConnectedUsers.Connected(request.SessionID) )
                                    {
                                        Send(new UserAuthenticationResponse(request.RequestID, UserAuthenticationResponseType.AccessFailed).ToPacket());
                                        return;
                                    }

                                    if ( RealtimeManager.ConnectedUsers.Connected(request.Login) )
                                    {
                                        Send(new UserAuthenticationResponse(request.RequestID, UserAuthenticationResponseType.AccountInUse).ToPacket());
                                        return;
                                    }

                                    Send(DataProvider.DataBase.User_Auth(request, ( LoginServiceSettings )Service.RemoteServiceSettings).ToPacket());

                                    return;
                                }
                            case UserDataLayer.CacheUserSessionRequest:
                                {
                                    CacheUserSessionRequest request = new CacheUserSessionRequest(p);

                                    if ( RealtimeManager.ConnectedUsers.Connected(request.Session.ID) || RealtimeManager.ConnectedUsers.Connected(request.Session.AccountName) )
                                    {
                                        Send(new CacheUserSessionResponse(request.RequestID, CacheUserSessionResponse.Failed).ToPacket());
                                        return;
                                    }

                                    RealtimeManager.ConnectedUsers.Register(request.Session);

                                    Send(new CacheUserSessionResponse(request.RequestID, CacheUserSessionResponse.Accepted).ToPacket());

                                    return;
                                }
                            case UserDataLayer.WorldsListRequest:
                                {
                                    WorldsListRequest request = new WorldsListRequest(p);
                                    Send(new WorldsListResponse(request.RequestID, RealtimeManager.WorldsInfo.Get()).ToPacket());
                                    return;
                                }
                            case UserDataLayer.UnCacheUser:
                                {
                                    UnCacheUser request = new UnCacheUser(p);

                                    // update user login / logout / used_time values in database.

                                    UserSession session = RealtimeManager.ConnectedUsers.Find(request.SessionID);

                                    if ( session != UserSession.Null )
                                    {
                                        DataProvider.DataBase.User_Logout(session.AccountID, session.StartTime, session.IPAddress, session.LastWorld);
                                        RealtimeManager.ConnectedUsers.Unregister(request.SessionID);
                                    }

                                    return;
                                }
                            case UserDataLayer.JoinWorldRequest:
                                {
                                    // check access level

                                    JoinWorldRequest request = new JoinWorldRequest(p);

                                    if ( !RealtimeManager.ConnectedUsers.Connected(request.SessionID) )
                                    {
                                        Send(new JoinWorldResponse(request.RequestID, JoinWorldRequestResult.AccessFailed).ToPacket());
                                        return;
                                    }

                                    if ( !RealtimeManager.WorldsInfo.Contains(request.WorldID) || !RealtimeManager.WorldsInfo.IsOnline(request.WorldID) )
                                    {
                                        Send(new JoinWorldResponse(request.RequestID, JoinWorldRequestResult.SystemError).ToPacket());
                                        return;
                                    }

                                    if ( RealtimeManager.WorldsInfo.IsFull(request.WorldID) )
                                    {
                                        Send(new JoinWorldResponse(request.RequestID, JoinWorldRequestResult.TooManyPlayers).ToPacket());
                                        return;
                                    }

                                    Send(new JoinWorldResponse(request.RequestID, JoinWorldRequestResult.Accepted).ToPacket());
                                    return;
                                }
                        }

                        break;
                    }
                default:
                    {
                        break;
                    }
            }

            Logger.WriteLine(Source.InnerNetwork, "Unknown packet received from {0} service:{1}{2}", ServiceType.LoginService, Environment.NewLine, p.ToString());
        }
        /// <summary>
        /// User authentication request processing.
        /// </summary>
        /// <param name="netRequest"><see cref="UserAuthenticationRequest"/> to verify user data from.</param>
        /// <param name="settings"><see cref="LoginServiceSettings"/> object.</param>
        /// <returns><see cref="UserAuthenticationResponse"/> struct.</returns>
        public override UserAuthenticationResponse User_Auth( UserAuthenticationRequest netRequest, LoginServiceSettings settings )
        {
            MsSqlDataCommand msdc = new MsSqlDataCommand
            (
                "[User_Auth]",
                CommandType.StoredProcedure,
                new SqlParameter("@login", SqlDbType.VarChar, 0x10) { Value = netRequest.Login },
                new SqlParameter("@password", SqlDbType.VarChar, 0x2f) { Value = netRequest.Password },
                new SqlParameter("@uid", SqlDbType.Int) { Direction = ParameterDirection.Output },
                new SqlParameter("@last_world", SqlDbType.TinyInt) { Direction = ParameterDirection.Output },
                new SqlParameter("@access_level", SqlDbType.TinyInt) { Direction = ParameterDirection.Output }
            );

            SetConnection(ref msdc, m_ActiveConnections.Next());

            msdc.ExecuteNonQuery();

            int uid = TypesConverter.GetInt(msdc.Parameters["@uid"].Value, int.MinValue);

            UserAuthenticationResponse rsp = new UserAuthenticationResponse(netRequest.RequestID, UserAuthenticationResponseType.UserOrPasswordWrong);

            switch ( uid )
            {
                case int.MinValue: // conversion error
                    {
                        rsp.Response = UserAuthenticationResponseType.SystemError;
                        break;
                    }
                case -2: // invalid credentials
                    break;
                case -1: // login doesn't exist
                    {
                        if ( settings != null && settings.AutoCreateUser )
                        {
                            // creating user
                            uid = User_Create(netRequest.Login, netRequest.Password, settings.DefaultAccessLevel);

                            switch ( uid )
                            {
                                case int.MinValue: // conversion error
                                case -2: // db insert error
                                    {
                                        rsp.Response = UserAuthenticationResponseType.SystemError;
                                        break;
                                    }
                                case -1: // login already exists
                                    break;
                                default: // user created
                                    {
                                        rsp.Response = UserAuthenticationResponseType.UserAccepted;
                                        rsp.UserID = uid;
                                        rsp.AccessLevel = settings.DefaultAccessLevel;
                                        rsp.LastWorldID = TypesConverter.GetByte(msdc.Parameters["@last_world"].Value, 1);
                                        break;
                                    }
                            }
                        }
                        else
                            goto case -2;
                        break;
                    }
                default:
                    {
                        rsp.Response = UserAuthenticationResponseType.UserAccepted;
                        rsp.UserID = uid;
                        rsp.LastWorldID = TypesConverter.GetByte(msdc.Parameters["@last_world"].Value, 1);
                        rsp.AccessLevel = TypesConverter.GetByte(msdc.Parameters["@access_level"].Value, 0);
                        break;
                    }
            }

            ReleaseCommand(msdc);

            return rsp;
        }