Перейти к содержанию
ANDREY94

исходник автошота c#

Рекомендуемые сообщения

Решил сам заняться написанием авто-шота, ребята у кого есть желание - присоединяйтесь, от помощи или каких либо советов не откажусь!

 

Пишу на C# - WindowsForm

 

Сегодня Михаил помог мне сделать алгоритм работы, всё пошагово разложено по полочкам, осталось только всё это реализовать в коде.

 

Принцип работы программы такой:

Программа не как не воздействует на игру, не читает/ не пишет в память, не инжектится в код, а работает как стороннее приложение благодаря чему не доступна для анти-читов, т.е. бан в игре получить почти не реально!

 

Программка сканирует цвет пикселей экрана в заранее заданной области, где обычно должен отображаться ник врага (по кому программа должна делать авто-выстрел), допустим цвет ника будет красный и должен появляться при наведении прицелом на врага, как только это условие соблюдается и в заданной области появляются пиксели заданного(красного) цвета то программа имитируя нажатие ЛКМ/ПКМ делает выстрел по врагу , задержка между выстрелами по желанию, и так далее....

 

 

Вот алгоритм:

первые задачи для алгоритма
1. Найти ширину экрана
2. Найти высоту экрана

Экран большой, а игра, возможно, запущена в оконном режиме. Значит, мы сможем отсечь часть экрана, которая нам не нужна. 
Поэтому мы можем выполнить следующие подзадачи:
1. Найти окно игры
2. Найти размер окна игры
3. Найти положение окна игры относительно экрана

Далее, нам нужно циклом пройтись по всем пикселям это области. Для этого нужно
1. Пройтись по всем строкам области (горизонтальная сетка пикселей)
2. В каждой итерации получить пиксель и сравнить с нужным цветом. Если совпадает - записать координаты пиксела в какой-то массив

Итак, после прохода у нас есть список координат, по которым нужно кликнуть мышкой. Что для этого нужно сделать? 
Можно попробовать послать системное сообщение для клика мыши (реализация потом, пока алгоритм). Но для него нужны координаты относительно экрана, а не относительно окна игры. Значит, задача стоит следующая
1. Взять каждую из найденных координат из предыдущей подзадачи
2. Перевести координату из оконной в экранную (возможно, это не придется делать, так как реализации бывают разные, и координаты в итоге получатся разные - либо относительно окна, либо сразу относительно экрана)
3. Послать сигнал нажатия мыши в полученную на втором шаге координату.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

попробовал найти процесс (для себя, нужно), имя окна, X Y окна игры не получилось пока определить.

 

Spoiler

void CheckStrGame()
        {
            var pList = Process.GetProcesses();
            if (pList.Count() != 0)
            {
                foreach (var process in pList)
                {
                    if (process.ProcessName == ProcStrGame)
                    {
                        IntPtr handle = FindWindow(null, ProcStrGame);

                        uint[,] pixels = null;
                        GetPixelsColor(1100, 650, out pixels);

                        bool white = true;

                        for (int i = 0; i < 3; i++)
                            for (int j = 0; j < 2; j++)
                            {
                                byte R, G, B;
                                GetColorFromUint(pixels[i, j], out R, out G, out B);
                                if (R != 246 || G != 246 || B != 246)



                                    white = false;
                            }
                        if (white)
                            MessageBox.Show("Область белая");
                    }
                }
            }

        }

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
44 минуты назад, ANDREY94 сказал:

X Y окна игры

GetWindowRect

 

44 минуты назад, ANDREY94 сказал:

имя окна

GetWindowText

 

44 минуты назад, ANDREY94 сказал:

IntPtr handle = FindWindow(null, ProcStrGame);

 

вторым аргументом должно быть имя окна, а не имя процесса

 

12 часа назад, ANDREY94 сказал:

Программка сканирует цвет пикселей экрана в заранее заданной области

Только работать будет это убого т.к. твой алгоритм должен будет каждый раз сканировать заданное окно, а это медленнее, считывания 1-8 байт из памяти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
9 часов назад, kiwipapayamongoose сказал:

вторым аргументом должно быть имя окна, а не имя процесса

Точно-точно, я это знаю но сам тупанул и вместо имени окна указал на процесс и даже не заметил этого...

 

9 часов назад, kiwipapayamongoose сказал:

GetWindowRect 

Не понял как пользоваться...

 

9 часов назад, kiwipapayamongoose сказал:

Только работать будет это убого т.к. твой алгоритм должен будет каждый раз сканировать заданное окно, а это медленнее, считывания 1-8 байт из памяти.

