示例#1
0
 void ScheduleTacticsWhenLowHp()
 {
     GameEvent.Register(GameEventType.UnitReceivedFire, args =>
     {
         // If attacking, run away
         if (args.MyUnit.ActionQueue.CurrentAction is Attack ||
             args.MyUnit.ActionQueue.CurrentAction is AttackMove)
         {
             UnitActionQueue oldActions = args.MyUnit.ActionQueue;
             if (args.MyUnit.Health < args.MyUnit.MaxHealth / 2)
             {
                 // Any unit of course exposes its position in form of coordinates; MyBotData contains data
                 args.MyUnit.MoveTo(MyBotData.HealMeetPointUnit.Position);
                 BotRunner.Log("Unit " + args.MyUnit + " is waiting to be healed");
                 MyBotData.MeetPointEvent = GameEvent.Register(GameEventType.UnitGainedHealth,
                                                               argsB => { argsB.MyUnit.ActionQueue = oldActions; });
             }
         }
         // If hiding, defend
         else if (args.EnemyUnits.Length > 0)
         {
             EnqueueFirst(new Attack(args.EnemyUnits[0]), args.MyUnit);
         }
     });
 }
示例#2
0
        /// <summary>
        /// Add a bot to the runner.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public void AddBot(Type type, string username, string password)
        {
            List <VTankBot> bots = BotRunner.GetRunningBots();

            // Remove old bot if it exists.
            for (int i = 0; i < bots.Count; ++i)
            {
                VTankBot bot = bots[i];
                if (bot.AuthInfo.Username == username)
                {
                    Print("Removed duplicate bot {0}.", username);
                    BotRunner.Kill(bot);
                    break;
                }
            }

            AuthInfo auth = new AuthInfo(username, password);

            BotRunner.Register(type, auth, null);
            BotRunner.Start(false);

            Print("Added new bot, {0}.", username);

            if (OnBotChange != null)
            {
                OnBotChange(null);
            }
        }
示例#3
0
        public ModuleEquip(BotRunner r) : base(r)
        {
            proTable      = new Dictionary <int, string>();
            ItemDetails   = new Dictionary <string, ItemDetail>();
            equipPosition = new Dictionary <string, int>();

            this.proTable[1] = "狂战士";
            this.proTable[2] = "刺客";
            this.proTable[3] = "魔法师";
            this.proTable[4] = "猎人";
            this.proTable[5] = "牧师";

            this.equipPosition["主手"]  = 1;
            this.equipPosition["副手"]  = 2;
            this.equipPosition["头部"]  = 3;
            this.equipPosition["上衣"]  = 4;
            this.equipPosition["腿部"]  = 5;
            this.equipPosition["腰部"]  = 6;
            this.equipPosition["手套"]  = 7;
            this.equipPosition["鞋子"]  = 8;
            this.equipPosition["勋章"]  = 9;
            this.equipPosition["项链"]  = 10;
            this.equipPosition["戒指"]  = 11;
            this.equipPosition["护身符"] = 12;

            client.GameSocket.listen <BagItemUpdatePush>(on_item_update);
            client.GameSocket.listen <EquipmentSimplePush>(on_equip_update);
            client.GameSocket.listen <ItemDetailPush>(on_item_detail_update);
        }
示例#4
0
 public SampleBot(BotRunner runner, TargetServer server, AuthInfo auth)
     : base(runner, server, auth)
 {
     lastStamp           = Network.Util.Clock.GetTimeMilliseconds();
     stateMachine        = new BotStateMachine();
     refreshStateMachine = true;
 }
示例#5
0
        public void CancelTests()
        {
            var adjudicator = new Mock <IAdjudicator>();
            var blackBot    = new Mock <IGoBot>();
            var whiteBot    = new Mock <IGoBot>();
            int count       = 0;

            adjudicator.Setup(s => s.Dispose()).Callback(() => count++);
            blackBot.Setup(s => s.Dispose()).Callback(() => count++);
            whiteBot.Setup(s => s.Dispose()).Callback(() => count++);

            blackBot.Setup(s => s.Name).Returns(() => "Alice");
            whiteBot.Setup(s => s.Name).Returns(() => "Tony");

            IBotRunner botRunner = new BotRunner(adjudicator.Object, blackBot.Object, whiteBot.Object);

            Assert.Equal(0, count);

            botRunner.Cancel();

            Assert.Equal(3, count);
            adjudicator.VerifyAll();
            blackBot.VerifyAll();
            whiteBot.VerifyAll();
        }
