public IPattern TakeScreenshot()
        {
            _superUser.SendCommand($"/system/bin/screencap {_imgPath}");

            using var f      = File.OpenRead(_imgPath);
            using var reader = new BinaryReader(f, Encoding.ASCII);
            var w      = reader.ReadInt32();
            var h      = reader.ReadInt32();
            var format = reader.ReadInt32();

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                reader.ReadInt32();
            }

            if (_buffer == null)
            {
                // If format is not RGBA, notify
                if (format != 1)
                {
                    AutomataApi.Toast($"Unexpected raw image format: {format}");
                }

                _buffer      = new byte[w * h * 4];
                _rootLoadMat = new Mat(h, w, CvType.Cv8uc4);
            }

            reader.Read(_buffer, 0, _buffer.Length);

            _rootLoadMat.Put(0, 0, _buffer);

            Imgproc.CvtColor(_rootLoadMat, _rootConvertMat, Imgproc.ColorRgba2gray);

            return(new DroidCvPattern(_rootConvertMat, false));
        }
Пример #2
0
        bool RegisterGestures()
        {
            IGestureService gestureService;

            try
            {
                if (Preferences.Instance.UseRootForGestures)
                {
                    gestureService = new RootGestures(GetSuperUser());
                }
                else
                {
                    gestureService = new AccessibilityGestureService(this);
                }
            }
            catch (Exception e)
            {
                Toast.MakeText(this, e.Message, ToastLength.Short).Show();
                return false;
            }

            _gestureService = gestureService;
            AutomataApi.RegisterGestures(_gestureService);
            return true;
        }
Пример #3
0
        public void PerformBattle()
        {
            AutomataApi.UseSameSnapIn(OnTurnStarted);
            AutomataApi.Wait(2);

            var NpsClicked = false;

            if (Preferences.Instance.EnableAutoSkill)
            {
                NpsClicked = AutoSkill.Execute();

                AutoSkill.ResetNpTimer();
            }

            if (!HasClickedAttack)
            {
                ClickAttack();
            }

            if (Card.CanClickNpCards)
            {
                NpsClicked = Card.ClickNpCards();
            }

            Card.ClickCommandCards(5);

            if (Preferences.Instance.UnstableFastSkipDeadAnimation)
            {
                SkipDeathAnimation();
            }

            Card.ResetCommandCards();

            AutomataApi.Wait(NpsClicked ? 25 : 5);
        }
Пример #4
0
        public void PerformBattle()
        {
            AutomataApi.UseSameSnapIn(OnTurnStarted);
            AutomataApi.Wait(2);

            var wereNpsClicked = false;

            if (Preferences.Instance.EnableAutoSkill)
            {
                wereNpsClicked = AutoSkill.Execute();

                AutoSkill.ResetNpTimer();
            }

            if (!HasClickedAttack)
            {
                ClickAttack();
            }

            if (Card.CanClickNpCards)
            {
                // We shouldn't do the long wait due to NP spam/danger modes
                // They click on NPs even when not charged
                // So, don't assign wereNpsClicked here
                Card.ClickNpCards();
            }

            Card.ClickCommandCards(5);

            Card.ResetCommandCards();

            AutomataApi.Wait(wereNpsClicked ? 25 : 5);
        }
