using System;
using System.Data;
using System.Timers;
using System.Data.SqlClient;
using System.Collections.Generic;

namespace FilterAPI
{
    public class Database
    {
        public Authentication Auth;

        public SqlConnection Connection;

        public String AccountDB;
        public String CharacterDB;
        public String GameLogDB;
        public String FilterDB;
        public String CustomCurrencyDB;
        public String IDColumn;
        public String AccountTable;
        public String TokenTable;

        public Database(Authentication A)
        {
            Auth = A;

            AccountDB = Auth.ConfigValues["AccountDB"];
            CharacterDB = Auth.ConfigValues["CharacterDB"];
            GameLogDB = Auth.ConfigValues["GameLogDB"];
            FilterDB = Auth.ConfigValues["FilterDB"];
            CustomCurrencyDB = Auth.ConfigValues["CustomCurrencyDB"];
            IDColumn = Auth.ConfigValues["UserIDColumn"];
            AccountTable = Auth.ConfigValues["AccountTable"];
            TokenTable = Auth.ConfigValues["TokenTable"];

            SqlConnectionStringBuilder ConnectionSB = new SqlConnectionStringBuilder();
            ConnectionSB.DataSource = Auth.ConfigValues["DataSource"];
            ConnectionSB.IntegratedSecurity = Convert.ToBoolean(Auth.ConfigValues["IntegratedSecurity"]);
            ConnectionSB.MultipleActiveResultSets = true;

            if (!Convert.ToBoolean(Auth.ConfigValues["IntegratedSecurity"]))
            {
                ConnectionSB.Password = Auth.ConfigValues["Password"];
                ConnectionSB.UserID = Auth.ConfigValues["UserID"];
            }

            Connection = new SqlConnection();
            Connection.ConnectionString = ConnectionSB.ConnectionString;
            Connection.Open();

            Timer DatabaseAlive = new Timer();
            DatabaseAlive.AutoReset = true;
            DatabaseAlive.Elapsed += DatabaseAlive_Elapsed;
            DatabaseAlive.Interval = 1500;
            DatabaseAlive.Start();
        }