示例#6
0
        /// <summary>
        /// Gets a list of currently online players.
        /// </summary>
        /// <param name="includeBots">If true, the bots ran by this bot runner are
        /// included in the list. If false, they are excluded.</param>
        /// <returns>List of tank names of online players. The list is null if the
        /// online player list cannot be accessed.</returns>
        public List <Player> GetOnlinePlayers(bool includeBots)
        {
            List <VTankBot> bots = BotRunner.GetRunningBots();

            List <Player> result = new List <Player>();

            for (int i = 0; i < bots.Count; ++i)
            {
                VTankBot bot = bots[i];
                if (bot.GameServer != null && bot.GameServer.Connected)
                {
                    AIFramework.Util.GameTracker game = bot.Game;
                    List <Player> playerList          = game.GetPlayerList();
                    foreach (AIFramework.Bot.Game.Player player in playerList)
                    {
                        if (includeBots)
                        {
                            result.Add(player);
                        }
                        else
                        {
                            if (!ContainsTank(bots, player.Name))
                            {
                                result.Add(player);
                            }
                        }
                    }

                    break;
                }
            }

            return(result);
        }
示例#7
0
 /// <summary>
 /// Disposes of the bot manager, ensuring that all bots are knocked offline and that
 /// all resources used are cleaned up.
 /// </summary>
 public void Dispose()
 {
     try
     {
         BotRunner.KillAll();
         buffer.Clear();
     }
     catch (Exception) {}
 }
示例#8
0
        /// <summary>
        /// Constructs a VTankBot.
        /// </summary>
        /// <param name="runner">Parent bot runner.</param>
        /// <param name="server">Target Echelon server.</param>
        /// <param name="auth">Authentication information.</param>
        public VTankBot(BotRunner runner, TargetServer server, AuthInfo auth)
        {
            BotRunner     = runner;
            ServerAddress = server;
            AuthInfo      = auth;
            Game          = new GameTracker(this);
            buffer        = new EventBuffer();

            CreateMasterCommunicator();
        }
示例#9
0
        /// <summary>
        /// Move an online bot to the reserved bot list.
        /// </summary>
        /// <param name="username"></param>
        public void MoveBotToReserve(string username)
        {
            List <VTankBot> bots = BotRunner.GetRunningBots();
            VTankBot        bot  = bots.Find((b) => { return(b.AuthInfo.Username == username); });

            if (bot != null)
            {
                MoveBotToReserve(bot);
            }
        }
示例#10
0
        /// <summary>
        /// Move an online bot to the reserved bot list.
        /// </summary>
        /// <param name="username"></param>
        public void MoveBotToReserve(VTankBot bot)
        {
            reservedList.Add(bot);
            BotRunner.Kill(bot);

            Print("{0} moved to reserve.", bot.AuthInfo.Username);

            if (OnBotChange != null)
            {
                OnBotChange(bot);
            }
        }
示例#11
0
        public void ItStartsAndStopsABot()
        {
            BotRunner runner = new BotRunner();
            BotStub   bot    = new BotStub();

            runner.Start(bot);

            Thread.Sleep(millisecondsTimeout: 100);
            runner.Stop();

            Assert.Greater(bot.get_updates_numcalls, 0);
            Assert.Greater(bot.handle_update_numcalls, 0);
        }
示例#12
0
 public override Task StopAsync(CancellationToken cancellationToken)
 {
     Log.Information("Service stop triggered");
     try
     {
         BotRunner.StopRunning();
         return(base.StartAsync(cancellationToken));
     }
     catch (Exception ex)
     {
         Log.Error(ex, "Exception occured when stopping the bot.");
         throw;
     }
 }
