Форум программистов, компьютерный форум, киберфорум
C#: API, боты
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.84/32: Рейтинг темы: голосов - 32, средняя оценка - 4.84
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
1

Быстрая эмуляция нажатия клавиш в боте для браузерки

14.02.2013, 19:20. Просмотров 6517. Ответов 42
Метки нет (Все метки)

Пишу бота для браузерных танчиков.Прицеливание работает по принципу:через BitBlt копируется нужное окно в память, там ищутся группы пикселей определенного цвета(цвет имени врага), и если таковые найдены, нужно жать определенную кнопку(z или x) до тех пор, пока разница по абсциссе между центром имени противника и центром своих жизней(по ним определяется направление пушки), не станет меньше определенного числа(25 пикселей в данном случае). Эмуляцию нажатия клавиш реализую через PostMessage, ибо работать должно в неактивном окне. Все вроде пашет, но загвоздка в том, что пушка нередко "проезжает" цель, и начинается вертеться перед ней туда-сюда, то бишь PostMessage об отпускании клавиши не доходит вовремя. Сам алгоритм определения, когда надо остановиться, в ряд ли может быть неверным, ибо 100 раз проверен и в целом работает(то есть останавливается вовремя в тех случаях, когда пушка вертится медленнее обычного, либо просто удачно повернулась). Сообщения, которые я посылаю, полностью соответствуют аналогичным при реальном нажатии клавиш(через Spy++ проверялось). Кроме того при попытке эмулировать через keybd_event получилось ровно то же самое. Чего только не пробовал-и задержки разные, и сообщения, все то же самое. Скачал виртуальную клавиатуру-при попытке управлять с нее все работает нормально, то есть теоретически такая эмуляция возможна. Сразу скажу, что производительность при обработке изображения тут не причем, FPS достаточный, чтобы несколько кадров попало в положение, когда надо остановиться. На данный момент прога работает с гугл хромом, там проще однозначно достать хэндл нужного окна. Часть кода прилагается, желающим могу скинуть заготовку проги в личку. Жду ваших предположений, как это устранить, я пока что в тупике( но выход ищу. Заранее благодарен. Рабочие способы реализовать такое на других языках и по другим принципам тоже буду рассматривать, ибо делаю чисто ради развлечения и саморазвития, никуда не спешу. Эти куски кода миллион раз переписывались, на мелкие несуразности можете не обращать внимание, главное-указанный выше вопрос.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
        [DllImport("USER32.DLL", EntryPoint = "PostMessageW", SetLastError = true,
                     CharSet = CharSet.Unicode, ExactSpelling = true,
                     CallingConvention = CallingConvention.StdCall)]
        public static extern bool PostMessage(int hwnd, int Msg, int wParam, int lParam);
 
        public static bool e5 = false;
        public static bool e6 = false;
        public static bool e4 = false;
        public static bool in5 = true;
        public static bool in6 = true;
        public static bool in4 = true;
        public static System.Timers.Timer t4 = new System.Timers.Timer(60);
        public static System.Timers.Timer t5 = new System.Timers.Timer(60);
        public static System.Timers.Timer t6 = new System.Timers.Timer(60);
 public static  void t4_Tick(object source, ElapsedEventArgs e)
{
   try
        {
    if (e4)
    {
            if (!in4)
            {
                int virtual_code = MapVirtualKey(0x11, 1);
                int lp = 0x11 << 16 | 1;
                PostMessage((int)win3, WM_KEYDOWN, virtual_code, lp);
                in4 = true;
            }
            else
            {
                int virtual_code = MapVirtualKey(0x11, 1);
                int lp = 0x11 << 16 | 1 << 30 | 1;
                PostMessage((int)win3, WM_KEYDOWN, virtual_code, lp);
            }
 
 
    }
    else
    {
        if (in4)
        {
            int virtual_code = MapVirtualKey(0x11, 1);
            int lp = 1 << 31 | 1 << 30 | 0x11 << 16 | 1;
            PostMessage((int)win3, WM_KEYUP, virtual_code, lp);
            in4 = false;
        }
    }
        }
             catch { }
}
 
public static void t5_Tick(object source, ElapsedEventArgs e)
{        try
        {
    if (e5)
    {
 
            if (!in5)
            {
                int virtual_code = MapVirtualKey(0x2D, 1);
                int lp = 0x2D << 16 | 1;
                PostMessage((int)win3, WM_KEYDOWN, virtual_code, lp);
                in5 = true;
            }
            else
            {
                int virtual_code = MapVirtualKey(0x2D, 1);
                int lp = 0x2D << 16 | 1 << 30 | 1;
                PostMessage((int)win3, WM_KEYDOWN, virtual_code, lp);
            }
        }
    else
    {
        if (in5)
        {
            int virtual_code = MapVirtualKey(0x2D, 1);
            int lp = 1 << 31 | 1 << 30 | 0x2D << 16 | 1;
            PostMessage((int)win3, WM_KEYUP, virtual_code, lp);
            in5 = false;
        }
    }
        }
catch { }
}
 
public static void t6_Tick(object source, ElapsedEventArgs e)
{        try
        {
    if (e6)
    {
 
            if (!in6)
            {
                int virtual_code = MapVirtualKey(0x2C, 1);
                int lp = 0x2C << 16 | 1;
                PostMessage((int)win3, WM_KEYDOWN, virtual_code, lp);
                in6 = true;
            }
            else
            {
                int virtual_code = MapVirtualKey(0x2C, 1);
                int lp = 0x2C << 16 | 1 << 30 | 1;
                PostMessage((int)win3, WM_KEYDOWN, virtual_code, lp);
            }
        }
    else
    {
        if (in6)
        {
            int virtual_code = MapVirtualKey(0x2C, 1);
            int lp = 1 << 31 | 1 << 30 | 0x2C << 16 | 1;
            PostMessage((int)win3, WM_KEYUP, virtual_code, lp);
            in6 = false;
        }
    }
        }
catch { }
}
 
 
   private void threader() {
            t4.Elapsed += new ElapsedEventHandler(t4_Tick);
            t5.Elapsed += new ElapsedEventHandler(t5_Tick);
            t6.Elapsed += new ElapsedEventHandler(t6_Tick);
            t4.Interval = 100;
            t5.Interval = 100;
            t6.Interval = 100;
            t4.Enabled = true;
            t5.Enabled = true;
            t6.Enabled = true;
        while (true)
        {
            try
            {
                mozgi();
            }
            catch { }
        }
        }
 
        private void mozgi()
        {
//тут делается снимок окна и находится minraznica.X = модуль разницы абсциссы между 
//центром имени врага и центром своей пушки. Корректно, проверено. А так же
//переменная pravo, определяющая сторону, с которой находится враг.
//enemynamesectorREAL это массив точек цвета имени врага.
                        if (enemynamesectorREAL.Count > 0 && e4)
                        {
                            e4 = false;
                        }
 
                        if (enemynamesectorREAL.Count > 0 && minraznica.X > 25 && (!(e5 || e6)))
                        {
                            if (pravo)
                            {
                                e5 = true;
                            }
 
                            else
                            {
                                e6 = true;
                            }
                        }
 
                        if ((pravo && e5) || (!pravo && e6) || enemynamesectorREAL.Count == 0 || minraznica.X <= 25)
                        {
                            bull = false;
                        }
                        else { bull = true; }
 
                        if ((minraznica.X <= 25 || bull) && (e5 || e6) && enemynamesectorREAL.Count != 0)
                        {
                            if (e5)
                            {
                                e5 = false;
                                int virtual_code = MapVirtualKey(0x2D, 1);
                                int lp = 1 << 31 | 0 << 30 | 0x2D << 16 | 1;
                                PostMessage((int)win3, WM_KEYUP, virtual_code, lp);
                                {
                                    notbuisy = false;
                                }
                            }
                            if (e6)
                            {
                                e6 = false;
                                int virtual_code = MapVirtualKey(0x2C, 1);
                                int lp = 1 << 31 | 1 << 30 | 0x2C << 16 | 1;
                                PostMessage((int)win3, WM_KEYUP, virtual_code, lp);
                                {
                                    notbuisy = false;
                                }
                            }
                        }
                    }
                    else { }
 
                        if ((enemynamesectorREAL.Count == 0 && !notbuisy) || (mls == 0 && !notbuisy))
                        {
                            if (e5 || e6)
                            {
                                notbuisy = true;
                            }
                            else
                            {
                                Random rand = new Random();
                                switch (rand.Next(1))
                                {
                                    case 0: 
                                        e5 = true;
                                        notbuisy = true;
                                        break;
                                    case 1: 
                                        e6 = true;
                                        notbuisy = true;
                                        break;
                                }
                            }
                        }
                        if ((enemynamesectorREAL.Count == 0 && !e4) || (mls == 0 && !e4))
                        {
                            e4 = true;
                        }
 
//тут можно вывести обрабатываемый битмап на экран с пометками, что удобно при отладке.
 
                    mem.Dispose();
                    
        }
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.02.2013, 19:20
Ответы с готовыми решениями:

Эмуляция нажатия клавиш для SDL
Столкнулся с такой проблемой что на эмуляцию нажатия клавиш, SDL не реагирует. Точнее DOSBox....

Эмуляция нажатия клавиш для неактивного/свёрнутого приложения.
Есть большое желание написать что-то наподобии программы-макроса, которая будет отправлять или...

Эмуляция нажатия клавиш для другого приложения (Win10 Под D3D) не работает
Добрый день! У меня такая трабла возникла. Нужно В игре под директ3Д зажать правую кнопку мышки на...

Перехватчик клавиш + эмуляция нажатия клавиш
Здравствуйте! Срочно нужна помощь! Моя программа работает в фоновом режиме. Мне нужно: 1) чтобы...

42
Winhttp
62 / 62 / 5
Регистрация: 05.01.2013
Сообщений: 235
14.02.2013, 22:03 2
я думаю, что это не лучшее решение - снятие скринов. как альтернативу - смотри в сторону - http://rghost.ru/42782537 . там можно и пиксели поискать без снятия скринов, и нажатия клавиш окну поотправлять
1
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
14.02.2013, 22:26  [ТС] 3
Спасибо, как разберусь что там к чему-отпишусь. У кого еще будут предложения-пишите
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
17.02.2013, 19:21  [ТС] 4
Если кому не лень, поясните пожалуйста, как этой библиотекой по ссылке воспользоваться, у меня как ни подключай-то один эксепшен то другой.