Пример #5
0
        // Click begin quest in Formation selection, then select boost item, if applicable, then confirm selection.
        void StartQuest()
        {
            Game.MenuStartQuestClick.Click();

            AutomataApi.Wait(2);

            var boostItem = Preferences.Instance.BoostItemSelectionMode;

            if (boostItem >= 0)
            {
                Game.MenuBoostItemClickArray[boostItem].Click();

                // in case you run out of items
                Game.MenuBoostItemSkipClick.Click();
            }

            if (Preferences.Instance.StorySkip)
            {
                AutomataApi.Wait(10);

                if (Game.MenuStorySkipRegion.Exists(ImageLocator.StorySkip))
                {
                    Game.MenuStorySkipClick.Click();
                    AutomataApi.Wait(0.5);
                    Game.MenuStorySkipYesClick.Click();
                }
            }
        }
        protected override void Script()
        {
            Scaling.Init();

            var isInSupport = AutoBattle.IsInSupport();

            var supportBound = new Region(53 * 2, 0, 143 * 2, 110 * 2);
            var regionAnchor = ImageLocator.SupportRegionTool;
            var regionArray  = AutomataApi.FindAll(new Region(2100, 0, 300, 1440), regionAnchor);
            var screenBounds = new Region(0, 0, Game.ScriptWidth, Game.ScriptHeight);

            var timestamp = DateTime.Now.Ticks;

            var i = 0;

            foreach (var testRegion in regionArray)
            {
                // At max two Servant+CE are completely on screen
                if (i > 1)
                {
                    break;
                }

                if (isInSupport)
                {
                    supportBound.Y = testRegion.Y - 70 + 68 * 2;
                }
                else // Assume we are on Friend List
                {
                    supportBound.Y  = testRegion.Y + 82;
                    supportBound.X += 10;
                }

                if (!screenBounds.Contains(supportBound))
                {
                    continue;
                }

                using var pattern = supportBound.GetPattern();

                var servant = pattern.Crop(new Region(0, 0, 125, 44));
                servant.Save(Path.Combine(ImageLocator.SupportServantImgFolder, $"{timestamp}_servant{i}.png"));

                var ce = pattern.Crop(new Region(0, 80, pattern.Width, 25));
                ce.Save(Path.Combine(ImageLocator.SupportCeImgFolder, $"{timestamp}_ce{i}.png"));

                ++i;
            }

            if (i == 0)
            {
                throw new ScriptExitException("No support images were found on the current screen. Are you on Support selection or Friend list screen?");
            }

            throw new ScriptExitException($"Support Image(s) were generated.");
        }
Пример #7
0
        void SkipDeathAnimation()
        {
            // https://github.com/29988122/Fate-Grand-Order_Lua/issues/55 Experimental
            for (var i = 0; i < 3; ++i)
            {
                Game.BattleSkipDeathAnimationClick.Click();

                AutomataApi.Wait(1);
            }
        }
Пример #8
0
        void ChooseTarget(int Index)
        {
            Game.BattleTargetClickArray[Index].Click();

            AutomataApi.Wait(0.5);

            Game.BattleExtrainfoWindowCloseClick.Click();

            HasChoosenTarget = true;
        }
Пример #9
0
        void SelectSkillTarget(Location Location)
        {
            Location.Click();

            AutomataApi.Wait(0.5);

            // Exit any extra menu
            Game.BattleExtrainfoWindowCloseClick.Click();

            WaitForAnimationToFinish();
        }
Пример #10
0
        void SelectEnemyTarget(Location Location)
        {
            Location.Click();

            AutomataApi.Wait(0.5);

            // Exit any extra menu
            Game.BattleExtrainfoWindowCloseClick.Click();

            ChangeArray(_defaultFunctionArray);
        }
Пример #11
0
        public void ClickAttack()
        {
            Game.BattleAttackClick.Click();

            // Although it seems slow, make it no shorter than 1 sec to protect user with less processing power devices.
            AutomataApi.Wait(1.5);

            HasClickedAttack = true;

            Card.ReadCommandCards();
        }
        public void Click(Location Location)
        {
            const int duration = 50;

            var swipePath = new Path();

            swipePath.MoveTo(Location.X, Location.Y);
            PerformGesture(new GestureDescription.StrokeDescription(swipePath, 0, duration));

            AutomataApi.Wait(clickWaitTime);
        }
Пример #13
0
        void Reset()
        {
            ResetClick.Click();
            AutomataApi.Wait(0.5);

            ResetConfirmationClick.Click();
            AutomataApi.Wait(3);

            ResetCloseClick.Click();
            AutomataApi.Wait(2);
        }
        public void Swipe(Location Start, Location End)
        {
            var swipePath = new Path();

            swipePath.MoveTo(Start.X, Start.Y);
            swipePath.LineTo(End.X, End.Y);
            var swipeStroke = new GestureDescription.StrokeDescription(swipePath, 0, GestureTimings.SwipeDurationMs);

            PerformGesture(swipeStroke);

            AutomataApi.Wait(GestureTimings.SwipeWaitTimeSec);
        }
