アサルトリリィ ラストバレットのレギオンマッチのバトルログをテキストに出力させてみた。

# 事の経緯

![スクリーンショット 2022-12-14 110616.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624329/15526bc4-2cbf-3953-c33d-8159aced9237.png)

アサルトリリィ ラストバレット(以下ラスバレ)というゲームには、レギオンマッチというコンテンツがあり、
9名でチーム(レギオン)を組み、チーム同士で対戦する、リアルタイムで最大18人同時参加で戦いが繰り広げられます。
私が参加しているレギオンは比較的ゆるガチのレギオンで（周3回レギオンマッチに参加してね、でもプライベート優先）、
月一ペースで行われるレギオンリーグ（レギオンバトルでランキングが決定するイベント）でも、そこそこ好成績を出しています。

この中での取り組みとして、バトル終了後にバトルログを見て反省・改善を行う、と言うのをやっています。
![Assaultlily 2022_12_14 11_14_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624329/62e554ae-1fee-dc0c-8d5f-b68f60d058e1.png)

ただ、このバトルログ、かなり詳細な情報を見ることができるのですが、アプリ上だけでしか見られないので、これをテキストファイルに落とせば、エクセルなどにインポートして解析がしやすくなるのでは？と思ったのです。

# 手段
ラスバレの画面のスクリーンショットを撮り、それをOCRに流し込んで、テキストを取得する、と言う方法を採りました。

# 環境
* Windows 11 (Pro)
* Python 3.10.4 

# 環境構築
## pyautogui
Windows上でマウス操作をコントロールするやーつ
```
pip3 install pyautogui
```

## Pillow
pyautoguiでスクリーンショットを撮るときに必要なやーつ
```
pip3 install Pillow
```

## pywin32
Windows上のWindow関連操作ができるようになるやーつ
```
pip3 install pywin32
```

## pyocr
PythonでOCRを利用できるようにするやーつ
```
pip3 install pyocr
```

## Tesseract
OCRで画像を解析する外部プログラム。
Pythonのモジュールとは別に、GitHubのサイトからインストーラーをダウンロードし、インストールする必要があります。
https://github.com/UB-Mannheim/tesseract/wiki/
**インストール中に言語を選択する画面があるので、日本語のチェックし忘れに注意。**

# 実装
```Python
import os
import sys
import time
import win32gui
import win32con
import win32api
import pyautogui
from PIL import Image
import pyocr

margin_top = 250
margin_left = 490
margin_bottom = 190
margin_right = 90

def set_window_top(hwnd):
    win32gui.SetWindowPos(hwnd,win32con.HWND_TOPMOST,0,0,0,0,win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)

def unset_window_top(hwnd):
    win32gui.SetWindowPos(hwnd,win32con.HWND_NOTOPMOST,0,0,0,0,win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)

def get_screenshot(x, y, width, height):
    return pyautogui.screenshot(region=(x, y, width, height))

hwnd = win32gui.FindWindow(None, 'Assaultlily')

#アサルトりりィのウインドウを前面に固定
set_window_top(hwnd)

left, top, right, bottom = win32gui.GetWindowRect(hwnd)

mouse_x_pos = right - 60
mouse_y_pos = top + 300
pyautogui.moveTo(mouse_x_pos, mouse_y_pos)
pyautogui.click()

clip_x = left + margin_left
clip_y = top + margin_top
clip_width = right - left - margin_left - margin_right
clip_height = bottom - top - margin_top - margin_bottom

tesseract_path = "C:\Program Files\Tesseract-OCR"
if tesseract_path not in os.environ["PATH"].split(os.pathsep):
    os.environ["PATH"] += os.pathsep + tesseract_path

tools = pyocr.get_available_tools() 
if len(tools) == 0:
    print("OCRエンジンが指定されていません")
    sys.exit(1)
else:
    tool = tools[0]

    builder = pyocr.builders.TextBuilder(tesseract_layout=6)

    f = open('output.txt', 'w', encoding='UTF-8')

    image = get_screenshot(clip_x, clip_y, clip_width, clip_height)
    result = tool.image_to_string(image, lang="jpn", builder=builder)
    f.write(result)

    for t in range(4500):
        pyautogui.moveTo(mouse_x_pos, mouse_y_pos)
        pyautogui.dragRel(0, -190, 0.2)
        time.sleep(0.5)
        image = get_screenshot(clip_x, clip_y, clip_width, clip_height)
        result = tool.image_to_string(image, lang="jpn", builder=builder)
        f.write(result)

    f.close()

#アサルトりりィのウインドウ固定を解除
unset_window_top(hwnd)
```

## やっていること
1. ラスバレのWindowハンドル番号を取得する。
2. ラスバレをデスクトップ前面に固定する。
3. ラスバレのWindow情報を取得する(マウスの座標指定に使用する)。
4. ラスバレをアクティブ状態にする
5. 環境変数のPATHにTesseractを追加する
6. OCRエンジンを取得する
7. 以下の操作をループで処理する。(ループの回数は適当)
　7.1. 画面のスクリーンショットを撮る。
　7.2. 画像をOCRに渡し、テキストを取得する。
　7.3. テキストをファイルに保存する。
　7.4. マウスのドラッグ操作をし、ログを上にスクロールする。
8. ラスバレをデスクトップ前面固定を解除する。

# やってみて解ったこと

ラスバレのバトルログは膨大な量があるので、
**バトルログを全て取得するのに1時間かかりました。**
その間、Windowsマシンは一切操作できません。
他にもログを取得するプログラムはあったのですが、
かなり昔からメンテされていないし、これまでも、誰も使った形跡が無い。
その理由が分かった気がしました。
おそらく、このプログラムを作ったけど、今後使うことは無いでしょう。

しかしながら、Pythonで操作を自動化する方法とか、
OCRを使用する方法を理解できたのが良かったと思います。

# 参考にしたサイト
https://tech-blog.rakus.co.jp/entry/20220613/python#:~:text=pyautogui.size())-,%E3%83%9E%E3%82%A6%E3%82%B9%E3%82%AB%E3%83%BC%E3%82%BD%E3%83%AB%E3%81%AE%E7%A7%BB%E5%8B%95,%E3%82%AB%E3%83%BC%E3%82%BD%E3%83%AB%E3%81%8C%E7%A7%BB%E5%8B%95%E3%81%97%E3%81%BE%E3%81%99%E3%80%82&text=%E5%BA%A7%E6%A8%99%E3%81%AE%E3%81%BF%E3%82%92%E4%B8%8E%E3%81%88%E3%81%9F,%E6%99%82%E9%96%93%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%BE%E3%81%97%E3%82%87%E3%81%86%E3%80%82

https://miyashinblog.com/pyautogui/#toc9

https://hajimete-program.com/blog/2017/10/12/python3-6%E3%81%A7%E3%83%A1%E3%83%A2%E5%B8%B3%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%80%81%E7%A7%BB%E5%8B%95%E3%81%A8%E3%83%AA%E3%82%B5%E3%82%A4%E3%82%BA%E3%82%92%E3%81%99%E3%82%8B%E3%82%B5%E3%83%B3/

https://takaaki-hobby-blog.com/python/python_ocr/#install_pyocr

https://qiita.com/ku_a_i/items/93fdbd75edacb34ec610