        private void DatabaseAlive_Elapsed(Object Sender, ElapsedEventArgs Args)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nCharNo FROM {0}..tCharacter", CharacterDB);
                Command.ExecuteNonQuery();
                Command.Dispose();
            }
        }

        public Boolean DatabaseExists(String Database)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM sys.databases WHERE Name = '{0}'", Database);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Boolean TableExists(String Database, String Table)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}.INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '{1}'", Database, Table);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public void CreateCCTable(String TableName, String Type)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("CREATE TABLE {0}..{1} ({2} int NOT NULL, Amount bigint NOT NULL)", CustomCurrencyDB, TableName, Type);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean TableHasColumn(String Database, String TableName, String ColumnName)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 COLUMN_NAME FROM {0}.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{1}' AND COLUMN_NAME = '{2}'", Database, TableName, ColumnName);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows) { return true; }
                }
            }

            return false;
        }

        public void AddObtainedToTable(String TableName)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("ALTER TABLE {0}..{1} ADD Obtained int NOT NULL DEFAULT '0'", CustomCurrencyDB, TableName);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean sUsernameExists(String sUsername)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) sUsername FROM {0}..{1} WHERE sUsername = @sUsername", AccountDB, AccountTable);
				Command.Parameters.AddWithValue("@sUsername", sUsername);
                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }
		
        public Boolean sUserPassMatchsUsername(String sUsername, String sUserPass)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) sUsername FROM {0}..{1} WHERE sUsername = @sUsername AND sUserPass = @sUserPass", AccountDB, AccountTable);
				Command.Parameters.AddWithValue("@sUsername", sUsername);
				Command.Parameters.AddWithValue("@sUserPass", sUserPass);
				return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Int32 GetnEMIDFromsUsername(String sUsername)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 {0} sUsername FROM {1}..{2} WHERE sUsername = @sUsername", IDColumn, AccountDB, AccountTable);
				Command.Parameters.AddWithValue("@sUsername", sUsername);
				return Convert.ToInt32(Command.ExecuteScalar());
            }
        }

		public String GetsUserPassFromsUsername(String sUsername)
		{
			if (Connection.State != ConnectionState.Open) { Connection.Open(); }

			using (SqlCommand Command = Connection.CreateCommand())
			{
				Command.CommandTimeout = 0;
				Command.CommandText = $"SELECT sUserPass FROM {AccountDB}..{AccountTable} WHERE sUsername = @sUsername";
				Command.Parameters.AddWithValue("@sUsername", sUsername);
				return Convert.ToString(Command.ExecuteScalar());
			}

		}

		public Boolean nEMIDHasToken(Int32 nEMID)
		{
			if (Connection.State != ConnectionState.Open) { Connection.Open(); }

			using (SqlCommand Command = Connection.CreateCommand())
			{
				Command.CommandTimeout = 0;
				Command.CommandText = $"SELECT COUNT(*) from {AccountDB}..{TokenTable} WHERE {IDColumn}= @nEMID";
				Command.Parameters.AddWithValue("@nEMID", nEMID);
				return Convert.ToInt16(Command.ExecuteScalar()) >= 1;
			}
		}

		public void DeletesTokenFornEMID(Int32 nEMID)
		{
			if (Connection.State != ConnectionState.Open) { Connection.Open(); }

			using (SqlCommand Command = Connection.CreateCommand())
			{
				Command.CommandTimeout = 0;
				Command.CommandText = $"DELETE FROM {AccountDB}..{TokenTable} WHERE {IDColumn} = @nEMID";
				Command.Parameters.AddWithValue("@nEMID", nEMID);
				if (nEMIDHasToken(nEMID))
				{
					Command.ExecuteNonQuery();
				}
			}
		}
		
		public String CreateOrUpdatesTokenFornEMID(Int32 nEMID)
		{
			if (Connection.State != ConnectionState.Open) { Connection.Open(); }

			using (SqlCommand Command = Connection.CreateCommand())
			{
				Command.CommandTimeout = 0;
				String sToken = Convert.ToString(Guid.NewGuid()).Substring(0, 25);
				if (nEMIDHasToken(nEMID))
				{
					Command.CommandText = $"UPDATE {AccountDB}..{TokenTable} SET {IDColumn} = @nEMID, sToken = @sToken WHERE {IDColumn} = @nEMID";
				}
				else
				{
					Command.CommandText = $"INSERT into {AccountDB}..{TokenTable} ({IDColumn}, sToken) VALUES (@nEMID,@sToken)";
				}
				Command.Parameters.AddWithValue("@nEMID", nEMID);
				Command.Parameters.AddWithValue("@sToken", sToken);
				Command.ExecuteNonQuery();
				return sToken;
			}
		}
        public String CreateAndInsertsTokenFornEMID(Int32 nEMID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                String sToken = Convert.ToString(Guid.NewGuid());

				DeletesTokenFornEMID(nEMID);

                Command.CommandText = $"INSERT INTO {AccountDB}..{TokenTable} ({IDColumn}, sToken) VALUES (@nEMID, @sToken)";
				Command.Parameters.AddWithValue("@nEMID", nEMID);
				Command.Parameters.AddWithValue("@sToken", sToken);
				Command.ExecuteNonQuery();

                return sToken;
            }
        }

        public void InsertNewtAccount(String sUsername, String sUserPass)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

			using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
				Command.CommandText = String.Format("INSERT INTO {0}..{1} (sUsername, sUserPass, sEmail, nAuthID, sIP, dDate, nAGPoints, nBonusAGPoints, sRID, sNotes) VALUES (@sUsername, @sUserPass, '-', '-', @sIP, @dDate, '0', '0', '-', @sNotes) ", AccountDB, AccountTable);
				Command.Parameters.Add("@sUsername", SqlDbType.NVarChar).Value = sUsername;
				Command.Parameters.Add("@sUserPass", SqlDbType.NVarChar).Value = sUserPass;
				Command.Parameters.Add("@sIP", SqlDbType.NVarChar).Value = "127.0.0.1";
				Command.Parameters.Add("@dDate", SqlDbType.DateTime).Value = DateTime.Now;
				Command.Parameters.Add("@sNotes", SqlDbType.NVarChar).Value = "FilterBot";
				Command.ExecuteNonQuery();
            }
        }

        public void SetsUserPassForsUsername(String sUsername, String sUserPass)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..{1} SET sUserPass = @sUserPass WHERE sUsername = @sUsername", AccountDB, AccountTable);
				Command.Parameters.AddWithValue("@sUsername", sUsername);
				Command.Parameters.AddWithValue("@sUserPass", sUserPass);
				Command.ExecuteNonQuery();
            }
        }

        public Boolean sTokenExists(String sToken)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..{1} WHERE sToken = @sToken", AccountDB, TokenTable);
				Command.Parameters.AddWithValue("@sToken", sToken);
				if (Convert.ToInt32(Command.ExecuteScalar()) != 0) { return true; }
            }

            return false;
        }

        public Boolean GetnEMIDFromsToken(String sToken, out Int32 nEMID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 {0} FROM {1}..{2} WHERE sToken = @sToken", IDColumn, AccountDB, TokenTable);
				Command.Parameters.AddWithValue("@sToken", sToken);
				using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        nEMID = Convert.ToInt32(Reader[IDColumn]);

                        return true;
                    }
                }
            }

            nEMID = -1;

            return false;
        }

        public Byte GetnAuthIDFromnEMID(Int32 nEMID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nAuthID FROM {0}..{1} WHERE {2} = @nEMID", AccountDB, AccountTable, IDColumn);
				Command.Parameters.AddWithValue("@nEMID", nEMID);
				return Convert.ToByte(Command.ExecuteScalar());
            }
        }

        public Byte GetnTypeIDfromnAuthID(Byte nAuthID, out Boolean nLoginable)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nLoginable, nTypeID FROM {0}..tAuth WHERE nAuthID = @nAuthID", AccountDB);
				Command.Parameters.AddWithValue("@nAuthID", nAuthID);
				using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    nLoginable = Convert.ToBoolean(Reader["nLoginable"]);

                    return Convert.ToByte(Reader["nTypeID"]);
                }
            }
        }

        public String GetsUsernameFromnEMID(Int32 nEMID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 sUsername FROM {0}..{1} WHERE {2} = @nEMID", AccountDB, AccountTable, IDColumn);
				Command.Parameters.AddWithValue("@nEMID", nEMID);
				return Convert.ToString(Command.ExecuteScalar());
            }
        }

        public Byte GetnUsesFromsToken(String sToken)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nUses FROM {0}..{1} WHERE sToken = @sToken", AccountDB, TokenTable);
				Command.Parameters.AddWithValue("@sToken", sToken);
				return Convert.ToByte(Command.ExecuteScalar());
            }
        }

        public void SetnUsesForsToken(Byte nUses, String sToken)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..{1} SET nUses = @nUses WHERE sToken = @sToken", AccountDB, TokenTable);
				Command.Parameters.AddWithValue("@nUses", nUses);
				Command.Parameters.AddWithValue("@sToken", sToken);
				Command.ExecuteNonQuery();
            }
        }

        public void DeleteFromtTokensUsingsToken(String sToken)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..{1} WHERE sToken = @sToken", AccountDB, TokenTable);
				Command.Parameters.AddWithValue("@sToken", sToken);
				Command.ExecuteNonQuery();
            }
        }

        public String GetsIDFromnUserIDAndnSlotNo(Int32 nUserNo, Byte nSlotNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 sID FROM {0}..tCharacter WHERE nUserNo = @nUserNO AND nSlotNo = @nSlotNo AND bDeleted = '0'", CharacterDB);
				Command.Parameters.AddWithValue("@nUserNo", nUserNo);
				Command.Parameters.AddWithValue("@nSlotNo", nSlotNo);
				return Convert.ToString(Command.ExecuteScalar());
            }
        }

        public String GetsIDFromnCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 sID FROM {0}..tCharacter WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                return Convert.ToString(Command.ExecuteScalar());
            }
        }

        public void WipetLoggedInChars()
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tLoggedInChars", FilterDB);
                Command.ExecuteNonQuery();
                Command.Dispose();
            }
        }

        public void InserttLoggedInChar(String sID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tLoggedInChars (sID) VALUES (@sID)", FilterDB);
				Command.Parameters.AddWithValue("@sID", sID);
				Command.ExecuteNonQuery();
                Command.Dispose();
            }
        }

        public void DeleteFromtLoggedInChar(String sID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tLoggedInChars WHERE sID = @sID", FilterDB);
				Command.Parameters.AddWithValue("@sID", sID);
				Command.ExecuteNonQuery();
                Command.Dispose();
            }
        }

        public Int32 GetOnlineCount()
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tLoggedInChars", FilterDB);

                return Convert.ToInt32(Command.ExecuteScalar());
            }
        }

        public Boolean GettLoggedInChar(String sID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 sID FROM {0}..tLoggedInChars WHERE sID = @sID", FilterDB);
				Command.Parameters.AddWithValue("@sID", sID);
				using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    return Reader.HasRows;
                }
            }
        }

        public Int32 GetnUserNoFromsID(String sID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nUserNo FROM {0}..tCharacter WHERE sID = @sID", CharacterDB);
				Command.Parameters.AddWithValue("@sID", sID);
				return Convert.ToInt32(Command.ExecuteScalar());
            }
        }

        public Int32 GetnCharNoFromsID(String sID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nCharNo FROM {0}..tCharacter WHERE sID = @sID", CharacterDB);
				Command.Parameters.AddWithValue("@sID", sID);
				return Convert.ToInt32(Command.ExecuteScalar());
            }
        }

        public String GetsMapFromsID(String sID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 sMap FROM {0}..tGameLog WHERE nType = '15' AND nCharNo = '{1}' ORDER BY nLogNo DESC", GameLogDB, GetnCharNoFromsID(sID));

                return Convert.ToString(Command.ExecuteScalar());
            }
        }

        public Byte GetnLevelFromsID(String sID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nLevel FROM {0}..tCharacter WHERE sID = @sID", CharacterDB);
				Command.Parameters.AddWithValue("@sID", sID);
				return Convert.ToByte(Command.ExecuteScalar());
            }
        }

        public Boolean HasPermission(Int32 nCharNo, String Type)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 b{0} FROM {1}..tPermissions WHERE nCharNo = @nCharNo", Type, FilterDB);
				Command.Parameters.AddWithValue("@nCharNo", nCharNo);
				return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Boolean IsQuestComplete(Int32 nCharNo, Int32 nQuestNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nQuestNo FROM {0}..tQuest WHERE nCharNo = @nCharNo AND nQuestNo = @nQuestNo", CharacterDB);
				Command.Parameters.AddWithValue("@nCharNo", nCharNo);
				Command.Parameters.AddWithValue("@nQuestNo", nQuestNo);
				using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows) { return true; }
                }
            }

            return false;
        }

        public Int64 GetAmountForCC(String TableName, String Type, Int32 Value)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 Amount FROM {0}..{1} WHERE {2} = '{3}'", CustomCurrencyDB, TableName, Type, Value);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows) { return Convert.ToInt64(Reader["Amount"]); }
                }
            }

            return -1;
        }

        public void AddAmountForCC(String TableName, Int64 Amount, String Type, Int32 Value)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 Amount FROM {0}..{1} WHERE {2} = '{3}'", CustomCurrencyDB, TableName, Type, Value);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("UPDATE {0}..{1} SET Amount = (Amount + {2}) WHERE {3} = '{4}'", CustomCurrencyDB, TableName, Amount, Type, Value);
                        Command.ExecuteNonQuery();
                    }
                    else
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("INSERT INTO {0}..{1} ({2}, Amount) VALUES ('{3}', '{4}')", CustomCurrencyDB, TableName, Type, Value, Amount);
                        Command.ExecuteNonQuery();
                    }
                }
            }
        }

        public void MinusAmountForCC(String TableName, Int64 Amount, String Type, Int32 Value)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..{1} SET Amount = (Amount - {2}) WHERE {3} = '{4}'", CustomCurrencyDB, TableName, Amount, Type, Value);
                Command.ExecuteNonQuery();
            }
        }

        public Int16 GetObtainedForCC(String TableName, String Type, Int32 Value)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 Obtained FROM {0}..{1} WHERE {2} = '{3}'", CustomCurrencyDB, TableName, Type, Value);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows) { return Convert.ToInt16(Reader["Obtained"]); }
                }
            }

            return -1;
        }

        public void AddObtainedForCC(String TableName, Int16 Obtained, String Type, Int32 Value)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 Obtained FROM {0}..{1} WHERE {2} = '{3}'", CustomCurrencyDB, TableName, Type, Value);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("UPDATE {0}..{1} SET Obtained = (Obtained + {2}) WHERE {3} = '{4}'", CustomCurrencyDB, TableName, Obtained, Type, Value);
                        Command.ExecuteNonQuery();
                    }
                    else
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("INSERT INTO {0}..{1} ({2}, Amount, Obtained) VALUES ('{3}', 0, '{4}')", CustomCurrencyDB, TableName, Type, Value, Obtained);
                        Command.ExecuteNonQuery();
                    }
                }
            }
        }

        public Int64 GetnItemKeyFromnOwnerAndnStorage(Int32 nOwner, Int32 nStorage, Int32 nStorageType = 9)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nItemKey FROM {0}..tItem WHERE nStorageType = '{1}' AND nOwner = @nOwner AND nStorage = @nStorage", CharacterDB, nStorageType);
				Command.Parameters.AddWithValue("@nOwner", nOwner);
				Command.Parameters.AddWithValue("@nStorage", nStorage);
				using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows) { return Convert.ToInt64(Reader["nItemKey"]); }
                }
            }

            return -1;
        }

        public Int16 GetAmountForItem(Int64 nItemKey)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nOptionData FROM {0}..tItemOptions WHERE nItemKey = @nItemKey AND nOptionType = '1'", CharacterDB);
				Command.Parameters.AddWithValue("@nItemKey", nItemKey);
				using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows) { return Convert.ToInt16(Reader["nOptionData"]); }
                }
            }

            return 1;
        }

        public void SetAmountForItem(Int64 nItemKey, Byte nOptionData)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tItemOptions SET nOptionData = @nOptionData WHERE nItemKey = @nItemKey AND nOptionType = '1'", CharacterDB);
				Command.Parameters.AddWithValue("@nItemKey", nItemKey);
				Command.Parameters.AddWithValue("@nOptionData", nOptionData);
				Command.ExecuteNonQuery();
            }
        }

        public void MinusAmountForItem(Int64 nItemKey, Byte Amount)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tItemOptions SET nOptionData = (nOptionData - @Amount) WHERE nItemKey = @nItemKey AND nOptionType = '1'", CharacterDB);
				Command.Parameters.AddWithValue("@nItemKey", nItemKey);
				Command.Parameters.AddWithValue("@Amount", Amount);
				Command.ExecuteNonQuery();
            }
        }

        public void DeleteItem(Int64 nItemKey)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tItem WHERE nItemKey = @nItemKey", CharacterDB);
				Command.Parameters.AddWithValue("@nItemKey", nItemKey);
				Command.ExecuteNonQuery();

                Command.CommandText = String.Format("DELETE FROM {0}..tItemOptions WHERE nItemKey = @nItemKey", CharacterDB);
                Command.ExecuteNonQuery();
            }
        }

        public Int32 GetnLuckyNo(Int32 nCharNo, out DateTime dDate)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nLuckyNo, dDate FROM {0}..tLuckyNos WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        dDate = Convert.ToDateTime(Reader["dDate"]);

                        return Convert.ToInt32(Reader["nLuckyNo"]);
                    }
                    else
                    {
                        dDate = DateTime.Now.AddDays(2);

                        return 0;
                    }
                }
            }
        }

        public List<Int32> GetnCharNosFromnLuckyNo(Int32 nLuckyNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            List<Int32> nCharNos = new List<Int32>();

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nCharNo FROM {0}..tLuckyNos", FilterDB);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        if (!GetbDeletedFromnCharNo(Convert.ToInt32(Reader["nCharNo"])) && GetdLastLoginDateFromnCharNo(Convert.ToInt32(Reader["nCharNo"])) > DateTime.Now.AddDays(-2)) { nCharNos.Add(Convert.ToInt32(Reader["nCharNo"])); }
                    }
                }
            }

            return nCharNos;
        }

        public Boolean GetbDeletedFromnCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 bDeleted FROM {0}..tCharacter WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public DateTime GetdLastLoginDateFromnCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 dLastLoginDate FROM {0}..tCharacter WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                return Convert.ToDateTime(Command.ExecuteScalar());
            }
        }

        public void SetnLuckyNo(Int32 nCharNo, Int32 nLuckyNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nLuckyNo, dDate FROM {0}..tLuckyNos WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("UPDATE {0}..tLuckyNos SET nLuckyNo = '{1}', dDate = '{2}' WHERE nCharNo = '{3}'", FilterDB, nLuckyNo, DateTime.Now, nCharNo);
                        Command.ExecuteNonQuery();
                    }
                    else
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("INSERT INTO {0}..tLuckyNos (nCharNo, nLuckyNo) VALUES ('{1}', '{2}')", FilterDB, nCharNo, nLuckyNo);
                        Command.ExecuteNonQuery();
                    }
                }
            }
        }

        public Int32 GetnNoFromnCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nNo FROM {0}..tGuildAcademyMember WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                return Convert.ToInt32(Command.ExecuteScalar());
            }
        }

        public Int64 GetnMoneyFromnNo(Int32 nNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nMoney FROM {0}..tGuildAcademy WHERE nNo = '{1}'", CharacterDB, nNo);

                return Convert.ToInt64(Command.ExecuteScalar());
            }
        }

        public void WipeStorage(Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tUserMoney WHERE nUserNo = '{1}'", CharacterDB, nUserNo);
                Command.ExecuteNonQuery();
            }
        }

        public void WipeCharacterMoney(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET nMoney = '0' WHERE nCharNo = '{1}'", CharacterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void SetCharacterDeleted(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET bDeleted = '1' WHERE nCharNo = '{1}'", CharacterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void SetnAuthIDFornEMID(Int32 nEMID, Byte nAuthID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..{1} SET nAuthID = '{2}' WHERE {3} = '{4}'", AccountDB, AccountTable, nAuthID, IDColumn, nEMID);
                Command.ExecuteNonQuery();
            }
        }

        public Byte GetnClassFromnCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nClass FROM {0}..tCharacterShape WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                return Convert.ToByte(Command.ExecuteScalar());
            }
        }

        public Boolean HasItemInSlot(Int32 nOwner, Int32 nStorage, Int32 nStorageType = 9)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nItemKey FROM {0}..tItem WHERE nStorageType = '{1}' AND nOwner = '{2}' AND nStorage = '{3}'", CharacterDB, nStorageType, nOwner, nStorage);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    return Reader.HasRows;
                }
            }
        }

        public Boolean HasSkill(Int32 nCharNo, Int32 nSkillNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nSkillNo FROM {0}..tSkill WHERE nCharNo = '{1}' AND nSkillNo = '{2}'", CharacterDB, nCharNo, nSkillNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    return Reader.HasRows;
                }
            }
        }

        public void DeleteSkill(Int32 nCharNo, Int32 nSkillNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tSkill WHERE nCharNo = '{1}' AND nSkillNo = '{2}'", CharacterDB, nCharNo, nSkillNo);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean HasPassive(Int32 nCharNo, Int32 nSkillNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                nSkillNo = nSkillNo + 30000;

                Command.CommandText = String.Format("SELECT TOP 1 nSkillNo FROM {0}..tSkill WHERE nCharNo = '{1}' AND nSkillNo = '{2}'", CharacterDB, nCharNo, nSkillNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    return Reader.HasRows;
                }
            }
        }

        public List<UInt16> GetnSkillNosFornCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nSkillNo FROM {0}..tSkill WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                List<UInt16> nSkillNos = new List<UInt16>();

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { nSkillNos.Add(Convert.ToUInt16(Reader["nSkillNo"])); }
                }

                return nSkillNos;
            }
        }

        public Dictionary<Int32, List<UInt16>> GetnSkillNos()
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nCharNo, nSkillNo FROM {0}..tSkill", CharacterDB);

                Dictionary<Int32, List<UInt16>> nSkillNos = new Dictionary<Int32, List<UInt16>>();

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        if (!nSkillNos.ContainsKey(Convert.ToInt32(Reader["nCharNo"]))) { nSkillNos.Add(Convert.ToInt32(Reader["nCharNo"]), new List<UInt16>()); }

                        nSkillNos[Convert.ToInt32(Reader["nCharNo"])].Add(Convert.ToUInt16(Reader["nSkillNo"]));
                    }
                }

                return nSkillNos;
            }
        }

        public void SetnMoneyFortTaxLottery(Int64 nMoney)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tTaxLottery SET nMoney = (nMoney + {1})", FilterDB, nMoney);
                Command.ExecuteNonQuery();
            }
        }

        public Int64 GettTaxLottery()
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nMoney FROM {0}..tTaxLottery", FilterDB);

                return Convert.ToInt64(Command.ExecuteScalar());
            }
        }

        public void WipetTaxLottery()
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tTaxLottery SET nMoney = '0'", FilterDB);
                Command.ExecuteNonQuery();
            }
        }

        public void InsertJoinMessage(Int32 nCharNo, String sMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tJoinMessages (nCharNo, sMessage) VALUES ('{1}', '{2}')", FilterDB, nCharNo, sMessage);
                Command.ExecuteNonQuery();
            }
        }

        public List<String> GetJoinMessages(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            List<String> Messages = new List<String>();

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT sMessage FROM {0}..tJoinMessages WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { Messages.Add(Convert.ToString(Reader["sMessage"])); }
                }
            }

            return Messages;
        }

        public void DeleteJoinMessages(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tJoinMessages WHERE nCharNo = '{1}'", FilterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void PutMoneyInStorage(String sID, Int64 nMoney)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nUserNo FROM {0}..tCharacter WHERE sID = '{1}'", CharacterDB, sID);

                Int32 nUserNo = Convert.ToInt32(Command.ExecuteScalar());

                Command.CommandText = String.Format("SELECT TOP 1 nUserMoney FROM {0}..tUserMoney WHERE nUserNo = '{1}'", CharacterDB, nUserNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (!Reader.HasRows)
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("INSERT INTO {0}..tUserMoney (nUserNo, nUserMoney) VALUES ('{1}', '{2}')", CharacterDB, nUserNo, nMoney);
                        Command.ExecuteNonQuery();
                    }
                    else
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("UPDATE {0}..tUserMoney SET nUserMoney = (nUserMoney + {1}) WHERE nUserNo = '{2}'", CharacterDB, nMoney, nUserNo);
                        Command.ExecuteNonQuery();
                    }
                }
            }
        }

        public void PutMoneyInStorage(Int32 nUserNo, Int64 nMoney)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nUserMoney FROM {0}..tUserMoney WHERE nUserNo = '{1}'", CharacterDB, nUserNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (!Reader.HasRows)
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("INSERT INTO {0}..tUserMoney (nUserNo, nUserMoney) VALUES ('{1}', '{2}')", CharacterDB, nUserNo, nMoney);
                        Command.ExecuteNonQuery();
                    }
                    else
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("UPDATE {0}..tUserMoney SET nUserMoney = (nUserMoney + {1}) WHERE nUserNo = '{2}'", CharacterDB, nMoney, nUserNo);
                        Command.ExecuteNonQuery();
                    }
                }
            }
        }

        public Dictionary<Byte, UInt16> GetItemsFromnStorageType(Int32 nOwner, Byte nStorageType)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            Dictionary<Byte, UInt16> Items = new Dictionary<Byte, UInt16>();

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nStorage, nItemID FROM {0}..tItem WHERE nOwner = '{1}' AND nStorageType = '{2}'", CharacterDB, nOwner, nStorageType);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        if (!Items.ContainsKey(Convert.ToByte(Reader["nStorage"]))) { Items.Add(Convert.ToByte(Reader["nStorage"]), Convert.ToUInt16(Reader["nItemID"])); }
                    }
                }
            }

            return Items;
        }

        public UInt16 GetnItemIDFromnOwnerAndnStorage(Int32 nOwner, Byte nStorage, Byte nStorageType = 9)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            Dictionary<Byte, UInt16> Items = new Dictionary<Byte, UInt16>();

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nStorage, nItemID FROM {0}..tItem WHERE nOwner = '{1}' AND nStorage = '{2}' AND nStorageType = '{3}'", CharacterDB, nOwner, nStorage, nStorageType);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows) { return Convert.ToUInt16(Reader["nItemID"]); }
                    else { return UInt16.MaxValue; }
                }
            }
        }

        public Int32 GetnAmountFromsName(String sName)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nAmount FROM {0}..tServerRates WHERE sName = '{1}'", FilterDB, sName);

                return Convert.ToInt32(Command.ExecuteScalar());
            }
        }

        public List<String> GetOnlinesIDs()
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            List<String> sIDs = new List<String>();

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT sID FROM {0}..tLoggedInChars", FilterDB);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        if (!sIDs.Contains(Convert.ToString(Reader["sID"]))) { sIDs.Add(Convert.ToString(Reader["sID"])); }
                    }
                }
            }

            return sIDs;
        }

        public List<String> GetJoinCommands(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            List<String> Commands = new List<String>();

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT sCommand FROM {0}..tJoinCommands WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { Commands.Add(Convert.ToString(Reader["sCommand"])); }
                }
            }

            return Commands;
        }

        public void DeleteJoinCommands(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tJoinCommands WHERE nCharNo = '{1}'", FilterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean PermissionRowExists(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tPermissions WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                if (Convert.ToByte(Command.ExecuteScalar()) != 0) { return true; }
                else { return false; }
            }
        }

        public void InserttPermission(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tPermissions (nCharNo) VALUES ('{1}')", FilterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean sIDTaken(String sID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tCharacter WHERE sID = '{1}'", CharacterDB, sID);

                if (Convert.ToInt32(Command.ExecuteScalar()) != 0) { return true; }
                else { return false; }
            }
        }

        public void InserttHolyPromise(Int32 nCharNo, Int32 nUpCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tHolyPromise WHERE nCharNo = '{1}'", CharacterDB, nCharNo);
                Command.ExecuteNonQuery();

                Command.CommandText = String.Format("INSERT INTO {0}..tHolyPromise (nCharNo, nUpCharNo, nFlags) VALUES ('{1}', '{2}', 0)", CharacterDB, nCharNo, nUpCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void InserttFriend(Int32 nCharNo, Int32 nFriendCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tFriend (nCharNo, nFriendCharNo, nFlags) VALUES ('{1}', '{2}', 0)", CharacterDB, nCharNo, nFriendCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void AddnFameFornCharNo(Int32 nCharNo, Int32 nFame)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET nFame = (nFame + {1}) WHERE nCharNo = '{2}'", CharacterDB, nFame, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void AddnMoneyFornCharNo(Int32 nCharNo, Int64 nMoney)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET nMoney = (nMoney + {1}) WHERE nCharNo = '{2}'", CharacterDB, nMoney, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void SetnLevelFornCharNo(Int32 nCharNo, Byte nLevel)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET nLevel = {1} WHERE nCharNo = '{2}'", CharacterDB, nLevel, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void AddnExpFornCharNo(Int32 nCharNo, Int64 nEXP)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET nExp = (nExp + {1}) WHERE nCharNo = '{2}'", CharacterDB, nEXP, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void SetnAdminLevelFornCharNo(Int32 nCharNo, Byte nAdminLevel)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET nAdminLevel = {1} WHERE nCharNo = '{2}'", CharacterDB, nAdminLevel, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void CleartItem(Int32 nOwner, Int32 nStorageType)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nItemKey FROM {0}..tItem WHERE nStorageType = '{1}' AND nOwner = '{2}'", CharacterDB, nStorageType, nOwner);

                List<Int64> nItemKeys = new List<Int64>();

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { nItemKeys.Add(Convert.ToInt64(Reader["nItemKey"])); }

                    Reader.Close();
                }

                foreach (Int64 nItemKey in nItemKeys)
                {
                    Command.CommandText = String.Format("DELETE FROM {0}..tItem WHERE nItemKey = '{1}'", CharacterDB, nItemKey);
                    Command.ExecuteNonQuery();

                    Command.CommandText = String.Format("DELETE FROM {0}..tItemMobList WHERE nItemKey = '{1}'", CharacterDB, nItemKey);
                    Command.ExecuteNonQuery();

                    Command.CommandText = String.Format("DELETE FROM {0}..tItemOptions WHERE nItemKey = '{1}'", CharacterDB, nItemKey);
                    Command.ExecuteNonQuery();

                    Command.CommandText = String.Format("DELETE FROM {0}..tItemTitle WHERE nItemKey = '{1}'", CharacterDB, nItemKey);
                    Command.ExecuteNonQuery();
                }
            }
        }

        public Boolean nEMIDExists(Int32 nEMID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..{1} WHERE {2} = '{3}'", AccountDB, AccountTable, IDColumn, nEMID);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Boolean nIDExists(Int64 nID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tSRPayments WHERE nID = '{1}'", FilterDB, nID);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public void InserttSRPayment(Int64 nID, Int64 nNew, Int64 nTotal, Int64 nOID, String sSig, Int64 nUID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tSRPayments (nID, nNew, nTotal, nOID, sSig, nUID) VALUES ('{1}', '{2}', '{3}', '{4}', '{5}', '{6}')", FilterDB, nID, nNew, nTotal, nOID, sSig, nUID);
                Command.ExecuteNonQuery();
            }
        }

        public List<String> GetsIDsFornUserNo(Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            List<String> sIDs = new List<String>();

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT sID FROM {0}..tCharacter WHERE nUserNo = '{1}' AND bDeleted = '0'", CharacterDB, nUserNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { sIDs.Add(Convert.ToString(Reader["sID"])); }
                }
            }

            return sIDs;
        }

        public void InserttFilterBan(Int32 nUserNo, String sReason)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tFilterBans (nUserNo, sReason) VALUES ('{1}', '{2}')", FilterDB, nUserNo, sReason);
                Command.ExecuteNonQuery();
            }
        }

		public void SetbInMaintenanceFornServerID(Byte nServerID, Boolean bInMaintenance)
		{
			if (Connection.State != ConnectionState.Open) { Connection.Open(); }
			
			using (SqlCommand Command = Connection.CreateCommand())
			{
				Command.CommandTimeout = 0;
				Command.CommandText = $"SELECT COUNT(*) bInMaintenance FROM {FilterDB}..tMaintenance WHERE nServerID = '{nServerID}'";
				int count = (int)Command.ExecuteScalar();

				if(count > 0)
				{
					Command.CommandText = $"UPDATE {FilterDB}..tMaintenance SET bInMaintenance = '{bInMaintenance}' WHERE nServerID = '{nServerID}'";
				}
				else
				{
					Command.CommandText = $"INSERT INTO {FilterDB}..tMaintenance (nServerID, bInMaintenance) VALUES ({nServerID}, '{bInMaintenance}')";
				}
				Command.ExecuteNonQuery();
			}
		}

        public Boolean GetbInMaintenanceFornServerID(Byte nServerID)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = $"SELECT TOP 1 bInMaintenance FROM {FilterDB}..tMaintenance WHERE nServerID = '{nServerID}'";

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public String GetsRecoveryKeyFornUserNo(Int32 nUserNo, out Boolean ShowMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 sRecoveryKey FROM {0}..tAccountRecovery WHERE nUserNo = '{1}'", FilterDB, nUserNo);

                String sRecoveryKey = Convert.ToString(Command.ExecuteScalar());

                if (sRecoveryKey == String.Empty)
                {
                    sRecoveryKey = Convert.ToString(Guid.NewGuid());

                    Command.CommandText = String.Format("INSERT INTO {0}..tAccountRecovery (nUserNo, sRecoveryKey) VALUES ('{1}', '{2}')", FilterDB, nUserNo, sRecoveryKey);
                    Command.ExecuteNonQuery();

                    ShowMessage = true;
                }
                else { ShowMessage = false; }

                return sRecoveryKey;
            }
        }

        public void GetnMinimumAndnMaximum(out Int32 nMinimum, out Int32 nMaximum)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nMinimum, nMaximum FROM {0}..tCen", FilterDB);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    nMinimum = Convert.ToInt32(Reader["nMinimum"]);
                    nMaximum = Convert.ToInt32(Reader["nMaximum"]);
                }
            }
        }

        public void InserttWhisper(String sID, String sIDReceive, String sMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..cl_Whisper_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@sID", sID));
                Command.Parameters.Add(new SqlParameter("@sIDReceive", sIDReceive));
                Command.Parameters.Add(new SqlParameter("@sMessage", sMessage));
                Command.ExecuteNonQuery();

                //Command.CommandText = String.Format("INSERT INTO {0}..tWhisper (sID, sIDReceive, sMessage) VALUES ('{1}', '{2}', '{3}')", FilterDB, sID, sIDReceive, sMessage);
                //Command.ExecuteNonQuery();
            }
        }

        public void InserttParty(String sID, String sMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..cl_Party_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@sID", sID));
                Command.Parameters.Add(new SqlParameter("@sMessage", sMessage));
                Command.ExecuteNonQuery();

                //Command.CommandText = String.Format("INSERT INTO {0}..tParty (sID, sMessage) VALUES ('{1}', '{2}')", FilterDB, sID, sMessage);
                //Command.ExecuteNonQuery();
            }
        }

        public void InserttGuild(String sID, String sMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..cl_Guild_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@sID", sID));
                Command.Parameters.Add(new SqlParameter("@sMessage", sMessage));
                Command.ExecuteNonQuery();

                //Command.CommandText = String.Format("INSERT INTO {0}..tGuild (sID, sMessage) VALUES ('{1}', '{2}')", FilterDB, sID, sMessage);
                //Command.ExecuteNonQuery();
            }
        }

        public void InserttAcademy(String sID, String sMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..cl_Academy_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@sID", sID));
                Command.Parameters.Add(new SqlParameter("@sMessage", sMessage));
                Command.ExecuteNonQuery();

                //Command.CommandText = String.Format("INSERT INTO {0}..tAcademy (sID, sMessage) VALUES ('{1}', '{2}')", FilterDB, sID, sMessage);
                //Command.ExecuteNonQuery();
            }
        }

        public void InserttNormal(String nZoneID, String sID, String sMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..cl_Normal_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@nZoneID", nZoneID));
                Command.Parameters.Add(new SqlParameter("@sID", sID));
                Command.Parameters.Add(new SqlParameter("@sMessage", sMessage));
                Command.ExecuteNonQuery();

                //Command.CommandText = String.Format("INSERT INTO {0}..tNormal (nZoneID, sID, sMessage) VALUES ('{1}', '{2}', '{3}')", FilterDB, nZoneID, sID, sMessage);
                //Command.ExecuteNonQuery();
            }
        }

        public void InserttRoar(String nZoneID, String sID, String sMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..cl_Roar_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@nZoneID", nZoneID));
                Command.Parameters.Add(new SqlParameter("@sID", sID));
                Command.Parameters.Add(new SqlParameter("@sMessage", sMessage));
                Command.ExecuteNonQuery();

                //Command.CommandText = String.Format("INSERT INTO {0}..tRoar (nZoneID, sID, sMessage) VALUES ('{1}', '{2}', '{3}')", FilterDB, nZoneID, sID, sMessage);
                //Command.ExecuteNonQuery();
            }
        }

        public void InserttShout(String nZoneID, String sID, String sMessage)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..cl_Shout_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@nZoneID", nZoneID));
                Command.Parameters.Add(new SqlParameter("@sID", sID));
                Command.Parameters.Add(new SqlParameter("@sMessage", sMessage));
                Command.ExecuteNonQuery();

                //Command.CommandText = String.Format("INSERT INTO {0}..tShout (nZoneID, sID, sMessage) VALUES ('{1}', '{2}', '{3}')", FilterDB, nZoneID, sID, sMessage);
                //Command.ExecuteNonQuery();
            }
        }

        public void InserttCommand(String nZoneID, String sID, String sCommand, String sParamaters)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..cl_Command_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@nZoneID", nZoneID));
                Command.Parameters.Add(new SqlParameter("@sID", sID));
                Command.Parameters.Add(new SqlParameter("@sCommand", sCommand));
                Command.Parameters.Add(new SqlParameter("@sParameters", sParamaters));
                Command.ExecuteNonQuery();
            }
        }

        public String GetValue(String Database, String Table, String Column, Boolean Order = true)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 {0} FROM {1}..{2}", Column, Database, Table);

                if (Order) { Command.CommandText += String.Format(" ORDER BY {0} DESC", Column); }

                return Convert.ToString(Command.ExecuteScalar());
            }
        }

        public Boolean GettMapRate(String sMapIndex, out Int32 nItemRate, out Int32 nExpRate)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nItemRate, nExpRate FROM {0}..tMapRates WHERE sMapIndex = '{1}'", FilterDB, sMapIndex);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        nItemRate = Convert.ToInt32(Reader["nItemRate"]);
                        nExpRate = Convert.ToInt32(Reader["nExpRate"]);
                    }
                    else
                    {
                        nItemRate = -1;
                        nExpRate = -1;
                    }

                    return Reader.HasRows;
                }
            }
        }

        public void InserttSkill(Int32 nCharNo, UInt16 nSkillNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tSkill (nCharNo, nSkillNo, nSkilllevel, nSkillExp, nSkillWriteTime, nSkillCoolTime, nSkillPowerDamage, nSkillPowerSP, nSkillPowerKeepTime, nSkillPowerCoolTime) VALUES ('{0}', '{1}', 1, 0, 0, 0, 0, 0, 0, 0)", nCharNo, nSkillNo);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean ShowCenMessage()
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 bShowMessage FROM {0}..tCen", FilterDB);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Boolean InGuild(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tGuildMember WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Byte GetnGradeFromnCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nGrade FROM {0}..tGuildMember WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                return Convert.ToByte(Command.ExecuteScalar());
            }
        }

        public void RemoveFromtGuildMember(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tGuildMember WHERE nCharNo = '{1}'", CharacterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean ChecksPassword(Int32 nUserNo, String sPassword) // TODO: redo this for BCrypt
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tPasswordChange WHERE nUserNo = '{1}' AND sPassword = '{2}'", FilterDB, nUserNo, sPassword);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public void InsertIntotPasswordChange(Int32 nUserNo, String sPassword)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tPasswordChange (nUserNo, sPassword) VALUES ('{1}', '{2}')", FilterDB, nUserNo, sPassword);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean DeleteMarriage(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tMarriage WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                Int32 RowsAffected = Command.ExecuteNonQuery();

                if (RowsAffected == 0) { return false; }

                Command.CommandText = String.Format("DELETE FROM {0}..tMarriage WHERE nPartnerCharNo = '{1}'", CharacterDB, nCharNo);
                Command.ExecuteNonQuery();

                return true;
            }
        }

        public Boolean CanCommandForsMap(String sMap)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tAntiCommand WHERE sMap LIKE '%{0}%'", FilterDB, sMap);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Boolean CanSeenCharNo(Int32 nUserNo, Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tChatBlock WHERE nUserNo = '{1}' AND nCharNo = '{2}'", CharacterDB, nUserNo, nCharNo);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public List<String> LoadRebirthablesIDs(Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                List<String> sIDs = new List<String>();

                Command.CommandText = String.Format("SELECT sID FROM {0}..tCharacter WHERE nUserNo = '{1}' AND bDeleted = '0' AND nLevel = '{2}'", CharacterDB, nUserNo, Auth.ConfigValues["RebirthLevel"]);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { sIDs.Add(Convert.ToString(Reader["sID"])); }
                }

                return sIDs;
            }
        }

        public Boolean nCharNoReachedMaxRebirth(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tRebirth WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                if (Convert.ToByte(Command.ExecuteScalar()) == Convert.ToByte(Auth.ConfigValues["RebirthMaximum"])) { return true; }

                return false;
            }
        }

        public Boolean sIDOwnedBynUserNo(String sID, Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tCharacter WHERE sID = '{1}' AND nUserNo = '{2}' AND bDeleted = '0'", CharacterDB, sID, nUserNo);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public void DecreasenMoneyFornCharNo(Int32 nCharNo, Int64 nMoney)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET nMoney = (nMoney - {1}) WHERE nCharNo = '{2}'", CharacterDB, nMoney, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void InserttRebirth(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tRebirth (nCharNo) VALUES ('{1}')", FilterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public Int64 GetnMoneyFornCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nMoney FROM {0}..tCharacter WHERE nCharNo = '{1}'", CharacterDB, nCharNo);

                return Convert.ToInt64(Command.ExecuteScalar());
            }
        }

        public void SetnExpFornCharNo(Int32 nCharNo, Int64 nExp)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tCharacter SET nExp = '{1}' WHERE nCharNo = '{2}'", CharacterDB, nExp, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean GettSendLocal(Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tSendLocal WHERE nUserNo = '{1}'", FilterDB, nUserNo);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public void DeletenStorageTypeFornCharNo(Int32 nCharNo, Byte nStorageType = 9)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tItem WHERE nOwner = '{1}' AND nStorageType = '{2}'", CharacterDB, nCharNo, nStorageType);
                Command.ExecuteNonQuery();
            }
        }

        public void InserttCookieClicker(Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tCookieClicker WHERE nUserNo = '{1}'", FilterDB, nUserNo);

                if (Convert.ToBoolean(Command.ExecuteScalar()))
                {
                    Command.CommandText = String.Format("UPDATE {0}..tCookieClicker SET nTotalClicks = (nTotalClicks + 1) WHERE nUserNo = '{1}'", FilterDB, nUserNo);
                    Command.ExecuteScalar();
                }
                else
                {
                    Command.CommandText = String.Format("INSERT INTO {0}..tCookieClicker (nUserNo, nTotalClicks) VALUES ('{1}', 1)", FilterDB, nUserNo);
                    Command.ExecuteScalar();
                }
            }
        }

        public String GetnTotalClicksFornUserNo(Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nTotalClicks FROM {0}..tCookieClicker WHERE nUserNo = '{1}'", FilterDB, nUserNo);

                return Convert.ToString(Command.ExecuteScalar());
            }
        }

        public void GiveAlltPermissions(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COLUMN_NAME FROM {0}.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'tPermissions'", FilterDB);

                List<String> ColumnNames = new List<String>();

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { ColumnNames.Add(Convert.ToString(Reader["COLUMN_NAME"])); }
                }

                ColumnNames.Remove("nCharNo");

                foreach (String ColumnName in ColumnNames)
                {
                    Command.CommandText = String.Format("UPDATE {0}..tPermissions SET {1} = '1' WHERE nCharNo = '{2}'", FilterDB, ColumnName, nCharNo);
                    Command.ExecuteNonQuery();
                }
            }
        }

        public Boolean HastUnlimitedRoars(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tUnlimitedRoars WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public void InserttUnlimitedRoars(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tUnlimitedRoars (nCharNo) VALUES ('{1}')", FilterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void InserttLoginQuery(Int32 nUserNo, String sQuery)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("{0}..l_Query_Insert", FilterDB);
                Command.CommandType = CommandType.StoredProcedure;
                Command.Parameters.Add(new SqlParameter("@nUserNo", nUserNo));
                Command.Parameters.Add(new SqlParameter("@sQuery", sQuery));
                Command.ExecuteNonQuery();
            }
        }

        public List<String> GetLoginQueries(Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            List<String> Queries = new List<String>();

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT sQuery FROM {0}..tLoginQueries WHERE nUserNo = '{1}'", FilterDB, nUserNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { Queries.Add(Convert.ToString(Reader["sQuery"])); }
                }
            }

            return Queries;
        }

        public void DeletetLoginQueries(Int32 nUserNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tLoginQueries WHERE nUserNo = '{1}'", FilterDB, nUserNo);
                Command.ExecuteNonQuery();
            }
        }

        public void ExecutesQuery(String sQuery)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = sQuery;
                Command.ExecuteNonQuery();
            }
        }

        public Boolean tDupeDetectRowExists(Int32 nCharNo, String sType)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tDupeDetection WHERE nCharNo = '{1}' AND sType = '{2}'", FilterDB, nCharNo, sType);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public void InserttDupeDetection(Int32 nCharNo, String sType)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tDupeDetection (nCharNo, sType) VALUES ('{1}', '{2}')", FilterDB, nCharNo, sType);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean GettForcePasswordReset(out String sMessage, out DateTime dResetDate)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 * FROM {0}..tForcePasswordReset ORDER BY dResetDate DESC", FilterDB);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        sMessage = Convert.ToString(Reader["sMessage"]);
                        dResetDate = Convert.ToDateTime(Reader["dResetDate"]);

                        return true;
                    }
                    else
                    {
                        sMessage = String.Empty;
                        dResetDate = DateTime.MaxValue;

                        return false;
                    }
                }
            }
        }

        public DateTime GetLasttPasswordChange(Int32 nUserNo)
        {
            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 dChangeDate FROM {0}..tPasswordChange WHERE nUserNo = '{1}' ORDER BY dChangeDate DESC", FilterDB, nUserNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows) { return Convert.ToDateTime(Reader["dChangeDate"]); }
                    else { return DateTime.MinValue; }
                }
            }
        }

        public List<UInt16> GettSkilllearnerFornCharNo(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nSkillNo FROM {0}..tSkillLearner WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                List<UInt16> nSkillNos = new List<UInt16>();

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { nSkillNos.Add(Convert.ToUInt16(Reader["nSkillNo"])); }
                }

                return nSkillNos;
            }
        }

        public void DeletetSkillLearner(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tSkilLLearner WHERE nCharNo = '{1}'", FilterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean GettAntiDNForsMap(String sMap)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tAntiCommand WHERE sMap LIKE '%{0}%'", FilterDB, sMap);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public void InserttPSC(Int32 nUserNo, String sKey, Double nAmount)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tPSC (nUserNo, sKey, nAmount) VALUES ('{1}', '{2}', '{3}')", FilterDB, nUserNo, sKey, nAmount);
                Command.ExecuteNonQuery();
            }
        }

        public Boolean tPSCRowExists(Int32 nUserNo, String sKey)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tPSC WHERE nUserNo = '{1}' AND sKey = '{2}'", FilterDB, nUserNo, sKey);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Boolean CanRerollItemStats(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nAmount FROM {0}..tStatReroll WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (!Reader.HasRows) { return false; }
                    else
                    {
                        Int64 Rerolls = Convert.ToInt64(Reader["nAmount"]);

                        if (Rerolls >= 1) { return true; }
                        else { return false; }
                    }
                }
            }
        }

        public void MinustStatReroll(Int32 nCharNo, UInt64 nAmount)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("UPDATE {0}..tStatReroll SET nAmount = (nAmount - {1}) WHERE nCharNo = '{2}'", FilterDB, nAmount, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public Byte GetnOptionDataFornOptionType(Int32 nOwner, Int32 nStorage, Int32 nOptionType, Int32 nStorageType = 9)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Int64 nItemKey = GetnItemKeyFromnOwnerAndnStorage(nOwner, nStorage, nStorageType);

                Command.CommandText = String.Format("SELECT TOP 1 nOptionData FROM {0}..tItem WHERE nItemKey = '{1}' AND nOptionType = '{2}''", FilterDB, nItemKey, nOptionType);

                return Convert.ToByte(Command.ExecuteScalar());
            }
        }

        public void AddtStatRerollFornCharNo(Int32 nCharNo, Int64 nAmount)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nAmount FROM {0}..tStatReroll WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("UPDATE {0}..tStatReroll SET nAmount = (nAmount + {1}) WHERE nCharNo = '{2}'", FilterDB, nAmount, nCharNo);
                        Command.ExecuteNonQuery();
                    }
                    else
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("INSERT INTO {0}..tStatReroll (nCharNo, nAmount) VALUES ('{1}', '{2}')", FilterDB, nCharNo, nAmount);
                        Command.ExecuteNonQuery();
                    }
                }
            }
        }

        public void AddnAmountForsIP(String sIP)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nAmount FROM {0}..tIPBlock WHERE sIP = '{1}'", FilterDB, sIP);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("UPDATE {0}..tIPBlock SET nAmount = (nAmount + 1) WHERE sIP = '{1}'", FilterDB, sIP);
                        Command.ExecuteNonQuery();
                    }
                    else
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("INSERT INTO {0}..tIPBlock (sIP, nAmount) VALUES ('{1}', '1')", FilterDB, sIP);
                        Command.ExecuteNonQuery();
                    }
                }
            }
        }

        public Boolean GetbBlockForsIP(String sIP)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 bBlock FROM {0}..tIPBlock WHERE sIP = '{1}'", FilterDB, sIP);

                return Convert.ToBoolean(Command.ExecuteScalar());
            }
        }

        public Dictionary<Int32, Dictionary<Byte, UInt16>> GetnItemIDsFornStorageType(Byte nStorageType = 9)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nOwner, nStorage, nItemID FROM {0}..tItem WHERE nStorageType = '{1}'", CharacterDB, nStorageType);

                Dictionary<Int32, Dictionary<Byte, UInt16>> nOwnernItemIDs = new Dictionary<Int32, Dictionary<Byte, UInt16>>();

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        if (!nOwnernItemIDs.ContainsKey(Convert.ToInt32(Reader["nOwner"]))) { nOwnernItemIDs.Add(Convert.ToInt32(Reader["nOwner"]), new Dictionary<Byte, UInt16>()); }

                        if (!nOwnernItemIDs[Convert.ToInt32(Reader["nOwner"])].ContainsKey(Convert.ToByte(Reader["nStorage"]))) { nOwnernItemIDs[Convert.ToInt32(Reader["nOwner"])].Add(Convert.ToByte(Reader["nStorage"]), Convert.ToUInt16(Reader["nItemID"])); }
                    }
                }

                return nOwnernItemIDs;
            }
        }

        public void InserttUserIP(Int32 nUserNo, String sIP)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tUserIPs (nUserNo, sIP) VALUES ('{1}', '{2}')", FilterDB, nUserNo, sIP);
                Command.ExecuteNonQuery();
            }
        }

        public void InserttParties(Int32 nCharNo, String sMastersID, List<String> sMembersIDs)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("INSERT INTO {0}..tParties (nCharNo, sMastersID, sMember1sID, sMember2sID, sMember3sID, sMember4sID) VALUES ('{1}', '{2}', '{3}', '{4}', '{5}', '{6}')", FilterDB, nCharNo, sMastersID, sMembersIDs.Count >= 1 ? sMembersIDs[0] : "-", sMembersIDs.Count >= 2 ? sMembersIDs[1] : "-", sMembersIDs.Count >= 3 ? sMembersIDs[2] : "-", sMembersIDs.Count >= 4 ? sMembersIDs[3] : "-");
                Command.ExecuteNonQuery();
            }
        }

        public void DeletetParties(Int32 nCharNo)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tParties WHERE nCharNo = '{1}'", FilterDB, nCharNo);
                Command.ExecuteNonQuery();
            }
        }

        public void WipetParties()
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("DELETE FROM {0}..tParties", FilterDB);
                Command.ExecuteNonQuery();
            }
        }

        public List<Int32> GettPartiesnCharNos()
        {
            List<Int32> nCharNos = new List<Int32>();

            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT nCharNo FROM {0}..tParties", FilterDB);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    while (Reader.Read()) { nCharNos.Add(Convert.ToInt32(Reader["nCharNo"])); }
                }
            }

            return nCharNos;
        }

        public Boolean GettPartiesFornCharNo(Int32 nCharNo, out String sMastersID, out List<String> sMastersIDs)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 sMastersID, sMember1sID, sMember2sID, sMember3sID, sMember4sID FROM {0}..tParties WHERE nCharNo = '{1}'", FilterDB, nCharNo);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        sMastersID = Convert.ToString(Reader["sMastersID"]);

                        sMastersIDs = new List<String>();

                        if (Convert.ToString(Reader["sMember1sID"]) != "-") { sMastersIDs.Add(Convert.ToString(Reader["sMember1sID"])); }

                        if (Convert.ToString(Reader["sMember2sID"]) != "-") { sMastersIDs.Add(Convert.ToString(Reader["sMember2sID"])); }

                        if (Convert.ToString(Reader["sMember3sID"]) != "-") { sMastersIDs.Add(Convert.ToString(Reader["sMember3sID"])); }

                        if (Convert.ToString(Reader["sMember4sID"]) != "-") { sMastersIDs.Add(Convert.ToString(Reader["sMember4sID"])); }

                        return true;
                    }

                    sMastersID = String.Empty;

                    sMastersIDs = null;

                    return false;
                }
            }
        }

        public Int64 GetnAmountForsIP(String sIP)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nAmount FROM {0}..tIPBlock WHERE sIP = '{1}'", FilterDB, sIP);

                return Convert.ToInt64(Command.ExecuteScalar());
            }
        }

        public Boolean TableEmpty(String Database, String Table)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..{1}", Database, Table);

                if (Convert.ToInt64(Command.ExecuteScalar()) == 0) { return true; }
                else { return false; }
            }
        }

        public Boolean GettWorldBan(Byte nWorldNo, String sUsername)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tWorldBans WHERE nWorldNo = '{1}' AND sUsername = '{2}'", FilterDB, nWorldNo, sUsername);

                if (Convert.ToInt32(Command.ExecuteScalar()) == 0) { return false; }
                else { return true; }
            }
        }

        public void AddnAttemptForsIP(String sIP)
        {
            if (Connection.State != ConnectionState.Open) { Connection.Open(); }

            using (SqlCommand Command = Connection.CreateCommand())
            {
                Command.CommandTimeout = 0;
                Command.CommandText = String.Format("SELECT TOP 1 nAttempt FROM {0}..tCancer WHERE sIP = '{1}'", FilterDB, sIP);

                using (SqlDataReader Reader = Command.ExecuteReader())
                {
                    Reader.Read();

                    if (Reader.HasRows)
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("UPDATE {0}..tCancer SET nAttempt = (nAttempt + 1) WHERE sIP = '{1}'", FilterDB, sIP);
                        Command.ExecuteNonQuery();
                    }
                    else
                    {
                        Reader.Close();

                        Command.CommandText = String.Format("INSERT INTO {0}..tCancer (sIP, nAttempt) VALUES ('{1}', '1')", FilterDB, sIP);
                        Command.ExecuteNonQuery();
                    }
                }
            }
        }
    }
}