[Из песочницы] И снова Dripstat!

Этот пост навеян вот этим постом: тыц.Прочитал я его и подумал, неужели подобным образом автоматизируются браузерные процессы? Кликер — это как-то слишком прямолинейно, и не подобают труъ программерам подобные автоматизации)По моему это слишком, заставлять браузер обрабатывать клики по одному, когда у нас в руках полный исходный код приложения.imageИтак, начнем разбираться:

1. Поверхностный анализ протокола обмена сообщениями между сервером и клиентом показал что подмену сообщений произвести не получится — сервер имеет внутренние механизмы верификации.

Неужели? Смотрим внимательно в код и видим, действительно, объекты шифруются каким-то XORCipher…Но разве нам это нужно? Смотрим метод отправки события на сервер, — в него приходит объект события, — шифруется, — отправляется на сервер

Анализируем объект события до шифрования, это простой json:

{ userid: «userid», events: [ массив событий ] }

Сами события содержат информацию— о накопленном количестве памяти— о прошедшем времени (это вообще гениально)— о покупках

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

Итак, приступим собственно к написанию майнераПлан— Запуск, конфигурация— Периодичное сохранение. Здесь я предпочел «скользящий» режим setTimeout, потому как с setInterval неизбежен завал при лагах сети— Откат к последнему валидному состоянию в случае ошибки валидации (слишком жадные:))

Конструктор:

function Miner (incr, dripK, delay) { var that = this; this.incr = incr || localStats.bps*1e3; // сколько памяти добываем за одну итерацию this.dripK = dripK || 0.5; // коэффициент сливания памяти this.delay = delay || 100; // задержка между итерациями document.hasFocus = function () {return true;}; NO_PINGY=1; // На проекте включен сбор статистики движений мышем, отключаем

// Redefine postEvent RestEventManager.prototype.postEventData = function (e, t, next) // Тут добавили параметр next, для замыкания цикла { var r=XORCipher.encode (DataSaver.key, JSON.stringify (e)); // Вот оно, шифрование! // Собственно запрос: return $.ajax ({type: «POST», async:!0, url: GAME_URL+(loggedIn? «events»: «eventsanon»), data: r, contentType: «text/plain», success: function () { var self = this; that.lastCorrect = localStats.byteCount; // Сохраняемся t.apply (self, arguments); // Родной callback setTimeout (function (){ if (localStats.byteCount > localStats.memoryCapacity * that.dripK) $('#btn-addGlobalMem').trigger ('click'); // Сливаем память }, 0); if (typeof next == 'function')next (); }, error: function (e) { localStats.byteCount = that.lastCorrect; // Откат console.error (e.responseText); // show error text if (typeof next == 'function') next (); // собственно, следующая итерация }}) } } Далее, нам нужно построить событие:

Miner.prototype.postEvent = function (mem, time, next) { var d = { userid: networkUser.userId, events: [{ generatedMem: mem, power: null, timeElapsed: time, type: 1 }] } RestEventManager.prototype.postEventData (d, function (){}, next); }; Готово.

Обвязываем запуск/остановку:

Miner.prototype.start = function () { var that = this; this.stopped = false; this.lastCorrect = localStats.byteCount; // save before the action function post (){ localStats.byteCount+=that.incr; // mine some bytes that.postEvent (localStats.byteCount, 120000, function (){ // tell to server that 2minutes passed if (! that.stopped) that.sI = setTimeout (post, that.delay); // next iteration on response }) } if (this.sI) clearTimeout (this.sI); if (! this.stopped) this.sI = setTimeout (post, this.delay); // first call };

Miner.prototype.stop = function () { this.stopped = true; }; Запускаем!

var miner = new Miner (); miner.start ();

Тут стоит заметить, что валидация накопленных Вами байтиков зависит от Вашей «способности генерировать», т.е. количества приобретенных агрегатов. Поэтому на старте я приобретаю, по 1 штуке всех девайсов, и штук 50–60 кластеров, постепенно повышая/играясь со скоростью добычи…

Результат: за полчаса написания и 4–5 часов работы скрипта вывел в топ 1–2 два аккаунта arth/Arth:)

1f2e90a934274819967b371525a10a65.png

ЗЫ: Инвайт, конечно хотелось бы, но после семи постов в песочнице я уже практически смирился с read-only. :(

ЗЗЫ: При попытке сохранения этого поста, получаю ошибку

{«system_errors»:[«SQLSTATE[HY000]: General error: 1364 Field 'description' doesn’t have a default value»]} Неожиданно для хабра)

© Habrahabr.ru