суббота, 15 октября 2011 г.

Monster World. Я миллионер.

В продолжении топика "Игры в соц.сетях на примере Wooga Monster World", решил выложить наброски скриптов, использующие слабые места игры. 
Как говорилось выше, обмен данными идет по протоколу amf3. У нас клиент будет написан на python. Поэтому первым делом понадобится библиотека pyamf. По поводу установки и пользования на сайте есть примеры. 

Адрес для API игры: http://api.live.monsters.wooga.com/amf

Для работы с игрой необходимо знать свой Google Plus ID. Не буду описывать здесь как его получить, информация есть здесь. После необходимо создать новую сессию, вызвав сервис FbContoller.setup. А дальше имитируем сбор мешочка с монетами (50 coins) на огороде соседа через сервис UsersContoller.redeem_visit. В качестве замечания хочу отметить тот факт, что разработчики не проверяют существование указанного "соседа", поэтому можно передать любое значение. В примере я получаю текущий unixtimestamp и использую его в качестве идентификатора соседа.

Ниже приведен исходный код скрипта, позволяющий выполнять сбор монеток у несуществующих друзей в 100 одновременных потоков. Остановить выполнение выполняемой программы можно нажав ctrl+с.

#!/usr/bin/python
import sys
import time
import urllib
import datetime
import threading

from pyamf import amf3
from pyamf import remoting
from pyamf.remoting.client import RemotingService

user_id 'хххххххххххххххххххх'

urlpath 'http://api.live.monsters.wooga.com/amf'
remoting.CONTENT_TYPE 'application/x-amf; charset=utf-8'

gw RemotingServiceurlpath )
gw.amf_version 3
srv gw.getService'FbController.setup' )
try:
  res srv
    'fb_user_id'user_id
    'locale''en_US'
    'social_network''google'
    'signed_request''' 
  )
  sess_id res'sessionId' ]
except:
  print 'ERROR Google ID'
  exit)

print 'Please waiting...'
working = True
money 0
def fncThreadnum ):
  global money
  while working:
    res None
    index strnum strinttime.time1000000 )
    gw RemotingServiceurlpath )
    gw.amf_version 3
    srv gw.getService'UsersController.redeem_visit' )
    try:
      res srv'is_mission_relevant'False
      'fb_user_id'user_id'friend_id'index
      'session_id'sess_id )
    except:
      res '0'
    money += intres )
    time.sleep0.01 )

for in range
100 ):
  fnc threading.Threadtarget fncThreadargs i)
  fnc.setDaemonTrue )
  fnc.start)

try:
  while True:
    time.sleep)
except:
  working = False

Рабочий вариант скрипта, который работает в режиме онлайн на проекте kodingen и расположен здесь, но с один ограничением - добыча монет ограничена количеством (около 5 000 coins).

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

6 комментариев:

  1. спасибо за статью, хоть немного стало понятнее. но все равно без опыта флекс-разработки я до конца не могу разобраться с отправкой/приемом запросов через pyamf. захотелось мне в целях обучения попробовать сделать карту одной онлайн игры, через charles перехватил запросы/ответы, но как их реализовать так и не понял. Официальные доки очень скудные, а инфы в нете толковой почти нет.
    Вот пример запроса
    http://www.pix.am/H0y8/
    и ответа
    http://www.pix.am/AjTT/

    буду очень благодарен если ктото поможет разобраться, или напишет подробную статью о pyamf client

    ОтветитьУдалить
    Ответы
    1. Ничего сложно в этом нет. Любые запросы/ответы это объекты. У каждого объекта есть набор каких-то свойств. Для передачи объектов между клиентом и сервером их необходимо сериализовать через библиотеку pyAmf. Самый примитив как раз и описан у меня в примере к игре Monster World. В документации вроде все принципы основные описаны, если что-то не понятно давай попробуем разобраться вместе. Буду ждать более конкретных вопросов.

      Удалить
    2. немного разобрался: варианта отправки/приема насколько я понял всего 2 - либо через мапинг классов, либо через ручное формирования запроса(как тут http://blog.gdssecurity.com/labs/2009/11/11/pentesting-adobe-flex-applications-with-a-custom-amf-client.html). но теперь возник вопрос по ручному формированию запроса: как мне в body указать тип объекта(этот http://pix.am/PI7O/)? если сделать body=[{'name':'EMPIRE_POWER'},'',-1]
      то тип будет пустой:(

      Удалить
    3. Хм, через "ручное" я также не смог организовать подстановку наименования объекта, поэтому использовал классы.

      Удалить
    4. Этот комментарий был удален автором.

      Удалить
    5. наконец появилось время снова попробовать решить свою задачу. удалось через ручное создание сформировать и отправить запрос и получить правильный ответ. но pyamf отказывается его декодировать:
      "pyamf.DecodeError: Malformed stream (amfVersion=8075)"
      гугл не помог решить проблему. в том что ответ получаю верный убедился в Charles. Буду рад любой помощи

      Удалить