Beispiel #1
0
        private void Initialize()
        {
            const string KEY_CROP_FILENAME = "key.lvb";
            const int KEY_CROP_X = 250, KEY_CROP_Y = 473, KEY_CROP_WIDTH = 524, KEY_CROP_HEIGHT = 58;
            const string BAR_CROP_FILENAME = "bar.lvb";
            const int BAR_CROP_X = 254, BAR_CROP_Y = 518, BAR_CROP_WIDTH = 524, BAR_CROP_HEIGHT = 43;

            windowFinder = new WindowFinder();
            imageFinder = new ImageFinder(0.9);

            // load all images based on Signal types. throws error if any of these are not found
            foreach (Signal s in Enum.GetValues(typeof(Signal)))
            {
                string subImagePath = String.Format("{0}{1}{2}", IMAGE_PATH, s.ToString(), IMAGE_EXT);
                imageFinder.SubImages.Add(s, new Image<Bgr, byte>(subImagePath));
            }

            // init gamestate
            for (int i = 0; i < gameState.Length; i++)
            {
                gameState[i] = new Signal[KEY_COLUMNS_MAX];
            }

            keyCropSettings = CropSettings.Load(KEY_CROP_FILENAME, KEY_CROP_X, KEY_CROP_Y, KEY_CROP_WIDTH, KEY_CROP_HEIGHT);
            keyCropSettings.SaveIfNotExist(KEY_CROP_FILENAME);

            barCropSettings = CropSettings.Load(BAR_CROP_FILENAME, BAR_CROP_X, BAR_CROP_Y, BAR_CROP_WIDTH, BAR_CROP_HEIGHT);
            barCropSettings.SaveIfNotExist(BAR_CROP_FILENAME);
        }
Beispiel #2
0
        public void PressThread()
        {
            ImageFinder barImageFinder = new ImageFinder(THRESHOLD_BAR);
            InitializeImageFinder(barImageFinder, "Bar_");

            // if the press-key signal is found, presses the keys found by the state thread

            while (_Enabled)
            {
                using (Image<Bgr, byte> bar_image_source = getCroppedBarScreenshot())
                {
                    if (bar_image_source == null) continue;

                    Dictionary<object, Rectangle[]> matches = barImageFinder.FindAllMatches(bar_image_source, "", false);

                    foreach (KeyValuePair<object, Rectangle[]> pairs in matches)
                    {
                        if (pairs.Value.Length <= 0) continue;

                        Signal matchSignal = (Signal) pairs.Key;

                        int barColumn = pairs.Value[0].Left / KEY_COLUMNS_WIDTH;
                        if (barColumn == lastColumnPressed) continue;

                        if (matchSignal == Signal.Bar_Key || matchSignal == Signal.Bar_Key_Fever)
                        {
                            lastColumnPressed = barColumn;
                            PressKeys(barColumn);

#if DEBUG
                            addDebugImage(bar_image_source, pairs);
#endif

                            System.Threading.Thread.Sleep(50);

                            break;
                        }
                        else // todo: check bar_space explicitly
                        {
                            if (
                                !(gameState[barColumn].Contains(Signal.Key_Space) ||
                                  gameState[barColumn].Contains(Signal.Key_Space_Fever))) continue; // don't press space if there is no space to be pressed, attempt to ignore false positive

                            lastColumnPressed = barColumn;
                            if(matchSignal == Signal.Bar_Space_Alt) System.Threading.Thread.Sleep((pairs.Value[0].Top * 3) / 2); // inaccurate
                            windowFinder.SendKeystroke((ushort)VirtualKeyCode.SPACE);

#if DEBUG
                            addDebugImage(bar_image_source, pairs);
#endif

                            System.Threading.Thread.Sleep(100);
                            break;
                        }
                    }
                }
            }
        }
Beispiel #3
0
        private void InitializeImageFinder(ImageFinder imgFinder, string startsWith = "")
        {
            foreach (Signal s in Enum.GetValues(typeof(Signal)))
            {
                if (startsWith.Length > 0 && !s.ToString().StartsWith(startsWith)) continue;

                string subImagePath = String.Format("{0}{1}{2}", IMAGE_PATH, s.ToString(), IMAGE_EXT);
                imgFinder.SubImages.Add(s, new Image<Bgr, byte>(subImagePath));
            }
        }
Beispiel #4
0
        public void StateThread()
        {
            ImageFinder stateImageFinder = new ImageFinder(THRESHOLD_KEY);
            InitializeImageFinder(stateImageFinder, "Key_");

            // continously updates key state by recognizing visible keys

            // stopwatch used for autoready
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            while (_Enabled)
            {
                List<PhysicalSignal>[] newGameState = new List<PhysicalSignal>[KEY_COLUMNS];

                for (int i = 0; i < newGameState.Length; i++)
                {
                    newGameState[i] = new List<PhysicalSignal>();
                }

                using (Image<Bgr, byte> key_image_source = getCroppedKeyScreenshot())
                {
                    if (key_image_source == null) continue;

                    Dictionary<object, Rectangle[]> matches = stateImageFinder.FindAllMatches(key_image_source, "", false, EightKeyMode ? "" : "Key_8_"); // ignore key_8 if eight key mode is not enabled

                    bool addedAtLeastOne = false;

                    foreach (KeyValuePair<object, Rectangle[]> pairs in matches)
                    {
                        if (pairs.Value.Length <= 0) continue;

                        foreach (Rectangle match in pairs.Value)
                        {
                            PhysicalSignal physicalSignal = new PhysicalSignal()
                            {
                                PositionX = match.Left,
                                PositionY = match.Top,
                                Type = (Signal) pairs.Key
                            };

                            // estimate column by match location
                            // possibility this may be off if key_image off-center
                            int column = match.Left / KEY_COLUMNS_WIDTH;
                            if (column > KEY_COLUMNS - 1) column = KEY_COLUMNS - 1;

                            newGameState[column].Add(physicalSignal);
                            addedAtLeastOne = true;
                        }
                    }

                    if (addedAtLeastOne)
                    {
                        stopwatch.Restart();
                    }
                    else if(AutoReady && stopwatch.ElapsedMilliseconds > TIME_BEFORE_AUTO_READY_MS)
                    {
                        windowFinder.SendKeystroke((ushort)VirtualKeyCode.F5);
                        stopwatch.Reset(); // reset ensures bot does not auto ready more than once (un-readying). can be bad if it misses ready moment, if cooldown is too short
                    }
                }

                Signal[][] rawGameState = new Signal[KEY_COLUMNS][];
                List<PhysicalSignal>[] oldPhysicalGameState = physicalGameState;

                for (int i = 0; i < newGameState.Length; i++)
                {
                    if (newGameState[i].Count > 0 && oldPhysicalGameState[i].Count > 1 && oldPhysicalGameState[i].Count > newGameState[i].Count)
                    {
                        // TEST: replaces gamestates per column if old game state had >=2 keys and this state has less, but not 0 (attempt to "fix" keys occasionally not being recognized in high bpm songs due to particles)
                        // similar to caching
                        // works
                        // TODO: proper
                        newGameState[i] = oldPhysicalGameState[i];
                    }

                    PhysicalSignal[] physicalSignalArray = newGameState[i].ToArray();
                    Array.Sort(physicalSignalArray);

                    rawGameState[i] = new Signal[KEY_COLUMNS_MAX];
                    for (int i2 = 0; i2 < physicalSignalArray.Length; i2++)
                    {
                        rawGameState[i][i2] = physicalSignalArray[i2].Type;
                    }
                }

                physicalGameState = newGameState;
                gameState = rawGameState;
            }
        }