示例#13
0
        public void BotRunnerCtorTest()
        {
            var injector    = new Mock <ISimpleInjectorWrapper>();
            var confService = new Mock <IConfigurationService>();

            injector.Setup(s => s.GetInstance <IConfigurationService>()).Returns(() => confService.Object);
            var fileService = new Mock <IFileService>();

            fileService.Setup(s => s.FileExists(It.IsAny <string>())).Returns(() => true);
            injector.Setup(s => s.GetInstance <IFileService>()).Returns(() => fileService.Object);
            var processFactory = new Mock <IProcessManagerFactory>();

            processFactory.Setup(s => s.Create(It.IsAny <string>(), It.IsAny <string>())).Returns(() => new Mock <IProcessManager>().Object);
            injector.Setup(s => s.GetInstance <IProcessManagerFactory>()).Returns(() => processFactory.Object);
            var adjudicator = new Adjudicator(injector.Object, new Duel());
            var blackBot    = new Mock <IGoBot>();
            var whiteBot    = new Mock <IGoBot>();

            blackBot.Setup(s => s.Name).Returns(() => "Alice");
            whiteBot.Setup(s => s.Name).Returns(() => "Jack");
            bool?whiteStarted = null;
            bool?blackStarted = null;

            whiteBot.Setup(s => s.StartGame(It.IsAny <bool>())).Callback <bool>(c => whiteStarted = c);
            blackBot.Setup(s => s.StartGame(It.IsAny <bool>())).Callback <bool>(c => blackStarted = c);

            IBotRunner botRunner = new BotRunner(adjudicator, blackBot.Object, whiteBot.Object);

            Assert.Equal(false, whiteStarted);
            Assert.Equal(true, blackStarted);

            Assert.False(botRunner.IsFinished);
            GameResult gameResult = null;

            botRunner.EndGame = result => gameResult = result;
            Assert.Null(gameResult);
            adjudicator.Resigned(new GameResult {
                EndReason = EndGameReason.Resign
            });

            Assert.True(botRunner.IsFinished);
            Assert.NotNull(gameResult);
            Assert.Equal(EndGameReason.Resign, gameResult.EndReason);

            Assert.NotNull(botRunner);
            Assert.NotNull(botRunner.EndGame);
            blackBot.VerifyAll();
            whiteBot.VerifyAll();
        }
示例#14
0
        public static void Gather(Worker worker)
        {
            var resource = ResourceHelper.GetNearestMineralTo(worker);

            if (resource == null)
            {
                BotRunner.Log("Worker couldn't find another Resource");
                return;
            }
            if (CreateBaseIfNone(worker))
            {
                return;
            }
            worker.SendGather(resource).After(new CustomFunction(() => Gather(worker)));
        }
示例#15
0
 void BuildArmy(Action startNextStage)
 {
     GameEvent.Register(GameEventType.MineralsChanged, argsMinerals =>
     {
         // First wave starts at 5 units
         if (!MyBotData.Rushed && MyBotData.Army >= 5)
         {
             startNextStage();
             MyBotData.Rushed = true;
         }
         // Production ends after 20
         else if (MyBotData.Army >= 20)
         {
             argsMinerals.ThisGameEvent.UnregisterEvent();
             return;
         }
         if (_producingDonkeyGun != null || argsMinerals.Minerals <= 100)
         {
             return;
         }
         foreach (NubianArmory armory in BuildingHelper.GetMyBuildings <NubianArmory>())
         {
             if (armory.QueuedUnits >= 2)
             {
                 continue;
             }
             if (armory.CanNowProduceUnit(UnitType.DonkeyGun))
             {
                 armory.ProduceUnit(UnitType.DonkeyGun);
                 // Additional mineral sink: producing one more expensive Unit if too rich
                 if (armory.CanNowProduceUnit(UnitType.WraithRaider))
                 {
                     armory.ProduceUnit(UnitType.WraithRaider);
                 }
                 _producingDonkeyGun = GameEvent.Register(GameEventType.UnitProduced, argsUnit =>
                 {
                     if (argsUnit.MyUnit is DonkeyGun)
                     {
                         MyBotData.Army++;
                         BotRunner.Log("My army contains " + MyBotData.Army + " battle units");
                         argsUnit.ThisGameEvent.UnregisterEvent();
                         _producingDonkeyGun = null;
                     }
                 });
             }
         }
     });
 }
