C# либа для зенки (148 методов с исходным кодом) – эмуляция мышки, ускорение и упрощение разработки шаблонов

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Продажи прекращены.
 

Вложения

Последнее редактирование:

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Пример шаблона на либе, для демонстрации, насколько упрощается разработка:

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



Решение простой капчи с поиском урла картинки, его передачей с апи хевил с помощью пост запроса и получение ответа на гет запросе:

// переход на страницу

_browser.Navigate("https://lessons.zennolab.com/ru/advanced");

// решение капчи

string answer = _captcha.XevilImageXpath("//img[contains(@src,'captcha')]");



Решение рекапчи в2:

// переход на страницу

_browser.Navigate("https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=low");

// решение капчи

_captcha.XevilReV2();



Решение капчи через скриншот (если по урлу картинка не доступна) - поиск картинки, определение координат, создание скриншота, отправка скриншота на апи хевил с помощью пост запроса и получение ответа на гет запросе:

// переход на страницу

_browser.Navigate("https://lessons.zennolab.com/ru/advanced");

// решение капчи

string answer = _captcha.XevilImageScreen("//img[contains(@src,'captcha')]", Registry.VarsStr["pathScreenShots"] + @"\captcha.jpg");



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

// получаем данные профиля (логин, пароль и год генерит либа, остальное из профиля зенки)

_profiles.GetData();

// переходим на страницу мейла

_browser.Navigate("https://mail.ru/");



// XpathClick - поиск элемента, проверка существования элемента, вывод инфы в лог, получение координат, человеческие движения мышкой, клик по элементу, ожидание загрузки страниц, допонительная пауза

// клик по кнопке "создать почту"

_findElem.XpathClick("//a[contains(@href,'signup')]", 2000, 1);

// если выдает страницу с регой через вк, клик по кнопке "пропустить"

_findElem.XpathClick("//button[contains(@class,'SkipLink')]", 1000, 0, false);



// XpathClickSendText - поиск элемента, проверка существования элемента, вывод инфы в лог, заполнение поля с рандомными задержками ввода, допонительная пауза

// заполнение поля Имя

_findElem.XpathClickSendText(_profiles.Data["name"], "//input[@id='fname']", 500);

// заполнение поля Фамилия

_findElem.XpathClickSendText(_profiles.Data["lastname"], "//input[@id='lname']", 500);



// открытие выпадающего списка День

_findElem.XpathClick("//span[text()='Day']", 500);

// выбор случайного дня от 1 до 12

_findElem.XpathClick("//span[text()='" + _rand.Next(1, 12) + "']", 500);



// открытие выпадающего списка Месяц

_findElem.XpathClick("//span[text()='Month']", 500);

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

List<string> monthList = new List<string> { "January", "February", "March", "April", "May", "June", "July", "August" };

// выбор случайного месяца

_findElem.XpathClick("//span[text()='" + monthList[_rand.Next(0, monthList.Count)] + "']", 500);



// XpathScroll - поиск элемента, проверка существования элемента, вывод инфы в лог, скролл элемента (в данном случае выпадающего списка), дополнительная пауза

// открытие выпадающего списка Год

_findElem.XpathClick("//span[text()='Year']", 500);

// прокрутка до года из текущего профиля

_findElem.XpathScroll("//span[text()='2021']", ((2021 - Convert.ToInt32(_profiles.Data["year"])) * 40), 500);

// клик по выбраному году

_findElem.XpathClick("//span[text()='" + _profiles.Data["year"] + "']", 500);



// если профиль мужской

if (_project.Profile.Sex.ToString() == "Male")

{

// выбор мужского пола

_findElem.XpathClick("//span[text()='Male']", 500);

}

// иначе

else

{

// выбор женского пола

_findElem.XpathClick("//span[text()='Female']", 500);

}



// заполнение поля логин

_findElem.XpathClickSendText(_profiles.Data["login"], "//input[@id='aaa__input']", 500);

// заполнение поля пароль

_findElem.XpathClickSendText(_profiles.Data["pass"], "//input[@id='password']", 500);

// заполнение поля повтор пароля

_findElem.XpathClickSendText(_profiles.Data["pass"], "//input[@id='repeatPassword']", 500);



// клик по кнопке "Create" (у меня англ вариант реги мейл ру, для русского надо заменить текст кнопки)

_findElem.XpathClick("//span[text()='Create']", 1000);



// XevilImageScreen - решение капчи с апи хевил с созданием и отправкой пост-запросом скриншота картинки с капчей (мейл не отдает картинку капчи по урлу)

// решение капчи

string answer = _captcha.XevilImageScreen("//img[@data-test-id='captcha-image']", Registry.VarsStr["pathScreenShots"] + @"\captcha.jpg", 500, 0, false);

// заполнение поля с ответом капчи

_findElem.XpathClickSendText(answer, "//input[@data-test-id='captcha']", 500, 0, false);

// отправка формы

_findElem.XpathClick("//button[@type='submit']", 1000, 0, false);



// сохраняем профиль зенки для дальнейшего использования и отдельно сохраняем основные данные профиля в текстовый файл

_profiles.SaveFull();
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Описание доступных классов и методов (всего в либе 4600 строк кода с комментариями, 16 классов и 148 методов):

Здесь будет краткое описание методов, чтобы были понятны возможности. Подробное описание методов, полей и свойств – в библиотеке непосредственно для разработчиков. Подробно прокомментирован основной класс, в котором пишется код шаблона, класс настроек, а также вызовы методов других классов. Остальное без подробных комментариев, туда лезть не нужно – а кто захочет, те и без комментов спокойно поймут. Для примера посмотрите прикрепленные скриншоты.



Droid

Класс Droid – для написания шаблонов кодом в студии без использования кубиков зенки, поэтому здесь подробно описывать не буду (в коде есть подробные комментарии).

Droid.Droid – конструктор класса.

