<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Записки &#187; боты</title>
	<atom:link href="http://blog.nsws.ru/tag/boty/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.nsws.ru</link>
	<description>Мысли о разработке</description>
	<lastBuildDate>Fri, 26 Aug 2011 07:55:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Написание ботов для веб-игр с помощью библиотеки QT</title>
		<link>http://blog.nsws.ru/napisanie-botov-dlya-veb-igr-s-pomoshhyu-biblioteki-qt.html</link>
		<comments>http://blog.nsws.ru/napisanie-botov-dlya-veb-igr-s-pomoshhyu-biblioteki-qt.html#comments</comments>
		<pubDate>Tue, 02 Mar 2010 10:35:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[QT]]></category>
		<category><![CDATA[Новости]]></category>
		<category><![CDATA[боты]]></category>
		<category><![CDATA[онлайн игры]]></category>

		<guid isPermaLink="false">http://blog.nsws.ru/?p=169</guid>
		<description><![CDATA[Как известно QT - это кросс-платформенная библиотека, позволяющая достаточно быстро создавать приложения. С появлением в ней встроенного веб-браузера webkit, ее стало возможно использовать для написания ботов для веб-игр, чем я и решил заняться несколько дней назад.]]></description>
			<content:encoded><![CDATA[<p>Как известно QT &#8211; это кросс-платформенная библиотека, позволяющая достаточно быстро создавать приложения. С появлением в ней встроенного веб-браузера webkit, ее стало возможно использовать для написания ботов для веб-игр, чем я и решил заняться несколько дней назад.<span id="more-169"></span>Сразу надо сказать что использование webkit подходит не для всех игр, а только для игр не проверяющих использование браузера IE.</p>
<p>Для создания бота через webkit можно пойти двумя путями:</p>
<ol>
<li>Использовать QTestLib и имитировать действия пользователя.</li>
<li>Использовать QWebFrame-&gt;evaluateJavaScript</li>
</ol>
<h2>Использование QTestLib</h2>
<p>При использовании QTestLib мы создаем собственную очередь сообщений, которые передаем указанному виджету (в данном случае виджету QWebView). Очередь сообщений может содержать события нажатий кнопок, движения мыши, клики мышкой (как одинарные так и двойные). Использование этой библиотеки позволяет, в теории, создать бота для любой игры, даже игры, написанной на flash, однако ее использование достаточно трудоемко.</p>
<h2>Использование QWebFrame-&gt;evaluateJavaScript</h2>
<p>Данный метод заключается в использовании вставок JavaScript, которые будут исполняться в контексте текущего фрейма. Таким образом можно написать бота только для игры, полностью построенной на html.</p>
<h2>Построения бот-программы</h2>
<p>Основной задачей бот-программы, кроме того, что она должна ботить, является скрытность, программа не должна выдавать себя. В идеале она должна вести себя точно также как и обычный игрок.</p>
<p>Я писал бота для иры <a href="http://r.carnage.ru/?1006069559">Carnage</a>. Боту был выбран следующий алгоритм работы:</p>
<ol>
<li>Зайти в игру.</li>
<li>Дождаться восстановления хитов</li>
<li>Создать заявку на хаотичный бой</li>
<li>Провести бой</li>
<li>Перейти к пункту 2</li>
</ol>
<p>Заход в игру делается с нажатия кнопки Login в интерфейсе программы самим пользователем. При нажатии кнопки Login необходимо запустить примерно такой скрипт:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">document.<span style="color: #660066;">login</span>.<span style="color: #660066;">value</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'You name'</span><span style="color: #339933;">;</span> 
document.<span style="color: #660066;">password</span>.<span style="color: #660066;">value</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'You password'</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">form</span>.<span style="color: #660066;">auth</span><span style="color: #339933;">-</span>form.<span style="color: #660066;">submit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Для выполнения этого скрипта необходимо получить QWebFrame на указанную страницу:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">QWebFrame <span style="color: #339933;">*</span>frame <span style="color: #339933;">=</span> webView<span style="color: #339933;">-&gt;</span>page<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>frameAt<span style="color: #009900;">&#40;</span>QPoint<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">100</span><span style="color: #339933;">,</span><span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Конкретно в данном случае получение фрейма по конкретным координатам не критично, но в дальнейшем это очень пригодится. Дело в том, что в игре Carnage используется несколько разных фреймов, поэтому нам необходимо получать именно требуемый фрейм, а точка 100,100 в моем случае находится именно в нем.</p>
<p>И выполнить JavaScript:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"> frame<span style="color: #339933;">-&gt;</span>evaluateJavaScript<span style="color: #009900;">&#40;</span>script<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>После логина начинается самое интересное. Для каждой страницы необходим свой скрипт, а на некоторые страницы (например на страницу подачи заявки) надо даже несколько скриптов которые будут вызваны с некоторым интервалом. Это необходимо, потому что  в игре активно используется innerHTML и редирект фрейма на туже самую страницу но с другими параметрами. Чтобы не усложнять себе жизнь и не анализировать содержимое страницы проще сделать задержки.</p>
<p>Скрипты, по вполне понятным причинам, следует выполнять только после того, как страница полностью загрузится. Для этого можно использовать слот: void loadFinished ( bool ok );</p>
<p>Внутри этого слота я проверяю на какой странице сейчас находится требуемый фрейм:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">QWebFrame <span style="color: #339933;">*</span>frame<span style="color: #339933;">=</span> webView<span style="color: #339933;">-&gt;</span>page<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>frameAt<span style="color: #009900;">&#40;</span>QPoint<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">100</span><span style="color: #339933;">,</span><span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
QString path <span style="color: #339933;">=</span> frame<span style="color: #339933;">-&gt;</span>url<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>path<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>path<span style="color: #339933;">==</span><span style="color: #ff0000;">&quot;/zayavka.pl&quot;</span><span style="color: #009900;">&#41;</span>...</pre></div></div>

<p>Получив требуемый адрес мы запускаем таймер на некоторую функцию, которая произведет обработку страницы с помощью JavaScript. Почему именно таймер? Просто из слота необходимо выйти как можно быстрее, а использовать потоки не очень хорошо, потому что у QT имеются на этот счет некоторые нехорошие мысли, когда я попытался использовать потоки то это часто приводило к падению приложения. Используя таймеры мы убиваем сразу двух зайцев &#8211; мы решаем проблему быстрого возврата из слота и мы решаем проблему задержек при заполнении данных на страницах. Мы не можем использовать зацикленный JavaScript код, потомучто это приводит к тому, что основной JavaScript код страницы перестает выполняться. И мы не можем сделать sleep в основном потоке, потому что  тогда опять таки перестанет выполняться JavaScript на странице.</p>
<h3>Возврат значений из JavaScript</h3>
<p>Временами возникает необходимость получать некоторые значения от JavaScript кода. Сделать это можно через возвращаемое значение функции evaluateJavaScript. Данная функция  возвращает QVariant содержащий результат вывода вашего скрипта. И например вот такой вот скрип, запущенный в Carnage, вернем вам количество ваших хитов:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">top.<span style="color: #660066;">currHP</span><span style="color: #339933;">;</span></pre></div></div>

<p>Собственно это все что необходимо чтобы написать бота для игры Carnage, Torment и еще десятка клонов этих игр.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nsws.ru/napisanie-botov-dlya-veb-igr-s-pomoshhyu-biblioteki-qt.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

