using System;
using System.Net;
using System.Text;
using System.Linq;
using System.Threading;
using System.Net.Sockets;
using System.Collections.Generic;

using FilterAPI;
using FilterAPI.Networking;
using FilterAPI.CustomCurrency;

namespace FilterLauncher.LauncherNetworking
{
    internal class LauncherClient : IDisposable
    {
        private Socket ClientSocket;
        private IPEndPoint ClientEndPoint;

        private Byte[] ClientBuffer;

        private Int32 IsConnected;

        public LauncherClient(Socket AcceptedSocket, IPEndPoint AcceptedEndPoint)
        {
            ClientSocket = AcceptedSocket;
            ClientEndPoint = AcceptedEndPoint;

            if (Program.SQL.GetbBlockForsIP(Convert.ToString(ClientEndPoint.Address)) || Program.SQL.GetnAmountForsIP(Convert.ToString(ClientEndPoint.Address)) >= Convert.ToInt64(Program.Auth.ConfigValues["MaximumCPIP"]))
            {
                Disconnect();

                return;
            }

            ClientBuffer = new Byte[1024];

            try { ClientSocket.BeginReceive(ClientBuffer, 0, ClientBuffer.Length, SocketFlags.None, new AsyncCallback(TokenReceived), null); }
            catch { Disconnect(); }
        }