Добавлено через 1 час 4 минуты
Нашел наконец-то на иностранном форуме как подключать такую библиотеку. Надо оказывается было качать отсюда http://www.autoitscript.com/site/autoit/downloads/ инсталлятор, а потом регистрировать вручную AutoItX3.dll вот так: regsvr32 "полный путь к dllке". Потом уже идешь в ссылки и выбираешь ее среди COM объектов, и тогда только она начинает пахать.

Добавлено через 16 часов 3 минуты
Если кто уже в курсе, объясните пожалуйста, как подать хэндл окна куда-нибудь в аутоите, ибо вот такой код:
C#
1
2
string x = autoit.WinGetHandle("Что-нибудь - Google Chrome", "");
int tt = autoit.ControlSend(x, "", "", "smth");
Не пашет, при том, что x находится корректно.
Не пашут так же любые попытки подать туда уже найденый апишными функциями хэндл. Хотелось бы пример.Если найду как это сделать-отпишусь, а то в сети что-то мало инфы по шарпу с аутоитом.

Добавлено через 9 часов 25 минут
C#
1
2
                  string some = win3.ToString("X8");
                  int tt = autoit.ControlSend("[handle:" + some + "]", "", "", "m");
Вот как оказывается это делается. Опять мне пришлось лазить по иноязычным форумам, а тут все молчат
0
Winhttp22
157 / 125 / 24
Регистрация: 16.02.2013
Сообщений: 828
17.02.2013, 21:30 5
EvilFromHell, ну там же документация была с библиотекой. она проста в использовании, и довольно удобна для работы с окнами, допустим - мне надо было найти окно одного процесса, а окно не имело заголовка, и тд. с помощью либы можно получить все окна процесса. я просто не представляю, как это бы выглядело на вин апи. наверное нужно было бы тонну кода писать а тут пару строчек - и все готово.

