public override sealed async Task RunAsync(IInteractionProvider provider)
 {
     provider.PressKey(key);
     // Use a accurate timer for measuring the time after we need to release the key.
     await provider.WaitAsync(duration, true);
     provider.ReleaseKey(key);
 }
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            provider.PressKey(this.key);
            // Use a accurate timer for measuring the time after we need to release the key.
            await provider.WaitAsync(this.duration, true);

            provider.ReleaseKey(this.key);
        }
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // write the text and presses enter.
            if (!pauseDuration.HasValue)
                provider.WriteText(text);
            else
            {
                for (int i = 0; i < text.Length; i++)
                {
                    provider.WriteText(text[i].ToString());
                    await provider.WaitAsync(pauseDuration.Value);
                }
            }

            // A CR LF (\r\n) in the above string would not have the desired effect;
            // instead we need to press the enter key.
            provider.PressKey(AbstractWindowsEnvironment.VirtualKeyShort.Enter);
            await provider.WaitAsync(100);
            provider.ReleaseKey(AbstractWindowsEnvironment.VirtualKeyShort.Enter);
        }
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Click on the "Plant Flower" button.
            await MouseHelpers.DoSimpleMouseClickAsync(provider, new Coordinates(76, 264),
                VerticalScaleAlignment.Left);
            await provider.WaitAsync(200);

            // Click on the jellybean fields.
            foreach (int jellybean in jellybeanCombination)
            {
                var c = new Coordinates((int)Math.Round(560 + jellybean * 60.5), 514);
                await MouseHelpers.DoSimpleMouseClickAsync(provider, c,
                    VerticalScaleAlignment.Center, 100);
                await provider.WaitAsync(100);
            }
            await provider.WaitAsync(100);

            // Click on the "Plant" button.
            await MouseHelpers.DoSimpleMouseClickAsync(provider, new Coordinates(975, 772));
        }
        protected override sealed async Task FinishThrowFishingRodAsync(IInteractionProvider provider)
        {
            // Simply throw the fishing rod straight, without checking for bubbles.
            Coordinates coords = new Coordinates(800, 1009);
            var pos = provider.GetCurrentWindowPosition();
            coords = pos.RelativeToAbsoluteCoordinates(pos.ScaleCoordinates(coords,
                MouseHelpers.ReferenceWindowSize));

            provider.MoveMouse(coords);
            await provider.WaitAsync(300);
            provider.ReleaseMouseButton();
        }
Пример #6
0
        public static async Task DoSimpleMouseClickAsync(IInteractionProvider provider,
            Coordinates coords, VerticalScaleAlignment valign = VerticalScaleAlignment.Center,
            int buttonDownTimeout = 200)
        {
            var pos = provider.GetCurrentWindowPosition();
            coords = pos.RelativeToAbsoluteCoordinates(pos.ScaleCoordinates(coords,
                ReferenceWindowSize, valign));

            provider.MoveMouse(coords);
            provider.PressMouseButton();
            await provider.WaitAsync(buttonDownTimeout);
            provider.ReleaseMouseButton();
        }
Пример #7
0
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Click on the "Plant Flower" button.
            await MouseHelpers.DoSimpleMouseClickAsync(provider, new Coordinates(76, 264),
                                                       VerticalScaleAlignment.Left);

            await provider.WaitAsync(200);

            // Click on the jellybean fields.
            foreach (int jellybean in this.jellybeanCombination)
            {
                var c = new Coordinates((int)Math.Round(560 + jellybean * 60.5), 514);
                await MouseHelpers.DoSimpleMouseClickAsync(provider, c,
                                                           VerticalScaleAlignment.Center, 100);

                await provider.WaitAsync(100);
            }
            await provider.WaitAsync(100);

            // Click on the "Plant" button.
            await MouseHelpers.DoSimpleMouseClickAsync(provider, new Coordinates(975, 772));
        }