        private void TokenReceived(IAsyncResult Result)
        {
            if (IsConnected != 0) { return; }

            Int32 ReceivedLength = 0;

            try { ReceivedLength = ClientSocket.EndReceive(Result); }
            catch
            {
                Disconnect();   

                return;
            }

            if (ReceivedLength >= 1)
            {
                try
                {
                    Array.Resize(ref ClientBuffer, ReceivedLength);

                    String HTTPRequest = Encoding.ASCII.GetString(ClientBuffer).Split(new String[] { " HTTP/1.1" }, StringSplitOptions.None)[0].Replace("GET /", "").Replace("?", "").Split('\n')[0];

                    String[] HTTPRequestSplit = HTTPRequest.Split('&');

                    Dictionary<String, String> HTTPParameters = new Dictionary<String, String>();

                    foreach (String HTTPParameter in HTTPRequestSplit) { HTTPParameters.Add(HTTPParameter.Split('=')[0], HTTPParameter.Split('=')[1]); }

                    if (HTTPParameters.ContainsKey("Type"))
                    {
                        if (HTTPParameters["Type"] == "Ping") { SendResponse("Pong"); }
                        else if (HTTPParameters["Type"] == "Login" && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("Password"))
                        {
                            String Username = HTTPParameters["Username"];
                            String Password = HTTPParameters["Password"];

                            if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(Password))
                            {
                                if (Username.Length <= 16 || Password.Length <= 32)
                                {
                                    if (!Program.SQL.sUsernameExists(Username) || !Program.SQL.sUserPassMatchsUsername(Username, Password))
                                    {
                                        SendResponse("Usernamme/Password is incorrect.");

                                        Program.SendConsoleText(ConsoleColor.Gray, "Username/Password was entered incorrectly with {0} as username.", Username);
                                    }
                                    else
                                    {
                                        Int32 nEMID = Program.SQL.GetnEMIDFromsUsername(Username);
                                        String sToken = Program.SQL.CreateAndInsertsTokenFornEMID(Program.SQL.GetnEMIDFromsUsername(Username));

                                        Currency MallCurrency = Program.Currencies.Currencies.Where(CurrencyID => CurrencyID.CurrencyID == Convert.ToByte(Program.Auth.ConfigValues["PaymentMCID"])).FirstOrDefault();

                                        Boolean ShowMessage;

                                        String sRecoveryKey = Program.SQL.GetsRecoveryKeyFornUserNo(nEMID, out ShowMessage);

                                        SendResponse(String.Format("Success#{0}#{1}#{2}#{3}#{4}", sToken, nEMID, Program.SQL.GetAmountForCC(MallCurrency.TableName, "nUserNo", nEMID), ShowMessage, sRecoveryKey));

                                        Program.SendConsoleText(ConsoleColor.Gray, "Successful login. sUsername: {0}. nEMID: {1}. sToken: {2}. Mall Points: {3}. sReceoveryKey: {4}.", Username, nEMID, sToken, Program.SQL.GetAmountForCC(MallCurrency.TableName, "nUserNo", nEMID), sRecoveryKey);
                                    }
                                }
                            }
                        }
                        else if (HTTPParameters["Type"] == "Register" && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("Password"))
                        {
                            String Username = HTTPParameters["Username"];
                            String Password = HTTPParameters["Password"];

                            if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(Password))
                            {
                                if (Username.Length <= 16 || Password.Length <= 32)
                                {
                                    if (Program.SQL.sUsernameExists(Username))
                                    {
                                        SendResponse("The username already exists. Please try another one.");

                                        Program.SendConsoleText(ConsoleColor.Gray, "New register from {0}, but username was taken.", Username);
                                    }
                                    else
                                    {
                                        Program.SQL.InsertNewtAccount(Username, Password);

                                        SendResponse(String.Format("Success#The account has been registered. Username: {0}. Password: {1}.", Username, Password));

                                        Program.SendConsoleText(ConsoleColor.Gray, "New account registered. sUsername: {0}.", Username);
                                    }
                                }
                            }
                        }
                        else if (HTTPParameters["Type"] == "PasswordChange" && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("OldPassword") && HTTPParameters.ContainsKey("NewPassword"))
                        {
                            String Username = HTTPParameters["Username"];
                            String OldPassword = HTTPParameters["OldPassword"];
                            String NewPassword = HTTPParameters["NewPassword"];

                            if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(OldPassword) && Injection.ContainsOnlyLetterOrDigit(NewPassword))
                            {
                                if (Username.Length <= 16 || OldPassword.Length <= 32 || NewPassword.Length <= 32)
                                {
                                    if (!Program.SQL.sUsernameExists(Username) || !Program.SQL.sUserPassMatchsUsername(Username, OldPassword))
                                    {
                                        SendResponse("Usernamme/Old-Password is incorrect.");

                                        Program.SendConsoleText(ConsoleColor.Gray, "Someone tried to change their password but entered incorrect old information. This could be some kind of attempt at injection. sUsername: {0}", Username);
                                    }
                                    else if (Program.SQL.ChecksPassword(Program.SQL.GetnEMIDFromsUsername(Username), NewPassword))
                                    {
                                        SendResponse(String.Format("You have previously used the password {0}. Please use another one (this is to try and help protect your account C:).", NewPassword));

                                        Program.SendConsoleText(ConsoleColor.Gray, "Someone tried to change their password but used a password they have used in the past. sUsername: {0}.", Username);
                                    }
                                    else
                                    {
                                        Program.SQL.SetsUserPassForsUsername(Username, NewPassword);
                                        Program.SQL.InsertIntotPasswordChange(Program.SQL.GetnEMIDFromsUsername(Username), OldPassword);

                                        SendResponse(String.Format("Success#Password for {0} has been updated to {1}.", Username, NewPassword));

                                        Program.SendConsoleText(ConsoleColor.Gray, "Password updated. Username: {0}.", Username);
                                    }
                                }
                            }
                        }
                        else if (HTTPParameters["Type"] == "InformationRequest" && HTTPParameters.ContainsKey("ServerID") && HTTPParameters.ContainsKey("InformationType"))
                        {
                            if (Injection.IsInt32(HTTPParameters["ServerID"]))
                            {
                                Byte ServerID = Convert.ToByte(HTTPParameters["ServerID"]);
                                String InformationType = Convert.ToString(HTTPParameters["InformationType"]);

                                if (InformationType == "LauncherTitle") { SendResponse(Program.Auth.ConfigValues["LauncherTitle"]); }
                                else if (InformationType == "LauncherVURL") { SendResponse(Program.Auth.ConfigValues["LauncherVURL"]); }
                                else if (InformationType == "LauncherUURL") { SendResponse(Program.Auth.ConfigValues["LauncherUURL"]); }
                                else if (InformationType == "LauncherSIPURL") { SendResponse(Program.Auth.ConfigValues["LauncherSIPURL"]); }
                                else if (InformationType == "LauncherVGURL") { SendResponse(Program.Auth.ConfigValues["LauncherVGURL"]); }
                                else if (InformationType == "LauncherVURL") { SendResponse(Program.Auth.ConfigValues["LauncherVURL"]); }
                                else if (InformationType == "LauncherMGURL") { SendResponse(Program.Auth.ConfigValues["LauncherMGURL"]); }
                                else if (InformationType == "LauncherMURL") { SendResponse(Program.Auth.ConfigValues["LauncherMURL"]); }
                                else if (InformationType == "ServerCount") { SendResponse(Program.Auth.ConfigValues["LauncherSC"]); }
                                else if (InformationType == "Donate") { SendResponse(Program.Auth.ConfigValues["SuperRewardsURL"]); }
                                else if (InformationType == "ServerName") { SendResponse(Program.Auth.ConfigValues[String.Format("LauncherS{0}SN", ServerID)]); }
                                else if (InformationType == "FolderName") { SendResponse(Program.Auth.ConfigValues[String.Format("LauncherS{0}FN", ServerID)]); }
                                else if (InformationType == "VersionURL") { SendResponse(Program.Auth.ConfigValues[String.Format("LauncherS{0}VURL", ServerID)]); }
                                else if (InformationType == "PatchesURL") { SendResponse(Program.Auth.ConfigValues[String.Format("LauncherS{0}PURL", ServerID)]); }
                                else if (InformationType == "PatchLogURL") { SendResponse(Program.Auth.ConfigValues[String.Format("LauncherS{0}PLURL", ServerID)]); }
                                else if (InformationType == "VersionFile") { SendResponse(Program.Auth.ConfigValues[String.Format("LauncherS{0}VF", ServerID)]); }
                                else if (InformationType == "StartupParameter") { SendResponse(Program.Auth.ConfigValues[String.Format("LauncherS{0}SUP", ServerID)]); }
                            }
                        }
                        else if (HTTPParameters["Type"] == "MaintenanceStatus" && HTTPParameters.ContainsKey("ServerID") && HTTPParameters.ContainsKey("Username"))
                        {
                            Byte ServerID = Convert.ToByte(HTTPParameters["ServerID"]);
                            String Username = Convert.ToString(HTTPParameters["Username"]);

                            if (Injection.ContainsOnlyLetterOrDigit(Username))
                            {
                                if (Username.Length <= 16)
                                {
                                    Boolean bInMaintenance = Program.SQL.GetbInMaintenanceFornServerID(ServerID);

                                    Byte nAuthID = Program.SQL.GetnAuthIDFromnEMID(Program.SQL.GetnEMIDFromsUsername(Username));
                                    Boolean nLoginable;
                                    Byte nTypeID = Program.SQL.GetnTypeIDfromnAuthID(nAuthID, out nLoginable);

                                    if (bInMaintenance)
                                    {
                                        if (nLoginable) { SendResponse("True"); }
                                        else { SendResponse("False"); }
                                    }
                                    else { SendResponse("True"); }
                                }
                            }
                        }
                        else if (HTTPParameters["Type"] == "PasswordStatus" && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("Password"))
                        {
                            String Username = HTTPParameters["Username"];
                            String Password = HTTPParameters["Password"];

                            if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(Password) && Username.Length <= 16 && Password.Length <= 32 && Program.SQL.sUsernameExists(Username) && Program.SQL.sUserPassMatchsUsername(Username, Password))
                            {
                                String sMessage;
                                DateTime dResetDate;

                                Boolean HasRows = Program.SQL.GettForcePasswordRest(out sMessage, out dResetDate);

                                if (HasRows)
                                {
                                    DateTime dChangeDate = Program.SQL.GetLasttPasswordChange(Program.SQL.GetnEMIDFromsUsername(Username));

                                    if (dResetDate > dChangeDate) { SendResponse(String.Concat("True#", sMessage)); }
                                    else { SendResponse("False#"); }
                                }
                                else { SendResponse("False#"); }
                            }
                        }
                        //else if (Convert.ToBoolean(Program.Auth.ConfigValues["LauncherRE"]) && HTTPParameters["Type"] == "Rebirth" && HTTPParameters.ContainsKey("RType") && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("Password"))
                        //{
                        //    String Username = HTTPParameters["Username"];
                        //    String Password = HTTPParameters["Password"];