Добавлено через 25 секунд
насчет регистрации библиотекы - хз., проверю у себя и отпишусь

Добавлено через 15 минут
Цитата Сообщение от EvilFromHell Посмотреть сообщение
C#
1
2
                  string some = win3.ToString("X8");
                  int tt = autoit.ControlSend("[handle:" + some + "]", "", "", "m");
Вот как оказывается это делается. Опять мне пришлось лазить по иноязычным форумам, а тут все молчат
так хендл, полученный с помощью вин апи не имеет тип string, ты какую среду используешь? когда создаешь обьект, и работаешь с ним, то есть такая полезная функция, как автозавершение кода. вот она и показывает, какой тип переменных нужно в функцию передавать. описание в документации заголовочного файла тоже есть вроде бы.

Добавлено через 6 минут
да при отмене регистрации либа не работает видимо эта библиотека просто вызывает функции из оригинальной а я то думал...
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
17.02.2013, 22:01  [ТС] 6
EvilFromHell, ну там же документация была с библиотекой. она проста в использовании, и довольно удобна для работы с окнами, допустим - мне надо было найти окно одного процесса, а окно не имело заголовка, и тд. в либе можно получить все окна процесса. я просто не представляю, как это бы выглядело на вин апи. наверное нужно было бы тонну кода писать а тут пару строчек - и все готово.
А вот мне кажется ровно наоборот-на апи это делается легко и просто, это у меня уже реализовано в данном проэкте, окно, в которое я посылаю сообщение, как раз таки без заголовка и определяется по стилю. Если понадобится-скину код Пока что как корректно что-либо отослать при помощи этой библиотеки я еще не разобрался, но было мало времени, еще разберусь. По умолчанию конкретно эта функция шлет WM_CHAR на который игра не реагирует и к тому же активирует окно, а мне надо в неактивное слать.
Документацию может быть я кривовато читал, но там нигде не написано про корректную подачу хэндла в эту функцию. В файле в архиве по ссылке про него не сказано ни слова в описании функции, а уж тем более про вызов ее из C#. Кроме того как именно ту библиотеку подключить, что по ссылке, я так и не врубился. Если про корректную эмуляцию в неактивное окно общеизвестно-отпишись пожалуйста, как это, чтобы долго не искать
И еще на счет пикселей интересно-реально узнать цвет пикселей в окне, которое не отображено(под другими) и быстрее чем указанным в первом посте способом? или можно не возиться, все равно не выйдет?

Добавлено через 4 минуты
Забыл среду написать-студия 2010.

Добавлено через 12 минут
Кстати на счет хэндла-у меня он имеет тип IntPtr, и найден через апи. А про эту хитрую форму записи так просто не догадаешься, в студии просто как стринг выглядит, никаких пояснений.
0
Winhttp22
157 / 125 / 24
Регистрация: 16.02.2013
Сообщений: 828
17.02.2013, 22:12 7
Цитата Сообщение от EvilFromHell Посмотреть сообщение
А вот мне кажется ровно наоборот-на апи это делается легко и просто
простой пример, как получить координаты окна на вин апи - Использование WinAPI в C#. Библиотека "User32.dll" , и ниже там я привел пример, как это сделать с помощью этой либы. если вам нравиться много писать - то хорошо, пишите на вин апи
и к тому же активирует окно, а мне надо в неактивное слать.
не знаю, что у тебя там активирует, но у меня вот такой код -
C#
1
2
        AutoItX3Class aue=new AutoItX3Class();
        aue.ControlSend("[CLASS:Notepad]", "", "Edit1", "Это эмуляция нажатия клавиш в неактивное окно блокнота",0);