Пример #8
0
        protected override sealed async Task FinishCastFishingRodAsync(IInteractionProvider provider)
        {
            // Simply cast the fishing rod straight, without checking for bubbles.
            var coords = new Coordinates(800, 1009);
            var pos    = provider.GetCurrentWindowPosition();

            coords = pos.ScaleCoordinates(coords,
                                          MouseHelpers.ReferenceWindowSize);

            provider.MoveMouse(coords);
            await provider.WaitAsync(300);

            provider.ReleaseMouseButton();
        }
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // write the text and presses enter.
            if (!this.pauseDuration.HasValue)
            {
                provider.WriteText(this.text);
            }
            else
            {
                for (int i = 0; i < this.text.Length; i++)
                {
                    provider.WriteText(this.text[i].ToString());
                    await provider.WaitAsync(this.pauseDuration.Value);
                }
            }

            // A CR LF (\r\n) in the above string would not have the desired effect;
            // instead we need to press the enter key.
            provider.PressKey(AbstractWindowsEnvironment.VirtualKeyShort.Enter);
            await provider.WaitAsync(100);

            provider.ReleaseKey(AbstractWindowsEnvironment.VirtualKeyShort.Enter);
        }
Пример #10
0
        public static async Task DoSimpleMouseClickAsync(IInteractionProvider provider,
                                                         Coordinates coords, VerticalScaleAlignment valign = VerticalScaleAlignment.Center,
                                                         int buttonDownTimeout = 150)
        {
            var pos = provider.GetCurrentWindowPosition();

            coords = pos.ScaleCoordinates(coords,
                                          ReferenceWindowSize, valign);

            provider.MoveMouse(coords);
            provider.PressMouseButton();
            await provider.WaitAsync(buttonDownTimeout);

            provider.ReleaseMouseButton();
        }
Пример #11
0
        /// <summary>
        /// Clicks on the fishing rod button.
        /// </summary>
        /// <param name="provider"></param>
        /// <returns></returns>
        protected async Task StartCastFishingRodAsync(IInteractionProvider provider)
        {
            var coords = new Coordinates(800, 846);
            var pos    = provider.GetCurrentWindowPosition();

            coords = pos.ScaleCoordinates(coords,
                                          MouseHelpers.ReferenceWindowSize);

            // Move the mouse and press the button.
            provider.MoveMouse(coords);
            provider.PressMouseButton();

            await provider.WaitAsync(300);

            CheckForFishErrorDialog(provider);
        }
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Click on the Speedchat Icon.
            Coordinates c = new Coordinates(122, 40);
            await MouseHelpers.DoSimpleMouseClickAsync(provider, c, VerticalScaleAlignment.Left, 100);

            int currentYNumber = 0;
            for (int i = 0; i < menuItems.Length; i++)
            {
                await provider.WaitAsync(300);

                currentYNumber += menuItems[i];
                c = new Coordinates(xWidths[i], (40 + currentYNumber * 38));
                await MouseHelpers.DoSimpleMouseClickAsync(provider, c, VerticalScaleAlignment.Left, 100);
            }
        }
Пример #13
0
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Click on the Speedchat Icon.
            var c = new Coordinates(122, 40);
            await MouseHelpers.DoSimpleMouseClickAsync(provider, c, VerticalScaleAlignment.Left, 100);

            int currentYNumber = 0;

            for (int i = 0; i < this.menuItems.Length; i++)
            {
                await provider.WaitAsync(300);

                currentYNumber += this.menuItems[i];
                c = new Coordinates(xWidths[i], (40 + currentYNumber * 38));
                await MouseHelpers.DoSimpleMouseClickAsync(provider, c, VerticalScaleAlignment.Left, 100);
            }
        }
