В продолжении топика "Игры в соц.сетях на примере 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
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 = RemotingService( urlpath )
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...'
remoting.CONTENT_TYPE = 'application/x-amf; charset=utf-8'
gw = RemotingService( urlpath )
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 fncThread( num ):
global money
while working:
res = None
index = str( num ) + str( int( time.time( ) * 1000000 ) )
gw = RemotingService( urlpath )
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 += int( res )
time.sleep( 0.01 )
for i in range( 100 ):
money = 0
def fncThread( num ):
global money
while working:
res = None
index = str( num ) + str( int( time.time( ) * 1000000 ) )
gw = RemotingService( urlpath )
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 += int( res )
time.sleep( 0.01 )
for i in range( 100 ):
fnc = threading.Thread( target = fncThread, args = ( i, ) )
fnc.setDaemon( True )
fnc.start( )
fnc.setDaemon( True )
fnc.start( )
try:
while True:
time.sleep( 1 )
except:
time.sleep( 1 )
except:
working = False
Рабочий вариант скрипта, который работает в режиме онлайн на проекте kodingen и расположен здесь, но с один ограничением - добыча монет ограничена количеством (около 5 000 coins).
П.С.: подобным образом осуществляется сбор звездочек - points, для повышения уровня, через сервис CustomersContoller.gift_at_friend, у несуществующих соседей. В следующий раз постараюсь выложить исходники по созданию автоматических продаж с Робертом и Робертой, а также комплексный сбор монет и звездочек с полей соседей.
спасибо за статью, хоть немного стало понятнее. но все равно без опыта флекс-разработки я до конца не могу разобраться с отправкой/приемом запросов через pyamf. захотелось мне в целях обучения попробовать сделать карту одной онлайн игры, через charles перехватил запросы/ответы, но как их реализовать так и не понял. Официальные доки очень скудные, а инфы в нете толковой почти нет.
ОтветитьУдалитьВот пример запроса
http://www.pix.am/H0y8/
и ответа
http://www.pix.am/AjTT/
буду очень благодарен если ктото поможет разобраться, или напишет подробную статью о pyamf client
Ничего сложно в этом нет. Любые запросы/ответы это объекты. У каждого объекта есть набор каких-то свойств. Для передачи объектов между клиентом и сервером их необходимо сериализовать через библиотеку pyAmf. Самый примитив как раз и описан у меня в примере к игре Monster World. В документации вроде все принципы основные описаны, если что-то не понятно давай попробуем разобраться вместе. Буду ждать более конкретных вопросов.
Удалитьнемного разобрался: варианта отправки/приема насколько я понял всего 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]
Удалитьто тип будет пустой:(
Хм, через "ручное" я также не смог организовать подстановку наименования объекта, поэтому использовал классы.
УдалитьЭтот комментарий был удален автором.
Удалитьнаконец появилось время снова попробовать решить свою задачу. удалось через ручное создание сформировать и отправить запрос и получить правильный ответ. но pyamf отказывается его декодировать:
Удалить"pyamf.DecodeError: Malformed stream (amfVersion=8075)"
гугл не помог решить проблему. в том что ответ получаю верный убедился в Charles. Буду рад любой помощи