шлет эмуляцию клавиш в свернутое окно и не активирует его.
но там нигде не написано про корректную подачу хэндла в эту функцию
там есть функция для получения хендла - используй ее. хотя она тоже может возвращать тип интежер, не помню, так что его придется так же приводить к строке.
И еще на счет пикселей интересно-реально узнать цвет пикселей в окне, которое не отображено(под другими) и быстрее чем указанным в первом посте способом? или можно не возиться, все равно не выйдет?
слышал, что надо сдвигать окно за пределы экрана и искать там уже пиксели, но я хз , будет ли это работать, не пробовал.
я так понимаю - нужен бот, чтобы работал и можно было еще кое что на компьютере делать? чтобы не "блокировал" комп? игра на флеше? ее можно же разобрать и написать бота без этих всех поисков пикселей. хотя если "разобрать" - то это наверное уже выходит за рамки закона, и за рамки этого форума. типо взлом же

Добавлено через 1 минуту
А про эту хитрую форму записи так просто не догадаешься, в студии просто как стринг выглядит, никаких пояснений
ну правильно, стринг. а ты шлешь
Кстати на счет хэндла-у меня он имеет тип IntPtr,
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
17.02.2013, 23:07  [ТС] 8
простой пример, как получить координаты окна на вин апи - Использование WinAPI в C#. Библиотека "User32.dll" , и ниже там я привел пример, как это сделать с помощью этой либы. если вам нравиться много писать - то хорошо, пишите на вин апи
С окном и его определением уже все давно готово, проблема только в скорости эмуляции, ну или в опитимизации имеющегося алгоритма распознавания пикселей.
там есть функция для получения хендла - используй ее. хотя она тоже может возвращать тип интежер, не помню, так что его придется так же приводить к строке.
Она получает то, что у меня в первой строке. А вот эта запись "[handle:" + some + "]" нашлась только на иностранном форуме
Да и хочется сделать так, чтобы бот никак не зависел собственно от игры, ее версий, пакетов, структуры и тд, раз это теоретически можно реализовать таким способом. Чтобы был прост как дубина-нажал кнопку и все катается, а юзер при этом делает что хочет
Игру вероятно видели в инете-танки онлайн зовется.

Добавлено через 4 минуты
Цитата Сообщение от Winhttp22 Посмотреть сообщение
ну правильно, стринг. а ты шлешь
Смотри внимательно код, я шлю стринг, причем отформатированный как 16тиричное число на 8 знаков(то бишь с нулями в начале). Такой же стринг дает та функция из библиотеки.

Добавлено через 26 минут
простой пример, как получить координаты окна на вин апи
Глянул тему, эта задача двумя строчками выполняется и на Winapi, просто там аццки извращенный вариант выложен Мой пост внизу глянь Если известен заголовок-то это 2 строчки: GetWindow и GetWindowRect.
C#
1
2
                    RECT rectal = new RECT();
                    GetWindowRect(new HandleRef(null, win3), out rectal);
из этого же бота.

Добавлено через 12 минут
что надо сдвигать окно за пределы экрана и искать там уже пиксели
Это тоже жесткий изврат, который тут явно не пойдойдет, но еще вопрос в том, как реализованы эти функции аутоита. Реализованы ли они на том же апи, или используют какие-то другие возможности. Буду тестить и искать инфу.
0
Winhttp22
157 / 125 / 24
Регистрация: 16.02.2013
Сообщений: 828
18.02.2013, 00:25 9
С окном и его определением уже все давно готово, проблема только в скорости эмуляции, ну или в опитимизации имеющегося алгоритма распознавания пикселей
можно не сканировать полностью окно, а допустим каждый третий или пятый пиксель. в аутоите есть такая функция. танки 3д? скажу, что поиск пикселей - довольно таки ресурсоемкая задача. когда не один пиксель сверяешь, а много.
чтобы бот никак не зависел собственно от игры, ее версий, пакетов, структуры и тд, раз это теоретически можно реализовать таким способом. Чтобы был прост как дубина-нажал кнопку и все катается, а юзер при этом делает что хочет
тут я вынужден разочаровать. с выходом новых версий если в графике будут какие то обновления, то бот может не работать. да и так, чтобы и пиксели искал и юзер делал что то - тоже маловероятно, что получится, разве что со сдвигом окна , как писал выше, хотя мне это кажется, что не будет работать, и это что то на грани фантастики. но я встречал на одном форуме, где об этом писали. я не понимаю, какие могут быть пиксели за пределом экрана, ну да ладно
Это тоже жесткий изврат, который тут явно не пойдойдет
ну ты сам изврат пишешь, если чесно с этими пикселями. где то какое то окно вылезет вверх и бот не будет работать, как надо. я говорил, что нужно разобрать игру, и смотреть, как можно бота сделать.
но еще вопрос в том, как реализованы эти функции аутоита. Реализованы ли они на том же апи, или используют какие-то другие возможности.
да мне самому было интересно. но я ничего по этому поводу не нашел.