Droid.ReInit – ре-инициализация для повторных выполнений, если кол-во повторений указывать в либе, а не в зенке.

Droid.Worker – основной код шаблона, если не используются кубики.



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

DLibRus.Droid droid = new DLibRus.Droid(project, instance);

Если вы хотите вызывать методы либы из других кубиков, а не из кода, добавьте к инициализации в экшен еще строку:

project.Context["droid"] = droid;

И потом в другом кубике, к примеру, для простого гет запроса:

project.Context["droid"].Http.GetSimple("http://localhost/");



Browser

Класс Browser – работа с браузером.

Browser. Browser – конструктор класса.

Browser.Tunes – всего 31 поле базовых настроек браузера, которые поддерживает зенка. Возможность очистки кеша, кук, прокси. Установка кук и суперкук. Настройка уровней эмуляции (в том числе сверх эмуляция с реалистичными движениями мышки на основе кривых безье и реалистичными задержками при вводе текста). Достаточно один раз настроить и потом использовать во всех проектах.

Browser.Proxy – получение прокси из файла по номеру потока (в файле ничего не затирается) и установка прокси в браузер, с проверкой на успешность установки.

Browser.WebRTC – настройка веб ртс, чтобы реальный айпи не утекал, а также настройка аудио и видео устройств.

Browser.Wait – ожидание готовности вкладки, если идет процесс загрузки страницы.

Browser.Navigate – переход на заданный адрес, с возможностью указать рефер и вкладку, с проверкой существования вкладки, ожиданием готовности вкладки и проверкой на осуществление перехода. То есть если переход не произошел, и вместо страницы открылась about.blank (бывает такое) – будет ошибка и сообщение в лог.



Благодаря классу Browser можно писать очень упрощенный код, к примеру, чтобы в проекте перейти на страницу, нужно просто написать одну строку кода, при этом все настройки и очистки барузера, вебртс, установка прокси будут сделаны при инициализации фреймворка, не нужно об этом даже вспоминать:

Browser.Navigate("https://mail.ru/");



Profiles

Класс Profiles – для работы с созданными и нагулянными профилями браузера.

Profiles.Profiles – конструктор класса.

Profiles.CreateOrLoad
– выбор номера профиля и проверка возможности его загрузки или необходимости генерации нового.

Profiles.GetData – генерация данных профиля.

Profiles.SaveFull
– сохранение полного профиля.

Profiles.SaveStr
– служебный прайвет метод, сохранение основных данных профиля в текстовый файл.

Profiles.LoadFull – служебный прайвет метод, загрузка полного профиля.

Profiles.LoadStr
– служебный прайвет метод, загрузка основных данных профиля из текстового файла.

Profiles.GetPathProfile – служебный прайвет метод, получение пути к профилю

Profiles.GenerateLogin – служебный прайвет метод, генерация логина.

Profiles.GeneratePass – служебный прайвет метод, генерация пароля.



Данный класс позволяет сохранять полные профили для их последующей загрузки, а также сохранять основные данные профиля в текстовые файлы для использования в других проектах, которые не позволяют загружать профили браузера.

Простой вызов одной строкой:

Profiles.SaveFull();



Mouse

Класс Mouse – класс работы с мышкой (наведение, клик, движение, скролл).

Mouse.Mouse – конструктор класса.

Mouse.FindCoordsForMouseMove – определение координат для движения мыши для методов Scroll и Move.

Mouse.RiseEvent – простое событие.

Mouse.Click – основной метод, включающий поиск координат, скролл до нужного места страницы, подводку мыши к элементу и непосредственно клик, имеет 4 уровня эмуляции.

Mouse.Move
– если вам отдельно нужно движение мыши, имеет 4 уровня эмуляции.

Mouse.Scroll – если вам отдельно нужен скролл, требует уровня FullEmulation и выше (3 и 4 уровни в либе, «полная эмуляция мыши» в зенке).

Mouse.MoveLikeHumanInViewport – если вам отдельно нужно естественное человеческое движение мыши.

Mouse.MoveWithRandomScroll – служебный прайвет метод частичного скролла страницы с паузами и движением мышки между скроллами.

Mouse.MoveWithRandomScrollRange – служебный прайвет метод движения мыши и скролла на определенное расстояние.

Mouse.MoveWithRandomScrollOverElement – служебный прайвет метод подведения мыши к элементу после скролла.

Mouse.MoveBezier – служебный прайвет метод движения по кривым Безье.

Mouse.DrawBezierX – служебный прайвет метод создания кривых Безье.

Mouse.DrawBezierY – служебный прайвет метод создания кривых Безье.

Mouse.DrawBezier – служебный прайвет метод создания кривых Безье.



Наиболее часто используется метод Click, он является наиболее простым в использовании и включает максимальные возможности.

На 1 уровне это просто мгновенный скролл и клик на JS.

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

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

На 4 уровне сначала определяются нужные координаты, потом в видимой части окна браузера по кривым Безье мышка делает хаотичные человеческие движения, как будто человек задумался и изучает сайт. Это также, как на 3 уровне. Но вот после происходит не быстрый прямой скролл, а страница пролистывается частями, и между скроллами совершаются движения мышки – опять же, как будто человек постепенно изучает страницу сайта и по привычке двигает мышкой. И, когда долистывается до нужного элемента, мышка подводится к нему и совершается клик с полной эмуляцией. При этом на 4 уровне разные движения мышки производятся с разной скоростью, как у обычного пользователя. На вебвизоре получается очень человечная картинка поведения пользователя.

Уровни эмуляции указываются один раз в настройках класса Registry.

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

Mouse.Click(element);



Txt

Класс Txt – работа с текстом.

Txt.Txt – конструктор класса.

Txt.Transliterate
– транслитерация кирилиццы.

Txt.RegexMatch – возвращает часть строки по регулярному выражению.