Пример #14
0
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Cast the fishing rod
            OnActionInformationUpdated("Casting…");
            await StartCastFishingRodAsync(provider);
            await FinishCastFishingRodAsync(provider);

            // Then, wait until we find a window displaying the caught fish
            // or the specified number of seconds has passed.
            OnActionInformationUpdated("Waiting for the fish result dialog…");
            var sw = new Stopwatch();

            sw.Start();

            bool found = false;

            while (!found && sw.ElapsedMilliseconds <= this.WaitingForFishResultDialogTime)
            {
                await provider.WaitAsync(500);

                // Get a current screenshot.
                var screenshot = provider.GetCurrentWindowScreenshot();

                foreach (var c in fishResultDialogCoordinates)
                {
                    var cc = screenshot.WindowPosition.ScaleCoordinates(
                        c, MouseHelpers.ReferenceWindowSize);
                    var col = screenshot.GetPixel(cc);

                    if (CompareColor(fishDialogColor, col, 10))
                    {
                        // OK, we caught a fish, so break from the loop.
                        found = true;
                        break;
                    }
                }
            }
        }
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Cast the fishing rod
            OnActionInformationUpdated("Casting…");
            await StartCastFishingRodAsync(provider);
            await FinishCastFishingRodAsync(provider);

            // Then, wait until we find a window displaying the caught fish
            // or the specified number of seconds has passed.
            OnActionInformationUpdated("Waiting for the fish result dialog…");
            Stopwatch sw = new Stopwatch();
            sw.Start();

            bool found = false;
            while (!found && sw.ElapsedMilliseconds <= WaitingForFishResultDialogTime)
            {
                await provider.WaitAsync(500);

                // Get a current screenshot.
                var screenshot = provider.GetCurrentWindowScreenshot();

                foreach (Coordinates c in fishResultDialogCoordinates)
                {
                    var cc = screenshot.WindowPosition.ScaleCoordinates(
                        c, MouseHelpers.ReferenceWindowSize);
                    var col = screenshot.GetPixel(cc);

                    if (CompareColor(fishDialogColor, col, 10))
                    {
                        // OK, we caught a fish, so break from the loop.
                        found = true;
                        break;
                    }
                }
            }
        }
