2015年12月28日 星期一

遊戲腳本撰寫紀錄

由於有網友對於遊戲的腳本製作過程有興趣

這篇也算是紀錄一下我寫手機遊戲腳本的心得

太細節的部份就不說明了

要擁有的知識可能有點雜


國際版ROB經歷了四五年總算要關閉服務了

 Rage of bahamut(rob)是一款卡牌遊戲

起源於日本的web卡牌遊戲(開發廠商為cygames)

移植到android與ios而讓卡牌遊戲成為眾多手機app廠商開發的仿效模式

遊戲本質上其實還是web

而mobage(rob代理商)有自己的登入器接口

也就是遊戲開啟後先做login的動作 輸入帳號密碼後

登入系統會配發cookie並redirrect到遊戲的web server

起先我使用bluestacks安卓模擬器來做登入動作

後來由於效能問題又改用了virtualbox直接安裝android os進去來執行

我們要自動化的第一步自然是透過程式讓app自動啟動

如何使用電腦來控制android模擬器 基本上都是使用adb這個程式來控制

adb devices #查詢電腦有無裝置連接
adb connect 192.168.56.1 #連接上位置於192.168.56.1的裝置
"""最常用的基本上就這兩個
只要連接上後續控制就是靠自動化了"""

google本身有提供一套自動化測試工具叫monkeyrunner 個人使用後感覺效能頗差

且在比對圖片時常常會掛掉

後來改用了androidviewclient這一套純python的自動化工具


#自動化連接上裝置範例

from com.dtmilano.android.adb.adbclient import AdbClient
if len(sys.argv) >= 2:
    serialno = sys.argv[1]

else:
    serialno = '.*'
print 'serialno= '+str(serialno)

device1 = AdbClient(serialno=serialno)
print 'connected'

#如果使用python script.py 192.168.56.1 這個script就會去操作192.168.56.1


連接上我們要做的事情自然就是開啟遊戲的app

事實上透過adb shell其實就能夠簡單達到了


#開啟app
adb shell am start -a android.intent.action.MAIN -n com.mobage.ww.a692.Bahamut_Android/.SplashActivity
#關閉app
adb shell pm clear com.mobage.ww.a692.Bahamut_Android
"""啟動的程式名稱可能要先開eclipse觀察logcat看app的啟動流程來知道啟動時的package name
這是adb shell的使用方法,我們寫進腳本內去開啟的方式也差不多,pm clear的話同時能有清除使用者資料的功能"""

遊戲啟動後我們就開始做登入動作

#這邊我設置了一個開頭名稱為test100登入帳號,擷取封包cookie資訊登入後執行script
import time
from PIL import Image,ImageStat
from lib.sniff import sniff_rob #自己寫的擷取封包extract出cookie的module

user_name = "test"
user_num = 100
password = 12345678
delay = 1 #登入帳號之間的間隔秒數
run_script = "script" #登入後帳號所要執行的script


device1.shell("pm clear com.mobage.ww.a692.Bahamut_Android") #androidviewclient下shell的方法
time.sleep(1);
print 'Login: '+user_name+str(user_num)
print 'Password: '+ str(password)
print user_name+str(user_num)+': Run Rage of Bahamut...'
device1.shell("am start -a android.intent.action.MAIN -n com.mobage.ww.a692.Bahamut_Android/.SplashActivity")
time.sleep(5) #我是直接用等待五秒的方式等程式開啟,嚴謹點自然可以找android看有無check程式是否執行中的方法

#開啟app後要比對圖片來確認有無正常開啟app並且比對成功後開始執行登入
i=1
    while i<=8:
    picstart = Image.open("./pic/picstart.png") #用PIL開啟一個圖片
    time.sleep(1);
    picstart2=device1.takeSnapshot(reconnect=True) #利用androidviewclient takeSnapshot method擷取安卓的當前畫面
    picstart2=picstart2.transform((20,20),Image.EXTENT, (120,160,140,180)) #將當前畫面擷取出想要的部分
    print user_name+str(user_num)+': Loading'
    if device1.sameAs(picstart, picstart2, 1)== 1: #比對成功進行以下動作
        i=10 #比對成功後跳出while,由於i==9有其他動作所以用此方式跳出
        print user_name+str(user_num)+': Start to login'
        device1.touch(120,160, 'DOWN_AND_UP') #androidviewclient 模擬點取螢幕120,160的位置
        time.sleep(0.2);
        device1.touch(120,160, 'DOWN_AND_UP')
        time.sleep(0.5);
        device1.shell("input keyevent 61")#下達鍵盤TAB鍵的意思
        time.sleep(1);
        device1.type(user_name + str(user_num)) #輸入帳號
        time.sleep(1);
        device1.shell("input keyevent 61")#TAB換欄位
        device1.type(str(password)) #輸入密碼
        time.sleep(1);
        device1.shell("input keyevent 66")# 點選登入
        user=user_name+str(user_num)
        if sniff_rob(user,'01'): break #擷取出cookie
            filec = open('./cookie/'+user+'.txt','r')
            cookie = filec.read()
            if cookie == '':
                user_num = user_num -1
                break
                #將此帳號執行run_script,由於我使用windows7來跑所以有些導入程式的參數部分看起來比較複雜,也不是什麼重要的地方
                command_lines = 'python ./lib/'+run_script+'.py --'+user 
                print user+' start popen'
                args = shlex.split(command_lines)
                p = Popen(args)

    else: #比對失敗後等兩秒再比對圖片
        i=i+1
        time.sleep(2)



run_script的部分由於還蠻多種script的

都是定義遊戲中腳色要怎麼動作

包含加好友領獎勵過任務之類的

由於都是url.get url.post之類的東西也沒什麼好說明的

而擷取封包是使用scapy有興趣找相關documentation即可

這個程式其實是登入100-999個帳號

我精簡了一些不然有點太囉嗦