Txt.SubBy – переводит строку в список по разделителю.

Txt.SendWithRandDelay – отправка текста в поле формы со случайной задержкой между символами (эмуляция ввода текста человеком с клавиатуры).

Txt.SendClearField – очистка поля формы (удаление текста).

Txt.Send – отправка текста в поле формы, имеет 4 уровня эмуляции.



Наиболее часто используется метод Send для заполнения полей формы на странице.

На 1 уровне это базовое мгновенное присвоение значение полю.

На 2 уровне используется вставка из буфера обмена – категорически не рекомендуется для использования в многопотоке.

На 3 уровне используется отправка текста с фиксированной задержкой между символами.

На 4 уровне используется отправка текста в поле формы со случайной задержкой между символами (эмуляция ввода текста человеком с клавиатуры) – то есть вызывается метод SendWithRandDelay.

Уровни эмуляции указываются один раз в настройках класса Registry.

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

Txt.Send(element, “текст”);



Captcha

Класс Captcha – решение каптчи через api сервисов и прог, по умолчанию (другой софт), можно на том же компе, что и зенка, можно на другом компе или сервере.

Captcha.Captcha – конструктор класса.

Captcha.XevilBalance – тест подключения к (другой софт).

Captcha.XevilReV2 – решение рекапчи v2 на текущей страницы (вызывается без аргументов, метод сам все делает).

Captcha.XevilReV2full – решение рекапчи v2 с аргументами метода, если вам нужно сформировать их самим.

Captcha.XevilImageUrl – решение капчи по адресу картинки.

Captcha.XevilImageXpath – находит адрес изображения капчи по xpath и решает через api (другой софт).

Captcha.XevilImageScreen – находит изображение капчи по xpath, делает скриншот, и пост-запросом отправляет его через api на решение в (другой софт).

Captcha.XevilImageFile – решение капчи в файле картинки.

Captcha.Base – служебный прайвет метод решения каптчи с настройкой подключения по api.

Captcha.ReV2 – служебный прайвет метод решения рекаптчи.

Captcha.Image – служебный прайвет метод решения каптчи на картинке.

Captcha.Response – служебный прайвет метод получения ответа по api с решением каптчи.



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

Browser.Navigate("https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=low");

Captcha.XevilReV2();




Files

Класс Files – работа с файлами.

Files.Files – конструктор класса.

Files.AddLineSync – добавить в файл строку, с синхронизацией.

Files.AddListNoSync – добавить в файл список строк, без синхронизации.

Files.SaveAllTextNoSync – создать файл и записать в него содержимое, без синхронизации.

Files.GetAllLinesToStringNoSync – считать все строки из файла в строку, без синхронизации.

Files.GetAllLinesToListSync – считать все строки из файла в список, с синхронизацией.

Files.GetNextLineSync – считать следующую строку из файла, с синхронизацией.

Files.GetRandomLineSync – считать случайную строку из файла, с синхронизацией.

Files.CountLinesSync – подсчет строк в файле (работает быстро, к примеру, считает строки в 500 мб файле за 4 секунды), с синхронизацией.

Files.CountFilesSync – подсчет файлов в директории.



Чтение и запись сделаны через потоки (FileStream, StreamReader, StreamWriter) для надежности и быстродействия. Простой вызов одной строкой:

Files.AddLineSync(“текст”,”путь к файлу”,”объект синхронизации”);



Http

Класс Http – работа с сетевыми запросами.

Http.Http – конструктор класса.

Http.CookieCreate – создание куки.

Http.PostUpload – загрузка файлов пост-запросом.

Http.PostXml – отправка xml пост-запросом.

Http.PostJson – отправка json пост-запросом.

Http.PostSimple – простой пост-запрос (отправка полей формы).

Http.GetFile – скачивание файла.

Http.GetSimple – простой гет-запрос.

Http.Post – пост-запрос со всеми аргументами.

Http.Get – гет-запрос со всеми аргументами.

Http.Exec – служебный прайвет метод выполнения запросов.

Http.ExecSettings – служебный прайвет метод настроек запросов.

Http.ExecCookie – служебный прайвет метод куки запросов.

Http.ExecProxy – служебный прайвет метод прокси запросов.

Http.ExecAuth – служебный прайвет метод авторизации запросов.

Http.ExecPost – служебный прайвет метод пост-запросов.

Http.ExecPostData – служебный прайвет метод данных в пост запросах

Http.ExecPostUpload – служебный прайвет метод загрузки файлов пост-запросами.

Http.ExecResponse – служебный прайвет метод получения и обработки ответа сервера на запрос.



Удобный класс для построения гет и пост запросов. Возможна работа через прокси, авторизация, скачивание и отправка файлов, xml, json. Используются HttpWebRequest. Возможна настройка таймаутов (базового и отдельно на чтение/запись, по умолчанию 15 секунд), количества допустимых редиректов, буфера, юзерагентов и заголовков, сделан обход проверки валидности сертификата.

Очень простой вызов, к примеру простой гет-запрос:

Http.GetSimple("http://localhost/");

Простой пост-запрос:

Http.PostSimple("http://localhost/", "inptxt=mytestvalue&inpsubmit=ok");

Отправка файла пост-запросом:

Http.PostUpload("http://localhost/", "inptxt=mytestvalue&inpsubmit=ok", @"inputname=inpfile&filename=c:\logo.gif&type=image/gif");



Email

Класс Email – работа с электронной почтой.

Email.Email – конструктор класса.

Email.ConfirmLinkSingle – подключение к почте и поиск в письмах ссылки для подтверждения.

Email.DeleteAll – удаление писем из ящика.

Email.GetConfirmLink – служебный прайвет метод получения подтверждающей ссылки.

Email.FindInBody – служебный прайвет метод поиска ссылки в письме.

Email.ConnectPop – служебный прайвет метод подключения к почтовому серверу.