Пример #16
0
 public override sealed async Task RunAsync(IInteractionProvider provider) =>
     await provider.WaitAsync(duration);
        protected override sealed async Task FinishCastFishingRodAsync(IInteractionProvider provider)
        {
            // Try to find a bubble.
            const string actionInformationScanning = "Scanning for fish bubbles…";
            OnActionInformationUpdated(actionInformationScanning);

            const int scanStep = 15;

            Stopwatch sw = new Stopwatch();
            sw.Start();

            Coordinates? oldCoords = null;
            Coordinates? newCoords;
            int coordsMatchCounter = 0;
            while (true)
            {
                var screenshot = provider.GetCurrentWindowScreenshot();
                newCoords = null;

                // TODO: The fish bubble detection should be changed so that it does not scan
                // for a specific color, but instead checks that for a point if the color is
                // darker than the neighbor pixels (in some distance).
                for (int y = spotData.Scan1.Y; y <= spotData.Scan2.Y && !newCoords.HasValue; y += scanStep)
                {
                    for (int x = spotData.Scan1.X; x <= spotData.Scan2.X; x += scanStep)
                    {
                        var c = new Coordinates(x, y);
                        c = screenshot.WindowPosition.ScaleCoordinates(c,
                            MouseHelpers.ReferenceWindowSize);
                        if (CompareColor(spotData.BubbleColor, screenshot.GetPixel(c),
                            spotData.Tolerance))
                        {
                            newCoords = new Coordinates(x + 20, y + 20);
                            Coordinates scaledCoords = screenshot.WindowPosition.RelativeToAbsoluteCoordinates(
                                screenshot.WindowPosition.ScaleCoordinates(
                                newCoords.Value, MouseHelpers.ReferenceWindowSize));

                            OnActionInformationUpdated($"Found bubble at {scaledCoords.X}, {scaledCoords.Y}…");
                            break;
                        }
                    }
                }
                if (!newCoords.HasValue)
                    OnActionInformationUpdated(actionInformationScanning);


                if (newCoords.HasValue && oldCoords.HasValue
                    && Math.Abs(oldCoords.Value.X - newCoords.Value.X) <= scanStep
                    && Math.Abs(oldCoords.Value.Y - newCoords.Value.Y) <= scanStep)
                {
                    // The new coordinates are (nearly) the same as the previous ones.
                    coordsMatchCounter++;
                }
                else
                {
                    // Reset the counter and update the coordinates even if we currently didn't
                    // find them.
                    oldCoords = newCoords;
                    coordsMatchCounter = 0;
                }


                // Now position the mouse already so that we just need to release the button.
                if (!newCoords.HasValue)
                {
                    // If we couldn't find the bubble we use default destination x,y values.
                    newCoords = new Coordinates(800, 1009);
                }
                else
                {
                    // Calculate the destination coordinates.
                    newCoords = new Coordinates(
                        (int)Math.Round(800d + 120d / 429d * (800d - newCoords.Value.X) *
                        (0.75 + (820d - newCoords.Value.Y) / 820 * 0.38)),
                        (int)Math.Round(846d + 169d / 428d * (820d - newCoords.Value.Y))
                    );
                }

                // Note: Instead of using a center position for scaling the X coordinate,
                // TTR seems to interpret it as being scaled from an 4/3 ratio. Therefore
                // we need to specify "NoAspectRatio" here.
                // However it could be that they will change this in the future, then 
                // we would need to use "Center".
                // Note: We assume the point to click on is exactly centered. Otherwise
                // we would need to adjust the X coordinate accordingly.
                var coords = screenshot.WindowPosition.RelativeToAbsoluteCoordinates(
                    screenshot.WindowPosition.ScaleCoordinates(newCoords.Value,
                    MouseHelpers.ReferenceWindowSize, VerticalScaleAlignment.NoAspectRatio));
                provider.MoveMouse(coords);


                if (coordsMatchCounter == 2)
                {
                    // If we found the same coordinates two times, we assume
                    // the bubble is not moving at the moment.
                    break;
                }
                
                await provider.WaitAsync(500);

                // Ensure we don't wait longer than 36 seconds.
                if (sw.ElapsedMilliseconds >= 36000)
                    break;
            }


            // There is no need to wait here because the mouse has already been positioned and we
            // waited at least 2x 500 ms at the new position, so now just release the mouse button.
            provider.ReleaseMouseButton();
        }
Пример #18
0
 public override sealed async Task RunAsync(IInteractionProvider provider) =>
 await provider.WaitAsync(this.duration);