示例#16
0
        public BotManager(BotRunner runner)
        {
            buffer       = new InvocationBuffer();
            reservedList = new List <VTankBot>();

            BotRunner         = runner;
            WaitTimeReconnect = 5000;

            BotRunner.OnCrash += new BotRunner.Disconnect((bot) =>
            {
                buffer.Enqueue(new Invocation.InvocationTarget(HandleCrash),
                               bot, WaitTimeReconnect);
            });

            BotRunner.OnBotStateChange += new BotRunner.BotStateChange(BotRunner_OnBotStateChange);
            needsBalance = false;
        }
示例#17
0
 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
 {
     Log.Information("Runnin started");
     try
     {
         var currentDirectory    = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
         var preferencesFilePath = Path.Combine(currentDirectory, "Preferences.txt");
         var serializedTags      = File.ReadAllText(preferencesFilePath);
         var tags = JsonConvert.DeserializeObject <List <Tag> >(serializedTags);
         await BotRunner.RunBotForTagsAsync(tags, new LoggerWrapper());
     }
     catch (Exception ex)
     {
         Log.Error(ex, "Exception occured when starting the bot. Attempting to stop.");
         throw;
     }
 }
示例#18
0
        public void BotHandlesAnUpdateMessage()
        {
            ApiClient api_client = new ApiClient(API_TOKEN, http_client_stub);
            BotRunner bot_runner = new BotRunner();
            Bot       bot        = new Bot(api_client, bot_runner);

            bot.InstallUpdateHandler(new HelloTestHandler());

            bot.Start();

            InjectUpdate(TEST_HELLO_MESSAGE);

            Thread.Sleep(millisecondsTimeout: 200);
            bot.Stop();

            Assert.AreEqual("Hello John", SentMessage().text);
            Assert.AreEqual(344365009, SentMessage().chat_id);
        }
示例#19
0
        private void Run(string message)
        {
            var container = new Container();

            container.RegisterInstance(null, typeof(IConfigurationRoot), this.configurationRootMock.Object);

            FrameworkBuilder.Create()
            .AddModule(m => m.Module(new SerializationModule()))
            .AddModule(m => m.Module(new BotModule()))
            .AddModule(m => m.Module(new BotAzureModule()))
            .AddModule(m => m.Module(new AzureApplicationInsightsModule()))
            .AddBotAction <TestReplyAction>()
            .AddBotForm <MyModel>()
            .Bootstrapp();

            string queueItem = QueueItem(message);

            BotRunner.Run(queueItem).Wait();
        }
示例#20
0
        /// <summary>
        /// Displays and configures the main window.
        /// Starts the bot runner.
        /// </summary>
        /// <param name="configurationFile">Path to the bot configuration file.</param>
        /// <param name="botRunner">Created bot runner.</param>
        public MainWindow(string configurationFile, BotRunner botRunner)
        {
            Visible = false;

            botManager           = new BotManager(botRunner);
            updateTimer          = new System.Windows.Forms.Timer();
            updateTimer.Interval = 100;
            updateTimer.Tick    += new EventHandler((sender, e) =>
            {
                botManager.Update();
            });

            this.configFile = configurationFile;
            this.runner     = botRunner;

            SetOptions();

            InitializeComponent();
        }
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            var kernel = new StandardKernel();

            // services dependency injections
            kernel.Bind <AuthenticationService>().To <AuthenticationService>().InSingletonScope();
            kernel.Bind <IMessangerService>().To <MessangerService>().InSingletonScope();
            kernel.Bind <IUserSearchingService>().To <UserSearchingService>().InSingletonScope();
            kernel.Bind <MessageSearchingService>().To <MessageSearchingService>().InSingletonScope();
            kernel.Bind <RegistrationService>().To <RegistrationService>().InSingletonScope();
            kernel.Bind <CsvUserExportService>().To <CsvUserExportService>().InSingletonScope();
            kernel.Bind <CsvMessageExportService>().To <CsvMessageExportService>().InSingletonScope();
            kernel.Bind <IFriendsService>().To <FriendsService>().InSingletonScope();
            kernel.Bind <UserValidationService>().To <UserValidationService>().InSingletonScope();
            kernel.Bind <IMessageSearchingService>().To <MessageSearchingService>().InSingletonScope();
            kernel.Bind <IMessageHistoryService>().To <MessagesHistoryService>().InSingletonScope();
            kernel.Bind <IShortestUserPathService>().To <ShortestUserPathService>().InSingletonScope();
            kernel.Bind <IPathProvider>().To <PathProvider>().InSingletonScope();
            kernel.Bind <IImageService>().To <ImageService>().InSingletonScope();
            kernel.Bind <IEndPointSetter>().To <AuthenticationService>().InSingletonScope();


            config.DependencyResolver = new NinjectResolver(kernel);
            // Run Bot1
            var botRunner = new BotRunner();

            botRunner.Run();

            // Configure Web API to use only bearer token authentication.
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
                );
        }