Пример #15
0
        void PreloadNp()
        {
            if (!Battle.HasClickedAttack)
            {
                Battle.ClickAttack();

                // There is a delay after clicking attack before NP Cards come up. DON'T DELETE!
                AutomataApi.Wait(2);
            }

            ChangeArray(_cardsPressed);
        }
        public void ContinueClick(Location Location, int Times)
        {
            while (Times-- > 0)
            {
                var swipePath = new Path();
                swipePath.MoveTo(Location.X, Location.Y);

                var stroke = new GestureDescription.StrokeDescription(swipePath, GestureTimings.ClickDelayMs, GestureTimings.ClickDurationMs);
                PerformGesture(stroke);
            }

            AutomataApi.Wait(GestureTimings.ClickWaitTimeSec);
        }
Пример #17
0
        void BeginOrderChange()
        {
            OpenMasterSkillMenu();

            Game.BattleMasterSkill3Click.Click();

            if (Preferences.Instance.SkillConfirmation)
            {
                Game.BattleSkillOkClick.Click();
            }

            AutomataApi.Wait(0.3);

            ChangeArray(_startingMemberFunctionArray);
        }
        public void ContinueClick(Location Location, int Times)
        {
            const int clickTime  = 50;
            const int clickDelay = 10;

            while (Times-- > 0)
            {
                var swipePath = new Path();
                swipePath.MoveTo(Location.X, Location.Y);

                var stroke = new GestureDescription.StrokeDescription(swipePath, clickDelay, clickTime);
                PerformGesture(stroke);
            }

            AutomataApi.Wait(clickWaitTime);
        }
Пример #19
0
        // Selections Support option
        void Support()
        {
            // Friend selection
            var hasSelectedSupport = _support.SelectSupport(Preferences.Instance.Support.SelectionMode);

            if (hasSelectedSupport && !_isContinuing)
            {
                AutomataApi.Wait(4);
                StartQuest();

                // Wait timer till battle starts.
                // Uses less battery to wait than to search for images for a few seconds.
                // Adjust according to device.
                AutomataApi.Wait(10);
            }
        }
        public void Scroll(Location Start, Location End)
        {
            const int swipeDuration = 300;

            var swipePath = new Path();

            swipePath.MoveTo(Start.X, Start.Y);
            swipePath.LineTo(End.X, End.Y);
            var swipeStroke = new GestureDescription.StrokeDescription(swipePath, 0, swipeDuration);

            PerformGesture(swipeStroke);

            const double scrollWaitTime = 0.7;

            AutomataApi.Wait(scrollWaitTime);
        }
        protected override void Script()
        {
            Scaling.Init();

            new Location(1400, 1120).Click();
            new Location(1600, 1120).Click();

            while (true)
            {
                new Location(1600, 1420).Click();
                new Location(1600, 1120).Click();
                AutomataApi.Wait(3);

                AutomataApi.ContinueClick(new Location(1600, 1300), 15);
                AutomataApi.Wait(0.5);
            }
        }
Пример #22
0
        static IPattern CreatePattern(string FilePath)
        {
            var assembly     = Assembly.GetExecutingAssembly();
            var resourceName = $"{nameof(FateGrandAutomata)}.{FilePath}";

            var stream = assembly.GetManifestResourceStream(resourceName);

            if (stream == null)
            {
                return(null);
            }

            using (stream)
            {
                return(AutomataApi.LoadPattern(stream));
            }
        }
Пример #23
0
        void SelectSubMemeber(Location Location)
        {
            Location.Click();

            AutomataApi.Wait(0.3);

            Game.BattleOrderChangeOkClick.Click();

            // Extra wait to allow order change dialog to close
            AutomataApi.Wait(1);

            WaitForAnimationToFinish(15);

            // Extra wait for the lag introduced by Order change
            AutomataApi.Wait(1);

            ChangeArray(_defaultFunctionArray);
        }
Пример #24
0
        void Withdraw()
        {
            if (!Preferences.Instance.WithdrawEnabled)
            {
                throw new ScriptExitException("All servants have been defeated and auto-withdrawing is disabled.");
            }

            Game.WithdrawRegion.Click();

            AutomataApi.Wait(0.5);

            // Click the "Accept" button after choosing to withdraw
            Game.WithdrawAcceptClick.Click();

            AutomataApi.Wait(1);

            // Click the "Close" button after accepting the withdrawal
            Game.StaminaBronzeClick.Click();
        }
