public ResponseStruct SpawnBoss(string BossName, string BossAmount, string TargetPlayer)
        {
            ResponseStruct Result;
            List<TShockAPI.TSPlayer> Players = TShockAPI.TShock.Utils.FindPlayer(TargetPlayer);
            int Amount = -1;

            if (!Int32.TryParse(BossAmount, out Amount))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng Boss không hợp lệ." }, Broadcast = new List<string>() { "Số lượng Boss phải là số nguyên dương và nên nhỏ hơn 200." } };
            }
            else if (!(Amount >= 1 && Amount <= Terraria.Main.maxNPCs))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng Boss không hợp lệ." }, Broadcast = new List<string>() { "Số lượng Boss phải là số nguyên dương và nên nhỏ hơn 200." } };
            }
            else if (Players.Count == 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Player Name trong Server." }, Broadcast = new List<string>() { "Chỉ có thể summon Boss nếu Player có mặt trong Server." } };
            }
            else if (Players.Count > 1)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { String.Format("Có {0} Player có tên phù hợp với tên Player được cung cấp.") }, Broadcast = new List<string>() { "Cung cấp Player Name đầy đủ." } };
            }
            else
            {
                int CurrentNpcCount = CountNPC();
                if (Amount > Terraria.Main.maxNPCs - CurrentNpcCount)
                    Amount = Terraria.Main.maxNPCs - CurrentNpcCount;

                TShockAPI.TSPlayer Player = Players[0];
                Terraria.NPC Npc = new Terraria.NPC();

                switch (BossName)
                {
                    case "Brain of Cthulhu":
                        Npc.SetDefaults(266);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned the Brain of Cthulhu {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "The Destroyer":
                        if (Terraria.Main.dayTime)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "The Destroyer phải được gọi vào ban đêm (trong game)." } };
                        }
                        else
                        {
                            Npc.SetDefaults(134);
                            TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                            TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned the Destroyer {1} time(s).", Player.Name, Amount);
                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        }
                        break;
                    case "Duke Fishron":
                        Npc.SetDefaults(370);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned Duke Fishron {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "Eater of Worlds":
                        Npc.SetDefaults(13);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned the Eater of Worlds {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "Eye of Cthulhu":
                        Npc.SetDefaults(4);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned the Eye of Cthulhu {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "Golem":
                        Npc.SetDefaults(245);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned Golem {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "King Slime":
                        Npc.SetDefaults(50);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned King Slime {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "Plantera":
                        Npc.SetDefaults(262);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned Plantera {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "Skeletron Prime":
                        Npc.SetDefaults(127);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned Skeletron Prime {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "Queen Bee":
                        Npc.SetDefaults(222);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned Queen Bee {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "Skeletron":
                        Npc.SetDefaults(35);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned Skeletron {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "The Twins":
                        if (Terraria.Main.dayTime)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "The Twins phải gọi vào ban đêm (trong game)." } };
                        }
                        else
                        {
                            Npc.SetDefaults(125);
                            TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                            Npc.SetDefaults(126);
                            TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                            TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned the Twins {1} time(s).", Player.Name, Amount);
                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        }
                        break;
                    case "Wall of Flesh":
                        if (Terraria.Main.wof > 0)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Wall of Flesh đang tồn tại trong World." } };
                        }
                        else if (Player.Y / 16f < Terraria.Main.maxTilesY - 205)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Nhân vật phải đứng tại \"hell\" để có thể gọi Wall of Flesh." } };
                        }
                        else
                        {
                            Terraria.NPC.SpawnWOF(new Vector2(Player.X, Player.Y));
                            TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned the Wall of Flesh.", Player.Name);
                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = "1" };
                        }
                        break;
                    case "Lunatic Cultist":
                        Npc.SetDefaults(439);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned the Lunatic Cultist {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    case "Moon Lord":
                        Npc.SetDefaults(398);
                        TShockAPI.TSPlayer.Server.SpawnNPC(type: Npc.type, name: Npc.name, amount: Amount, startTileX: Player.TileX, startTileY: Player.TileY);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned the Moon Lord {1} time(s).", Player.Name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Convert.ToString(Amount) };
                        break;
                    default:
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tên Boss không hợp lệ." }, Broadcast = new List<string>() { "Cần đúng tên Boss hợp lệ để summon." } };
                        break;
                }
            }

            return Result;
        }
        public ResponseStruct AddPlayerBalance(string PlayerName, string Amount, string Message)
        {
            ResponseStruct Result;

            List<TShockAPI.TSPlayer> Players = TShockAPI.TShock.Utils.FindPlayer(PlayerName);
            if (Players.Count == 1)
            {
                IBankAccount PlayerBank = SEconomyPlugin.Instance.GetBankAccount(Players[0]);

                if (PlayerBank != null)
                {
                    SEconomyPlugin.Instance.WorldAccount.TransferTo(Account: PlayerBank, Amount: long.Parse(Amount), Options: BankAccountTransferOptions.IsPayment, TransactionMessage: Message, JournalMessage: Message);
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Tài khoản của Player đã được cộng thêm." } };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "SEconomy Bank không tồn tại." } };
                }
            }
            else if (Players.Count == 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Player." } };
            }
            else
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Nhiều Player có tên tương tự như đã cung cấp." } };
            }

            return Result;
        }
        public ResponseStruct AddUser(string UserName, string Password, string GroupName)
        {
            ResponseStruct Result;

            TShockAPI.DB.User user = new TShockAPI.DB.User();

            user.Name = UserName;
            user.Group = GroupName;

            try
            {
                user.CreateBCryptHash(Password);
            }
            catch (ArgumentOutOfRangeException)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Mật khẩu không đủ dài." }, Broadcast = new List<string>() { String.Format("Mật khẩu phải bằng hoặc dài hơn {0} kí tự.", TShockAPI.TShock.Config.MinimumPasswordLength) } };
                return Result;
            }

            if (TShockAPI.TShock.Groups.GetGroupByName(user.Group) == null)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "\"Group\" không tồn tại." }, Broadcast = new List<string>() { "Sử dụng \"Group\" hợp lệ." } };
            }
            else
            {
                if (TShockAPI.TShock.Users.GetUserByName(user.Name) == null && user.Name != TShockAPI.TSServerPlayer.AccountName)
                {
                    try
                    {
                        TShockAPI.TShock.Users.AddUser(user);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Tài khoản đã được khởi tạo." } };
                    }
                    catch (TShockAPI.DB.UserManagerException e)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { e.Message }, 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>() { "Tài khoản đã tồn tại." }, Broadcast = new List<string>() { "Sử dụng một tên tài khoản khác." } };
                }
            }

            return Result;
        }
        private void TShockControllerWorker()
        {
            IModel channel = OverallInformations.conn.CreateModel();
            channel.ExchangeDeclare(exchange: OverallInformations.LauncherServerTShockExchange, type: "direct", durable: false, autoDelete: true, arguments: null);
            channel.QueueDeclare(queue: OverallInformations.LauncherServerSendRequestToTShockQueue, durable: false, exclusive: false, autoDelete: true, arguments: null);
            channel.QueueBind(queue: OverallInformations.LauncherServerSendRequestToTShockQueue, exchange: OverallInformations.LauncherServerTShockExchange, routingKey: OverallInformations.LauncherServerSendRequestToTShockRouterKey, arguments: null);
            channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
            EventingBasicConsumer consumer = new EventingBasicConsumer(channel);

            TShockControllerService ServiceInstance = new TShockControllerService();

            consumer.Received += (model, ea) =>
            {
                try
                {
                    IBasicProperties deliveredProps = ea.BasicProperties;
                    IBasicProperties replyProps = channel.CreateBasicProperties();
                    replyProps.CorrelationId = ea.BasicProperties.CorrelationId;
                    byte[] deliveredBody = ea.Body;

                    string deliveredString = Encoding.UTF8.GetString(deliveredBody);

                    Request02 RequestContent = Newtonsoft.Json.JsonConvert.DeserializeObject<Request02>(deliveredString);

                    string RequestOutString = String.Empty;

                    if (ServiceInstance.CheckAuthCode(RequestContent.AuthCode))
                    {
                        if (RequestContent.RequestType == "AddUser")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.AddUser(RequestContent.Parameters[0], RequestContent.Parameters[1], RequestContent.Parameters[2]));
                        }
                        else if (RequestContent.RequestType == "ChangeUserGroup")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.ChangeUserGroup(RequestContent.Parameters[0], RequestContent.Parameters[1]));
                        }
                        else if (RequestContent.RequestType == "GetUserGroup")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.GetUserGroup(RequestContent.Parameters[0]));
                        }
                        else if (RequestContent.RequestType == "Kick")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.Kick(RequestContent.Parameters[0], RequestContent.Parameters[1]));
                        }
                        else if (RequestContent.RequestType == "KickAll")
                        {
                            ServiceInstance.KickAll(RequestContent.Parameters[0]);
                            RequestOutString = "";
                        }
                        else if (RequestContent.RequestType == "SpawnBoss")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.SpawnBoss(RequestContent.Parameters[0], RequestContent.Parameters[1], RequestContent.Parameters[2]));
                        }
                        else if (RequestContent.RequestType == "SpawnMob")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.SpawnMob(RequestContent.Parameters[0], RequestContent.Parameters[1], RequestContent.Parameters[2]));
                        }
                        else if (RequestContent.RequestType == "StartEvent")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.StartEvent(RequestContent.Parameters[0], RequestContent.Parameters[1], RequestContent.Parameters[2]));
                        }
                        else if (RequestContent.RequestType == "GetPlayerBalance")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.GetPlayerBalance(RequestContent.Parameters[0]));
                        }
                        else if (RequestContent.RequestType == "AddPlayerBalance")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.AddPlayerBalance(RequestContent.Parameters[0], RequestContent.Parameters[1], RequestContent.Parameters[2]));
                        }
                        else if (RequestContent.RequestType == "SubtractPlayerBalance")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.SubtractPlayerBalance(RequestContent.Parameters[0], RequestContent.Parameters[1], RequestContent.Parameters[2]));
                        }
                        else if (RequestContent.RequestType == "GiveItem")
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(ServiceInstance.GiveItem(RequestContent.Parameters[0], RequestContent.Parameters[1], RequestContent.Parameters[2], RequestContent.Parameters[3]));
                        }
                        else if (RequestContent.RequestType == "SendAChatText")
                        {
                            ServiceInstance.SendAChatText(RequestContent.Parameters[0], RequestContent.Parameters[1]);
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Message has been sent." } });
                        }
                        else
                        {
                            RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Unknow function." } });
                        }
                    }
                    else
                    {
                        RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Authentication code is not vaild." } });
                    }

                    byte[] RequestOutBytes = Encoding.UTF8.GetBytes(RequestOutString);
                    channel.BasicPublish(exchange: OverallInformations.LauncherServerTShockExchange, routingKey: deliveredProps.ReplyTo, basicProperties: replyProps, body: RequestOutBytes);
                }
                catch (Exception ex)
                {
                    IBasicProperties deliveredProps = ea.BasicProperties;
                    IBasicProperties replyProps = channel.CreateBasicProperties();
                    replyProps.CorrelationId = ea.BasicProperties.CorrelationId;

                    ResponseStruct Failed = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { ex.Message } };
                    string RequestOutString = Newtonsoft.Json.JsonConvert.SerializeObject(Failed);
                    byte[] RequestOutBytes = Encoding.UTF8.GetBytes(RequestOutString);

                    channel.BasicPublish(exchange: OverallInformations.LauncherServerTShockExchange, routingKey: deliveredProps.ReplyTo, basicProperties: replyProps, body: RequestOutBytes);
                }
            };

            channel.BasicConsume(queue: OverallInformations.LauncherServerSendRequestToTShockQueue, noAck: true, consumer: consumer);
        }
        public ResponseStruct ChangeUserGroup(string UserName, string GroupName)
        {
            ResponseStruct Result;

            try
            {
                TShockAPI.DB.User aUser = new TShockAPI.DB.User();
                aUser.Name = UserName;

                TShockAPI.TShock.Users.SetUserGroup(aUser, GroupName);
                Result = new ResponseStruct() { Status = ResponseStatusType.Done };
            }
            catch (Exception ex)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { ex.Message } };
            }

            return Result;
        }
        public ResponseStruct StartEvent(string EventName, string WaveString = "1", string SourcePlayer = "Launcher Server")
        {
            ResponseStruct Result;

            List<string> ListOfEvents = new List<string>()
            {
                "Rain",
                "Slime Rain",
                "Blood Moon",
                "Solar Eclipse",
                "Goblin Army",
                "Frost Legion",
                "Pirate Invasion",
                "Pumpkin Moon",
                "Frost Moon",
                "Martian Madness"
            };

            if (String.IsNullOrWhiteSpace(EventName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tên của event không hợp lệ." }, Broadcast = new List<string>() { "Sử dụng event trong danh sách được cung cấp sẵn." } };
            }
            else if (String.IsNullOrWhiteSpace(WaveString))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Wave String không hợp lệ." } };
            }
            else if (String.IsNullOrWhiteSpace(EventName))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Source Player không hợp lệ." } };
            }
            else
            {
                int Wave;
                if (!int.TryParse(WaveString, out Wave))
                {
                    Wave = -1;
                }

                if (EventName == "Rain")
                {
                    if (Terraria.Main.raining)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Đang có mưa trong Terraria World." } };
                    }
                    else if (Terraria.Main.slimeRain)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Đang có mưa slime trong Terraria World." } };
                    }
                    else
                    {
                        //
                        TShockAPI.TSPlayer.All.SendInfoMessage("{0} caused it to rain.", SourcePlayer);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                    }
                }
                else if (EventName == "Slime Rain")
                {
                    if (Terraria.Main.raining)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Đang có mưa trong Terraria World." } };
                    }
                    else if (Terraria.Main.slimeRain)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Đang có mưa slime trong Terraria World." } };
                    }
                    else
                    {
                        //
                        TShockAPI.TSPlayer.All.SendInfoMessage("{0} caused it to rain slime.", SourcePlayer);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                    }
                }
                else if (EventName == "Blood Moon")
                {
                    if (Terraria.Main.dayTime)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Hiện tại World Terraria đang là ban ngày." } };
                    }
                    else if (Terraria.Main.bloodMoon)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Blood Moon đang diễn ra." } };
                    }
                    else
                    {
                        TShockAPI.TSPlayer.Server.SetBloodMoon(true);
                        TShockAPI.TSPlayer.All.SendInfoMessage("{0} started a blood moon.", SourcePlayer);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                    }
                }
                else if (EventName == "Solar Eclipse")
                {
                    if (!Terraria.Main.dayTime)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Hiện tại World Terraria đang là ban ngày." } };
                    }
                    else if (Terraria.Main.eclipse)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Solar Eclipse đang diễn ra." } };
                    }
                    else
                    {
                        TShockAPI.TSPlayer.Server.SetEclipse(true);
                        TShockAPI.TSPlayer.All.SendInfoMessage("{0} started an eclipse.", SourcePlayer);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                    }
                }
                else if (EventName == "Goblin Army" && Terraria.Main.invasionSize <= 0)
                {
                    TShockAPI.TSPlayer.All.SendInfoMessage("{0} has started a Goblin Army invasion.", SourcePlayer);
                    TShockAPI.TShock.StartInvasion(1);
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                }
                else if (EventName == "Frost Legion" && Terraria.Main.invasionSize <= 0)
                {
                    TShockAPI.TSPlayer.All.SendInfoMessage("{0} has started a Frost Legion invasion.", SourcePlayer);
                    TShockAPI.TShock.StartInvasion(2);
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                }
                else if (EventName == "Pirate Invasion" && Terraria.Main.invasionSize <= 0)
                {
                    TShockAPI.TSPlayer.All.SendInfoMessage("{0} has started a Pirate invasion.", SourcePlayer);
                    TShockAPI.TShock.StartInvasion(3);
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                }
                else if (EventName == "Pumpkin Moon" && Terraria.Main.invasionSize <= 0)
                {
                    if (Terraria.Main.dayTime)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Hiện tại World Terraria đang là ban ngày." } };
                    }
                    else if (Terraria.Main.bloodMoon)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Blood Moon đang diễn ra." } };
                    }
                    else if (Terraria.Main.pumpkinMoon)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Pumpkin Moon đang diễn ra." } };
                    }
                    else
                    {
                        if (Wave >= 1 && Wave <= 15)
                        {
                            TShockAPI.TSPlayer.Server.SetPumpkinMoon(true);
                            Terraria.Main.bloodMoon = false;
                            Terraria.NPC.waveKills = 0f;
                            Terraria.NPC.waveCount = Wave;
                            TShockAPI.TSPlayer.All.SendInfoMessage("{0} started the Pumpkin Moon at wave {1}!", SourcePlayer, Wave);

                            Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số \"wave\" không hợp lệ." }, Broadcast = new List<string>() { "Số \"wave\" của Pumpkin Moon là từ 1 đến 15." } };
                        }
                    }
                }
                else if (EventName == "Frost Moon" && Terraria.Main.invasionSize <= 0)
                {
                    if (Terraria.Main.dayTime)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Hiện tại World Terraria đang là ban ngày." } };
                    }
                    else if (Terraria.Main.bloodMoon)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Blood Moon đang diễn ra." } };
                    }
                    else if (Terraria.Main.snowMoon)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Frost Moon đang diễn ra." } };
                    }
                    else
                    {
                        if (Wave >= 1 && Wave <= 20)
                        {
                            TShockAPI.TSPlayer.Server.SetFrostMoon(true);
                            Terraria.Main.bloodMoon = false;
                            Terraria.NPC.waveKills = 0f;
                            Terraria.NPC.waveCount = Wave;
                            TShockAPI.TSPlayer.All.SendInfoMessage("{0} started the Frost Moon at wave {1}!", SourcePlayer, Wave);

                            Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                        }
                        else
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số \"wave\" không hợp lệ." }, Broadcast = new List<string>() { "Số \"wave\" của Frost Moon là từ 1 đến 20." } };
                        }
                    }
                }
                else if (EventName == "Martian Madness" && Terraria.Main.invasionSize <= 0)
                {
                    TShockAPI.TSPlayer.All.SendInfoMessage("{0} has started a Martian invasion.", SourcePlayer);
                    TShockAPI.TShock.StartInvasion(4);
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done };
                }
                else if (ListOfEvents.Contains(EventName) && Terraria.Main.invasionSize > 0)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "World đang có một \"Invasion\" đang diễn ra." }, Broadcast = new List<string>() { "Hãy đợi cho đến khi \"Invasion\" đó kết thúc." } };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tên của event không có trong danh sách hợp lệ." }, Broadcast = new List<string>() { "Sử dụng event trong danh sách được cung cấp sẵn." } };
                }
            }

            return Result;
        }
        public ResponseStruct SpawnMob(string MobNameOrID, string MobAmount, string TargetPlayer)
        {
            ResponseStruct Result;
            List<TShockAPI.TSPlayer> Players = TShockAPI.TShock.Utils.FindPlayer(TargetPlayer);
            int Amount = 1;

            if (!Int32.TryParse(MobAmount, out Amount))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng mob không hợp lệ." } };
            }
            else if (!(Amount >= 1 && Amount <= Terraria.Main.maxNPCs))
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng mob không hợp lệ." } };
            }
            else if (Players.Count == 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Player." } };
            }
            else if (Players.Count > 1)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tìm thấy nhiều hơn một Player với tên Player được cung cấp." } };
            }
            else
            {
                int CurrentNpcCount = CountNPC();
                if (Amount > Terraria.Main.maxNPCs - CurrentNpcCount)
                {
                    Amount = Terraria.Main.maxNPCs - CurrentNpcCount;
                }

                TShockAPI.TSPlayer Player = Players[0];

                List<Terraria.NPC> NPCs = TShockAPI.TShock.Utils.GetNPCByIdOrName(MobNameOrID);

                if (NPCs.Count == 0)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy NPC theo yêu cầu." } };
                }
                else if (NPCs.Count > 1)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Tìm thấy nhiều NPC có trùng tên." } };
                }
                else
                {
                    Terraria.NPC NPC = NPCs[0];
                    if (NPC.type >= 1 && NPC.type < Terraria.Main.maxNPCTypes && NPC.type != 113)
                    {
                        TShockAPI.TSPlayer.Server.SpawnNPC(NPC.type, NPC.name, Amount, Player.TileX, Player.TileY, 50, 20);
                        TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned {1} {2} time(s).", Player.Name, NPC.name, Amount);
                        Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = Amount };
                    }
                    else if (NPC.type == 113)
                    {
                        if (Terraria.Main.wof >= 0 || (Player.Y / 16f < (Terraria.Main.maxTilesY - 205)))
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không thể gọi Wall of Flesh tại vị trí Player đang đứng." } };
                        }
                        else
                        {
                            Terraria.NPC.SpawnWOF(new Vector2(Player.X, Player.Y));
                            TShockAPI.TSPlayer.All.SendSuccessMessage("{0} has spawned a Wall of Flesh.", Player.Name);
                            Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = 1 };
                        }
                    }
                    else
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Loại mob yêu cầu không hợp lệ." } };
                    }
                }
            }

            return Result;
        }
        public ResponseStruct Kick(string PlayerName, string Reason)
        {
            ResponseStruct Result;

            List<TShockAPI.TSPlayer> Players = TShockAPI.TShock.Utils.FindPlayer(PlayerName);
            if (Players.Count == 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { String.Format("Can not find Player named {0}.", PlayerName) } };
            }
            else if (Players.Count > 1)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { String.Format("Launcher Server has found more than one Player named {0}.", PlayerName) } };
            }
            else
            {
                if (TShockAPI.TShock.Utils.Kick(player: Players[0], reason: Reason, force: true, silent: false, adminUserName: "******", saveSSI: true))
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { String.Format("Launcher Server force kicked {0} for '{1}'.", Players[0].Name, Reason) } };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { String.Format("Launcher Server can't kick {0}.", Players[0].Name) } };
                }
            }

            return Result;
        }
        public ResponseStruct GiveItem(string PlayerName, string ItemNameOrID, string AmountString, string ModifierString)
        {
            ResponseStruct Result;

            int ItemAmount;
            Int32.TryParse(AmountString, out ItemAmount);

            List<Terraria.Item> Items = TShockAPI.TShock.Utils.GetItemByIdOrName(ItemNameOrID);
            List<int> Modifiers = TShockAPI.TShock.Utils.GetPrefixByIdOrName(ModifierString);
            List<TShockAPI.TSPlayer> Players = TShockAPI.TShock.Utils.FindPlayer(PlayerName);

            if (Players.Count == 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Player." }, Broadcast = new List<string>() { "Cung cấp tên Player Name hợp lệ." } };
            }
            else if (Players.Count > 1)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { String.Format("Có {0} Player trùng tên.", Players.Count) } };
            }
            else
            {
                if (Items.Count == 0)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Item có tên được cung cấp." }, Broadcast = new List<string>() { "Cung cấp tên Item hợp lệ." } };
                }
                else if (Items.Count > 1)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { String.Format("Tìm thấy {0} Item có tên tương tự.", Items.Count) }, Broadcast = new List<string>() { "Cung cấp tên Item hợp lệ." } };
                }
                else
                {
                    if (ItemAmount <= 0 || ItemAmount > 999)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng Item không hợp lệ." }, Broadcast = new List<string>() { "Số lượng Item phải lớn hơn 0 và không vượt quá 999." } };
                    }
                    else if (ItemAmount > Items[0].maxStack)
                    {
                        Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Số lượng Item không hợp lệ." }, Broadcast = new List<string>() { String.Format("Số lượng Item phải nhỏ hơn {0}.", Items[0].maxStack) } };
                    }
                    else
                    {
                        if (Modifiers.Count > 1)
                        {
                            Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Modifier không hợp lệ.", "Tìm thấy nhiều Modifier trùng tên." }, Broadcast = new List<string>() { "Cung cấp Modifier hợp lệ." } };
                        }
                        else
                        {
                            if (Players[0].InventorySlotAvailable || (Items[0].type > 70 && Items[0].type < 75) || Items[0].ammo > 0 || Items[0].type == 58 || Items[0].type == 184)
                            {
                                if (Players[0].GiveItemCheck(type: Items[0].type, name: Items[0].name, width: Items[0].width, height: Items[0].height, stack: ItemAmount, prefix: Modifiers.Count == 0 ? 0 : Modifiers[0]))
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Broadcast = new List<string>() { "Item đã được chuyển vào Inventory của Player." } };
                                }
                                else
                                {
                                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Player không có khả năng chứa Item trong Inventory." }, Broadcast = new List<string>() { "Kiểm tra lại Inventory." } };
                                }
                            }
                            else
                            {
                                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Player không còn Slot trong Inventory." }, Broadcast = new List<string>() { "Xóa hoặc lấy bớt Item ra khỏi Inventory để có Slot trống." } };
                            }
                        }
                    }
                }
            }

            return Result;
        }
        public ResponseStruct GetUserGroup(string UserName)
        {
            ResponseStruct Result;

            TShockAPI.DB.User aUser = TShockAPI.TShock.Users.GetUserByName(UserName);

            if (aUser != null)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = aUser.Group };
            }
            else
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail };
            }

            return Result;
        }
        public ResponseStruct GetPlayerBalance(string PlayerName)
        {
            ResponseStruct Result;

            List<TShockAPI.TSPlayer> Players = TShockAPI.TShock.Utils.FindPlayer(PlayerName);
            if (Players.Count == 1)
            {
                IBankAccount SelectedBankAccount = SEconomyPlugin.Instance.GetBankAccount(Players[0]);

                if (SelectedBankAccount != null)
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Done, Content = SelectedBankAccount.Balance.Value };
                }
                else
                {
                    Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "SEconomy Bank không tồn tại." } };
                }
            }
            else if (Players.Count == 0)
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Không tìm thấy Player." } };
            }
            else
            {
                Result = new ResponseStruct() { Status = ResponseStatusType.Fail, Error = new List<string>() { "Nhiều Player có tên tương tự như đã cung cấp." } };
            }

            return Result;
        }