Пример #19
0
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Run the actions.
            int currentIdx  = -1;
            var randomOrder = null as int[];

            Func <int> getNextActionIndex;

            if (this.type == CompoundActionType.Sequential)
            {
                getNextActionIndex = () =>
                                     (!this.loop && currentIdx + 1 == this.actionList.Count) ? -1
                    : currentIdx = (currentIdx + 1) % this.actionList.Count;
            }
            else if (this.type == CompoundActionType.RandomIndex)
            {
                getNextActionIndex = () => this.rng.Next(this.actionList.Count);
            }
            else
            {
                randomOrder        = new int[this.actionList.Count];
                getNextActionIndex = () =>
                {
                    if (!this.loop && currentIdx + 1 == this.actionList.Count)
                    {
                        return(-1);
                    }

                    currentIdx = (currentIdx + 1) % this.actionList.Count;
                    if (currentIdx == 0)
                    {
                        // Generate a new order array.
                        for (int i = 0; i < randomOrder.Length; i++)
                        {
                            randomOrder[i] = i;
                        }
                        for (int i = 0; i < randomOrder.Length; i++)
                        {
                            int rIdx = this.rng.Next(randomOrder.Length - i);
                            int tmp  = randomOrder[i];
                            randomOrder[i]        = randomOrder[i + rIdx];
                            randomOrder[i + rIdx] = tmp;
                        }
                    }

                    return(randomOrder[currentIdx]);
                };
            }

            while (true)
            {
                int nextIdx = getNextActionIndex();
                if (nextIdx == -1)
                {
                    break;
                }

                OnActionInformationUpdated($"Running action {nextIdx + 1}");

                while (true)
                {
                    try
                    {
                        // Check if the simulator has already been canceled.
                        provider.EnsureNotCanceled();

                        OnSubActionStartedOrStopped(nextIdx);
                        try
                        {
                            await this.actionList[nextIdx].RunAsync(provider);
                        }
                        finally
                        {
                            OnSubActionStartedOrStopped(null);
                        }

                        // After running an action, wait.
                        int waitInterval = this.rng.Next(this.minimumPauseDuration, this.maximumPauseDuration);
                        OnActionInformationUpdated($"Pausing {waitInterval} ms");

                        await provider.WaitAsync(waitInterval);
                    }
                    catch (Exception ex) when(!(ex is SimulatorCanceledException))
                    {
                        await provider.CheckRetryForExceptionAsync(ex);

                        continue;
                    }
                    break;
                }
            }
        }
        public override sealed async Task RunAsync(IInteractionProvider provider)
        {
            // Run the actions.
            int currentIdx = -1;
            int[] randomOrder = null;

            Func<int> getNextActionIndex;
            if (type == CompoundActionType.Sequential)
                getNextActionIndex = () => 
                    (!loop && currentIdx + 1 == actionList.Count) ? -1 
                    : currentIdx = (currentIdx + 1) % actionList.Count;
            else if (type == CompoundActionType.RandomIndex)
                getNextActionIndex = () => rng.Next(actionList.Count);
            else
            {
                randomOrder = new int[actionList.Count];
                getNextActionIndex = () =>
                {
                    if (!loop && currentIdx + 1 == actionList.Count)
                        return -1;

                    currentIdx = (currentIdx + 1) % actionList.Count;
                    if (currentIdx == 0)
                    {
                        // Generate a new order array.
                        for (int i = 0; i < randomOrder.Length; i++)
                            randomOrder[i] = i;
                        for (int i = 0; i < randomOrder.Length; i++)
                        {
                            int rIdx = rng.Next(randomOrder.Length - i);
                            int tmp = randomOrder[i];
                            randomOrder[i] = randomOrder[i + rIdx];
                            randomOrder[i + rIdx] = tmp;
                        }
                    }

                    return randomOrder[currentIdx];
                };
            }

            while (true)
            {
                // Check if the simulator has already been canceled.
                provider.EnsureNotCanceled();

                int nextIdx = getNextActionIndex();
                if (nextIdx == -1)
                    break;

                OnActionInformationUpdated($"Running action {nextIdx + 1}");

                OnSubActionStartedOrStopped(nextIdx);
                try
                {
                    IAction action = actionList[nextIdx];
                    await action.RunAsync(provider);
                }
                finally
                {
                    OnSubActionStartedOrStopped(null);
                }

                // After running an action, wait.
                int waitInterval = rng.Next(minimumPauseDuration, maximumPauseDuration);
                OnActionInformationUpdated($"Pausing {waitInterval} ms");

                await provider.WaitAsync(waitInterval);
            }
        }