Пример #25
0
        public static IPattern LoadSupportImagePattern(string FileName)
        {
            if (!SupportCachedPatterns.ContainsKey(FileName))
            {
                var stream = FileLoader(FileName);

                if (stream == null)
                {
                    throw new ScriptExitException(
                              $"Unable to load image: {FileName}. Put images in {SupportImgFolder} folder");
                }

                using (stream)
                {
                    SupportCachedPatterns.Add(FileName, AutomataApi.LoadPattern(stream));
                }
            }

            return(SupportCachedPatterns[FileName]);
        }
Пример #26
0
        static IPattern GetScaledScreenshot()
        {
            var sshot = _platformImpl.Screenshot()
                        .Crop(GameAreaManager.GameArea);

            var scale = TransformationExtensions.ScreenToImageScale();

            if (scale != null)
            {
                if (_resizeTarget == null)
                {
                    _resizeTarget = AutomataApi.GetResizableBlankPattern();
                }

                sshot.Resize(_resizeTarget, new Size(sshot.Width, sshot.Height) * scale.Value);

                return(_resizeTarget);
            }

            return(sshot);
        }
Пример #27
0
        CardScore GetCardType(Region Region)
        {
            if (Region.Exists(ImageLocator.Buster))
            {
                return(CardScore.Buster);
            }

            if (Region.Exists(ImageLocator.Art))
            {
                return(CardScore.Arts);
            }

            if (Region.Exists(ImageLocator.Quick))
            {
                return(CardScore.Quick);
            }

            AutomataApi.Toast($"Failed to determine Card type (X: {Region.X}, Y: {Region.Y}, W: {Region.W}, H: {Region.H})");

            return(CardScore.Buster);
        }
Пример #28
0
        void RefillStamina()
        {
            if (Preferences.Instance.Refill.Enabled && _stonesUsed < Preferences.Instance.Refill.Repetitions)
            {
                switch (Preferences.Instance.Refill.Resource)
                {
                case RefillResource.SQ:
                    Game.StaminaSqClick.Click();
                    break;

                case RefillResource.AllApples:
                    Game.StaminaBronzeClick.Click();
                    Game.StaminaSilverClick.Click();
                    Game.StaminaGoldClick.Click();
                    break;

                case RefillResource.Gold:
                    Game.StaminaGoldClick.Click();
                    break;

                case RefillResource.Silver:
                    Game.StaminaSilverClick.Click();
                    break;

                case RefillResource.Bronze:
                    Game.StaminaBronzeClick.Click();
                    break;
                }

                AutomataApi.Wait(1);
                Game.StaminaOkClick.Click();
                ++_stonesUsed;

                AutomataApi.Wait(3);
            }
            else
            {
                throw new ScriptExitException("AP ran out!");
            }
        }
Пример #29
0
        Dictionary <CardScore, List <int> > GetCommandCards()
        {
            var storagePerPriority = new Dictionary <CardScore, List <int> >();

            AutomataApi.UseSameSnapIn(() =>
            {
                for (var cardSlot = 0; cardSlot < 5; ++cardSlot)
                {
                    var score = GetCardAffinity(Game.BattleCardAffinityRegionArray[cardSlot])
                                | GetCardType(Game.BattleCardTypeRegionArray[cardSlot]);

                    if (!storagePerPriority.ContainsKey(score))
                    {
                        storagePerPriority.Add(score, new List <int>());
                    }

                    storagePerPriority[score].Add(cardSlot);
                }
            });

            return(storagePerPriority);
        }
Пример #30
0
        // Reset battle state, then click quest and refill stamina if needed.
        void Menu()
        {
            _battle.ResetState();

            if (Preferences.Instance.Refill.Enabled)
            {
                var refillRepetitions = Preferences.Instance.Refill.Repetitions;
                if (refillRepetitions > 0)
                {
                    AutomataApi.Toast($"{_stonesUsed} refills used out of {refillRepetitions}");
                }
            }

            // Click uppermost quest
            Game.MenuSelectQuestClick.Click();
            AutomataApi.Wait(1.5);

            // Auto refill
            while (Game.StaminaScreenRegion.Exists(ImageLocator.Stamina))
            {
                RefillStamina();
            }
        }