                        //    if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(Password) && Username.Length <= 16 && Password.Length <= 32 && Program.SQL.sUsernameExists(Username) && Program.SQL.sUserPassMatchsUsername(Username, Password))
                        //    {
                        //        Int32 nEMID = Program.SQL.GetnEMIDFromsUsername(Username);

                        //        if (HTTPParameters["RType"] == "LEC")
                        //        {
                        //            List<String> RebirthablesIDs = Program.SQL.LoadRebirthablesIDs(nEMID);

                        //            String RebirthableString = String.Empty;

                        //            if (Program.SQL.GetLoginQueries(nEMID).Count == 0)
                        //            {
                        //                foreach (String RebirthablesID in RebirthablesIDs) { RebirthableString += String.Concat(RebirthablesID, "#"); }
                        //            }

                        //            SendResponse(RebirthableString.TrimEnd('#'));
                        //        }
                        //        else if (HTTPParameters["RType"] == "RC" && HTTPParameters.ContainsKey("Name"))
                        //        {
                        //            String Name = HTTPParameters["Name"];

                        //            if (Name.Length <= 16 && Injection.ContainsOnlyLetterOrDigit(HTTPParameters["Name"]) && Program.SQL.sIDOwnedBynUserNo(Name, nEMID) && Program.SQL.GetnLevelFromsID(Name) == Convert.ToByte(Program.Auth.ConfigValues["RebirthLevel"]))
                        //            {
                        //                Int32 nUserNo = Program.SQL.GetnEMIDFromsUsername(HTTPParameters["Username"]);
                        //                Int32 nCharNo = Program.SQL.GetnCharNoFromsID(Name);

                        //                if (Program.SQL.nCharNoReachedMaxRebirth(nCharNo)) { SendResponse(String.Format("This character has reached its maximum amount of rebirths. Maximum rebirths: {0}.", Program.Auth.ConfigValues["RebirthMaximum"])); }
                        //                else if (Program.SQL.GetnMoneyFornCharNo(nCharNo) < Convert.ToInt64(Program.Auth.ConfigValues["RebirthMoney"])) { SendResponse(String.Format("You do not have enough money on the character {0}. You need to have atleast {1} to rebirth.", Name, Money.ConvertMoney(Convert.ToInt64(Program.Auth.ConfigValues["RebirthMoney"])))); }
                        //                //else if (Program.SQL.GetItemsFromnStorageType(nCharNo, 8).Count != 0) { SendResponse("Please unequip everything from your character before trying to rebirth again."); }
                        //                //else if (Program.SQL.GetOnlinesIDs().Contains(Name)) { SendResponse("Your character is currently on the server please either go to character select or close your game."); }
                        //                else
                        //                {
                        //                    using (var LocalPacket = new Packet(4, 7))
                        //                    {
                        //                        LocalPacket.PacketWriter.Write(Name);
                        //                        LocalPacket.PacketWriter.Write(true);
                        //                        LocalPacket.PacketWriter.Write("Server");
                        //                        LocalPacket.PacketWriter.Write("You have been disconnected from the server by the rebirth system, this is to prevent your level from bugging when it is set! C:");

                        //                        Program.LocalClient.SendPacket(LocalPacket);
                        //                    }

                        //                    Program.SQL.DecreasenMoneyFornCharNo(nCharNo, Convert.ToInt64(Program.Auth.ConfigValues["RebirthMoney"]));
                        //                    Program.SQL.DeletenStorageTypeFornCharNo(nCharNo, 2);
                        //                    Program.SQL.InserttLoginQuery(nUserNo, String.Format("UPDATE {0}..tCharacter SET nLevel = '{1}', nExp = '{2}' WHERE nCharNo = '{3}'", Program.Auth.ConfigValues["CharacterDB"], Program.Auth.ConfigValues["RebirthSetLevel"], Program.Auth.ConfigValues["RebirthSetExp"], nCharNo));
                        //                    Program.SQL.InserttRebirth(nCharNo);

                        //                    SendResponse("Success#The character has been rebirthed successfully!");
                        //                }
                        //            }
                        //        }
                        //    }
                        //}
                        //else if (Convert.ToBoolean(Program.Auth.ConfigValues["LauncherCCE"]) && HTTPParameters["Type"] == "ClickCookie" && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("Password"))
                        //{
                        //    String Username = HTTPParameters["Username"];
                        //    String Password = HTTPParameters["Password"];

                        //    if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(Password) && Username.Length <= 16 && Password.Length <= 32 && Program.SQL.sUsernameExists(Username) && Program.SQL.sUserPassMatchsUsername(Username, Password))
                        //    {
                        //        if (!Program.CCInfo.ContainsKey(Username)) { Program.CCInfo.Add(Username, DateTime.Now.AddSeconds(1).AddMilliseconds(500)); }
                        //        else if (Program.CCInfo[Username] > DateTime.Now)
                        //        {
                        //            SendResponse("TOO FAST SLOW DOWN");

                        //            Disconnect();

                        //            return;
                        //        }
                        //        else if (Program.CCInfo[Username] < DateTime.Now) { Program.CCInfo[Username] = DateTime.Now; }

                        //        Int32 nEMID = Program.SQL.GetnEMIDFromsUsername(Username);

                        //        Program.SQL.InserttCookieClicker(nEMID);
                        //        Program.SQL.PutMoneyInStorage(nEMID, 100000);

                        //        SendResponse(Program.SQL.GetnTotalClicksFornUserNo(nEMID));

                        //        Program.CCInfo[Username] = DateTime.Now.AddSeconds(1).AddMilliseconds(500);
                        //    }
                        //}
                        else if (HTTPParameters["Type"] == "GiveCoins" && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("Password") && HTTPParameters.ContainsKey("GiveUsername") && HTTPParameters.ContainsKey("Amount"))
                        {
                            String Username = HTTPParameters["Username"];
                            String Password = HTTPParameters["Password"];
                            String GiveUsername = HTTPParameters["GiveUsername"];

                            if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(Password) && Username.Length <= 16 && Password.Length <= 32 && Program.SQL.sUsernameExists(Username) && Program.SQL.sUserPassMatchsUsername(Username, Password) && Injection.ContainsOnlyLetterOrDigit(GiveUsername) && GiveUsername.Length <= 16)
                            {
                                Boolean AmountIsInt = false;
                                Int32 Amount = 0;

                                try
                                {
                                    Amount = Convert.ToInt32(HTTPParameters["Amount"]);
                                    AmountIsInt = true;
                                }
                                catch { }

                                if (AmountIsInt)
                                {
                                    if (Amount <= 0) { SendResponse(String.Format("{0} is not a valid amount to give.", Amount)); }
                                    else
                                    {
                                        Int32 nEMID = Program.SQL.GetnEMIDFromsUsername(Username);

                                        Currency MallCurrency = Program.Currencies.Currencies.Where(CurrencyID => CurrencyID.CurrencyID == Convert.ToByte(Program.Auth.ConfigValues["PaymentMCID"])).FirstOrDefault();

                                        Int64 CurrentAmount = Program.SQL.GetAmountForCC(MallCurrency.TableName, "nUserNo", nEMID);

                                        if (Amount > CurrentAmount) { SendResponse(String.Format("You cannot give {0} coins as you only have {1}.", Amount, CurrentAmount)); }
                                        else if (!Program.SQL.sUsernameExists(GiveUsername)) { SendResponse(String.Format("{0} does not exist in our database.", GiveUsername)); }
                                        else
                                        {
                                            Program.SQL.MinusAmountForCC(MallCurrency.TableName, Amount, "nUserNo", nEMID);
                                            Program.SQL.AddAmountForCC(MallCurrency.TableName, Amount, "nUserNo", Program.SQL.GetnEMIDFromsUsername(GiveUsername));

                                            SendResponse(String.Format("Success#{0}#{1} coins have been given to {2} you now have {0} coins left.", CurrentAmount - Amount, Amount, GiveUsername));
                                        }
                                    }
                                }
                            }
                        }
                        else if (HTTPParameters["Type"] == "PSCKey" && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("Key") && HTTPParameters.ContainsKey("Amount"))
                        {
                            String Username = HTTPParameters["Username"];
                            String Key = HTTPParameters["Key"];

                            if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(Username) && Username.Length <= 16)
                            {
                                if (Injection.CheckPSC(Key) || Key.Length != 19) { SendResponse("The PSC you tried to send to the server is invalid. PSC are 19 in length and they look like this: \"1234-1234-1234-1234\" or \"1234 1234 1234 1234\"."); }
                                else if (Program.SQL.tPSCRowExists(Program.SQL.GetnEMIDFromsUsername(Username), Key)) { SendResponse("You have already sent this key to our server."); }
                                else
                                {
                                    Boolean AmountIsDouble = false;
                                    Double Amount = 0;

                                    try
                                    {
                                        Amount = Convert.ToDouble(HTTPParameters["Amount"]);
                                        AmountIsDouble = true;
                                    }
                                    catch { }

                                    if (AmountIsDouble)
                                    {
                                        if (Amount <= 0) { SendResponse(String.Format("{0} is not a valid amount for PSC.", Amount)); }
                                        //else if (Amount > 25) { SendResponse(String.Format("{0} we can no longer accept cards that have more than 25 EUR on them, as PSC believe that it is a security risk since it is being used from a different country. Sorry for the inconvience. Please do not send the code with amount 25 as if we cannot use it we will no longer accept it. Thanks for understanding!")); }
                                        else if (Amount > 500) { SendResponse(String.Format("{0} is too high of an amount for PSC.", Amount)); }
                                        else
                                        {
                                            Program.SQL.InserttPSC(Program.SQL.GetnEMIDFromsUsername(Username), Key, Amount);

                                            SendResponse("Success#The key has been saved to the server and will be processed soon!");
                                        }
                                    }
                                }
                            }
                        }
                        else if (HTTPParameters["Type"] == "Unstuck" && HTTPParameters.ContainsKey("UType") && HTTPParameters.ContainsKey("Username") && HTTPParameters.ContainsKey("Password"))
                        {
                            String Username = HTTPParameters["Username"];
                            String Password = HTTPParameters["Password"];

                            if (Injection.ContainsOnlyLetterOrDigit(Username) && Injection.ContainsOnlyLetterOrDigit(Password) && Username.Length <= 16 && Password.Length <= 32 && Program.SQL.sUsernameExists(Username) && Program.SQL.sUserPassMatchsUsername(Username, Password))
                            {
                                Int32 nEMID = Program.SQL.GetnEMIDFromsUsername(Username);

                                if (HTTPParameters["UType"] == "LUC")
                                {
                                    List<String> UnstucksIDs = Program.SQL.GetsIDsFornUserNo(nEMID);

                                    String UnstuckString = String.Empty;

                                    foreach (String UnstucksID in UnstucksIDs) { UnstuckString += String.Concat(UnstucksID, "#"); }

                                    SendResponse(UnstuckString.TrimEnd('#'));
                                }
                                else if (HTTPParameters["UType"] == "UC" && HTTPParameters.ContainsKey("Name"))
                                {
                                    String Name = HTTPParameters["Name"];

                                    if (Name.Length <= 16 && Injection.ContainsOnlyLetterOrDigit(HTTPParameters["Name"]) && Program.SQL.sIDOwnedBynUserNo(Name, nEMID) && Program.SQL.GetnLevelFromsID(Name) == Convert.ToByte(Program.Auth.ConfigValues["RebirthLevel"]))
                                    {
                                        Int32 nUserNo = Program.SQL.GetnEMIDFromsUsername(HTTPParameters["Username"]);
                                        Int32 nCharNo = Program.SQL.GetnCharNoFromsID(Name);

                                        using (var LocalPacket = new Packet(4, 7))
                                        {
                                            LocalPacket.PacketWriter.Write(Name);
                                            LocalPacket.PacketWriter.Write(true);
                                            LocalPacket.PacketWriter.Write("Server");
                                            LocalPacket.PacketWriter.Write("You have been disconnected from the server by the unstuck system, this is to prevent your location from bugging when it is set!");

                                            Program.LocalClient.SendPacket(LocalPacket);
                                        }
                                        
                                        Program.SQL.InserttLoginQuery(nUserNo, String.Format("UPDATE {0}..tCharacter SET sLoginZone = '{1}' WHERE nCharNo = '{2}'", Program.Auth.ConfigValues["CharacterDB"], Program.Auth.ConfigValues["LauncherUMI"], nCharNo));

                                        SendResponse("Success#The character has been moved successfully!");
                                    }
                                }
                            }
                        }

                        Disconnect();
                    }
                }
                catch { }
            }
            else { Disconnect(); }
        }

        private void SendResponse(String Text)
        {
            String ResponseData = String.Empty;

            ResponseData = String.Concat(ResponseData, "HTTP/1.1 200 OK", Environment.NewLine);
            ResponseData = String.Concat(ResponseData, "Date: ", String.Format("{0:r}", DateTime.Now), Environment.NewLine);
            ResponseData = String.Concat(ResponseData, "Server: Kobalts Web Server.", Environment.NewLine);
            ResponseData = String.Concat(ResponseData, "Content-Length: ", Text.Length, Environment.NewLine);
            ResponseData = String.Concat(ResponseData, "Content-Type: text/html", Environment.NewLine);
            ResponseData = String.Concat(ResponseData, Environment.NewLine);
            ResponseData = String.Concat(ResponseData, Text);

            ClientSocket.Send(Encoding.ASCII.GetBytes(ResponseData));
        }

        private void Disconnect()
        {
            if (IsConnected == 0 && Interlocked.CompareExchange(ref IsConnected, 1, 0) == 0)
            {
                try { ClientSocket.Dispose(); }
                catch { }

                ClientEndPoint = null;

                ClientBuffer = new Byte[0];
            }
        }

        ~LauncherClient() { Dispose(); }

        public void Dispose() { Disconnect(); }
    }
}