Добавлено через 2 минуты
да насчет функции той. что мешает использовать заголовок окна, а не хендл?
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
18.02.2013, 00:47  [ТС] 10
можно не сканировать полностью окно, а допустим каждый третий или пятый пиксель. в аутоите есть такая функция. танки 3д? скажу, что поиск пикселей - довольно таки ресурсоемкая задача. когда не один пиксель сверяешь, а много.
Ресурсоемкая, но при использовании небезопасного кода и Api получается приемлимая скорость обработки. ФПС виден при выводе на экран и по миллисекундам я замерял, он приемлим. Кроме того у меня там сейчас использованы не самые быстрые методы местами, можно еще оптимизировать. Да, танки 3d, но управление там простое, и набивать ботом звание в дм на маленькой карте-можно стоя на месте и просто ворочая пушкой куда надо. А 3тий и 5тый пиксель можно по-разному сканировать-в шарпе вон тоже есть GetPixel, но это ТАК тормознуто... Это вопрос реализации. Кроме того мне все равно надо проверять всю картинку. А функция аутоита в ряд ли станет делать то, что я хочу Гибкой настройки пока не нашел там.
тут я вынужден разочаровать. с выходом новых версий если в графике будут какие то обновления, то бот может не работать. да и так, чтобы и пиксели искал и юзер делал что то - тоже маловероятно, что получится, разве что со сдвигом окна , как писал выше, хотя мне это кажется, что не будет работать, и это что то на грани фантастики. но я встречал на одном форуме, где об этом писали. я не понимаю, какие могут быть пиксели за пределом экрана, ну да ладно
Это все учтено, у бота останутся настройки цветов. Конечно, могут поменять что-то радикально, но не думаю, что такое будет. Остальное все уже сделано-проблема лишь в том, что иногда мажет. Так что никакой фантастики тут нет.
ну ты сам изврат пишешь, если чесно с этими пикселями. где то какое то окно вылезет вверх и бот не будет работать, как надо. я говорил, что нужно разобрать игру, и смотреть, как можно бота сделать.
Повторюсь, он уже работает на том алгоритме, что в первом посте. Подо всеми окнами. Хоть там и ставится автоматом пауза, когда с окна уходит фокус, но я нашел способ ее отключать через PostMessage. Что это все изврат-знаю но зато весело и познавательно, ведь управление чужими приложениями мне еще миллион раз пригодится.
0
Winhttp22
157 / 125 / 24
Регистрация: 16.02.2013
Сообщений: 828
18.02.2013, 01:14 11
EvilFromHell, под файтастикой я имел ввиду - окно свернутое, и что бы бот исал пиксели.
Подо всеми окнами
свернутого окна что ли скрин делаешь?
А 3тий и 5тый пиксель можно по-разному сканировать-в шарпе вон тоже есть GetPixel, но это ТАК тормознуто...
да, тормознуто. я тоже когда искал в шарпе функции для работы с пикселями, то пробовал использовать эту. вот функция аутоита -
PixelSearch
--------------------------------------------------------------------------------

Найти пиксел заданного цвета в указанном прямоугольнике

PixelSearch ( left, top, right, bottom, color )



Параметры