Данный класс не имеет отношения к методам зенки, написан с использованием бесплатной библиотеки OpenPop. Простая работа с почтой – получение ссылок для подтверждения аккаунтов при регистрации и удаление писем в ящике. Вызывается очень просто, ищет письмо с нужным текстом и возвращает ссылку для подтверждения:

Email.ConfirmLinkSingle(“адрес почтового сервера” ,”логин” ,”пароль” ,”искать в адресе” ,”искать в теме” ,”искать в теле письма”);

Дополнительно можно указать таймаут (по умолчанию 15 секунд), использование ssl, порт, удаление найденных писем, выводить ли информацию в лог.

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

Обратите внимание, что данный метод не поддерживает прокси, мне на pop3 протоколе они не были нужны. Это можно решить, используя вместо бесплатной OpenPop – платную либу типа Mail.dll, которая поддерживает и соксы и oauth.



Procs

Класс Procs – работа с процессами.

Procs.Procs – конструктор класса.

Procs.RunAndReadOutput – запуск процесса через командную строку с аргументами со скрытым окном и получение результатов вывода в список.

Procs.MemoryCurrent – проверка потребления памяти текущего процесса, только для дебага, вызывает утечки памяти.

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

Procs.GetPidCurrent – получить pid текущего процесса.

Procs.GetPidByName – получить pid процессов по имени.



Запустить процесс в скрытом окне и получить результать вывода в лист можно одной строкой:

Procs.RunAndReadOutput(“путь к исполняемому файлу”,“аргументы”);

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



Screens

Класс Screens – создание скриншотов.

Screens.Screens – конструктор класса.

Screens.Full – скриншот всего окна браузера.

Screens.Crop – скриншот части окна браузера по координатам.



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

Вызов одной строкой (для текущей вкладки браузера):

Screens.Full();



Elem

Класс Elem – класс для работы с элементами html.

Elem.Elem – конструктор класса.

Elem.GetAttribute – получение значения атрибута элемента.



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

Для понимания, что за проверки, и насколько короче становится код, вот так вызывается метод:

Elem.GetAttribute(element, attributeName);

А вот столько проверок и вывода информации в лог содержится в методе, иначе бы их пришлось писать в коде шаба (здесь приведен код без комментариев, в либе они есть):

public static string GetAttribute(HtmlElement el, string attrName, bool throwError = true, bool throwLog = true)

{

string attrValue = "";

if (el != null && !el.IsNull && !el.IsVoid && !el.ErrorDetected)

{

attrValue = el.GetAttribute(attrName);



if (attrValue == null || attrValue == "")

{

if (throwLog) { Logs.MsgError("пустое значение атрибута " + attrName); }

if (throwError) { Registry.SetErrorWorker(); }

}

}

else

{

if (throwLog) { Logs.MsgError("невозможно получить значение атрибута – элемент отсутствует на странице"); }

if (throwError) { Registry.SetErrorWorker(); }

}

return attrValue;

}



FindElem

Класс FindElem – класс для поиска элементов html на странице.

FindElem.FindElem – конструктор класса.

FindElem.SingleWaitForValue – поиск одного элемента с ожиданием, пока тот примет значение.

FindElem.XpathClick – поиск элемента по xpath и клик по нему.

FindElem.XpathScroll – поиск элемента по xpath, подведение мыши и скролл на заданное расстояние.

FindElem.XpathSendText
– поиск элемента по xpath и заполнение текстом.

FindElem.XpathClickSendText
– поиск элемента по xpath, клик по нему и заполнение текстом.

FindElem.SingleById – поиск элемента по айди.

FindElem.SingleByTag – поиск элемента по тегу.

FindElem.SingleByName – поиск элемента по имени.

FindElem.SingleByXpath – поиск элемента по xpath.

FindElem.CollectionByTag – поиск коллекции элементов по тегу.

FindElem.CollectionByName – поиск коллекции элементов по имени.

FindElem.CollectionByXpath – поиск коллекции элементов по xpath.

FindElem.ChildById – поиск дочернего элемента по айди.

FindElem.ChildByTag – поиск дочернего элементов по тегу.

FindElem.ChildByName – поиск дочернего элементов по имени.

FindElem.ChildByXpath – поиск дочернего элементов по xpath.

FindElem.ChildrenByTag – поиск коллекции дочерних элементов по тегу.

FindElem.ChildrenByName – поиск коллекции дочерних элементов по имени.

FindElem.ChildrenByXpath – поиск коллекции дочерних элементов по xpath.

FindElem.Single – служебный прайвет метод поиска отдельного элемента.

FindElem.Collection – служебный прайвет метод поиска коллекции элементов.

FindElem.Child – служебный прайвет метод одного дочернего элемента.

FindElem.Children – служебный прайвет метод поиск коллекции дочерних элементов.



По сути, данный класс – это обертка над методами поиска элемента зенки, нужен он, чтобы сразу включить необходимые проверки и вывод информации о ходе выполнения в лог, а не писать это каждый раз при вызове отдельных методов зенки, так код шаба становится намного короче и прозрачнее. Вместо отдельных методов можно было сделать просто перезагрузку, но с отдельными методами с говорящими названиями код лучше читается. Также сделаны методы для таких частых действий, как найти элемент и кликнуть по нему или найти поле и заполнить его текстом.

Пример вызова поиска элемента и клика по нему:

FindElem.XpathAndClick(“xpath”);



Registry

Класс Registry – регистр переменных, настроек путей либы и уровней эмуляции, глобалок зенки и проверка запуска повторных выполнений воркера, править его нужно только для перенастройки либы, поэтому подробно не буду останавливаться (в коде есть подробные комментарии).

Registry.Registry – конструктор класса.

Registry.ClearErrors – сброс ошибок

Registry.CheckPermission – проверка разрешений

Registry.SetErrorWorker – установка рабочей ошибки

