Сегодня я хочу рассказать вам про сервис, который обнаружил буквально недавно — Dripstat. Он позволяет установить на локальную JVM специальный java-агент который собирает статистику работы сервера приложений и отправляет на сайт, где с ней можно детальнее ознакомиться.
— Ну какие сервисы мониторинга? Сегодня суббота! — скажете вы, и будете правы. Более того, я даже поддержу эту мысль и в данной заметке расскажу как раз об обратной, развлекательной, стороне медали, и чуть-чуть о программировании на JS.
Итак, приглашаю дочитать тех кто заинтересовался.
Сразу же идем по ссылке на страничку игры — dripstat.com/game/. Над интерфейсом разработчики не заморачивались, но это и к лучшему — все интуитивно понятно и разобраться можно за 5 минут.
Потратив немного времени на кликанье чашки и сбрасываение накликаного в «кошелек» (capacity) и по ходу дела осмотревшись в интерфейсе стает ясна основная цель игры — «накапать» (drip) побольше памяти. Справа видно оранжевый progress-bar, который показывает текущую цель, но не стоит пугаться столь большому числу, над его достижением работают все участники (ниже видно небольшой рейтинг и диаграмму активности), а не один игрок.
Но капать по 1 байту не интересно. Что же у нас есть для того что бы прокачаться? По мере завершения обучения стают доступными средства которые позволяют как генерировать память вместо вас так и улучшать показатели ручной генерации.
Я не буду дублировать информацию и перечислять их все — лучше увидеть самим (все они перечислены в правой панели, первая строка — доступные улучшения, а последующие строки — перечень самих генераторов памяти).
Ну вот собственно и все что касается самой игрушки.
Но на этом я не остановился, ведь инстинкт программиста заиграл внутри и потребовал проболжения банкета. Поэтому я решил все таки попробовать ломануть автоматизировать процесс.
1. Поверхностный анализ протокола обмена сообщениями между сервером и клиентом показал что подмену сообщений произвести не получится — сервер имеет внутренние механизмы верификации. Ковыряться детальнее желания не было, поэтому я пошел другим путем — со стороны клиента.
2. Можно конечно обойтись автокликером, но это не так интересно да и браузер должен быть постоянно в фокусе, плюс кроме чашки кофе кликать нужно и по другим элементам страницы. Первое что пришло в голову как дешевое и эффективное решение — userscript (ну и firebug естественно, ведь без него в разы сложнее смотреть на внутренности странички). Рассказывать про то как установить необходимый плагин и запустить сам скрипт я не буду, этой информации полно на просторах интернета да и на хабре тоже. Но самим скриптом, конечно же поделюсь.
Основная идея была в следующем:
0) Кликаем-кликаем-кликаем!
1) Пробуем закупать апгрейды, ибо они дают целых 10% мощности для генератора.
2) Далее ищем самый дорогой генератор и покупаем его. Сначала порядок был обратный и постоянные закупки курсора очень вяло влияли на прогресс, поэтому порядок был изменен.
3) Если накликали 90% памяти, то сбрасываем ее расширяя capacity. Этот пункт выполняется в случае когда все что можно было купить уже куплено и для дальнейших закупок нужен кошелек побольше. К примеру и генераторы и апгрейды уже по цене превзошли capacity и единственное что остается — Drip Memory.
Реализация:
// ==UserScript== // @name dripstat_clicker // @namespace x_lab.ice // @include https://dripstat.com/game/ // @version 1 // @grant GM_openInTab // ==/UserScript== unsafeWindow.document.hasFocus = function () {return true;}; // в игрушке есть проверка на наличие фокуса у документа, // и как только фокус теряется мы уже не можем жать на чашку, соответственно требуется грязный хак (function (window, undefined) { if (window.top != window.self) { return; } // избегаем запусков нашего скрипта в iframe window.addEventListener("load", LocalMain, false); // как только страница прогрузилась запускам нашего бота function LocalMain() { setInterval(function() { Shopping(); }, 10000); // покупаем улучшения и генераторы 1 раз в 10 сек setInterval(function() { Clicker(); }, 10); // а кликаем по чашке 100 раз в сек // (ну или пытаемся, ведь поток JS занят и другими делами, поэтому непрерывной генерации не получим) } function Clicker() { $('#btn-addMem').click(); // собственно жмем на чашку if(localStats.byteCount > localStats.memoryCapacity * 0.9) { // если накликали уже около 90% а потратить некуда $('#btn-addGlobalMem').click(); // то увеличиваем capacity } } function Shopping() { // идем за покупками var evt = document.createEvent("MouseEvents"); // готовим фиктивную мышку evt.initEvent("click", true, true); var upgrades = document.querySelector('#upgrades'); // сначала глянем что можно проапгрейдить var upgChildren = upgrades.childNodes; for(var j=0; j < upgChildren.length; j++) { // проходимся по витрине начиная с самого дешевого var upgChild = upgChildren[j]; if(upgChild.className == 'upgcontainer') { // как раз по имени класса можно определить отключен ли элемент upgChild.dispatchEvent(evt); // и если он включен - покупаем } } var store = document.querySelector('#powerupstore'); // далее идем к генераторам памяти var children = store.childNodes; for(var i=(children.length-1); i >= 0; i--) { // но смотрим самое дорогое var child = children[i]; if(child.className == 'storeItem') { // нашли! child.dispatchEvent(evt); // покупаем! } } } })(window); // вот так и живем :)
На данный момент (чистого времени работы кликера прошло не так и много), мой результат такой
Алгоритм не идеален но это и не было целью. Главное удовольствие, да и мозги размял.
Айда устроим турнир между AI!
P.S. Скажи печенкам — Нет! (если кто не знал — orteil.dashnet.org/cookieclicker/)
ссылка на оригинал статьи http://habrahabr.ru/post/217507/
Добавить комментарий