示例#22
0
        public static void RegisterReceiveFire()
        {
            var receivedFire = new Action <Arguments>(args =>
            {
                foreach (var enemyUnit in args.EnemyUnits)
                {
                    BotRunner.Log(enemyUnit + " attacked me");
                    // The Unit defends itself
                    if (args.MyUnit != null)
                    {
                        EnqueueFirst(new Attack(enemyUnit), args.MyUnit);
                    }
                    // Another Unit helps
                    AttackUnit(enemyUnit);
                }
            });

            GameEvent.Register(GameEventType.UnitReceivedFire, args => receivedFire.Invoke(args));
            GameEvent.Register(GameEventType.BuildingReceivedFire, args => receivedFire.Invoke(args));
        }
示例#23
0
        private static void Main()
        {
            using (var work = new UnitOfWork())
            {
                var res = work.Cities;
            }

            var iOService = NinjectKernel.Get <IInputOutputSevice>();

            // Run Bot1
            var botRunner = new BotRunner();

            botRunner.Run();

            iOService.Out.WriteLine(Resources.InfoGreeting);
            Logger.Info(Resources.InfoGreeting);

            Command authenHandlers   = GetAuthenticationCommand();
            Command loggedInHandlers = GetLoggedInCommand();

            var exitCommand = false;

            exitMethod = (sender, e) => { exitCommand = true; };
            while (!exitCommand)
            {
                while (!CommandHandler.Session.IsLogged)
                {
                    iOService.Out.WriteLine(Resources.InfoFirsUsage);
                    iOService.Out.Write(Resources.InfoNewCommandLine);

                    authenHandlers.Execute(iOService.In.ReadLine());

                    iOService.Out.WriteLine();
                }

                iOService.Out.Write(Resources.InfoNewCommandLine);
                loggedInHandlers.Execute(iOService.In.ReadLine());

                iOService.Out.WriteLine();
            }
        }
示例#24
0
        public ModuleRank(BotRunner r) : base(r)
        {
            Kinds = new List <int>();

            Kinds.Add(101);
            Kinds.Add(102);
            Kinds.Add(103);
            Kinds.Add(104);
            Kinds.Add(105);
            Kinds.Add(106);
            Kinds.Add(200);
            Kinds.Add(300);
            Kinds.Add(400);
            Kinds.Add(500);
            Kinds.Add(600);
            Kinds.Add(700);
            Kinds.Add(10001);
            Kinds.Add(10002);
            Kinds.Add(10003);
            Kinds.Add(10004);
            Kinds.Add(10005);
        }
示例#25
0
        private static async Task DoTest(BenchmarkSettings settings)
        {
            Console.WriteLine("____________________________________");
            Console.WriteLine("Board size: {0}, bot #1 strength : {1}, bot #2 strength: {2}", settings.BoardSize, settings.FirstBotLevel, settings.SecondBotLevel);
            tcs = new TaskCompletionSource <bool>();
            Watch.Restart();

            var botWhite = botFactory.CreateBotInstance(botKind, "WhiteBot");

            botWhite.BoardSize = settings.BoardSize;
            botWhite.Level     = settings.FirstBotLevel;

            var botBlack = botFactory.CreateBotInstance(new BotKind {
                BinaryPath = botKind.BinaryPath, FullClassName = botKind.FullClassName
            }, "BlackBot");

            botBlack.BoardSize = settings.BoardSize;
            botBlack.Level     = settings.SecondBotLevel;

            var judge = new Adjudicator(
                Bootstrap(),
                new Duel
            {
                BoardSize = settings.BoardSize,
                BlackBot  = "BlackBot",
                WhiteBot  = "WhiteBot",
                Name      = "Benchmarking"
            })
            {
                SaveGameResults = true, GenerateLastBoard = true
            };
            var runner = new BotRunner(judge, botBlack, botWhite)
            {
                EndGame = OnTestFinised
            };
            await tcs.Task;

            runner.Cancel();
        }