Registry.SetErrorCrit – установка критической ошибки

Registry.Local – настройки путей либы и уровней эмуляции

Registry.Global – глобальные переменные зенки

Registry.WorkerNext – настройки перехода к следующему выполнению, если кол-во повторений указывать в либе, а не в зенке.



Crypto

Класс Crypto – работа с криптографией.

Crypto.Crypto – конструктор класса.

Crypto.StringMD5 – получение MD5 хеша строки

Crypto.FileMD5 – получение MD5 хеша файла



MD5 хеш полезен к примеру при сравнении файлов, намного надежнее, чем по размеру сравнивать. Вызов одной строкой:

Crypto. FileMD5 (“путь к файлу”);



Logs

Класс Logs – вывод информации о ходе выполнения и об ошибках в лог.

Logs.Logs – конструктор класса.

Logs.Start – инициализация лога (вызывается при инициализации либы).

Logs.HandleErrors – обработка вывода информации об ошибках.

Logs.HandleErrorsZenno – вывод информации об ошибках только в лог зенно.

Logs.MsgError – вывод ошибок в лог.

Logs.Msg – вывод сообщения в лог.

Logs.Flush – отправка кешированной части логи на запись в файл.

Logs.Stop – остановка лога (вызывается при завершении работы либы).

Logs.StartVars – служебный прайвет метод, обрабатывающий переменные инициализации.

Logs.Write – служебный прайвет метод, кеширование лога.

Logs.WriteError – служебный прайвет метод, кеширование информации об ошибках.

Logs.SavePageDom – служебный прайвет метод, сохранение страницы, на которой произошла ошибка.

Logs.ElapsedTime – служебный прайвет метод, запись времени выполнения потока.

Logs.SaveTxt – служебный прайвет метод, сохранение кешированной части лога в файл.



В настройках либы можно указать, выводить ли всю информацию в лог или только информацию об ошибках. Также можно указать, использовать ли мой лог или только зенно. Мой лог создает отдельные файлы с расширенной информацией, при необходимости делает скриншоты и сохраняет код страницы, выдает полную информацию об ошибках (message, targetSite, StackTrace), а также замеряет время выполнения потока. В том числе мой лог выводит подробную информацию не только в прожект мейкере, но и в зеннопостере (это отключаемая опция, для дебага).

Сообщение в лог отправляется строкой:

Logs.Msg(“текст”);

Ошибка отправляется в лог строкой:

Logs.MsgError(“текст”);

Подробная информация об ошибке из блока try{}catch{}:

Logs.HandleErrors(exception);
 

dmitriy1384

Client
Регистрация
04.11.2013
Сообщения
377
Благодарностей
133
Баллы
43
Если код открытый, то можно в складчину купить ? 8-)
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 674
Благодарностей
1 859
Баллы
113
  • Спасибо
Реакции: AndrewSuul

avtostopshik

Client
Регистрация
09.09.2016
Сообщения
756
Благодарностей
135
Баллы
43
Уже давно использую эту библиотеку в своих проектах (получал за пределами зенно форума) - больше всего порадовала именно эмуляция и все методы работы с мышкой. Сделано очень качественно, движения курсора выглядят как настоящие. Даже яндекс метрика первые несколько дней роботность вообще не показывала, а потом начала (видимо задолбил сайт одними и теми же запросами, но попробовать на бОльшем их количестве руки не дошли).
Что касается самой библиотеки - она очень большая и всеобъемлющая. Решение рекапчи, работа с пост/гет запросами и так далее - все методы и всё в библиотеке структурированы и разложены по полочкам. Видно, что была написана грамотным программистом, не то что мы, чайники
В общем с этой библиотекой у вас будет всё и сразу в одном месте + эмуляция, качества которой я ещё не видел в других либах
 
  • Спасибо
Реакции: -=Dzen=-

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Если код открытый, то можно в складчину купить ? 8-)
Я не одобряю такого подхода. Вы, конечно, можете купить скинувшись с кем-то. Но консультации я буду оказывать только тому, кто купил.
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
а чем отличается от бесплатных вариантов из коллекции готовых сниппетов и конкурсной статьи ну и от методов описанных в документации зенки?
Всем отличается) Я же на 15 вордовских страницах описал и особенности, и отличия, и все методы и выложил это выше в трех постах в начале темы))) Давайте еще раз, в паре слов кратко скажу:
1) Многих решений, которые есть в моей либе нет ни в кубиках зенки, ни в бесплатных шабах/сниппетах.
Некоторые решения есть в виде отдельных платных шабов или либ с закрытым кодом.
К примеру, один только аналог движений мышки в другой теме на форуме стоит $250 с закрытым кодом (ссылку убрал).
А в моей либе это лишь часть, и помимо этого еще множество удобных решений включено, и все это с открытым кодом, то есть не нужно платить мне каждый раз, когда вы используете эти решения в шабе, который продаете клиенту.
К тому же даже по той же мышке, кроме непосредственно человеческих движений, у меня есть такие методы, как пошаговый скролл страницы с разной скоростью и движениями мышки между этапа скролла, имитирующие чтение страницы человеком, и тд.
В общем, повторно 15 страниц тут писать не буду, все есть в постах выше.
2) По поводу тех методов, которые являются фасадами/адаптерами (если вам знакомы данные паттерны ООП) к стандартным методом зенки и/или шарпа - они сделаны уже с необходимыми проверками и в очень простом для использования виде.
Согласитесь, вот так отправлять пост-запросы
Http.PostSimple("http://localhost/", "inptxt=mytestvalue&inpsubmit=ok");
или вот так загружать картинки пост-запросом
Http.PostUpload("http://localhost/", "inptxt=mytestvalue&inpsubmit=ok", @"inputname=inpfile&filename=c:\logo.gif&type=image/gif");
намного проще (все проверки и выводы в лог присутствуют в режиме дебага, на продакшен лог можно отключать).
3) По поводу использования готовых бесплатных решений (шабов, сниппетов) - я вообще редко видел хорошие качественные решения в бесплатном доступе (если это не опен-сурс софт). В конкурсных статьях и шабах люди, безусловно, деляется интересными наработками, но в очень ограниченном урезанном виде, скорее в виде превью их возможностей. Конкретно по тем ссылкам, которые вы скинули, вообще решений очень и очень мало, сравнивать с моей либой это невозможно.
4) Конечно, любой хороший программист может сделать свою библиотеку, но это займет время. Для тех же, кто раньше писал только в кубиках, это займет очень много времени. А тут уже все готовое, и можно и дальше расширять.
 
