/// <summary>
        /// Executes when lazy queue dumps actual <see cref="Command"/> objects collection.
        /// </summary>
        /// <param name="queue"><see cref="MsSqlDataCommand"/> objects to execute.</param>
        private void LazyQueue_DumpHandler( MsSqlDataCommand[] queue )
        {
            Logger.WriteLine(Source.DataProvider, "Running LazyCommandsQueue dump, {0} commands in queue", queue.Length);

            if ( queue.Length > 0 )
                new Thread(new ParameterizedThreadStart(LazyQueue_DumpHandlerThread)) { IsBackground = false, Priority = ThreadPriority.BelowNormal }.Start(queue);
        }
 /// <summary>
 /// Sets <see cref="MsSqlDataConnection"/> reference to provided <see cref="MsSqlDataCommand"/> object and prepares it.
 /// </summary>
 /// <param name="msdc"><see cref="MsSqlDataCommand"/> object.</param>
 /// <param name="connection"><see cref="MsSqlDataConnection"/> to reference.</param>
 private static void SetConnection( ref MsSqlDataCommand msdc, MsSqlDataConnection connection )
 {
     msdc.Prepare(ref connection);
 }
 /// <summary>
 /// Releases provided <see cref="MsSqlDataCommand"/> resources.
 /// </summary>
 /// <param name="msdc"><see cref="MsSqlDataCommand"/> object to release.</param>
 private static void ReleaseCommand( MsSqlDataCommand msdc )
 {
     if ( msdc != null )
     {
         msdc.Dispose();
         msdc = null;
     }
 }
        /// <summary>
        /// Gets worlds list from database.
        /// </summary>
        /// <returns>Worlds list pre-cached data.</returns>
        public override WorldSummary[] Worlds_Cache()
        {
            MsSqlDataCommand msdc = new MsSqlDataCommand
                (
                    "[Worlds_Cache]",
                    CommandType.StoredProcedure
                );

            SetConnection(ref msdc, m_ActiveConnections.Next());
            DataTable worlds = new DataTable();

            WorldSummary[] array = new WorldSummary[0] { };

            if ( msdc.Execute(ref worlds) && worlds.Rows.Count > 0 )
            {
                array = new WorldSummary[worlds.Rows.Count];

                for ( int i = 0; i < array.Length; i++ )
                {
                    DataRow row = worlds.Rows[i];

                    array[i] = new WorldSummary()
                    {
                        ID = ( byte )row["id"],
                        Address = System.Net.IPAddress.Parse(( string )row["outer_ip"]).GetAddressBytes(),
                        Port = ( int )row["port"],
                        AccessLevel = ( byte )row["access_level"],
                        UsersMax = ( short )row["max_users"],
                        AgeLimit = ( byte )row["age_limit"],
                        IsPvP = ( bool )row["is_pvp"],
                        IsTestServer = ( bool )row["is_test"],
                        ShowClock = ( bool )row["show_clock"],
                        ShowBrackets = ( bool )row["show_brackets"]
                    };
                }
            }

            ReleaseCommand(msdc);

            return array;
        }
        /// <summary>
        /// User creation request processing.
        /// </summary>
        /// <param name="login">User login.</param>
        /// <param name="password">User password.</param>
        /// <param name="accessLevel">User account access level.</param>
        /// <returns>User account unique id.</returns>
        public override int User_Create( string login, string password, byte accessLevel )
        {
            MsSqlDataCommand msdc = new MsSqlDataCommand
                (
                    "[User_Create]",
                     CommandType.StoredProcedure,
                     new SqlParameter("@login", SqlDbType.VarChar, 0x10) { Value = login },
                     new SqlParameter("@password", SqlDbType.VarChar, 0x2f) { Value = password },
                     new SqlParameter("@access_level", SqlDbType.TinyInt) { Value = accessLevel },
                     new SqlParameter("@uid", SqlDbType.Int) { Direction = ParameterDirection.Output }
                );

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

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

            ReleaseCommand(msdc);

            return uid;
        }
        /// <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;
        }