示例#26
0
        static void Main(string[] args)
        {
            var included = new StreamReader(File.OpenRead("categories.txt")).ReadToEnd().Split('\n').Select(a => a.Trim('\r'));

            var restAPIKey         = ConfigurationManager.AppSettings["wooCommerceRestAPIKey"];
            var restAPISecret      = ConfigurationManager.AppSettings["wooCommerceRestAPISecret"];
            var priceLowCap        = ConfigurationManager.AppSettings["priceLowCap"];
            var priceHighCap       = ConfigurationManager.AppSettings["priceHighCap"];
            var maxItemPerCategory = int.Parse(ConfigurationManager.AppSettings["maxItemPerCategory"]);

            var markUpPercentage     = Double.Parse(ConfigurationManager.AppSettings["markUpPercentage"]);
            var usdtoMyrCurrencyRate = Double.Parse(ConfigurationManager.AppSettings["usdtoMyrCurrencyRate"]);
            var postTypeStr          = ConfigurationManager.AppSettings["postAs"];

            var productPauseDelay = int.Parse(ConfigurationManager.AppSettings["productPauseDelay"]);

            var productMinPriceAfterConvert = Double.Parse(ConfigurationManager.AppSettings["productMinPriceAfterConvert"]);
            var productBelowMinMarkup       = Double.Parse(ConfigurationManager.AppSettings["productBelowMinMarkup"]);

            var bot = new BotRunner(
                postTypeStr,
                included,
                priceLowCap,
                priceHighCap,
                restAPIKey,
                restAPISecret,
                markUpPercentage,
                usdtoMyrCurrencyRate,
                productMinPriceAfterConvert,
                productBelowMinMarkup,
                maxItemPerCategory,
                productPauseDelay,
                new ConsoleLogger(),
                new ConsoleResultHandler(),
                15 * 60 * 1000);

            bot.Run();
        }
示例#27
0
        /// <summary>
        /// Remove a bot from the entire bot manager, including the reserved list.
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public bool Remove(string username)
        {
            bool found = false;

            if (!BotRunner.Kill(username))
            {
                VTankBot bot = reservedList.Find((b) => { return(b.AuthInfo.Username == username); });
                if (bot != null)
                {
                    found = reservedList.Remove(bot);
                }
            }
            else
            {
                found = true;
            }

            if (found && OnBotChange != null)
            {
                OnBotChange(null);
            }

            return(found);
        }
示例#28
0
 public ModuleRequest(BotRunner r) : base(r)
 {
 }
示例#29
0
 public BotModuleAutoBattle(BotRunner r) : base(r)
 {
     base.Client.OnZoneActorEntered += Client_OnZoneActorEntered;
 }
示例#30
0
        public override int Run(string[] remainingArguments)
        {
            BotRunner.Run();

            return(1);
        }
示例#31
0
        public void SetUp()
        {
            _module1 = MockRepository.GenerateStub<IModule>();
            _module2 = MockRepository.GenerateStub<IModule>();
            _modules = new List<IModule> {_module1, _module2};

            _configurationManager = MockRepository.GenerateStub<IConfigurationManager>();
            _client = MockRepository.GenerateStub<IIrcClient>();
            _runner = new BotRunner(_configurationManager, _client, _modules);

            _configurationManager.Server = SERVER;
            _configurationManager.Port = PORT;
            _configurationManager.Nickname = NICKNAME;
            _configurationManager.Hostname = HOSTNAME;
            _configurationManager.Email = EMAIL;
            _configurationManager.Channels = new List<string> { "#a", "#b" };
        }