Пример #21
0
        protected override sealed async Task FinishCastFishingRodAsync(IInteractionProvider provider)
        {
            // Try to find a bubble.
            const string actionInformationScanning = "Scanning for fish bubbles…";

            OnActionInformationUpdated(actionInformationScanning);

            const int scanStep = 15;

            var sw = new Stopwatch();

            sw.Start();

            Coordinates?oldCoords = null;
            Coordinates?newCoords;
            int         coordsMatchCounter = 0;

            while (true)
            {
                var screenshot = provider.GetCurrentWindowScreenshot();
                newCoords = null;

                // TODO: The fish bubble detection should be changed so that it does not scan
                // for a specific color, but instead checks that for a point if the color is
                // darker than the neighbor pixels (in some distance).
                for (int y = this.spotData.Scan1.Y; y <= this.spotData.Scan2.Y && !newCoords.HasValue; y += scanStep)
                {
                    for (int x = this.spotData.Scan1.X; x <= this.spotData.Scan2.X; x += scanStep)
                    {
                        var c = new Coordinates(x, y);
                        c = screenshot.WindowPosition.ScaleCoordinates(c,
                                                                       MouseHelpers.ReferenceWindowSize);
                        if (CompareColor(this.spotData.BubbleColor, screenshot.GetPixel(c),
                                         this.spotData.Tolerance))
                        {
                            newCoords = new Coordinates(x + 20, y + 20);
                            var scaledCoords = screenshot.WindowPosition.ScaleCoordinates(
                                newCoords.Value, MouseHelpers.ReferenceWindowSize);

                            OnActionInformationUpdated($"Found bubble at {scaledCoords.X}, {scaledCoords.Y}…");
                            break;
                        }
                    }
                }
                if (!newCoords.HasValue)
                {
                    OnActionInformationUpdated(actionInformationScanning);
                }


                if (newCoords.HasValue && oldCoords.HasValue &&
                    Math.Abs(oldCoords.Value.X - newCoords.Value.X) <= scanStep &&
                    Math.Abs(oldCoords.Value.Y - newCoords.Value.Y) <= scanStep)
                {
                    // The new coordinates are (nearly) the same as the previous ones.
                    coordsMatchCounter++;
                }
                else
                {
                    // Reset the counter and update the coordinates even if we currently didn't
                    // find them.
                    oldCoords          = newCoords;
                    coordsMatchCounter = 0;
                }


                // Now position the mouse already so that we just need to release the button.
                if (!newCoords.HasValue)
                {
                    // If we couldn't find the bubble we use default destination x,y values.
                    newCoords = new Coordinates(800, 1009);
                }
                else
                {
                    // Calculate the destination coordinates.
                    newCoords = new Coordinates(
                        (int)Math.Round(800d + 120d / 429d * (800d - newCoords.Value.X) *
                                        (0.75 + (820d - newCoords.Value.Y) / 820 * 0.38)),
                        (int)Math.Round(846d + 169d / 428d * (820d - newCoords.Value.Y))
                        );
                }

                // Note: Instead of using a center position for scaling the X coordinate,
                // TTR seems to interpret it as being scaled from an 4/3 ratio. Therefore
                // we need to specify "NoAspectRatio" here.
                // However it could be that they will change this in the future, then
                // we would need to use "Center".
                // Note: We assume the point to click on is exactly centered. Otherwise
                // we would need to adjust the X coordinate accordingly.
                var coords = screenshot.WindowPosition.ScaleCoordinates(newCoords.Value,
                                                                        MouseHelpers.ReferenceWindowSize, VerticalScaleAlignment.NoAspectRatio);
                provider.MoveMouse(coords);


                if (coordsMatchCounter == 2)
                {
                    // If we found the same coordinates two times, we assume
                    // the bubble is not moving at the moment.
                    break;
                }

                await provider.WaitAsync(500);

                // Ensure we don't wait longer than 36 seconds.
                if (sw.ElapsedMilliseconds >= 36000)
                {
                    break;
                }
            }


            // There is no need to wait here because the mouse has already been positioned and we
            // waited at least 2x 500 ms at the new position, so now just release the mouse button.
            provider.ReleaseMouseButton();
        }
        /// <summary>
        /// Clicks on the fishing rod button.
        /// </summary>
        /// <param name="provider"></param>
        /// <returns></returns>
        protected async Task StartCastFishingRodAsync(IInteractionProvider provider)
        {
            Coordinates coords = new Coordinates(800, 846);
            var pos = provider.GetCurrentWindowPosition();
            coords = pos.RelativeToAbsoluteCoordinates(pos.ScaleCoordinates(coords,
                MouseHelpers.ReferenceWindowSize));

            // Move the mouse and press the button.
            provider.MoveMouse(coords);
            provider.PressMouseButton();

            await provider.WaitAsync(300);

            CheckForFishErrorDialog(provider);
        }