PS4 DQ11S automation with chiaki and uiautomator2

週末宅在家不能出門不知道要幹嘛,只好把一陣子沒碰的 勇者鬥惡龍 11S 拿出來繼續冒險吧!

防疫期間就是要來玩遊戲啊,不然要做什麼?

但玩一玩竟然也跑去寫自動化賭場以及打怪程式了...不用買特殊搖桿的喔!!

才不會有這種賭場呢

終於到了有賭場的城鎮了,為了任務需要得進去玩一下才行,逛了一輪之後發現我只會玩最簡單的拉啊,就是吃角子老虎那種。
但是在兌換任務需要獎品的時候,發現這邊也有高級武器跟防具可以換,像是 白金大劍 需要十萬代幣,沒記錯的話一枚代幣要 20 塊,而且代幣也不能換回一般的錢幣。
不過後來發現即使不用策略,最簡單的拉霸機的期望值也是大於一的,只需要時間一直按按按就可以,難怪網路上有人說用連發搖桿放著一直掛就好,大概一個小時就幾萬代幣了。

PS4 搖桿 Dual Shock 4 的 HID

不過我沒有連發搖桿啊,能不能自己做一個呢?

但是我有 esp32 可以變成 bluetooth gamepad,很快試了一下發現模擬成一般的藍芽搖桿的話,PS4 會說不支援這種類型。

題外話就是 esp32 關於藍芽裝置的 github code 都還不錯,但看下去發現其實沒有規劃好,要改寫擴充實在有點麻煩。

另外也有找到人家查到的 Dual Shock 4 的 HIDReportDescriptor
可能需要花點時間改一下才可以讓 PS4 接上自製的 esp32 gamepad。

其實有 PS Remote Play

就只是想要一直按按鈕而已,有沒有簡單一點的方法呢?上網查了一下發現 PS 的 App 有所謂的遠端遊玩的功能,既然可以遠端玩遊戲那就一定可以透過網路傳搖桿的訊號進去,好像值得研究一下。
不過用官方的 App 好像都失敗,而也 Sony 很多的 App 也不知道現在到底應該選那一個,這時候發現一個 open source 的實做,叫做 Chiaki 千秋,原始碼在這裡,是可以直接 Play Store 安裝的,不過也有放在 F-Droid 上推薦用這邊的。

如果 PS4 的版本 > 7.0 的話,遠端遊玩的登錄需要知道玩家的 PSN AccountID,Chiaki 也有題供計算 AccountID 的 script 可以使用,看起來為此他們還申請了一個開發 licence 樣子?

這樣就可以順利連結上可以遠端控制了。

嘗試過用 Android-Emulator 去跑,是可以連上的但是解畫面回來實在太慢,不太能用的程度。

Chiaki 畫面與 uiaumator2

既然可以遠端拿著手機玩了,那麼就可以利用之前提過的 uiautomator2 來寫自動掛機拉霸的程式了。
看了一下 chiaki 的 UI 架構,發覺控制的界面命名也是很清楚,以 PS 搖桿的商標為例就是取名為底下這樣

  • crossButtonView
  • moonButtonView
  • pyramidButtonView
  • boxButtonView

所以可以很容易地自己寫連按這個 圈圈 的功能

import uiautomator2
import time

def main_casino():
    d = uiautomator2.connect()
    while True:
        if d(text='RECONNECT').exists():
            d(text='RECONNECT').click()
            time.sleep(5)
        d(resourceID='com.metallic.chiaki:id/moonButtonView')
        time.sleep(0.564)

這樣到賭場選擇好機台後,就執行這串就可以一直幫忙按了,而的確放一個晚上就到達想買什麼就可以買什麼的程度。另外說白金大劍代幣十萬元,是可以到一般商店賣掉換錢的,可以換回 3500,算了一下這時間不如去打怪還賺得比較喔。

那麼為了連線穩定,有將 chiaki 調整成低 fps 以及 320p,反正是拿來自動跑的沒有想要畫面那麼漂亮。

掛著打怪物也是可以的

賭場這種是最簡單的例子,因為不需要移動搖桿,不過透過上面的機制要寫出需要移動的流程也是可以的,像是可以在原野上自動移動吸引怪物來打。

但可以會不小心按到跟同伴講話,反而沒有效率

那麼就把場景換到海上吧,就可以一直移動不怕轉到身邊的同伴而落入對話的陷阱了!
不過還是有個小問題,DS11S 的船呢在邊界一直走的話會繞一圈,理論上可以找到一條直線一直走下去,但實際上怎麼調整好像最後都會走偏掉,可能會遇到角落卡住走步出來。

原來網路上人家都想好了,可以壓住左右搖桿,讓船原地自轉就可以了。

import time
import random
import uiautomator2

def main_ocean():
    d = uiautomator2.connect()

    def _check_reconnect():
        if d(text='RECONNECT').exists():
            d(text='RECONNECT').click()
            time.sleep(5)

    d(resourceId='com.metallic.chiaki:id/moonButtonView').click()
    d.touch.down(200, 900)
    d.touch.move(500, 900)
    d.touch.down(1200, 900)
    d.touch.move(1500, 900)
    while True:
        _check_reconnect()
        d(resourceId='com.metallic.chiaki:id/moonButtonView').click()
        time.sleep(0.345)

搞不好還可以這樣

這次雖然是很快地利用原本就會的方法來自動化掛機,但還是有一些缺點,像是需要解開遊戲畫面其實有點耗資源,啊又沒有利用到畫面的資訊。

按了一下 chiaki 的 source code 覺得寫得很好也非常有趣,雖然沒有一個 cli 的最簡連線流程,也沒有看到相關的 document,但是覺得有時間可以好好研究一下,應該可以做出 command line 版本的,甚至可以看到某些特徵畫面再做判斷的事。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *