public static ResponseStruct DeleteAllImages()
        {
            ResponseStruct Result;
            try
            {
                MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DBConnection.Open();
                string SQLQuery = "TRUNCATE TABLE images_from_players";
                MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                DBCommand.ExecuteNonQuery();
                DBCommand.Dispose();
                DBConnection.Dispose();

                string[] ImageFileNames = Directory.GetFiles(OverallInformations.ImagePath, "*.*", SearchOption.AllDirectories);
                foreach (string anImageFileName in ImageFileNames)
                {
                    File.Delete(anImageFileName);
                }

                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Đã xóa." } };
            }
            catch (Exception ex)
            {
                LauncherServer.OutputMessage(String.Format("[Server]: DeleteAllImages() | Error: {0}", ex.Message), LauncherServer.MessageType.Error);
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { ex.Message }, Broadcast = new List<string>() { "Kiểm tra hệ thống để xác định nguyên nhân." } };
            }
            return Result;
        }
        public ResponseStruct DeleteLauncherClient(string SeasonID, string SeasonIdOfLauncherClient)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.ManagementClients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Management Client không tồn tại." }, Broadcast = new List<string>() { "Có thể kết nối mạng của bạn có độ trễ lớn nên bản ghi của bạn trên Terraria Launcher Server đã bị xóa, vui lòng khởi động lại Management Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Bạn chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục." } };
            }
            else
            {
                LauncherClientInformations aLauncherClient;
                if (OverallInformations.Clients.TryRemove(SeasonIdOfLauncherClient, out aLauncherClient))
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Launcher Client đã được xóa khỏi bản ghi của Launcher Server." } };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể xóa được Launcher Client với SeasonID được cung cấp." }, Broadcast = new List<string>() { "Client với SeasonID có thể không tồn tại hoặc đã bị xóa từ trước đó." } };
                }
            }

            return Result;
        }
        public ResponseStruct CheatDetected(string SeasonID, string Reason)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." } };
            }
            else
            {
                string PlayerName;
                if (IsAnUserPlayingOnTShock(aClient.UserName, out PlayerName))
                {
                    string ResponseString;
                    if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "Kick", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { PlayerName, Reason } }, out ResponseString))
                    {
                        ResponseStruct ResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(ResponseString);
                        if (ResponseContent.Status == ResponseStatusType.Done)
                        {
                            LauncherServer.OutputMessage(String.Format("[Server]: {0} has been kicked. Reason: {1}", aClient.UserName, Reason), LauncherServer.MessageType.Warning);
                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Đã kick xong Player sử dụng chương trình cheat." } };
                        }
                        else
                        {
                            LauncherServer.OutputMessage(String.Format("[Server]: CheatDetected() | Error: {0}", LauncherServer.JoinListOfStrings(ResponseContent.Error)), LauncherServer.MessageType.Error);
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không kick được Player." } };
                        }
                    }
                    else
                    {
                        LauncherServer.OutputMessage(String.Format("[Server]: CheatDetected() | Error: Can not kick '{0}' for '{1}'. TShock Server does not response.", PlayerName, Reason), LauncherServer.MessageType.Error);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng yêu cầu kick Player." } };
                    }
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Player trong TShock Server." } };
                }
            }
            return Result;
        }
        public ResponseStruct DeleteAllImages(string SeasonID)
        {
            ResponseStruct Result;
            LauncherClientInformations aClient;
            if (!OverallInformations.ManagementClients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Management Client không tồn tại." }, Broadcast = new List<string>() { "Có thể kết nối mạng của bạn có độ trễ lớn nên bản ghi của bạn trên Terraria Launcher Server đã bị xóa, vui lòng khởi động lại Management Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục." } };
            }
            else
            {
                Result = DeleteAllImages();
            }

            return Result;
        }
        public ResponseStruct Login(string SeasonID, string UserName, string Password)
        {
            ResponseStruct Result;

            MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TShockDBConnectionString);
            DBConnection.Open();

            string SQLQuery = "SELECT Username,Password,Usergroup FROM users WHERE Username=@UserName";
            MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
            DBCommand.Prepare();
            DBCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;
            MySqlDataReader DBReader = DBCommand.ExecuteReader();

            List<TShockUserInformations> TShockUserList = new List<TShockUserInformations>();

            while(DBReader.Read())
            {
                TShockUserInformations TShockUserInstance = new TShockUserInformations();
                TShockUserInstance.UserName = DBReader.GetString("Username");
                TShockUserInstance.Password = DBReader.GetString("Password");
                TShockUserInstance.UserGroup = DBReader.GetString("Usergroup");
                TShockUserList.Add(TShockUserInstance);
            }

            DBReader.Dispose();
            DBCommand.Dispose();
            DBConnection.Dispose();

            LauncherClientInformations aClient;
            if (!OverallInformations.ManagementClients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Season ID." }, Broadcast = new List<string>() { "Khởi động lại Launcher Client." } };
            }
            else if (UserName == "")
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "'User Name' trống rỗng." }, Broadcast = new List<string>() { "'User Name' không được phép để trống, nhập đầy đủ thông tin để tiếp tục." } };
            }
            else if (UserName.Length > 32)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tên tài khoản quá dài." }, Broadcast = new List<string>() { "Nhập tên tài khoản với độ dài không quá 32 kí tự." } };
            }
            else if (TShockUserList.Count == 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản không tồn tại." }, Broadcast = new List<string>() { "Tạo tài khoản để có thể bắt đầu chơi." } };
            }
            else if (TShockUserList.Count > 1)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản bị trùng." }, Broadcast = new List<string>() { "Liên hệ Admin quản lí cơ sở dữ liệu." } };
            }
            else if (String.IsNullOrWhiteSpace(Password))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Mật mã trống rỗng." }, Broadcast = new List<string>() { "Nhập mật mã đầy đủ." } };
            }
            else
            {
                if (BCrypt.Net.BCrypt.Verify(Password, TShockUserList[0].Password))
                {
                    if (TShockUserList[0].UserGroup != "superadmin")
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản của bạn không có quyền sử dụng Launcher Management." }, Broadcast = new List<string>() { "Yêu cầu tài khoản phải có quyền quản trị cao nhất: superadmin." } };
                    }
                    else
                    {
                        if (OverallInformations.ManagementClients.TryUpdate(SeasonID, new LauncherClientInformations { SeasonID = aClient.SeasonID, UserName = UserName, Password = Password, TheFirstQueueName = aClient.TheFirstQueueName }, aClient))
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Error = new List<string>() { "Không có lỗi xảy ra." }, Broadcast = new List<string>() { "Đăng nhập thành công.", "Bạn có quyền sử dụng Launcher Management." } };
                            LauncherServer.OutputMessage(String.Format("[Management]: {0} has logged in.", UserName), LauncherServer.MessageType.Success);
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể thêm bản ghi của bạn vào danh sách Client." }, Broadcast = new List<string>() { "Khởi động lại Launcher Management và tiến hành đăng nhập." } };
                        }
                    }
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Mật mã không chính xác." }, Broadcast = new List<string>() { "Nhập lại mật mã nếu có sai sót. Liên hệ Admin nếu quên mật mã." } };
                }
            }

            return Result;
        }
 public ResponseStruct GetListOfLauncherClient(string SeasonID)
 {
     ResponseStruct Result;
     LauncherClientInformations aClient;
     if (!OverallInformations.ManagementClients.TryGetValue(SeasonID, out aClient))
     {
         Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Management Client không tồn tại." }, Broadcast = new List<string>() { "Có thể kết nối mạng của bạn có độ trễ lớn nên bản ghi của bạn trên Terraria Launcher Server đã bị xóa, vui lòng khởi động lại Management Client." } };
     }
     else if (String.IsNullOrWhiteSpace(aClient.UserName))
     {
         Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục." } };
     }
     else
     {
         List<LauncherClientInformations> LauncherClients = OverallInformations.Clients.Select(kvp => kvp.Value).ToList();
         Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(LauncherClients) };
     }
     return Result;
 }
        public ResponseStruct BuyRegularItem(string SeasonID, string ItemName, string ItemCountString, string BalanceType)
        {
            ResponseStruct Result;

            int ItemCount;
            LauncherClientInformations aClient;

            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Client." } };
            }
            else if (string.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Đăng nhập để tiếp tục sử dụng." } };
            }
            else if (string.IsNullOrWhiteSpace(ItemName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tên item trống rỗng." }, Broadcast = new List<string>() { "Chọn đúng item được cung cấp." } };
            }
            else if (!int.TryParse(ItemCountString, out ItemCount))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng item có kích thước hoặc định dạng không hợp lệ." }, Broadcast = new List<string>() { "Chỉnh lại cho phù hợp: Chỉ chứa mỗi các kí tự số." } };
            }
            else if (ItemCount <= 0 || ItemCount > 999)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng Item không hợp lệ." }, Broadcast = new List<string>() { "Chỉnh lại cho phù hợp: 0 < Số lượng < Max Stack." } };
            }
            else if (string.IsNullOrWhiteSpace(BalanceType))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Currency không đúng chủng loại." }, Broadcast = new List<string>() { "Lựa chọn theo đúng danh sách có sẵn." } };
            }
            else
            {
                string UserName = aClient.UserName;
                string PlayerName;

                if (IsAnUserPlayingOnTShock(UserName, out PlayerName))
                {

                    #region Get item informations
                    MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                    DBConnection.Open();

                    string SQLQuery = "SELECT * FROM shop_items WHERE ItemName=@ItemName";
                    MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                    DBCommand.Prepare();
                    DBCommand.Parameters.Add("@ItemName", MySqlDbType.Text).Value = ItemName;
                    MySqlDataReader DBReader = DBCommand.ExecuteReader();

                    List<ShopItemInformations> ItemList = new List<ShopItemInformations>();

                    while (DBReader.Read())
                    {
                        ShopItemInformations item = new ShopItemInformations();
                        if (!DBReader.IsDBNull(DBReader.GetOrdinal("ItemID")))
                        {
                            item.ItemID = DBReader.GetInt32("ItemID");
                        }
                        if (!DBReader.IsDBNull(DBReader.GetOrdinal("ItemName")))
                        {
                            item.ItemName = DBReader.GetString("ItemName");
                        }
                        if (!DBReader.IsDBNull(DBReader.GetOrdinal("ItemType")))
                        {
                            item.ItemType = DBReader.GetString("ItemType");
                        }
                        if (!DBReader.IsDBNull(DBReader.GetOrdinal("MaxStack")))
                        {
                            item.MaxStack = DBReader.GetInt32("MaxStack");
                        }
                        if (!DBReader.IsDBNull(DBReader.GetOrdinal("PremiumPrice")))
                        {
                            item.PremiumPrice = DBReader.GetInt32("PremiumPrice");
                        }
                        if (!DBReader.IsDBNull(DBReader.GetOrdinal("StandardPrice")))
                        {
                            item.StandardPrice = DBReader.GetInt32("StandardPrice");
                        }
                        ItemList.Add(item);
                    }

                    DBReader.Close();
                    #endregion

                    if (ItemList.Count <= 0)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Item." }, Broadcast = new List<string>() { "Lựa chọn Item cho chính xác." } };
                    }
                    else if (ItemList.Count > 1)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Item bị trùng lặp." }, Broadcast = new List<string>() { "Báo với Admin nếu có thể." } };
                    }
                    else if (String.IsNullOrWhiteSpace(ItemList[0].ItemName) || ItemList[0].MaxStack <= 0)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Thông tin của Item có sai sót." }, Broadcast = new List<string>() { "Báo với Admin nếu có thể." } };
                    }
                    else if (ItemList[0].StandardPrice == -1 && BalanceType == "Standard Balance")
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Item không thể mua với Standard Balance." }, Broadcast = new List<string>() { "Vui lòng chọn cách thanh toán khác nếu có thể." } };
                    }
                    else if (ItemList[0].PremiumPrice == -1 && BalanceType == "Premium Balance")
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Item không thể mua với Premium Balance." }, Broadcast = new List<string>() { "Vui lòng chọn cách thanh toán khác nếu có thể." } };
                    }
                    else
                    {
                        ShopItemInformations item = ItemList[0];
                        if (ItemCount <= item.MaxStack && ItemCount > 0)
                        {
                            if (BalanceType == "Standard Balance")
                            {
                                #region Pay with Standard Account
                                long Balance;
                                if (!Int64.TryParse(Convert.ToString(GetBalance(aClient.SeasonID, "Standard Balance").Content), out Balance))
                                {
                                    Balance = 0;
                                }
                                long CalcPrice = item.StandardPrice * ItemCount;
                                if (CalcPrice > Balance)
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đủ sức mạnh." }, Broadcast = new List<string>() { "Tài khoản người chơi chưa đủ chi trả.", "Nếu người chơi chắc chắn rằng tài khoản có đủ thì Trading System chưa lấy được thông tin Balance của người dùng, vui lòng thực hiện lại sau giây lát." } };
                                }
                                else
                                {
                                    string GiveItemResponse;
                                    if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "GiveItem", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { PlayerName, ItemName, ItemCount.ToString(), "0" } }, out GiveItemResponse))
                                    {
                                        ResponseStruct GiveItemResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(GiveItemResponse);
                                        if (GiveItemResponseContent.Status == ResponseStatusType.Done)
                                        {
                                            string SubtractPlayerResponse;
                                            if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "SubtractPlayerBalance", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { PlayerName, CalcPrice.ToString(), String.Format("Buy {0}", ItemName) } }, out SubtractPlayerResponse))
                                            {
                                                ResponseStruct SubtractPlayerBalanceResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(SubtractPlayerResponse);
                                                if (SubtractPlayerBalanceResponseContent.Status == ResponseStatusType.Done)
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2} {3}.\nChi phí: {4} Credits {5}.", UserName, PlayerName, ItemCount, ItemName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), BalanceType) } };
                                                    LogWriter(UserName: UserName, Task: "Buy Regular Item - Standard Balance", Details: String.Join("\n", Result.Broadcast));
                                                }
                                                else if (SubtractPlayerBalanceResponseContent.Status == ResponseStatusType.Fail)
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = SubtractPlayerBalanceResponseContent.Error, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2} {3}.\nChi phí: {4} Credits {5}.", UserName, PlayerName, ItemCount, ItemName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), BalanceType) } };
                                                    LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                }
                                                else
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ dữ liệu trả về từ Server." }, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2} {3}.\nChi phí: {4} Credits {5}.", UserName, PlayerName, ItemCount, ItemName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), BalanceType) } };
                                                    LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                }
                                            }
                                            else
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Server không đáp ứng." }, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2} {3}.\nChi phí: {4} Credits {5}.", UserName, PlayerName, ItemCount, ItemName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), BalanceType) } };
                                                LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                            }
                                        }
                                        else if (GiveItemResponseContent.Status == ResponseStatusType.Fail)
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = GiveItemResponseContent.Error, Broadcast = GiveItemResponseContent.Broadcast };
                                        }
                                        else
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ dữ liệu trả về từ Server." }, Broadcast = new List<string>() { "Báo cáo với Admin nếu có thể." } };
                                        }
                                    }
                                    else
                                    {
                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Server không đáp ứng." }, Broadcast = new List<string>() { "Báo cáo với Admin nếu có thể." } };
                                    }
                                }
                                #endregion
                            }
                            else if (BalanceType == "Premium Balance")
                            {
                                #region Pay with Premium Account
                                long Balance;
                                if (!Int64.TryParse(Convert.ToString(GetBalance(aClient.SeasonID, "Premium Balance").Content), out Balance))
                                {
                                    Balance = 0;
                                }
                                long CalcPrice = item.PremiumPrice * ItemCount;
                                if (CalcPrice > Balance)
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đủ sức mạnh." }, Broadcast = new List<string>() { "Liên hệ Admin để nạp thêm sức mạnh bằng cách Donate." } };
                                }
                                else
                                {
                                    string GiveItemResponse;
                                    if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "GiveItem", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { PlayerName, ItemName, ItemCount.ToString(), "0" } }, out GiveItemResponse))
                                    {
                                        ResponseStruct GiveItemResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(GiveItemResponse);
                                        if (GiveItemResponseContent.Status == ResponseStatusType.Done)
                                        {
                                            SQLQuery = "UPDATE shop_accounts SET Balance=@Balance WHERE UserName=@UserName";
                                            DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                                            DBCommand.Prepare();
                                            DBCommand.Parameters.Add("@Balance", MySqlDbType.Int32).Value = int.Parse((Balance - CalcPrice).ToString());
                                            DBCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = aClient.UserName;
                                            DBCommand.ExecuteNonQuery();

                                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2} {3}.\nChi phí: {4} Credits {5}.", UserName, PlayerName, ItemCount, ItemName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), BalanceType) } };

                                            LogWriter(UserName, "Buy Regular Item - Premium Balance", String.Join("\n", Result.Broadcast));
                                        }
                                        else if (GiveItemResponseContent.Status == ResponseStatusType.Fail)
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = GiveItemResponseContent.Error, Broadcast = GiveItemResponseContent.Broadcast };
                                        }
                                        else
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ dữ liệu trả về từ Server." }, Broadcast = new List<string>() { "Thông báo cho Admin nếu có thể." } };
                                        }
                                    }
                                    else
                                    {
                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Server không đáp ứng." }, Broadcast = new List<string>() { "Báo cáo với Admin nếu có thể." } };
                                    }
                                }
                                #endregion
                            }
                            else
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Credit không theo chuẩn." }, Broadcast = new List<string>() { "Lựa chọn theo đúng danh sách có sẵn." } };
                            }
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng item không hợp lệ." }, Broadcast = new List<string>() { "Chỉnh lại cho phù hợp: 0 < Số lượng < Max Stack." } };
                        }
                    }
                    DBReader.Dispose();
                    DBCommand.Dispose();
                    DBConnection.Dispose();
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Player trong Server." }, Broadcast = new List<string>() { "Player phải có mặt trong Server để tiếp tục." } };
                }
            }
            return Result;
        }
        private ResponseStruct GetPremiumBalance(string UserName)
        {
            ResponseStruct Result;

            MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
            DBConnection.Open();

            string SQLQuery = "SELECT * FROM shop_accounts WHERE UserName=@UserName";
            MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
            DBCommand.Prepare();
            DBCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;
            MySqlDataReader DBReader = DBCommand.ExecuteReader();

            int i = -1;
            int Balance = 0;
            while (DBReader.Read())
            {
                i += 1;
                Balance = DBReader.GetInt32("Balance");
            }

            if (i <= -1)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản không tồn tại." }, Broadcast = new List<string>() { "Liên hệ Admin hoặc nạp Credit để tạo tài khoản." } };
            }
            else if (i >= 1)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản bị trùng." }, Broadcast = new List<string>() { "Báo cáo với Admin nếu có thể." } };
            }
            else
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Balance };
            }

            DBReader.Dispose();
            DBCommand.Dispose();
            DBConnection.Dispose();

            if (Result.Status == ResponseStatusType.Fail)
            {
                Result.Content = 0;
            }

            return Result;
        }
        public ResponseStruct GetBalance(string SeasonID, string BalanceType)
        {
            ResponseStruct Result;
            LauncherClientInformations aClient;

            string UserName = String.Empty;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Client" } };
            }
            else if (String.IsNullOrWhiteSpace(UserName = aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để sử dụng Shop." } };
            }
            else
            {
                if (BalanceType == "Standard Balance")
                {
                    string PlayerName;
                    if (IsAnUserPlayingOnTShock(UserName, out PlayerName))
                    {
                        ResponseStruct GetStandardBalanceResponse = GetStandardBalance(PlayerName);
                        if (GetStandardBalanceResponse.Status == ResponseStatusType.Done)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = GetStandardBalanceResponse.Content };
                        }
                        else if (GetStandardBalanceResponse.Status == ResponseStatusType.Fail)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = GetStandardBalanceResponse.Error, Broadcast = GetStandardBalanceResponse.Broadcast };
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Dữ liệu trả về không đúng định nghĩa." }, Broadcast = new List<string>() { "Báo cáo với Admin nếu có thể." } };
                        }
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Player không có trên Server." }, Broadcast = new List<string>() { "Player phải có mặt trong Server để lấy thông tin." } };
                    }
                }
                else if (BalanceType == "Premium Balance")
                {
                    ResponseStruct GetPremiumBalanceResponse = GetPremiumBalance(UserName);
                    if (GetPremiumBalanceResponse.Status == ResponseStatusType.Done)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = GetPremiumBalanceResponse.Content };
                    }
                    else if (GetPremiumBalanceResponse.Status == ResponseStatusType.Fail)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = GetPremiumBalanceResponse.Error, Broadcast = GetPremiumBalanceResponse.Broadcast };
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Dữ liệu trả về không đúng định nghĩa." }, Broadcast = new List<string>() { "Báo cáo với Admin nếu có thể." } };
                    }
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Loại Credit được yêu cầu không có định nghĩa." }, Broadcast = new List<string>() { "Sử dụng đúng loại Credit được cho phép." } };
                }
            }

            if (Result.Status == ResponseStatusType.Fail)
            {
                Result.Content = 0;
            }

            return Result;
        }
        public ResponseStruct GetAvailableLevelsForUpgrade(string SeasonID)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Launcher để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục sử dụng." } };
            }
            else
            {
                MySqlConnection DbConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DbConnection.Open();

                string SqlQuery = "SELECT COUNT(*) FROM shop_players_progress WHERE UserName=@UserName";
                MySqlCommand DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                DbCommand.Prepare();
                DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = aClient.UserName;

                int Count = Convert.ToInt32(DbCommand.ExecuteScalar());

                DbCommand.Dispose();

                if (Count == 1)
                {
                    SqlQuery = "SELECT * FROM shop_players_progress WHERE UserName=@UserName";
                    DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                    DbCommand.Prepare();
                    DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = aClient.UserName;

                    MySqlDataReader DbReader = DbCommand.ExecuteReader();

                    string CurrentLevel = null;

                    while (DbReader.Read())
                    {
                        if (!DbReader.IsDBNull(DbReader.GetOrdinal("CurrentLevel")))
                        {
                            CurrentLevel = DbReader.GetString("CurrentLevel");
                        }
                    }
                    DbReader.Dispose();
                    DbCommand.Dispose();

                    if (!String.IsNullOrWhiteSpace(CurrentLevel))
                    {
                        SqlQuery = "SELECT * FROM shop_levels_and_ranks WHERE ParentLevelName=@ParentLevelName";
                        DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                        DbCommand.Prepare();
                        DbCommand.Parameters.Add("@ParentLevelName", MySqlDbType.VarChar).Value = CurrentLevel;

                        DbReader = DbCommand.ExecuteReader();

                        List<ShopLevelInformations> ListOfLevels = new List<ShopLevelInformations>();

                        while (DbReader.Read())
                        {
                            ShopLevelInformations aLevel = new ShopLevelInformations() { LevelName = null, LevelFullName = null, Level = -1, ParentLevelName = null, TShockGroupName = null, StandardPrice = -1, PremiumPrice = -1 };

                            if (!DbReader.IsDBNull(DbReader.GetOrdinal("LevelName")))
                            {
                                aLevel.LevelName = DbReader.GetString("LevelName");
                            }

                            if (!DbReader.IsDBNull(DbReader.GetOrdinal("LevelFullName")))
                            {
                                aLevel.LevelFullName = DbReader.GetString("LevelFullName");
                            }

                            if (!DbReader.IsDBNull(DbReader.GetOrdinal("Level")))
                            {
                                aLevel.Level = DbReader.GetInt32("Level");
                            }

                            if (!DbReader.IsDBNull(DbReader.GetOrdinal("ParentLevelName")))
                            {
                                aLevel.ParentLevelName = DbReader.GetString("ParentLevelName");
                            }

                            if (!DbReader.IsDBNull(DbReader.GetOrdinal("TShockGroupName")))
                            {
                                aLevel.TShockGroupName = DbReader.GetString("TShockGroupName");
                            }

                            if (!DbReader.IsDBNull(DbReader.GetOrdinal("StandardPrice")))
                            {
                                aLevel.StandardPrice = DbReader.GetInt32("StandardPrice");
                            }

                            if (!DbReader.IsDBNull(DbReader.GetOrdinal("PremiumPrice")))
                            {
                                aLevel.PremiumPrice = DbReader.GetInt32("PremiumPrice");
                            }

                            ListOfLevels.Add(aLevel);
                        }
                        DbReader.Dispose();
                        DbCommand.Dispose();

                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(ListOfLevels) };
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                    }
                }
                else if (Count == 0)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Người chơi phải chọn class để có thể nâng cấp độ theo class đó." } };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                }

                DbConnection.Dispose();
            }

            return Result;
        }
        // Just get price.
        public ResponseStruct GetAnEvent(string SeasonID, string EventName)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Launcher." } };
            }
            else if (string.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục sử dụng." } };
            }
            else if (string.IsNullOrWhiteSpace(EventName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tên event không hợp lệ." }, Broadcast = new List<string>() { "Chọn event được cung cấp để tiếp tục." } };
            }
            else
            {
                MySqlConnection DbConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DbConnection.Open();

                string SqlQuery = "SELECT * FROM shop_events WHERE EventName=@EventName";
                MySqlCommand DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                DbCommand.Prepare();
                DbCommand.Parameters.Add("@EventName", MySqlDbType.String).Value = EventName;

                MySqlDataReader DbReader = DbCommand.ExecuteReader();

                List<int> EventPrice = new List<int>(2) { -1, -1 };
                int Counter = 0;

                while (DbReader.Read())
                {
                    Counter++;
                    if (!DbReader.IsDBNull(DbReader.GetOrdinal("StandardPrice")))
                    {
                        EventPrice[0] = DbReader.GetInt32("StandardPrice");
                    }

                    if (!DbReader.IsDBNull(DbReader.GetOrdinal("PremiumPrice")))
                    {
                        EventPrice[1] = DbReader.GetInt32("PremiumPrice");
                    }
                }

                if (Counter == 0)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy event với tên được cung cấp." } };
                }
                else if (Counter != 1)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu, báo với Admin nếu có thể." } };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(EventPrice) };
                }

                DbReader.Dispose();
                DbCommand.Dispose();
                DbConnection.Dispose();
            }
            return Result;
        }
        public ResponseStruct GetALevel(string SeasonID, string LevelName)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Launcher để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(LevelName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Level không hợp lệ." }, Broadcast = new List<string>() { "Sử dụng level được cung cấp sẵn trong danh sách." } };
            }
            else
            {
                ShopLevelInformations aLevel;
                if (GetInformationsAboutALevel(LevelName, out aLevel))
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(aLevel) };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy level theo yêu cầu." }, Broadcast = new List<string>() { "Dùng tên level hợp lệ để có thể lấy được thông tin." } };
                }
            }

            return Result;
        }
        public ResponseStruct ChangeCurreny(string SeasonID, string ChangeType, string AmountString)
        {
            ResponseStruct Result;
            LauncherClientInformations aClient;
            long Amount;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Đăng nhập để tiếp tục" } };
            }
            else if (!long.TryParse(AmountString, out Amount))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lượng Credit chuyển đổi không hợp lệ." }, Broadcast = new List<string>() { "Lượng Credit phải là dạng số." } };
            }
            else if (Amount <= 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lượng Credit phải là số dương." }, Broadcast = new List<string>() { "Điều chỉnh lượng Credit phù hợp để tiếp tục." } };
            }
            else
            {
                string UserName = aClient.UserName;
                string PlayerName;

                if (IsAnUserPlayingOnTShock(UserName, out PlayerName))
                {
                    if (ChangeType == "Premium Balance to Standard Balance")
                    {
                        long Balance;
                        if (!long.TryParse(Convert.ToString(GetBalance(SeasonID, "Premium Balance").Content), out Balance))
                        {
                            Balance = 0;
                        }
                        if (Amount > Balance)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lượng Credit chuyển đối lớn hơn số dư trong tài khoản." }, Broadcast = new List<string>() { "Điều chỉnh lượng Credit phù hợp." } };
                        }
                        else
                        {
                            long CalcStandardAmount = Amount * MarketInfo.RatioPremiumVsStandard;
                            string ResponseIn;
                            if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "AddPlayerBalance", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { PlayerName, CalcStandardAmount.ToString(), "Transfer from Premium Balance." } }, out ResponseIn))
                            {
                                ResponseStruct ResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(ResponseIn);
                                if (ResponseContent.Status == ResponseStatusType.Done)
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("{0}:{1} vừa chuyển {2} Credits Premium Balance sang {3} Standard Balance.", UserName, PlayerName, String.Format(CultureInfo.InvariantCulture, "{0:#,#0}", Amount), String.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcStandardAmount)) } };

                                    MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                                    DBConnection.Open();
                                    string SQLQuery = "UPDATE shop_accounts SET Balance=@Balance WHERE UserName=@UserName";
                                    MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                                    DBCommand.Prepare();
                                    DBCommand.Parameters.Add("@Balance", MySqlDbType.Int32).Value = int.Parse((Balance - Amount).ToString());
                                    DBCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = aClient.UserName;
                                    DBCommand.ExecuteNonQuery();
                                    DBCommand.Dispose();
                                    DBConnection.Dispose();

                                    LogWriter(UserName, "Change Currency", String.Join("\n", Result.Broadcast));
                                }
                                else
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = ResponseContent.Error, Broadcast = new List<string>() { } };
                                }
                            }
                            else
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng." }, Broadcast = new List<string>() { "Báo cáo cho Admin nếu có thể." } };
                            }
                        }
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Kiểu chuyển đổi không được định nghĩa." }, Broadcast = new List<string>() { "Sử dụng kiểu chuyển đổi được định nghĩa sẵn." } };
                    }
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Player trong Server." }, Broadcast = new List<string>() { "Player phải ở trong Server để có thể chuyển đổi Credit." } };
                }
            }

            return Result;
        }
        public ResponseStruct ChangeClass(string SeasonID, string ClassToChange, string BalanceType)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Đăng nhập để có thể tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(ClassToChange))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Class muốn thay đổi không hợp lệ." }, Broadcast = new List<string>() { "Sử dụng class được cung cấp trong danh sách có sẵn." } };
            }
            else
            {
                string UserName = aClient.UserName;

                MySqlConnection DbConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DbConnection.Open();

                string SqlQuery = "SELECT COUNT(*) FROM shop_players_progress WHERE UserName=@UserName";
                MySqlCommand DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                DbCommand.Prepare();
                DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                int Count = Convert.ToInt32(DbCommand.ExecuteScalar());
                DbCommand.Dispose();

                if (Count == 1)
                {
                    SqlQuery = "SELECT * FROM shop_players_progress WHERE UserName=@UserName";
                    DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                    DbCommand.Prepare();
                    DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                    MySqlDataReader DbReader = DbCommand.ExecuteReader();

                    string CurrentClass = null;
                    string CurrentLevel = null;

                    while (DbReader.Read())
                    {
                        if (!DbReader.IsDBNull(DbReader.GetOrdinal("CurrentClass")))
                        {
                            CurrentClass = DbReader.GetString("CurrentClass");
                        }

                        if (!DbReader.IsDBNull(DbReader.GetOrdinal("CurrentLevel")))
                        {
                            CurrentLevel = DbReader.GetString("CurrentLevel");
                        }
                    }
                    DbReader.Dispose();
                    DbCommand.Dispose();

                    if (!(String.IsNullOrWhiteSpace(CurrentClass) || String.IsNullOrWhiteSpace(CurrentLevel)))
                    {
                        SqlQuery = "SELECT COUNT(*) FROM shop_levels_and_ranks WHERE LevelName=@LevelName";
                        DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                        DbCommand.Prepare();
                        DbCommand.Parameters.Add("@LevelName", MySqlDbType.VarChar).Value = CurrentLevel;

                        Count = Convert.ToInt32(DbCommand.ExecuteScalar());
                        DbCommand.Dispose();

                        if (Count == 1)
                        {
                            SqlQuery = "SELECT Level FROM shop_levels_and_ranks WHERE LevelName=@LevelName";
                            DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                            DbCommand.Prepare();
                            DbCommand.Parameters.Add("@LevelName", MySqlDbType.VarChar).Value = CurrentLevel;

                            DbReader = DbCommand.ExecuteReader();

                            int CurrentLevelNumber = -1;
                            while (DbReader.Read())
                            {
                                if (!DbReader.IsDBNull(DbReader.GetOrdinal("Level")))
                                {
                                    CurrentLevelNumber = DbReader.GetInt32("Level");
                                }
                            }
                            DbReader.Dispose();
                            DbCommand.Dispose();

                            if (CurrentLevelNumber != -1)
                            {
                                SqlQuery = "SELECT COUNT(*) FROM shop_classes WHERE ClassName=@ClassName";
                                DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                DbCommand.Prepare();
                                DbCommand.Parameters.Add("@ClassName", MySqlDbType.VarChar).Value = ClassToChange;

                                Count = Convert.ToInt32(DbCommand.ExecuteScalar());
                                DbCommand.Dispose();

                                if (Count == 1)
                                {
                                    SqlQuery = "SELECT Change_StandardPrice,Change_PremiumPrice FROM shop_classes WHERE ClassName=@ClassName";
                                    DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                    DbCommand.Prepare();
                                    DbCommand.Parameters.Add("@ClassName", MySqlDbType.VarChar).Value = ClassToChange;

                                    DbReader = DbCommand.ExecuteReader();

                                    int StandardPrice = -1;
                                    int PremiumPrice = -1;

                                    while (DbReader.Read())
                                    {
                                        if (!DbReader.IsDBNull(DbReader.GetOrdinal("Change_StandardPrice")))
                                        {
                                            StandardPrice = DbReader.GetInt32("Change_StandardPrice");
                                        }

                                        if (!DbReader.IsDBNull(DbReader.GetOrdinal("Change_PremiumPrice")))
                                        {
                                            PremiumPrice = DbReader.GetInt32("Change_PremiumPrice");
                                        }
                                    }
                                    DbReader.Dispose();
                                    DbCommand.Dispose();

                                    if (CurrentClass != ClassToChange)
                                    {
                                        if (StandardPrice == -1 && BalanceType == "Standard Balance")
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể chuyển sang class này bằng Standard Balance." } };
                                        }
                                        else if (PremiumPrice == -1 && BalanceType == "Premium Balance")
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể chuyển sang class này bằng Premium Balance." } };
                                        }
                                        else
                                        {
                                            string LevelToChange = ClassToChange + "." + CurrentLevelNumber;
                                            SqlQuery = "SELECT COUNT(*) FROM shop_levels_and_ranks WHERE LevelName=@LevelName";
                                            DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                            DbCommand.Prepare();
                                            DbCommand.Parameters.Add("@LevelName", MySqlDbType.VarChar).Value = LevelToChange;

                                            Count = Convert.ToInt32(DbCommand.ExecuteScalar());
                                            DbCommand.Dispose();

                                            if (Count == 1)
                                            {
                                                SqlQuery = "SELECT TShockGroupName FROM shop_levels_and_ranks WHERE LevelName=@LevelName";
                                                DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                                DbCommand.Prepare();
                                                DbCommand.Parameters.Add("@LevelName", MySqlDbType.VarChar).Value = LevelToChange;

                                                DbReader = DbCommand.ExecuteReader();

                                                string TShockGroupNameToChange = null;
                                                while (DbReader.Read())
                                                {
                                                    if (!DbReader.IsDBNull(DbReader.GetOrdinal("TShockGroupName")))
                                                    {
                                                        TShockGroupNameToChange = DbReader.GetString("TShockGroupName");
                                                    }
                                                }
                                                DbReader.Dispose();
                                                DbCommand.Dispose();

                                                if (TShockGroupNameToChange != null)
                                                {
                                                    if (BalanceType == "Standard Balance")
                                                    {
                                                        long Balance;
                                                        if (!Int64.TryParse(Convert.ToString(GetBalance(aClient.SeasonID, "Standard Balance").Content), out Balance))
                                                        {
                                                            Balance = 0;
                                                        }
                                                        long CalcPrice = StandardPrice * CurrentLevelNumber;
                                                        if (CalcPrice > Balance)
                                                        {
                                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Standard Balance không đủ để có thể chuyển class." }, Broadcast = new List<string>() { String.Format("Cần {0} Credit{1} để chuyển từ {2} sang {3}.", CalcPrice, CalcPrice > 1 ? "s" : String.Empty, CurrentClass, ClassToChange) } };
                                                        }
                                                        else
                                                        {
                                                            string ChangeGroupResonseString;
                                                            if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "ChangeUserGroup", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { UserName, TShockGroupNameToChange } }, out ChangeGroupResonseString))
                                                            {
                                                                ResponseStruct ChangeGroupResult = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(ChangeGroupResonseString);
                                                                if (ChangeGroupResult.Status == ResponseStatusType.Done)
                                                                {
                                                                    SqlQuery = "UPDATE shop_players_progress SET CurrentClass=@CurrentClass,CurrentLevel=@CurrentLevel WHERE UserName=@UserName";
                                                                    DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                                                    DbCommand.Prepare();
                                                                    DbCommand.Parameters.Add("@CurrentClass", MySqlDbType.VarChar).Value = ClassToChange;
                                                                    DbCommand.Parameters.Add("@CurrentLevel", MySqlDbType.VarChar).Value = LevelToChange;
                                                                    DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                                                                    DbCommand.ExecuteNonQuery();
                                                                    DbCommand.Dispose();

                                                                    string SubtractPlayerResponse;
                                                                    if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "SubtractPlayerBalance", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { UserName, Convert.ToString(CalcPrice), String.Format("Change class from {0} to {1}.", CurrentClass, ClassToChange) } }, out SubtractPlayerResponse))
                                                                    {
                                                                        ResponseStruct SubtractResult = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(SubtractPlayerResponse);
                                                                        if (SubtractResult.Status == ResponseStatusType.Done)
                                                                        {
                                                                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Error = new List<string>() { }, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa chuyển class từ {1} sang {2}.\nChi phí: {3} Credit{4} {5}.", UserName, CurrentClass, ClassToChange, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), CalcPrice > 1 ? "s" : String.Empty, BalanceType) } };
                                                                            LogWriter(UserName: UserName, Task: "Change Class - Standard Balance", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                                        }
                                                                        else if (SubtractResult.Status == ResponseStatusType.Fail)
                                                                        {
                                                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể trừ tài khoản SEconomy của User." }, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa chuyển class từ {1} sang {2}.\nChi phí: {3} Credit{4} {5}.", UserName, CurrentClass, ClassToChange, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), CalcPrice > 1 ? "s" : String.Empty, BalanceType) } };
                                                                            LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                                        }
                                                                        else
                                                                        {
                                                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ dữ liệu trả về từ TShock Server." }, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa chuyển class từ {1} sang {2}.\nChi phí: {3} Credit{4} {5}.", UserName, CurrentClass, ClassToChange, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), CalcPrice > 1 ? "s" : String.Empty, BalanceType) } };
                                                                            LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                                        }
                                                                    }
                                                                    else
                                                                    {
                                                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng yêu cầu." }, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa chuyển class từ {1} sang {2}.\nChi phí: {3} Credit{4} {5}.", UserName, CurrentClass, ClassToChange, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), CalcPrice > 1 ? "s" : String.Empty, BalanceType) } };
                                                                        LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                                    }
                                                                }
                                                                else if (ChangeGroupResult.Status == ResponseStatusType.Fail)
                                                                {
                                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = ChangeGroupResult.Error, Broadcast = ChangeGroupResult.Broadcast };
                                                                }
                                                                else
                                                                {
                                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ kết quả trả về từ TShock Server." } };
                                                                }
                                                            }
                                                            else
                                                            {
                                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng." } };
                                                            }
                                                        }
                                                    }
                                                    else if (BalanceType == "Premium Balance")
                                                    {
                                                        long Balance;
                                                        if (!Int64.TryParse(Convert.ToString(GetBalance(aClient.SeasonID, "Premium Balance").Content), out Balance))
                                                        {
                                                            Balance = 0;
                                                        }
                                                        long CalcPrice = PremiumPrice * CurrentLevelNumber;
                                                        if (CalcPrice > Balance)
                                                        {
                                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Premium Balance không đủ để có thể chuyển class." }, Broadcast = new List<string>() { String.Format("Cần {0} Credit{1} để chuyển từ {2} sang {3}.", CalcPrice, CalcPrice > 1 ? "s" : String.Empty, CurrentClass, ClassToChange) } };
                                                        }
                                                        else
                                                        {
                                                            string ChangeGroupResonseString;
                                                            if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "ChangeUserGroup", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { UserName, TShockGroupNameToChange } }, out ChangeGroupResonseString))
                                                            {
                                                                ResponseStruct ChangeGroupResult = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(ChangeGroupResonseString);
                                                                if (ChangeGroupResult.Status == ResponseStatusType.Done)
                                                                {
                                                                    SqlQuery = "UPDATE shop_players_progress SET CurrentClass=@CurrentClass,CurrentLevel=@CurrentLevel WHERE UserName=@UserName";
                                                                    DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                                                    DbCommand.Prepare();
                                                                    DbCommand.Parameters.Add("@CurrentClass", MySqlDbType.VarChar).Value = ClassToChange;
                                                                    DbCommand.Parameters.Add("@CurrentLevel", MySqlDbType.VarChar).Value = LevelToChange;
                                                                    DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                                                                    DbCommand.ExecuteNonQuery();
                                                                    DbCommand.Dispose();

                                                                    SqlQuery = "UPDATE shop_accounts SET Balance=@Balance WHERE UserName=@UserName";
                                                                    DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                                                    DbCommand.Prepare();
                                                                    DbCommand.Parameters.Add("@Balance", MySqlDbType.Int32).Value = int.Parse((Balance - CalcPrice).ToString());
                                                                    DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                                                                    DbCommand.ExecuteNonQuery();
                                                                    DbCommand.Dispose();

                                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa chuyển class từ {1} sang {2}.\nChi phí: {3} Credit{4} {5}.", UserName, CurrentClass, ClassToChange, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", CalcPrice), CalcPrice > 1 ? "s" : String.Empty, BalanceType) } };
                                                                    LogWriter(UserName, "Change Class - Premium Balance", String.Join("\n", Result.Broadcast));
                                                                }
                                                                else if (ChangeGroupResult.Status == ResponseStatusType.Fail)
                                                                {
                                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = ChangeGroupResult.Error, Broadcast = ChangeGroupResult.Broadcast };
                                                                }
                                                                else
                                                                {
                                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ kết quả trả về từ TShock Server." } };
                                                                }
                                                            }
                                                            else
                                                            {
                                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng." } };
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoàn thanh toán không hợp lệ." }, Broadcast = new List<string>() { "Sử dụng tài khoàn để thanh toán trong danh sách có sẵn." } };
                                                    }
                                                }
                                                else
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                                                }
                                            }
                                            else if (Count == 0)
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                                            }
                                            else
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Class định chuyển trùng với class đang dùng." }, Broadcast = new List<string>() { "Chọn một class phù hợp để tiếp tục." } };
                                    }
                                }
                                else if (Count == 0)
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Class muốn chuyển không tồn tại." }, Broadcast = new List<string>() { "Sử dụng class được cung cấp sẵn trong danh sách." } };
                                }
                                else
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                                }
                            }
                            else
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                            }
                        }
                        else if (Count == 0)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                        }
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                    }
                }
                else if (Count == 0)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản chưa chọn class." }, Broadcast = new List<string>() { "Tài khoản phải đang theo một class nào đó để có thể sử dụng chức năng chuyển class." } };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                }
                DbConnection.Dispose();
            }
            return Result;
        }
        public ResponseStruct Login(string SeasonID, string UserName, string Password)
        {
            ResponseStruct Result;
            #region Lấy danh sách bản ghi có User Name theo yêu cầu trong tshock\users.

            MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TShockDBConnectionString);
            DBConnection.Open();

            string SQLQuery = "SELECT Username,Password FROM users WHERE Username=@UserName";
            MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
            DBCommand.Prepare();
            DBCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;
            MySqlDataReader DBReader = DBCommand.ExecuteReader();

            List<TShockUserInformations> TShockUserList = new List<TShockUserInformations>();

            while (DBReader.Read())
            {
                TShockUserInformations TShockUserInstance = new TShockUserInformations();
                if (!DBReader.IsDBNull(DBReader.GetOrdinal("Username")))
                {
                    TShockUserInstance.UserName = DBReader.GetString("Username");
                }
                if (!DBReader.IsDBNull(DBReader.GetOrdinal("Password")))
                {
                    TShockUserInstance.Password = DBReader.GetString("Password");
                }
                TShockUserList.Add(TShockUserInstance);
            }

            DBReader.Dispose();
            DBCommand.Dispose();
            DBConnection.Dispose();
            #endregion
            #region Kiểm tra điều kiện.
            LauncherClientInformations aClient;

            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Season ID." }, Broadcast = new List<string>() { "Khởi động lại Launcher Client." } };
            }
            else if (UserName == "")
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "'User Name' trống rỗng." }, Broadcast = new List<string>() { "'User Name' không được phép để trống, nhập đầy đủ thông tin để tiếp tục." } };
            }
            else if (UserName.Length > 32)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tên tài khoản quá dài." }, Broadcast = new List<string>() { "Nhập tên tài khoản với độ dài không quá 32 kí tự." } };
            }
            else if (TShockUserList.Count == 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản không tồn tại." }, Broadcast = new List<string>() { "Tạo tài khoản để có thể bắt đầu chơi." } };
            }
            else if (TShockUserList.Count > 1)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản bị trùng." }, Broadcast = new List<string>() { "Liên hệ Admin để xử lí." } };
            }
            else if (Password == "")
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Mật khẩu trống rỗng." }, Broadcast = new List<string>() { "Nhập mật mã đầy đủ." } };
            }
            else if (IsAnUserLoggedOnLauncherServer(UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Phát hiện tài khoản đang có mặt trên hệ thống." }, Broadcast = new List<string>() { "Không dùng đăng nhập trên hai nơi khác nhau." } };
            }
            else
            {
                if (BCrypt.Net.BCrypt.Verify(Password, TShockUserList[0].Password))
                {
                    if (OverallInformations.Clients.TryUpdate(SeasonID, new LauncherClientInformations { SeasonID = aClient.SeasonID, UserName = UserName, Password = Password, TheFirstQueueName = aClient.TheFirstQueueName }, aClient))
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Đăng nhập thành công.", "Chào mừng bạn trở lại với Terraria Việt Nam." } };
                        LauncherServer.OutputMessage(String.Format("[Client]: {0} has logged in.", UserName), LauncherServer.MessageType.Success);
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Thông tin đăng nhập vừa bị thay đổi." }, Broadcast = new List<string>() { "Thử đăng nhập lại một lần nữa." } };
                    }
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Mật mã không chính xác." }, Broadcast = new List<string>() { "Nhập lại mật mã nếu có sai sót.", "Liên hệ Admin nếu quên mật mã." } };
                }
                #endregion
            }
            return Result;
        }
        public ResponseStruct UpgradeLevel(string SeasonID, string LevelName, string BalanceType)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Launcher để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(LevelName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Level không hợp lệ." }, Broadcast = new List<string>() { "Sử dụng level được cung cấp trong danh sách." } };
            }
            else
            {
                string UserName = aClient.UserName;

                MySqlConnection DbConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DbConnection.Open();

                string SqlQuery = "SELECT COUNT(*) FROM shop_players_progress WHERE UserName=@UserName";
                MySqlCommand DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                DbCommand.Prepare();
                DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                int Count = Convert.ToInt32(DbCommand.ExecuteScalar());

                DbCommand.Dispose();

                if (Count == 1)
                {
                    SqlQuery = "SELECT * FROM shop_players_progress WHERE UserName=@UserName";
                    DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                    DbCommand.Prepare();
                    DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                    MySqlDataReader DbReader = DbCommand.ExecuteReader();

                    string CurrentLevel = null;

                    while (DbReader.Read())
                    {
                        if (!DbReader.IsDBNull(DbReader.GetOrdinal("CurrentLevel")))
                        {
                            CurrentLevel = DbReader.GetString("CurrentLevel");
                        }
                    }
                    DbReader.Dispose();
                    DbCommand.Dispose();

                    if (!String.IsNullOrWhiteSpace(CurrentLevel))
                    {
                        SqlQuery = "SELECT COUNT(*) FROM shop_levels_and_ranks WHERE ParentLevelName=@ParentLevelName AND LevelName=@LevelName";
                        DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                        DbCommand.Prepare();
                        DbCommand.Parameters.Add("@ParentLevelName", MySqlDbType.VarChar).Value = CurrentLevel;
                        DbCommand.Parameters.Add("@LevelName", MySqlDbType.VarChar).Value = LevelName;

                        Count = Convert.ToInt32(DbCommand.ExecuteScalar());
                        DbCommand.Dispose();

                        if (Count == 1)
                        {
                            SqlQuery = "SELECT * FROM shop_levels_and_ranks WHERE ParentLevelName=@ParentLevelName AND LevelName=@LevelName";
                            DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                            DbCommand.Prepare();
                            DbCommand.Parameters.Add("@ParentLevelName", MySqlDbType.VarChar).Value = CurrentLevel;
                            DbCommand.Parameters.Add("@LevelName", MySqlDbType.VarChar).Value = LevelName;

                            DbReader = DbCommand.ExecuteReader();

                            ShopLevelInformations NextLevel = new ShopLevelInformations() { LevelName = null, LevelFullName = null, Level = -1, ParentLevelName = null, TShockGroupName = null, StandardPrice = -1, PremiumPrice = -1 };
                            while (DbReader.Read())
                            {
                                if (!DbReader.IsDBNull(DbReader.GetOrdinal("LevelName")))
                                {
                                    NextLevel.LevelName = DbReader.GetString("LevelName");
                                }

                                if (!DbReader.IsDBNull(DbReader.GetOrdinal("LevelFullName")))
                                {
                                    NextLevel.LevelFullName = DbReader.GetString("LevelFullName");
                                }

                                if (!DbReader.IsDBNull(DbReader.GetOrdinal("Level")))
                                {
                                    NextLevel.Level = DbReader.GetInt32("Level");
                                }

                                if (!DbReader.IsDBNull(DbReader.GetOrdinal("ParentLevelName")))
                                {
                                    NextLevel.ParentLevelName = DbReader.GetString("ParentLevelName");
                                }

                                if (!DbReader.IsDBNull(DbReader.GetOrdinal("TShockGroupName")))
                                {
                                    NextLevel.TShockGroupName = DbReader.GetString("TShockGroupName");
                                }

                                if (!DbReader.IsDBNull(DbReader.GetOrdinal("StandardPrice")))
                                {
                                    NextLevel.StandardPrice = DbReader.GetInt32("StandardPrice");
                                }

                                if (!DbReader.IsDBNull(DbReader.GetOrdinal("PremiumPrice")))
                                {
                                    NextLevel.PremiumPrice = DbReader.GetInt32("PremiumPrice");
                                }
                            }
                            DbReader.Dispose();
                            DbCommand.Dispose();

                            if (NextLevel.StandardPrice == -1 && BalanceType == "Standard Balance")
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Level không sử dụng Standard Balance để nâng cấp." } };
                            }
                            else if (NextLevel.PremiumPrice == -1 && BalanceType == "Premium Balance")
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Level không sử dụng Premium Balance để nâng cấp." } };
                            }
                            else if (String.IsNullOrWhiteSpace(NextLevel.TShockGroupName))
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Group không hợp lệ." }, Broadcast = new List<string>() { "Báo cho Admin level và lỗi này nếu có thể." } };
                            }
                            else
                            {
                                if (BalanceType == "Standard Balance")
                                {
                                    long Balance;
                                    if (!Int64.TryParse(Convert.ToString(GetBalance(aClient.SeasonID, "Standard Balance").Content), out Balance))
                                    {
                                        Balance = 0;
                                    }

                                    if (NextLevel.StandardPrice > Balance)
                                    {
                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Standard Balance không đủ để có thể nâng cấp." }, Broadcast = new List<string>() { "-_-" } };
                                    }
                                    else
                                    {
                                        string ChangeGroupResonseString;
                                        if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "ChangeUserGroup", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { UserName, NextLevel.TShockGroupName } }, out ChangeGroupResonseString))
                                        {
                                            ResponseStruct ChangeGroupResult = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(ChangeGroupResonseString);
                                            if (ChangeGroupResult.Status == ResponseStatusType.Done)
                                            {
                                                SqlQuery = "UPDATE shop_players_progress SET CurrentLevel=@NextLevel WHERE UserName=@UserName";
                                                DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                                DbCommand.Prepare();
                                                DbCommand.Parameters.Add("@NextLevel", MySqlDbType.VarChar).Value = NextLevel.LevelName;
                                                DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                                                DbCommand.ExecuteNonQuery();
                                                DbCommand.Dispose();

                                                string SubtractPlayerResponse;
                                                if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "SubtractPlayerBalance", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { UserName, Convert.ToString(NextLevel.StandardPrice), String.Format("Upgrade to {0}.", NextLevel.LevelFullName) } }, out SubtractPlayerResponse))
                                                {
                                                    ResponseStruct SubtractResult = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(SubtractPlayerResponse);
                                                    if (SubtractResult.Status == ResponseStatusType.Done)
                                                    {
                                                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Error = new List<string>() { }, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa nâng cấp lên {1}.\nChi phí: {2} Credits {3}.", UserName, NextLevel.LevelFullName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", NextLevel.StandardPrice), BalanceType) } };
                                                        LogWriter(UserName: UserName, Task: "Upgrade Level - Standard Balance", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                    }
                                                    else if (SubtractResult.Status == ResponseStatusType.Fail)
                                                    {
                                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể trừ tài khoản SEconomy của User." }, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa nâng cấp lên {1}.\nChi phí: {2} Credits {3}.", UserName, NextLevel.LevelFullName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", NextLevel.StandardPrice), BalanceType) } };
                                                        LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                    }
                                                    else
                                                    {
                                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ dữ liệu trả về từ TShock Server." }, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa nâng cấp lên {1}.\nChi phí: {2} Credits {3}.", UserName, NextLevel.LevelFullName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", NextLevel.StandardPrice), BalanceType) } };
                                                        LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                    }
                                                }
                                                else
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng yêu cầu." }, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa nâng cấp lên {1}.\nChi phí: {2} Credits {3}.", UserName, NextLevel.LevelFullName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", NextLevel.StandardPrice), BalanceType) } };
                                                    LogWriter(UserName: UserName, Task: "Pending Transaction", Details: String.Join("\n", String.Join("\n", Result.Error), String.Join("\n", Result.Broadcast)));
                                                }
                                            }
                                            else if (ChangeGroupResult.Status == ResponseStatusType.Fail)
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = ChangeGroupResult.Error, Broadcast = ChangeGroupResult.Broadcast };
                                            }
                                            else
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ kết quả trả về từ TShock Server." } };
                                            }
                                        }
                                        else
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng." } };
                                        }
                                    }
                                }
                                else if (BalanceType == "Premium Balance")
                                {
                                    long Balance;
                                    if (!Int64.TryParse(Convert.ToString(GetBalance(aClient.SeasonID, "Premium Balance").Content), out Balance))
                                    {
                                        Balance = 0;
                                    }

                                    if (NextLevel.PremiumPrice > Balance)
                                    {
                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Premium Balance không đủ để có thể nâng cấp." }, Broadcast = new List<string>() { "-_-" } };
                                    }
                                    else
                                    {
                                        string ChangeGroupResonseString;
                                        if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "ChangeUserGroup", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { UserName, NextLevel.TShockGroupName } }, out ChangeGroupResonseString))
                                        {
                                            ResponseStruct ChangeGroupResult = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(ChangeGroupResonseString);
                                            if (ChangeGroupResult.Status == ResponseStatusType.Done)
                                            {
                                                SqlQuery = "UPDATE shop_players_progress SET CurrentLevel=@NextLevel WHERE UserName=@UserName";
                                                DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                                DbCommand.Prepare();
                                                DbCommand.Parameters.Add("@NextLevel", MySqlDbType.VarChar).Value = NextLevel.LevelName;
                                                DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                                                DbCommand.ExecuteNonQuery();
                                                DbCommand.Dispose();

                                                SqlQuery = "UPDATE shop_accounts SET Balance=@Balance WHERE UserName=@UserName";
                                                DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                                DbCommand.Prepare();
                                                DbCommand.Parameters.Add("@Balance", MySqlDbType.Int32).Value = int.Parse((Balance - NextLevel.PremiumPrice).ToString());
                                                DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = UserName;

                                                DbCommand.ExecuteNonQuery();
                                                DbCommand.Dispose();

                                                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("Tài khoản \"{0}\" vừa nâng cấp lên {1}.\nChi phí: {2} Credits {3}.", UserName, NextLevel.LevelFullName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", NextLevel.PremiumPrice), BalanceType) } };
                                                LogWriter(UserName, "Upgrade Level - Premium Balance", String.Join("\n", Result.Broadcast));
                                            }
                                            else if (ChangeGroupResult.Status == ResponseStatusType.Fail)
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = ChangeGroupResult.Error, Broadcast = ChangeGroupResult.Broadcast };
                                            }
                                            else
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ kết quả trả về từ TShock Server." } };
                                            }
                                        }
                                        else
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng." } };
                                        }
                                    }
                                }
                                else
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản thanh toán không hợp lệ." }, Broadcast = new List<string>() { "Chọn tài khoản để thanh toán theo danh sách có sẵn." } };
                                }
                            }
                        }
                        else if (Count == 0)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Level được yêu cầu không hợp lệ." }, Broadcast = new List<string>() { "Cung cấp level hợp lệ để tiếp tục." } };
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Thông báo cho Admin nếu có thể." } };
                        }
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                    }
                }
                else if (Count == 0)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Người chơi phải chọn class để có thể nâng cấp độ theo class đó." } };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu, thông báo cho Admin nếu có thể." } };
                }

                DbConnection.Dispose();
            }

            return Result;
        }
        public ResponseStruct BuyEvent(string SeasonID, string EventName, string BalanceType, string WaveString = "1")
        {
            ResponseStruct Result;
            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Launcher." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(EventName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tên event không hợp lệ." }, Broadcast = new List<string>() { "Sử dụng event được cung cấp sẵn trong danh sách." } };
            }
            else
            {
                switch (EventName)
                {
                    case "Blood Moon":
                    case "Goblin Army":
                    case "Rain":
                    case "Slime Rain":
                    case "Frost Legion":
                    case "Solar Eclipse":
                    case "Pirate Invasion":
                    case "Pumpkin Moon":
                    case "Frost Moon":
                    case "Martian Madness":
                        string UserName = aClient.UserName;
                        string PlayerName;

                        if (IsAnUserPlayingOnTShock(UserName, out PlayerName))
                        {
                            MySqlConnection DbConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                            DbConnection.Open();

                            string SqlQuery = "SELECT COUNT(*) FROM shop_events WHERE EventName=@EventName";
                            MySqlCommand DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                            DbCommand.Prepare();
                            DbCommand.Parameters.Add("@EventName", MySqlDbType.Text).Value = EventName;

                            int Count = Convert.ToInt32(DbCommand.ExecuteScalar());
                            DbCommand.Dispose();

                            if (Count == 1)
                            {
                                string SQLQuery = "SELECT * FROM shop_events WHERE EventName=@EventName";
                                DbCommand = new MySqlCommand(SQLQuery, DbConnection);
                                DbCommand.Prepare();
                                DbCommand.Parameters.Add("@EventName", MySqlDbType.Text).Value = EventName;
                                MySqlDataReader DbReader = DbCommand.ExecuteReader();

                                int StandardPrice = -1;
                                int PremiumPrice = -1;

                                while (DbReader.Read())
                                {
                                    if (!DbReader.IsDBNull(DbReader.GetOrdinal("StandardPrice")))
                                    {
                                        StandardPrice = DbReader.GetInt32("StandardPrice");
                                    }
                                    if (!DbReader.IsDBNull(DbReader.GetOrdinal("PremiumPrice")))
                                    {
                                        PremiumPrice = DbReader.GetInt32("PremiumPrice");
                                    }
                                }
                                DbReader.Dispose();
                                DbCommand.Dispose();

                                #region Check Wave Number
                                int Wave = 1;
                                if (!int.TryParse(WaveString, out Wave))
                                {
                                    Wave = 1;
                                }

                                if (Wave < 1)
                                {
                                    Wave = 1;
                                }

                                if (EventName == "Pumpkin Moon")
                                {
                                    if (Wave > 15)
                                    {
                                        Wave = 15;
                                    }
                                }
                                else if (EventName == "Frost Moon")
                                {
                                    if (Wave > 20)
                                    {
                                        Wave = 20;
                                    }
                                }
                                else
                                {
                                    Wave = 1;
                                }
                                #endregion

                                #region Pay with Standard Balance
                                if (BalanceType == "Standard Balance")
                                {
                                    if (StandardPrice != -1)
                                    {
                                        long Balance;
                                        if (!Int64.TryParse(Convert.ToString(GetBalance(aClient.SeasonID, "Standard Balance").Content), out Balance))
                                        {
                                            Balance = 0;
                                        }

                                        if ((StandardPrice = StandardPrice + (Wave - 1) * 1000000) <= Balance)
                                        {
                                            string StartEventResponse;
                                            if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "StartEvent", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { EventName, Convert.ToString(Wave), PlayerName } }, out StartEventResponse))
                                            {
                                                ResponseStruct StartEventResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(StartEventResponse);
                                                if (StartEventResponseContent.Status == ResponseStatusType.Done)
                                                {
                                                    string SubtractPlayerResponse;
                                                    if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "SubtractPlayerBalance", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { PlayerName, Convert.ToString(StandardPrice), String.Format("Buy {0}.", EventName) } }, out SubtractPlayerResponse))
                                                    {
                                                        ResponseStruct SubtractPlayerResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(SubtractPlayerResponse);
                                                        if (SubtractPlayerResponseContent.Status == ResponseStatusType.Done)
                                                        {
                                                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2}.\nChi phí: {3} Credits {4}.", UserName, PlayerName, EventName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", StandardPrice), BalanceType) } };
                                                            LogWriter(UserName, "Buy Event - Standard Balance", string.Join("\n", Result.Broadcast));
                                                        }
                                                        else if (SubtractPlayerResponseContent.Status == ResponseStatusType.Fail)
                                                        {
                                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = SubtractPlayerResponseContent.Error, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2}.\nChi phí: {3} Credits {4}.", UserName, PlayerName, EventName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", StandardPrice), BalanceType) } };
                                                            LogWriter(UserName, "Pending Transaction", string.Join("\n", string.Join("\n", Result.Error), string.Join("\n", Result.Broadcast)));
                                                        }
                                                        else
                                                        {
                                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ dữ liệu trả về." }, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2}.\nChi phí: {3} Credits {4}.", UserName, PlayerName, EventName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", StandardPrice), BalanceType) } };
                                                            LogWriter(UserName, "Pending Transaction", string.Join("\n", string.Join("\n", Result.Error), string.Join("\n", Result.Broadcast)));
                                                        }
                                                    }
                                                    else
                                                    {
                                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể đáp ứng yêu cầu." }, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2}.\nChi phí: {3} Credits {4}.", UserName, PlayerName, EventName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", StandardPrice), BalanceType) } };
                                                        LogWriter(UserName, "Pending Transaction", string.Join("\n", string.Join("\n", Result.Error), string.Join("\n", Result.Broadcast)));
                                                    }
                                                }
                                                else if (StartEventResponseContent.Status == ResponseStatusType.Fail)
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = StartEventResponseContent.Error, Broadcast = StartEventResponseContent.Broadcast };
                                                }
                                                else
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ kết quả trả về từ TShock." }, Broadcast = new List<string>() { "Thử lại hoặc báo cáo với Admin nếu có thể." } };
                                                }
                                            }
                                            else
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Yêu cầu không thể đáp ứng tại thời điểm này" }, Broadcast = new List<string>() { "Thử lại hoặc báo cáo với Admin nếu có thể." } };
                                            }
                                        }
                                        else
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản không đủ Credit." } };
                                        }
                                    }
                                    else
                                    {
                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Event không thể mua bằng Standard Balance." } };
                                    }
                                }
                                #endregion
                                #region Pay with Premium Balance
                                else if (BalanceType == "Premium Balance")
                                {
                                    if (PremiumPrice != -1)
                                    {
                                        long Balance;
                                        if (!Int64.TryParse(Convert.ToString(GetBalance(aClient.SeasonID, "Premium Balance").Content), out Balance))
                                        {
                                            Balance = 0;
                                        }

                                        if ((PremiumPrice = PremiumPrice + (Wave - 1) * 1000) <= Balance)
                                        {
                                            string StartEventResponse;
                                            if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "StartEvent", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { EventName, Convert.ToString(Wave), PlayerName } }, out StartEventResponse))
                                            {
                                                ResponseStruct StartEventResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(StartEventResponse);
                                                if (StartEventResponseContent.Status == ResponseStatusType.Done)
                                                {
                                                    SQLQuery = "UPDATE shop_accounts SET Balance=@Balance WHERE UserName=@UserName";
                                                    DbCommand = new MySqlCommand(SQLQuery, DbConnection);
                                                    DbCommand.Prepare();
                                                    DbCommand.Parameters.Add("@Balance", MySqlDbType.Int32).Value = Balance - PremiumPrice;
                                                    DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = aClient.UserName;
                                                    DbCommand.ExecuteNonQuery();
                                                    DbCommand.Dispose();

                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("{0}:{1} vừa mua {2}.\nChi phí: {3} Credits {4}.", UserName, PlayerName, EventName, string.Format(CultureInfo.InvariantCulture, "{0:#,#0}", PremiumPrice), BalanceType) } };

                                                    LogWriter(UserName, "Buy Event - Premium Balance", string.Join("\n", Result.Broadcast));
                                                }
                                                else if (StartEventResponseContent.Status == ResponseStatusType.Fail)
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = StartEventResponseContent.Error, Broadcast = StartEventResponseContent.Broadcast };
                                                }
                                                else
                                                {
                                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ kết quả trả về từ TShock." }, Broadcast = new List<string>() { "Thử lại hoặc báo cáo với Admin nếu có thể." } };
                                                }
                                            }
                                            else
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Yêu cầu không thể đáp ứng." } };
                                            }
                                        }
                                        else
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản không đủ Credit." } };
                                        }
                                    }
                                    else
                                    {
                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Event không thể mua bằng Premium Balance." } };
                                    }
                                }
                                #endregion
                                else
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Phương thức thanh toán không hợp lệ." }, Broadcast = new List<string>() { "Lựa chọn phương thức thanh toán có sẵn để tiếp tục." } };
                                }

                            }
                            else if (Count != 0)
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Lỗi cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                            }
                            else
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy event trong cơ sở dữ liệu." }, Broadcast = new List<string>() { "Báo cho Admin nếu có thể." } };
                            }

                            DbConnection.Dispose();
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Player không xuất hiện trong Server." } };
                        }
                        break;
                    default:
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Event yêu cầu không có trong danh sách có sẵn." } };
                        break;
                }
            }

            return Result;
        }
        public ResponseStruct GetItemByID(string SeasonID, int ItemID)
        {
            ResponseStruct Result;
            ShopItemInformations item = new ShopItemInformations();
            LauncherClientInformations aClient;

            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Client" } };
            }
            else if (string.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để sử dụng Shop." } };
            }
            else
            {
                MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DBConnection.Open();

                string SQLQuery = "SELECT * FROM shop_items WHERE ItemID=@ItemID";
                MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                DBCommand.Prepare();
                DBCommand.Parameters.Add("@ItemID", MySqlDbType.Int32).Value = ItemID;

                MySqlDataReader DBReader = DBCommand.ExecuteReader();

                while (DBReader.Read())
                {
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("ItemID")))
                    {
                        item.ItemID = DBReader.GetInt32("ItemID");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("ItemName")))
                    {
                        item.ItemName = DBReader.GetString("ItemName");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("ItemType")))
                    {
                        item.ItemType = DBReader.GetString("ItemType");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("MaxStack")))
                    {
                        item.MaxStack = DBReader.GetInt32("MaxStack");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("PremiumPrice")))
                    {
                        item.PremiumPrice = DBReader.GetInt32("PremiumPrice");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("StandardPrice")))
                    {
                        item.StandardPrice = DBReader.GetInt32("StandardPrice");
                    }
                }

                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(item) };

                DBReader.Dispose();
                DBCommand.Dispose();
                DBConnection.Dispose();
            }

            return Result;
        }
        private ResponseStruct GetStandardBalance(string PlayerName)
        {
            ResponseStruct Result;

            string Response;
            if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "GetPlayerBalance", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { PlayerName } }, out Response))
            {
                ResponseStruct ResponseContent = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(Response);
                if (ResponseContent.Status == ResponseStatusType.Done)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = ResponseContent.Content };
                }
                else if (ResponseContent.Status == ResponseStatusType.Fail)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = ResponseContent.Error, Broadcast = ResponseContent.Broadcast };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Dữ liệu gửi trả về từ TShock Server không được định nghĩa." }, Broadcast = new List<string>() { "Báo cáo với Admin nếu có thể." } };
                }
            }
            else
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng." }, Broadcast = new List<string>() { "Báo cáo với Admin nếu có thể." } };
            }
            if (Result.Status == ResponseStatusType.Fail)
            {
                Result.Content = 0;
            }
            return Result;
        }
        public ResponseStruct GetListOfEvents(string SeasonID)
        {
            ResponseStruct Result;
            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Launcher." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục sử dụng." } };
            }
            else
            {
                MySqlConnection DbConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DbConnection.Open();

                string SqlQuery = "SELECT EventName FROM shop_events";
                MySqlCommand DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                DbCommand.Prepare();

                MySqlDataReader DbReader = DbCommand.ExecuteReader();

                List<string> ListOfEvents = new List<string>();

                while (DbReader.Read())
                {
                    if (!DbReader.IsDBNull(DbReader.GetOrdinal("EventName")))
                    {
                        ListOfEvents.Add(DbReader.GetString("EventName"));
                    }
                }

                DbReader.Dispose();
                DbCommand.Dispose();
                DbConnection.Dispose();

                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(ListOfEvents) };
            }
            return Result;
        }
        public ResponseStruct GetImageByID(string SeasonID, int ID)
        {
            ResponseStruct Result = null;

            LauncherClientInformations aClient;
            if (!OverallInformations.ManagementClients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Management Client không tồn tại." }, Broadcast = new List<string>() { "Có thể kết nối mạng của bạn có độ trễ lớn nên bản ghi của bạn trên Terraria Launcher Server đã bị xóa, vui lòng khởi động lại Management Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục." } };
            }
            else
            {
                MySqlConnection DBConnection = new MySqlConnection(OverallInformations.LauncherDBConnectionString);
                DBConnection.Open();

                string SQLQuery = "SELECT FileName FROM images_from_players WHERE ID=@ID";
                MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                DBCommand.Prepare();
                DBCommand.Parameters.Add("@ID", MySqlDbType.Int32).Value = ID;

                MySqlDataReader DBReader = DBCommand.ExecuteReader();

                while (DBReader.Read()) // Chắc chắn chỉ lặp nhiều nhất 1 lần.
                {
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("FileName")))
                    {
                        string FilePath = Path.Combine(OverallInformations.ImagePath, DBReader.GetString(DBReader.GetOrdinal("FileName")));
                        if (File.Exists(FilePath))
                        {
                            Base64Utils base64 = new Base64Utils();
                            FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.None);
                            string Content = String.Empty;
                            Content = base64.ImageToBase64(Image.FromStream(fs), System.Drawing.Imaging.ImageFormat.Png);
                            fs.Close();
                            fs.Dispose();
                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Content };
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy tập tin hình theo yêu cầu." } };
                        }
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Cơ sở dữ liệu bị lỗi." } };
                    }
                    break;
                }

                DBReader.Dispose();
                DBCommand.Dispose();
                DBConnection.Dispose();
            }

            if (Result == null)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Cơ sở dữ liệu bị lỗi." } };
            }

            return Result;
        }
        public ResponseStruct GetMarketInfo(string SeasonID, string WhatInfo)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Client." }, Broadcast = new List<string>() { "Khởi động lại Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập." } };
            }
            else
            {
                if (WhatInfo == "RatioPremiumVs.Standard")
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = MarketInfo.RatioPremiumVsStandard.ToString() };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Kiểu yêu cầu không có trong định nghĩa." }, Broadcast = new List<string>() { "Sử dụng các định nghĩa cho sẵn." } };
                }
            }

            return Result;
        }
        public ResponseStruct GetListOfImagesOfAnUser(string SeasonID, string UserName)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.ManagementClients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Management Client không tồn tại." }, Broadcast = new List<string>() { "Có thể kết nối mạng của bạn có độ trễ lớn nên bản ghi của bạn trên Terraria Launcher Server đã bị xóa, vui lòng khởi động lại Management Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục." } };
            }
            else
            {
                List<ImageSavedInformations> ImageInfoList = new List<ImageSavedInformations>();

                MySqlConnection DBConnection = new MySqlConnection(OverallInformations.LauncherDBConnectionString);
                DBConnection.Open();

                string SQLQuery;
                if (UserName == "Uncategorized")
                {
                    SQLQuery = "SELECT ID,UserName,ShotTime FROM images_from_players WHERE UserName IS NULL OR UserName = ''";
                }
                else
                {
                    SQLQuery = "SELECT ID,UserName,ShotTime FROM images_from_players WHERE UserName=@UserName";
                }

                MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                DBCommand.Prepare();

                if (UserName == "Uncategorized")
                {
                    //
                }
                else
                {
                    DBCommand.Parameters.Add("@UserName", MySqlDbType.Text).Value = UserName;
                }

                MySqlDataReader DBReader = DBCommand.ExecuteReader();

                while (DBReader.Read())
                {
                    ImageSavedInformations imageInfo = new ImageSavedInformations();
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("ID")))
                    {
                        imageInfo.ID = DBReader.GetInt32("ID");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("UserName")))
                    {
                        imageInfo.UserName = DBReader.GetString("UserName");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("ShotTime")))
                    {
                        imageInfo.ShotTime = DBReader.GetString("ShotTime");
                    }
                    ImageInfoList.Add(imageInfo);
                }

                DBReader.Dispose();
                DBCommand.Dispose();
                DBConnection.Dispose();

                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(ImageInfoList) };
            }

            return Result;
        }
        public ResponseStruct GetNpcsByType(string SeasonID, string NpcType)
        {
            ResponseStruct Result;
            List<ShopNpcInformations> NpcList = new List<ShopNpcInformations>();
            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Client" } };
            }
            else if (string.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để sử dụng Shop." } };
            }
            else
            {
                MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DBConnection.Open();

                string SQLQuery;

                if (NpcType == "Uncategorized")
                {
                    SQLQuery = "SELECT * FROM shop_npcs WHERE NpcType IS NULL OR NpcType = '' ORDER BY NpcName ASC";
                }
                else
                {
                    SQLQuery = "SELECT * FROM shop_npcs WHERE NpcType=@NpcType ORDER BY NpcName ASC";
                }

                MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                DBCommand.Prepare();

                if (NpcType == "Uncategorized")
                {
                    //
                }
                else
                {
                    DBCommand.Parameters.Add("@NpcType", MySqlDbType.Text).Value = NpcType;
                }

                MySqlDataReader DBReader = DBCommand.ExecuteReader();

                while (DBReader.Read())
                {
                    ShopNpcInformations npc = new ShopNpcInformations();
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("NpcID")))
                    {
                        npc.NpcID = DBReader.GetInt32("NpcID");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("NpcName")))
                    {
                        npc.NpcName = DBReader.GetString("NpcName");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("NpcType")))
                    {
                        npc.NpcType = DBReader.GetString("NpcType");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("PremiumPrice")))
                    {
                        npc.PremiumPrice = DBReader.GetInt32("PremiumPrice");
                    }
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("StandardPrice")))
                    {
                        npc.StandardPrice = DBReader.GetInt32("StandardPrice");
                    }
                    NpcList.Add(npc);
                }

                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(NpcList) };

                DBReader.Dispose();
                DBCommand.Dispose();
                DBConnection.Dispose();
            }
            return Result;
        }
        public ResponseStruct GetListOfUsersHaveImages(string SeasonID)
        {
            ResponseStruct Result;
            LauncherClientInformations aClient;

            if (!OverallInformations.ManagementClients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Management Client không tồn tại." }, Broadcast = new List<string>() { "Có thể kết nối mạng của bạn có độ trễ lớn nên bản ghi của bạn trên Terraria Launcher Server đã bị xóa, vui lòng khởi động lại Management Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục." } };
            }
            else
            {
                List<string> Content = new List<string>();

                MySqlConnection DBConnection = new MySqlConnection(OverallInformations.LauncherDBConnectionString);
                DBConnection.Open();

                string SQLQuery = "SELECT DISTINCT UserName FROM images_from_players ORDER BY UserName ASC";
                MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                MySqlDataReader DBReader = DBCommand.ExecuteReader();

                string userName;
                while (DBReader.Read())
                {
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("UserName")))
                    {
                        userName = DBReader.GetString("UserName");
                        if (!string.IsNullOrWhiteSpace(userName))
                        {
                            Content.Add(userName);
                        }
                    }
                }

                Content.Add("Uncategorized");

                DBReader.Dispose();
                DBCommand.Dispose();
                DBConnection.Dispose();

                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(Content) };
            }

            return Result;
        }
        public ResponseStruct GetNpcTypes(string SeasonID)
        {
            ResponseStruct Result;
            List<string> NpcTypeList = new List<string>();
            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để sử dụng Shop." } };
            }
            else
            {
                MySqlConnection DBConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DBConnection.Open();

                string SQLQuery = "SELECT DISTINCT NpcType FROM shop_npcs ORDER BY NpcType ASC";
                MySqlCommand DBCommand = new MySqlCommand(SQLQuery, DBConnection);
                MySqlDataReader DBReader = DBCommand.ExecuteReader();

                string TypeString;
                while (DBReader.Read())
                {
                    if (!DBReader.IsDBNull(DBReader.GetOrdinal("NpcType")))
                    {
                        TypeString = DBReader.GetString("NpcType");
                        if (!string.IsNullOrWhiteSpace(TypeString))
                        {
                            NpcTypeList.Add(TypeString);
                        }
                    }
                }
                NpcTypeList.Add("Uncategorized");

                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(NpcTypeList) };

                DBReader.Dispose();
                DBCommand.Dispose();
                DBConnection.Dispose();
            }
            return Result;
        }
        public ResponseStruct Logout(string SeasonID)
        {
            ResponseStruct Result;
            LauncherClientInformations aClient;

            if (!OverallInformations.ManagementClients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Management Client không tồn tại." }, Broadcast = new List<string>() { "Có thể kết nối mạng của bạn có độ trễ lớn nên bản ghi của bạn trên Terraria Launcher Server đã bị xóa, vui lòng khởi động lại Management Client." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục." } };
            }
            else
            {
                string UserName = aClient.UserName;
                if (OverallInformations.ManagementClients.TryUpdate(SeasonID, new LauncherClientInformations() { SeasonID = aClient.SeasonID, UserName = "", Password = "", TheFirstQueueName = aClient.TheFirstQueueName }, aClient))
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Đăng xuất thành công." } };
                    LauncherServer.OutputMessage(String.Format("[Management]: {0} has logged out.", UserName), LauncherServer.MessageType.Info);
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Thông tin đăng nhập vừa bị thay đổi." }, Broadcast = new List<string>() { "Đăng xuất một lần nữa." } };
                }
            }
            return Result;
        }
        public ResponseStruct GetUserProgress(string SeasonID)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Launcher để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục sử dụng." } };
            }
            else
            {
                string UserName = aClient.UserName;
                ShopUserProgressInformations aUserProgress;
                if (GetProgressOfAnUser(UserName, out aUserProgress))
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Newtonsoft.Json.JsonConvert.SerializeObject(aUserProgress) };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản chưa (không thể) sử dụng hệ thống class nên không thể lấy thông tin được." }, Broadcast = new List<string>() { "Hãy chọn một class hoặc sử dụng tài khoản phù hợp." } };
                }
            }

            return Result;
        }
        /*
         * Mô tả hoạt động:
         * 1. Kiểm tra trong bảng "shop_players_progress" có bản ghi nào chứa User Name của Client đang đăng nhập hay không.
         * Nếu có, thì có nghĩa User đó đã chọn một class từ trước, cho nên không cho phép chọn nữa.
         * Nếu không, thì có nghĩa User đó chưa dùng hệ thống class, cho nên sẽ tiếp tục kiểm tra các điều kiện tiếp theo như thế nào.
         *
         * 2. Tiếp theo sẽ kiểm tra TShockGroup hiện tại của User đó có trùng với default group hay không.
         * Nếu không, có nghĩa là User này không phải là User thông thường. Nghĩa là sẽ không cho chọn class.
         * Nếu có, nghĩa là User này là User thông thường, kết hợp điều kiện 1. thì đã đủ điều kiện cho User đó được phép chọn một class.
         *
         * 3. Lấy thông tin và kiểm tra của class trùng tên với ClassName trong bảng "shop_classes". Nếu lấy thành công và thông tin hợp lệ thì tiếp tục.
         *
         * 4. Thay đổi TShockGroup của User bằng level đầu tiên của class, thêm một bản ghi chứa trạng thái của User khi dùng hệ thống class để tiện cho việc quản lí sau này.
         *
         * Bảng "shop_classes" có chứa thông tin của từng class một, có chứa "TheFirstLevelName" để xác định level đầu tiên của class đó trong bảng "shop_levels_and_ranks".
         * Bảng "shop_players_progress" có chứa tên User sử dụng class nào, và level hiện tại.
         * Khi chọn class, sử dụng thông tin trong bảng "shop_classes" để làm cơ sở ban đầu, rồi ghi trong bảng "shop_players_progress".
         *
        */
        public ResponseStruct PickAClass(string SeasonID, string ClassName)
        {
            ResponseStruct Result;

            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." }, Broadcast = new List<string>() { "Khởi động lại Launcher để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để tiếp tục sử dụng." } };
            }
            else if (String.IsNullOrWhiteSpace(ClassName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Class không hợp lệ." }, Broadcast = new List<string>() { "Sử dụng class được cung cấp trong danh sách." } };
            }
            else
            {
                MySqlConnection DbConnection = new MySqlConnection(OverallInformations.TradingSystemDBConnectionString);
                DbConnection.Open();

                string SqlQuery = "SELECT COUNT(*) FROM shop_players_progress WHERE UserName=@UserName";
                MySqlCommand DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                DbCommand.Prepare();
                DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = aClient.UserName;

                int RecordNumber = Convert.ToInt32(DbCommand.ExecuteScalar());

                DbCommand.Dispose();

                if (RecordNumber != 0)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản đã chọn một class từ trước đó." }, Broadcast = new List<string>() { "Nếu bạn muốn chọn một class khác, hãy dùng tính năng thay đổi class." } };
                }
                else
                {
                    string GetUserGroup_ResponseString;
                    if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "GetUserGroup", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { aClient.UserName } }, out GetUserGroup_ResponseString))
                    {
                        ResponseStruct GetUserGroup_Result = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(GetUserGroup_ResponseString);
                        if (GetUserGroup_Result.Status == ResponseStatusType.Done)
                        {
                            string UserGroupName = Convert.ToString(GetUserGroup_Result.Content);
                            if (UserGroupName == OverallInformations.DefaultUserGroup)
                            {
                                ShopClassInformations aClass;
                                if (GetInformationsAboutAClass(ClassName, out aClass))
                                {
                                    ShopLevelInformations aLevel;
                                    if (GetInformationsAboutALevel(aClass.TheFirstLevelName, out aLevel))
                                    {
                                        string ChangeUserGroup_ResponseString;
                                        if (LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "ChangeUserGroup", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { aClient.UserName, aLevel.TShockGroupName } }, out ChangeUserGroup_ResponseString))
                                        {
                                            ResponseStruct ChangeUserGroup_Result = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponseStruct>(ChangeUserGroup_ResponseString);
                                            if (ChangeUserGroup_Result.Status == ResponseStatusType.Done)
                                            {
                                                SqlQuery = "INSERT INTO shop_players_progress (UserName,CurrentClass,CurrentLevel) VALUES (@UserName,@CurrentClass,@CurrentLevel)";
                                                DbCommand = new MySqlCommand(SqlQuery, DbConnection);
                                                DbCommand.Prepare();
                                                DbCommand.Parameters.Add("@UserName", MySqlDbType.VarChar).Value = aClient.UserName;
                                                DbCommand.Parameters.Add("@CurrentClass", MySqlDbType.VarChar).Value = aClass.ClassName;
                                                DbCommand.Parameters.Add("@CurrentLevel", MySqlDbType.VarChar).Value = aClass.TheFirstLevelName;

                                                DbCommand.ExecuteNonQuery();
                                                DbCommand.Dispose();

                                                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("Tài khoản đã chọn class {0}. Lưu ý: Class chỉ chọn được một lần, nếu muốn thay đổi phải tạo character mới hoặc sử dụng chức năng thay đổi class (có tính phí).", ClassName) } };
                                            }
                                            else if (ChangeUserGroup_Result.Status == ResponseStatusType.Fail)
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = ChangeUserGroup_Result.Error, Broadcast = ChangeUserGroup_Result.Broadcast };
                                            }
                                            else
                                            {
                                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ dữ liệu trả về từ TShock Server." } };
                                            }
                                        }
                                        else
                                        {
                                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng." } };
                                        }
                                    }
                                    else
                                    {
                                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể lấy thông tin của level được yêu cầu." } };
                                    }
                                }
                                else
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể lấy thông tin của class được yêu cầu." } };
                                }
                            }
                            else
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tài khoản của bạn hiện tại không thể chọn class." } };
                            }
                        }
                        else if (GetUserGroup_Result.Status == ResponseStatusType.Fail)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = GetUserGroup_Result.Error };
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không rõ dữ liệu trả về từ TShock Server." } };
                        }
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "TShock Server không đáp ứng." } };
                    }
                }

                DbConnection.Dispose();
            }

            return Result;
        }
        public ResponseStruct SendChat(string SeasonID, string ChatText)
        {
            ResponseStruct Result;
            LauncherClientInformations aClient;
            if (!OverallInformations.Clients.TryGetValue(SeasonID, out aClient))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Client không tồn tại." } };
            }
            else if (String.IsNullOrWhiteSpace(aClient.UserName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Chưa đăng nhập." }, Broadcast = new List<string>() { "Tiến hành đăng nhập để sử dụng tính năng Chat." } };
            }
            else if (String.IsNullOrWhiteSpace(ChatText))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tin nhắn SPAM." }, Broadcast = new List<string>() { "Tin nhắn rỗng hoặc chứa toàn khoảng trắng." } };
            }
            else if (ChatText.Length > 200)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tin nhắn SPAM." }, Broadcast = new List<string>() { "Tin nhắn dài hơn 200 kí tự." } };
            }
            else
            {
                string aResponse;
                LauncherServerSendRequestToTShockInstance.SendRequest(new Request02() { RequestType = "SendAChatText", AuthCode = OverallInformations.AuthCode, Parameters = new List<string>() { "[o] " + aClient.UserName + ": " + ChatText, "LightSteelBlue" } }, out aResponse);
                OverallInformations.TShockPlayerChatStorage.Add(new TShockAChatInformations() { UserName = aClient.UserName, PlayerName = aClient.UserName, RawText = "[o] " + aClient.UserName + ": " + ChatText, FormatedText = "[o] " + aClient.UserName + ": " + ChatText });
                Result = new ResponseStruct() { Status = ResponseStatusType.Done};
            }

            return Result;
        }