Последнее редактирование:

Alex733

Client
Регистрация
27.11.2017
Сообщения
316
Благодарностей
230
Баллы
43
Всё, что мно написано - моё личное мнение на основе прочитанного и не является призывом к дейтсвию.
Автора я не знаю и библиотеку не покупал, но хочу написать в его поддержку: цена достойная и, я бы сказал, даже занижена.
В силу, того, что я часто использую C# в разработке, работа проделана огромная и что бы принять взвешенное решение, о приобретении, нужно поизучать довольно много информации. Сто сорок восемь методов - это не шутки, а огромная работа, которая, наверняка, будет продолжаться.
Решиться, - что нароботано годами, высижено в кресле (или выстояно - может быть у автора стол, приспособленный для такого вида производства шаблонов), потом оформлено, переоформлено, прокомментировано, удалено, добавлено, минуты, часы, недели поиска правильного решения - что бы продать, довольно сложное решение.
Я думаю, что это достойный продукт и обязательно найдутся пользователи, которые не пожалеют о приобретении и смогут использовать в своих проектах.
 

RoyalBank

Client
Регистрация
07.09.2015
Сообщения
557
Благодарностей
547
Баллы
93
Покажите, как реализовали метод добавления/записи строки в текстовый файл (Files.AddLineSync). По коду будет понятен уровень всего остального.
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Всё, что мно написано - моё личное мнение на основе прочитанного и не является призывом к дейтсвию.
Автора я не знаю и библиотеку не покупал, но хочу написать в его поддержку: цена достойная и, я бы сказал, даже занижена.
В силу, того, что я часто использую C# в разработке, работа проделана огромная и что бы принять взвешенное решение, о приобретении, нужно поизучать довольно много информации. Сто сорок восемь методов - это не шутки, а огромная работа, которая, наверняка, будет продолжаться.
Решиться, - что нароботано годами, высижено в кресле (или выстояно - может быть у автора стол, приспособленный для такого вида производства шаблонов), потом оформлено, переоформлено, прокомментировано, удалено, добавлено, минуты, часы, недели поиска правильного решения - что бы продать, довольно сложное решение.
Я думаю, что это достойный продукт и обязательно найдутся пользователи, которые не пожалеют о приобретении и смогут использовать в своих проектах.
Спасибо!

Покажите, как реализовали метод добавления/записи строки в текстовый файл (Files.AddLineSync). По коду будет понятен уровень всего остального.
/// <summary>
/// добавить в файл строку, с синхронизацией
/// </summary>
/// <param name="line">строка для добавления</param>
/// <param name="filePath">путь к файлу</param>
/// <param name="syncObj">ссылка на статический объект для синхронизации доступа</param>
public void AddLineSync(string line, string filePath, object syncObj)
{
lock (syncObj)
{
Stream stream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None);
using (StreamWriter strWriter = new StreamWriter(stream))
{
strWriter.WriteLine(line);
}
if (stream != null) { stream.Dispose(); }
}
}
 

Konrod_m

Client
Регистрация
18.09.2014
Сообщения
1 662
Благодарностей
919
Баллы
113
Записали бы видео написания какого-нибудь простенького шаблона с вашей библиотекой. + демо инструкции (описания-руководства).

Из описания не понятно, смогут ли простые пользователи постера с этим работать, а не простым - оно наверное и не надо вовсе..
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 690
Баллы
113
Спасибо!


/// <summary>
/// добавить в файл строку, с синхронизацией
/// </summary>
/// <param name="line">строка для добавления</param>
/// <param name="filePath">путь к файлу</param>
/// <param name="syncObj">ссылка на статический объект для синхронизации доступа</param>
public void AddLineSync(string line, string filePath, object syncObj)
{
lock (syncObj)
{
Stream stream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None);
using (StreamWriter strWriter = new StreamWriter(stream))
{
strWriter.WriteLine(line);
}
if (stream != null) { stream.Dispose(); }
}
}
не то что я придираюсь.... но ведь файл может быть занят другим шаблоном, на который не распространяется статичный объект синхронизации или вообще другой программой.... а тут нет обработки ошибок, нет попыток для повтора записи, при занятости файла.
но это фигня на самом деле, так как либа то для зенки, а не для работы с файлами. И вот для зенки очень важно как сделана работа с элементами.
 
  • Спасибо