а какие еще варианты?... да и не пойму почему убого-то, там все равно перед сканированием/выстрелом еще задержка будет 1-2 сек, чтоб стрельба с автомата была одиночными выстрелами а не зажимом лупила куда попало...

 

или ты имеешь в виду, что он будет постоянно с тормозами работать и не всегда стрелять в нужный момент?

Изменено пользователем ANDREY94

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так определить имя окна и его размеры?

 

IntPtr handle = FindWindow(null, "CROSSFIRE");
int w = this.Size.Wight;
int h = this.Size.Height;

я с телефона пишу, не имею пока доступа к С#

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В 17.02.2018 в 09:24, ANDREY94 сказал:

так определить имя окна и его размеры?

Спойлер

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left, Top, Right, Bottom;
}

IntPtr hwnd = FindWindow(null, "CROSSFIRE");
RECT rect;



GetWindowRect(hwnd, out rect);
int Width = rect.Right - rect.Left;
int Height = rect.Bottom - rect.Top;

 

  • Спасибо 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как ты вообще представляешь себе это? Тригербот на цвету пикселя...Намного легче и эффективнее читать память. А так алгоритм то легкий.

- Получить hwnd игры

- Получить размеры окна

- Вычислить центр в этом окне

- От цента сделать квадрат, например 50x50 px

- Сканировать этот квадрат в цикле GetPixel

 

И всё это будет криво работать, потому-что в игре куча разных цветов и оттенков. И еще игра может перехватывать обычные сообщения мыши, а принимать только DirectInput.

  • Спасибо 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
3 часа назад, ANDREY94 сказал:

а какие еще варианты?

если принципиально без использования памяти, то несколько буферов/потоков на сканирование пикселей, так раза в 2-3 увеличишь скорость работы, либо вылизать весь код, чтобы на сканирование уходило меньше 33 миллисекунд(время кадра) при 60 фпс.

  • Спасибо 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
6 минут назад, kiwipapayamongoose сказал:

если принципиально без использования памяти, то несколько буферов/потоков на сканирование пикселей, так раза в 2-3 увеличишь скорость работы, либо вылизать весь код, чтобы на сканирование уходило меньше 33 миллисекунд(время кадра) при 60 фпс.

В игру вообще желательно не лезть, там анти-чит стоит и нужно будет постоянно искать новые попытки его обхода так как он обновляется... Вот несколько потоков на сканирование добавить можно, не помешает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
1 час назад, ANDREY94 сказал:

В игру вообще желательно не лезть, там анти-чит стоит

Большинство анти-читов не замечают если лезть в память с использованием драйвера или же открывать процесс только с правами на чтение, сейчас наверное всего 2-3 анти-чита с доступом ring 0, остальные с правами юзера работают.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
5 часов назад, kiwipapayamongoose сказал:

Большинство анти-читов не замечают если лезть в память с использованием драйвера или же открывать процесс только с правами на чтение, сейчас наверное всего 2-3 анти-чита с доступом ring 0, остальные с правами юзера работают.

 

mrac например?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как продвигается создание автошота? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В 17.02.2018 в 08:59, ANDREY94 сказал:

а какие еще варианты?...

А что  если считывать экран по пикселям только у цели в радиусе Х(то есть не весь экран игры,а только часть) , и при обнаружении красного (противника) стрелять ? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
3 минуты назад, IzerodayI сказал:

А что  если считывать экран по пикселям только у цели в радиусе Х(то есть не весь экран игры,а только часть) , и при обнаружении красного (противника) стрелять ? 

Ну так и запланировано, зачем нам весь экран если ник противника появляется чуть ниже прицела?! да и смысл сканировать весь экран, там такой цвет частенько будет попадаться в разных облостях экрана и автошот будет постоянно реагировать на них и стрелять в самый не подходящий момент, это не удобно и очень палевно!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
4 часа назад, Habar сказал:

Как продвигается создание автошота? :)

пока только нашел имя окна игры, взял его разрешение и нашел имитация нажатия клавиш ЛКМ/ПКМ. с опредлением цвета и координатами пока проблемы, определение цвета не происходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот пока что как то так:

 

Функцию свою еще не выполняет пока

