/// <summary>
        /// Search the server database for a server by name, and return any
        /// matching online servers (zero or more).
        /// </summary>
        /// <param name="Product">Supplies the product name, such as NWN2.</param>
        /// <param name="ServerName">Supplies the server name.</param>
        /// <returns>A list of matching online servers is returned.</returns>
        public IList <NWGameServer> LookupServerByName(string Product, string ServerName)
        {
            List <NWGameServer> Servers = new List <NWGameServer>();

            string Query = String.Format(
                StandardServerQueryPrefix +
                @"WHERE `product_id` = {0}
    AND `online` = true
    AND `server_name` = '{1}'
    ",
                ProductNameToId(Product),
                MySqlHelper.EscapeString(ServerName));

            using (MySqlDataReader Reader = MySqlHelper.ExecuteReader(ConnectionString, Query))
            {
                while (Reader.Read())
                {
                    NWGameServer Server = LoadGameServerFromQuery(Reader);

                    Server.Product = Product;

                    Servers.Add(Server);
                }
            }

            return(Servers);
        }
        /// <summary>
        /// Read server parameters from the standard database query column
        /// layout and construct and return a NWGameServer corresponding to the
        /// data in question.
        /// </summary>
        /// <param name="Reader">Supplies a reader containing the results of a
        /// query that correspond to the standard column set.</param>
        /// <returns>A NWGameServer object describing the current row.</returns>
        private NWGameServer LoadGameServerFromQuery(MySqlDataReader Reader)
        {
            NWGameServer Server = new NWGameServer();

            Server.ExpansionsMask     = Reader.GetUInt32(1);
            Server.BuildNumber        = Reader.GetUInt32(2);
            Server.ModuleName         = Reader.GetString(3);
            Server.ServerName         = Reader.GetString(4);
            Server.ActivePlayerCount  = Reader.GetUInt32(5);
            Server.MaximumPlayerCount = Reader.GetUInt32(6);
            Server.LocalVault         = Reader.GetBoolean(7);
            Server.LastHeartbeat      = Reader.GetDateTime(8);
            Server.ServerAddress      = Reader.GetString(9);
            Server.Online             = Reader.GetBoolean(10);
            Server.PrivateServer      = Reader.GetBoolean(11);
            Server.ModuleDescription  = Reader.GetString(12);
            Server.ModuleUrl          = Reader.GetString(13);
            Server.GameType           = Reader.GetUInt32(14);
            Server.MinimumLevel       = Reader.GetUInt32(15);
            Server.MaximumLevel       = Reader.GetUInt32(16);
            Server.PVPLevel           = Reader.GetUInt32(17);
            Server.PlayerPause        = Reader.GetBoolean(18);
            Server.OnePartyOnly       = Reader.GetBoolean(19);
            Server.ELCEnforced        = Reader.GetBoolean(20);
            Server.ILREnforced        = Reader.GetBoolean(21);
            Server.PWCUrl             = Reader.GetString(22);
            Server.ServerDescription  = Reader.GetString(23);

            return(Server);
        }
        /// <summary>
        /// Search the server database for all servers that are online for the
        /// given game product.
        /// </summary>
        /// <param name="Product">Supplies the product name, such as NWN2.</param>
        /// <returns>A list of matching online servers is returned.</returns>
        public IList <NWGameServer> GetOnlineServerList(string Product)
        {
            List <NWGameServer> Servers = new List <NWGameServer>();

            string Query = String.Format(
                StandardServerQueryPrefix +
                @"WHERE `product_id` = {0}
    AND `online` = true
    ",
                ProductNameToId(Product));

            using (MySqlDataReader Reader = MySqlHelper.ExecuteReader(ConnectionString, Query))
            {
                while (Reader.Read())
                {
                    NWGameServer Server = LoadGameServerFromQuery(Reader);

                    Server.Product = Product;

                    Servers.Add(Server);
                }
            }

            return(Servers);
        }
        /// <summary>
        /// Search the server database for a server by address, and return stored
        /// information about it (the server may be offline).
        /// </summary>
        /// <param name="Product">Supplies the product name, such as NWN2.</param>
        /// <param name="ServerAddress">Supplies the server address.  This value
        /// takes the form of "ip:port".</param>
        /// <returns>The matching server.</returns>
        public NWGameServer LookupServerByAddress(string Product, string ServerAddress)
        {
            string Query = String.Format(
                StandardServerQueryPrefix +
                @"WHERE `product_id` = {0}
    AND `server_address` = '{1}'
    ",
                ProductNameToId(Product),
                MySqlHelper.EscapeString(ServerAddress));

            using (MySqlDataReader Reader = MySqlHelper.ExecuteReader(ConnectionString, Query))
            {
                if (Reader.Read())
                {
                    NWGameServer Server = LoadGameServerFromQuery(Reader);

                    Server.Product = Product;

                    return(Server);
                }
            }

            return(null);
        }
        /// <summary>
        /// Read server parameters from the standard database query column
        /// layout and construct and return a NWGameServer corresponding to the
        /// data in question.
        /// </summary>
        /// <param name="Reader">Supplies a reader containing the results of a
        /// query that correspond to the standard column set.</param>
        /// <returns>A NWGameServer object describing the current row.</returns>
        private NWGameServer LoadGameServerFromQuery(MySqlDataReader Reader)
        {
            NWGameServer Server = new NWGameServer();

            Server.ExpansionsMask = Reader.GetUInt32(1);
            Server.BuildNumber = Reader.GetUInt32(2);
            Server.ModuleName = Reader.GetString(3);
            Server.ServerName = Reader.GetString(4);
            Server.ActivePlayerCount = Reader.GetUInt32(5);
            Server.MaximumPlayerCount = Reader.GetUInt32(6);
            Server.LocalVault = Reader.GetBoolean(7);
            Server.LastHeartbeat = Reader.GetDateTime(8);
            Server.ServerAddress = Reader.GetString(9);
            Server.Online = Reader.GetBoolean(10);
            Server.PrivateServer = Reader.GetBoolean(11);
            Server.ModuleDescription = Reader.GetString(12);
            Server.ModuleUrl = Reader.GetString(13);
            Server.GameType = Reader.GetUInt32(14);
            Server.MinimumLevel = Reader.GetUInt32(15);
            Server.MaximumLevel = Reader.GetUInt32(16);
            Server.PVPLevel = Reader.GetUInt32(17);
            Server.PlayerPause = Reader.GetBoolean(18);
            Server.OnePartyOnly = Reader.GetBoolean(19);
            Server.ELCEnforced = Reader.GetBoolean(20);
            Server.ILREnforced = Reader.GetBoolean(21);
            Server.PWCUrl = Reader.GetString(22);
            Server.ServerDescription = Reader.GetString(23);

            return Server;
        }