Реакции: DevOps

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
не то что я придираюсь.... но ведь файл может быть занят другим шаблоном, на который не распространяется статичный объект синхронизации или вообще другой программой.... а тут нет обработки ошибок, нет попыток для повтора записи, при занятости файла.
но это фигня на самом деле, так как либа то для зенки, а не для работы с файлами. И вот для зенки очень важно как сделана работа с элементами.
В моих шабах (а я повторюсь, либа писалась для моих шабов) файл не может быть занят другим шабом или другой программой. Поэтому более чем достаточно делать синхронизацию доступа потоков к файлам. Код открытый, в случае вами описанным, можно сделать еще один метод (или перезагрузку/фасад/адаптер, как угодно) конкретно под задачу, если файл может быть занят другими процессами. Причем это можно сделать как сам человек, который приобрел либу, так и заказать мне написание нужных ему методов за отдельную плату.
Обработки ошибок и выводов в лог очень много, там где нужно. Когда я отправляю строку на запись в файл, который относится только к этому шабу, я не вижу, что тут еще можно обработать и вывести в лог.
К примеру на чтении файла конечно проверку существования и вывод ошибки в лог надо сделать
if (File.Exists(filePath))
{
}
else
{
_logs.MsgError("file not exists " + filePath);
_registry.SetErrorWorker();
}
Или вот еще кусочек кода поиска элемента с обработкой ошибок и выводом в лог (эти сообщения можно подавить в зависимости от задачи)
if (el == null || el.IsVoid)
{
if (throwLog)
{
if (throwError)
{
_logs.MsgError("dom element not found", 1, 1);
}
else
{
_logs.MsgError("dom element not found");
}
}
if (throwError) { _registry.SetErrorWorker(); }
}
else
{
if (throwLog) { _logs.Msg("dom element is found"); }
}
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Записали бы видео написания какого-нибудь простенького шаблона с вашей библиотекой. + демо инструкции (описания-руководства).

Из описания не понятно, смогут ли простые пользователи постера с этим работать, а не простым - оно наверное и не надо вовсе..
Я же сделал подробнейшее описание методов + как пример простого шаба в первых постах, там 15 вордовских страниц, так что это все есть.
Также я сделал примечание "Обратите внимание, что для работы с либой вам понадобятся, как минимум, базовые знания C#, ООП, XPATH, принципов верстки и работы сайтов и т.д."
Я не знаю, что именно вы вкладываете в понятие "простой пользователь" - каждый сам решит, требуется ли ему либа или нет.
К примеру avtostopshik уже давно использует мою библиотеку, и его отзыв вы можете видеть выше.
 

Konrod_m

Client
Регистрация
18.09.2014
Сообщения
1 662
Благодарностей
919
Баллы
113
Я же сделал подробнейшее описание методов + как пример простого шаба в первых постах, там 15 вордовских страниц, так что это все есть.
не настаиваю. просто написал, что не понятно. так же как и не нашел описания на 15 вордовских страниц.

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

я предложил продемонстрировать - вы отказались. все норм.
 
  • Спасибо
Реакции: djaga

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
не настаиваю. просто написал, что не понятно. так же как и не нашел описания на 15 вордовских страниц.
ужасный пример. вообще не показательный. + ктоже знает. как именно он начал ей пользоваться - возможно с какого нибудь обучения.
я предложил продемонстрировать - вы отказались. все норм.
Простенький шаблон (регистрация на мейл ру) есть в моих первых постах, так же как описание всех методов. То есть то, что вы запросили, уже есть в виде текста, а не на видео.
Если вам нужна инструкция, как использовать методы классов, помимо их описания - то я указал в примечании, что требуются базовые знания шарпа и ООП, без них либой будет пользоваться сложновато.
Час консультации-обучения по либе по голосовой или видео связи включен в стоимость, возможно проведение дополнительных консультаций за дополнительную стоимость.
Но, люди уже приобретают и пользуются, и им даже не требуется консультация, код подробно прокомментирован, как вы можете видеть на скринах.
 

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 327
Благодарностей
5 429
Баллы
113
Так давайте не будем говорить что лучше или хуже других и уж тем более ссылками бросатся. Тему почищу.
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Так давайте не будем говорить что лучше или хуже других и уж тем более ссылками бросатся. Тему почищу.
Я ни в коем случае не говорю, что лучше или хуже других, я указывал, что функционал, который продается в другой теме отдельно, у меня является лишь частью, среди прочих возможностей.
 

Mikhail B.

Moderator
Регистрация
23.12.2014
Сообщения
14 327
Благодарностей
5 429
Баллы
113
Я ни в коем случае не говорю, что лучше или хуже других, я указывал, что функционал, который продается в другой теме отдельно, у меня является лишь частью, среди прочих возможностей.
Да @radv первый начал)) такие обсуждения лучше без ссылок и названий вести
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 674
Благодарностей
1 859
Баллы
113
Да @radv первый начал))
я просто вопрос задал, мне ответили.
А насчет предложений других пользователей, согласен. Что новичкам лучше наглядный видеопример использования на практике, а не сухое описание и документация с примерами. Но автор не хочет это делать, и это его право. Пример с видео, поможет сэкономить время на консультациях по начальному использованию после покупки.
 