Спойлер

 void CheckStrGame()
        {
            //IntPtr handle = FindWindow(null, "CROSSFIRE");
            IntPtr hwnd = FindWindow(null, "CROSSFIRE");
            RECT rect;
            
            GetWindowRect(hwnd, out rect);
            int Width = rect.Right - rect.Left;
            int Height = rect.Bottom - rect.Top;
                        ////////////////////////////////////
                        {
                            uint[,] pixels = null;
                            GetPixelsColor(1100, 650, out pixels);
                            //GetPixelsColor(0, 650, out pixels);

                            bool white = true;

                            for (int i = 0; i < 3; i++)
                                for (int j = 0; j < 2; j++)
                                {
                                    byte R, G, B;
                                    GetColorFromUint(pixels[i, j], out R, out G, out B);
                                    if (R != 171 || G != 59 || B != 46)
                                    {
                                        //SetCursorPos(500, 600);
                                        //PostMessage(handle, 0x100, 0x01, 0);
                                        Console.Beep(500, 500);
 
                                    }

                                        white = false;
                                }
                            if (white)
                                MessageBox.Show("Область белая");
                        }
                    }
        private void timer1_Tick(object sender, EventArgs e)
        {
            var pList = Process.GetProcesses();
            if (pList.Count() != 0)
            {
                foreach (var process in pList)
                {
                    if (process.ProcessName == ProcStrGame)
                    {
                        Console.Beep(500, 500);
                        timer1.Stop();
                        CheckStrGame();
                    }
                }
            }
            

        }

 

Вместо того, чтобы определить заданный цвет и выполнить действие, выполняет его при каждом поиске цвета и не важно тот это цвет или нет, надо ставить условие наверное...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуй вместо PostMessage использовать SendInput. Это первое. 

  if (R != 171 || G != 59 || B != 46)

Эту конструкцию я вообще не понял. Что оно должно делать в твоем понимании?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
45 минут назад, Xipho сказал:

Попробуй вместо PostMessage использовать SendInput. Это первое. 


  if (R != 171 || G != 59 || B != 46)

Эту конструкцию я вообще не понял. Что оно должно делать в твоем понимании?

определить этот цвет - это RGB Color

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
19 минут назад, ANDREY94 сказал:

определить этот цвет - это RGB Color

Это понятно. Только судя по самом выражению, оно у тебя не определяет цвет, а срабатывает только тогда, когда какая-то из цветовых составляющих не равна той, что указано. Другими словами, это выражение значит, что код внутри выполнится
если
R составляющая не равна 171

или

G составляющая не равна 59

или 

B составляющая не равна 46

Ты уверен, что ты именно этого добиваешься? Под это условие попадет огромное количество цветов ведь.

Если ты хотел сделать так, чтобы внутри код выполнился, если цвет совпадет с этим, то правильнее было бы сделать
 

if (R == 171 && G == 59 && B == 46)

Но в этом случае не проще ли сравнивать hex значение цвета, и не тратить драгоценные такты процессора на разложение цвета по составляющим?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В 19.02.2018 в 14:01, Xipho сказал:

Но в этом случае не проще ли сравнивать hex значение цвета, и не тратить драгоценные такты процессора на разложение цвета по составляющим?

я не знаю как сравнивать  hex значения цвета, но если это проще и лучше то наверное именно так и делать

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Их сравнивают как обычные числа. К примеру, приведенный выше цвет в hex (16-ричном) равен AB3B2E (в памяти будет "перевернут" 2E3BAB). Значит, если тебе нужно выполнить какие-то действия, если считанный пиксель будет такого цвета, тебе нужно сделать следующее:

if (pixels[i, j] == 0xAB3B2E) {
  // TODO: Тут выполнить действия, которые нужно
}

 

  • Спасибо 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В 19.02.2018 в 15:25, Xipho сказал:

Их сравнивают как обычные числа.

Попробуем, посмотрим что получится.

 

и считывает он всего лишь один пиксель по X Y, я так понимаю, но я еще не знаю как определить где находится нужные мне пиксели(!) то есть хотя бы одна строчка небольшая где высвечивается ник этим цветом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В 17.02.2018 в 10:40, Habar сказал:

Как ты вообще представляешь себе это? 

если указать область наиболее меньшую и конкретно там где высвечивается ник то и задевание "левых" пикселей будет происходить очень редко но все же желательно вообще их исключить... А память игры это уже другое, это я еще даже не рассматривал и не думал на счет этого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот это вроде как расположение одного пикселя

GetPixelsColor(1100, 650, out pixels);
                            

то есть мне надо определить конкретные координаты где появляется нужный цвет и далее цепочкой продлить строку всех пикселей по очередности чтобы захватить хотя бы часть того места где будет высвечиваться имя, так как имя персонажа может быть разной длины.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтобы определить координаты пикселов нужного цвета, тебе нужно в цикле считывать каждый пиксель области, и если пиксель равен нужному цвету, заносить его в массив или же сразу в него "стрелять". Вообще, идея поиска нужного пространства по цвету пиксела - весьма слабопроизводительна, если нужно найти объект на экране, лучше искать его в памяти игры. Точнее, искать его координаты, которые затем конвертировать в экранные, чтобы дать "мышке" знать, куда надо кликнуть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

×

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.