left левая координата прямоугольника.
top верхняя координата прямоугольника.
right правая координата прямоугольника.
bottom верхняя координата прямоугольника.
color десятичное значение цвета.
shade-variation [опциональный] величина от 0 до 255 указывает разрешенное число каналов сопоставимого цвета для rgb компонентов. Стандартное значение 0 (точное сопоставление).
step [опциональный] шаг поиска (в пикселах). Значение 2 означает проверку каждого второго пиксела. Стандартное значение 1.
шаг поиска задаешь, и ищет
но зато весело и познавательно, ведь управление чужими приложениями мне еще миллион раз пригодится.
мне тоже так казалось первое время. но когда начал писать приложения для фриланса, то понял что мне это нафиг не надо.

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

Добавлено через 1 минуту
C#
1
2
3
        public static System.Timers.Timer t4 = new System.Timers.Timer(60);
        public static System.Timers.Timer t5 = new System.Timers.Timer(60);
        public static System.Timers.Timer t6 = new System.Timers.Timer(60);
я где то читал, что больше одного таймера в одном потоке запускать не есть гуд
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
18.02.2013, 01:18  [ТС] 12
свернутого окна что ли скрин делаешь?
Совсем свернутого не выходит, а вот расположенного под остальными на экране-делается элементарно через BitBlt по хэндлу.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  BitmapData bmpData = mem.LockBits(new Rectangle(0, 0, mem.Width, mem.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                    byte[] bitmapBuffer = new byte[bmpData.Stride * bmpData.Height];
                    Marshal.Copy(bmpData.Scan0, bitmapBuffer, 0, bitmapBuffer.Length);
                    for (int j = 0; j < (int)ypos; j++)
                    {
                        int strideY = bmpData.Stride * j;
                        for (int i = 0; i < (int)xpos; i++)
                        {
                            int index = strideY + i * byteLen;
                            RGBcolor x = new RGBcolor();
                            x.B = bitmapBuffer[index + 0];
                            x.G = bitmapBuffer[index + 1];
                            x.R = bitmapBuffer[index + 2];
                            if (x.R == mylife.R && x.G == mylife.G && x.B == mylife.B)
                            {
                                Coords coord;
                                coord.X = i;
                                coord.Y = j;
                                if (lifeminx > i) { lifeminx = i; }
                                if (lifemaxx < i) { lifemaxx = i; }
                                if (lifeminy > j) { lifeminy = j; }
                                if (lifemaxy < j) { lifemaxy = j; }
                                mylifesector.Add(coord);
                                mls++;
                            }
                            if ((Math.Abs(x.R - enemyname.R) < 20) && (Math.Abs(x.G - enemyname.G) < 30) && (Math.Abs(x.B - enemyname.B) < 20))
                            {
                                Coords coord;
                                coord.X = i;
                                coord.Y = j;
                                enemynamesector.Add(coord);
                                ens++;
                            }
                            if ((Math.Abs(x.R - colorpuli.R) < 20) && (Math.Abs(x.G - colorpuli.G) < 25) && (Math.Abs(x.B - colorpuli.B) < 15))
                            {
                                Coords coord;
                                coord.X = i;
                                coord.Y = j;
                                colorpulisector.Add(coord);
                                cps++;
                            }
                        }
                    }
                    mem.UnlockBits(bmpData);
Вот эта конструкция куда быстрее работает, мне ведь все равно перебирать всю картинку.
мне тоже так казалось первое время. но когда начал писать приложения для фриланса, то понял что мне это нафиг не надо.
Ну так кроме фриланса можно для себя писать, за деньги обычно однотипная скучная работа.

Добавлено через 2 минуты
Эти таймеры вроде бы запускаются в своем потоке, их там аж 3 вида.. по крайней мере дело тут по-моему не в них( Я кроме таймеров чего только не пробовал.
0
Winhttp22
157 / 125 / 24
Регистрация: 16.02.2013
Сообщений: 828
18.02.2013, 01:25 13
Совсем свернутого не выходит
а я же говорил о свернутом. работать то с компьютером не сможешь толком, окно должно быть всегда видимым.
за деньги обычно однотипная скучная работа
я бы не сказал, что скучная и уж тем более однотипная
Эти таймеры вроде бы запускаются в своем потоке, их там аж 3 вида
попробуй запустить обычный бесконечный цикл в таймере. он заморозит твой поток.
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
18.02.2013, 01:33  [ТС] 14
попробуй запустить обычный бесконечный цикл в таймере. он заморозит твой поток.
Если я так сделаю, у меня комп повиснет. У таймера тики асинхронные, даже у того, что в формах, и у этого как я понимаю тоже. Можно создать потоки конечно-не думаю, что будет разница-к таймерам вроде нет нареканий, я их долго тестил.
я бы не сказал, что скучная и уж тем более однотипная
Ну у меня пока не получилось в жизни найти такого дела, за которое бы платили деньги и от которого бы не тошнило..
а я же говорил о свернутом. работать то с компьютером не сможешь толком, окно должно быть всегда видимым.
А зачем его сворачивать? что мне мешает запустить бота и врубить игрушку/браузер/cтудию поверх и заниматься своими делами, забыв о нем?
0
Winhttp22
157 / 125 / 24
Регистрация: 16.02.2013
Сообщений: 828
18.02.2013, 01:41 15
Если я так сделаю, у меня комп повиснет.
Thread.Sleep() , не слышал?
Можно создать потоки конечно-не думаю, что будет разница-к таймерам вроде нет нареканий, я их долго тестил.
на чем тестил?
ну если снимает скрин с окна нижнего - тогда ок
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
18.02.2013, 01:50  [ТС] 16
на чем тестил?
Я и потоки делал вместо них, и сам главный цикл пытался запускать в таймере, и по spy++ смотрел что и когда прилетает. На счет слипа-попробовал так сделать в одном, ни форма, ни поток в котором цикл, ни остальные 2 таймера не зависли.
0
Winhttp22
157 / 125 / 24
Регистрация: 16.02.2013
Сообщений: 828
18.02.2013, 02:03 17
а я вот сделал тестовое приложение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
namespace capchatest
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        public MainForm()
        {
            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();
            
            //
            // TODO: Add constructor code after the InitializeComponent() call.
            //
        }
        
        void Button1Click(object sender, EventArgs e)
        {
            
        }
        
        void Timer1Tick(object sender, EventArgs e)
        {
            textBox1.Text+="1"+Environment.NewLine;
        }
        
        void Timer2Tick(object sender, EventArgs e)
        {
            textBox1.Text+="2"+Environment.NewLine;
        }
        
        void Timer3Tick(object sender, EventArgs e)
        {
            while (true) {
                System.Threading.Thread.Sleep(122);
            }
        }
        
    }
}
и форма намертво повисла если бы цикл запускал в отдельном потоке - то такого бы не случилось
вывод - таймер не создает поток, а использует тот, из которого он вызван
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
18.02.2013, 02:04  [ТС] 18
Ты глянь свой таймер и мой, они разные и из разных пространств имен
0
Winhttp22
157 / 125 / 24
Регистрация: 16.02.2013
Сообщений: 828
18.02.2013, 02:08 19
и почитай - несколько таймеров в программе? . у тебя операции попросту ставятся в "очередь" возможно изза этого и тормозит.
0
EvilFromHell
959 / 855 / 347
Регистрация: 26.04.2012
Сообщений: 2,648
18.02.2013, 02:09  [ТС] 20
Но даже у твоего таймера тики хоть и в одном потоке работают, но относительно друг друга-асинхронно, что легко проверить выведя мессадж бокс.
0
18.02.2013, 02:09
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.02.2013, 02:09

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Эмуляция нажатия клавиш.
Программа заключается в том, чтоб был постоянно повторяющийся цикл(по моему так) раз в пол...

Эмуляция нажатия клавиш
здрасте.мне нужно проэмулировать нажатие кнопок мыши и нажатий клавиш в неактивном окне(конкретно в...

Эмуляция нажатия клавиш
Всем привет! Помогите написать простенькую программу. Что должна делать? Вводим число в Edit (в...

Эмуляция нажатия клавиш
помогите с кодом разобраться, не работает( Var PWD, Login : String; procedure...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.