Последнее редактирование:

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
А насчет предложений других пользователей, согласен. Что новичкам лучше наглядный видеопример использования на практике, а не сухое описание и документация с примерами. Но автор не хочет это делать, и это его право. Пример с видео, поможет сэкономить время на консультациях по начальному использованию после покупки.
Ту же самую информацию, что изложена текстом, переносить в видео формат я смысла не вижу (насчет сухости, кто то предпочитает читать, кто то слушать - зависит от предпочтений в восприятии).
А делать подробный видео обзор либы с кодом - все равно что выложить ее в паблик, слишком много инфы придется раскрывать.
Поэтому подобный разбор по видео или голосом - для клиентов в прайвет режиме, с ответами именно на те вопросы, которые у них возникают.
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Я немного удивляюсь пожеланиям подробных видео обзоров, потому что, как программист, я привык использовать сторонние решения - либы, сдк, апи и прочее - и в работе с ними уже за счастье, когда есть подробная текстовая документация, часто и без этого приходится разбираться самостоятельно, просто по названиям методов с парой примечаний, вообще без возможности задать разрабам вопросы, и это нормально и привычно. А тут и пример использования, и подробное описание всех методов, и весь код прокомментирован, и можно по видео или голосом задать разработчику вопросы - и этого все равно мало. Давайте все таки еще раз уточню, я продаю готовую либу, которую писал для себя - и тем, кому она пригодится, все будет понятно из описания без всяких консультаций (люди уже пользуются и им не требуется помощь, чтобы разобраться). Я не предусматривал в этой либе всех возможных запросов разработчиков (как пример выше с занятием файлов сторонними процессами) и я не предусматривал либу, как наглядное пособие для обучения программированию и как использовать методы классов в шарпе (чтобы делать по этой теме видео уроки). Тем не менее, за ваши деньги - любой каприз по либе, хоть изменить, хоть дописать, хоть многочасовые видео консультации по либе и шарпу с самого нуля)))))))
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 674
Благодарностей
1 859
Баллы
113
Ту же самую информацию, что изложена текстом, переносить в видео формат я смысла не вижу (насчет сухости, кто то предпочитает
А делать подробный видео обзор либы с кодом - все равно что выложить ее в паблик, слишком много инфы придется раскрывать.
я думаю имели ввиду использование готовых методов либы, а не разбор кода методов. Ведь использовать ее будут и те, кто далек от программирования и для кого комментарии в коде могут быть тоже непонятны. А программистам с опытом конечно такое видео не нужно.
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Продажи либы в данной теме временно приостанавливаются до закрытия темы на складчике.

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

amyboose

Client
Регистрация
21.04.2016
Сообщения
2 312
Благодарностей
1 191
Баллы
113
Спасибо!


/// <summary>
/// добавить в файл строку, с синхронизацией
/// </summary>
/// <param name="line">строка для добавления</param>
/// <param name="filePath">путь к файлу</param>
/// <param name="syncObj">ссылка на статический объект для синхронизации доступа</param>
public void AddLineSync(string line, string filePath, object syncObj)
{
lock (syncObj)
{
Stream stream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None);
using (StreamWriter strWriter = new StreamWriter(stream))
{
strWriter.WriteLine(line);
}
if (stream != null) { stream.Dispose(); }
}
}
Автор, ну можно же было развернуть нормально метод без использования такого количества конструкций try/ catch. Одна лежит внутри lock, другая - внутри using.

Вот простой вариант:
C#:
/// <summary>
/// добавить в файл строку, с синхронизацией
/// </summary>
/// <param name="path">путь к файлу</param>
/// <param name="line">строка для добавления</param>
/// <param name="syncObj">ссылка на статический объект для синхронизации доступа</param>
public void AddLineSync(string path, string line, object syncObj)
{
    bool acquiredLock = false;
    StreamWriter strWriter = null;

    try
    {
        Monitor.Enter(syncObj, ref acquiredLock);
        FileStream stream = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.None);
        strWriter = new StreamWriter(stream);

        strWriter.WriteLine(line);

    }
    finally
    {
        strWriter?.Dispose();

        if (acquiredLock)
            Monitor.Exit(syncObj);
    }
}
Похоже на то, что автор перешел в c# из другого языка или самоучка, так как многие реализации сделаны простым понятным способом. Это хорошо для новичков, но когда дело доходит до сложных конструкций, такое не сработает
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 690
Баллы
113
Продажи либы в данной теме временно приостанавливаются до закрытия темы на складчике.
Да какие тут бесплатные видео уроки делать - коммьюнити настолько не уважает труд коллег, что тут же пилят складчину, хотя я прямо высказал, что не одобряю такого подхода.
пфф... 2 или 3 года назад в чате зеннолаба в открытую выкладывали исходники из темы человеческого движения мыши.
и твою либу выложат. но сначала она разойдется по закрытым группам по интересам :bk:
интересно... были мысли что будет как то по другому ?
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
Автор, ну можно же было развернуть нормально метод без использования такого количества конструкций try/ catch. Одна лежит внутри lock, другая - внутри using.

Похоже на то, что автор перешел в c# из другого языка или самоучка, так как многие реализации сделаны простым понятным способом. Это хорошо для новичков, но когда дело доходит до сложных конструкций, такое не сработает
1) У меня в коде этого метода вообще нет блоков try{}catch{}, что как бы видно невооруженным глазом. Также, как нет блока catch в вашем коде. Собственно, на этом дискуссию можно было бы уже закончить - потому что вы пытались очернить чужой код в достаточно грубой форме и похвастаться своими навыками, но получилось ровно наоборот с первой же фразы.

Давайте я вам даже дам определения и ссылки на мсдн, чтобы вы все таки узнали разницу между using{} и try{}catch{} - это вам серьезно пригодится в программировании, все таки основы основ!

The try-catch statement consists of a try block followed by one or more catch clauses, which specify handlers for different exceptions.

Using statement provides a convenient syntax that ensures the correct use of IDisposable objects. Beginning in C# 8.0, the using statement ensures the correct use of IAsyncDisposable objects.

2) Стилистически предложенные вами правки, такие как отказ от using и lock, полностью противоречат гайдлайнам MS (может вы и с разработчиками языка хотите поспорить, показать какие они неучи, зато вы в белом?).

3) Практически же вы совершили грубую ошибку, не используя using в инициализации потока FileStream stream = new FileStream и при этом даже не сделав его Dispose().

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

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

А конкретно вам желаю снизить поток злости и желчи по отношение к другим людям и относиться ко всему с позитивом. Успехов в программировании!
 

-=Dzen=-

Client
Регистрация
22.05.2020
Сообщения
32
Благодарностей
15
Баллы
8
пфф... 2 или 3 года назад в чате зеннолаба в открытую выкладывали исходники из темы человеческого движения мыши.
и твою либу выложат. но сначала она разойдется по закрытым группам по интересам :bk:
интересно... были мысли что будет как то по другому ?
У меня были мысли, безусловно, что либой могут поделиться с друзьями в закрытом доступе, но что вот так сразу будут открывать складчину, пытаясь сэкономить пару сотен баксов, при этом лишаясь поддержки и консультаций разработчика, не предполагал. Привык к совершенно другому коммьюнити. Ну что же, если здесь это норма - пусть будет так, просто немного удивлен.
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)