MENU

BGAアグリコラをする際一人で盛り上がるツール作ってみた。ー農村の茶番ー

目次

農村の茶番とは

windowsで動くアプリです。このアプリを経由してbgaアグリコラを行うとアクションごとにやかましいボイスが流れ,友達の煽りやつまらないギャグを聞きながらゲームをするのに近い体験をすることができます。

アプリを起動するとchormeが立ち上がりbgaにつながります。あとはそのままアグリコラをすればokです。ドラフト後から音声がなり始めます。
※ドラフト中特に何もないのは使用です。(2024/4/27)

導入方法

以下からインストールします。windows専用になります。Macでは動作しません。

農村の茶番var0.0.3最新版 

https://drive.google.com/file/d/1A_gMXrSphiX3WYmoUQQKS81b-Q-tQ5QL/view?usp=drive_link

1リンク先から以下のような画面になります。赤矢印の先からダウンロードします。

2このままダウンロードをクリックします。

3zipファイルを解凍します。

4農村の茶番.exeと同じディレクトリ(農村の茶番.exeがあるフォルダ内)にある”ユーザー名.txt”,”パスワード.txt”というファイルにbgaのユーザー名とパスワードをそれぞれ記入して保存しておくとbga起動時に自動でログインをすることができます。
※これらのファイルにデータを入力しない場合,ログインは毎回手動で行う必要があります。

5農村の茶番.exeを起動します。初回起動時に以下の画面が出ます。詳細情報をクリックします。

6実行をクリックします。

7ショートカットを作成しデスクトップに置いておくなどすると便利です。
※農村の茶番.exeファイルをフォルダーから移動させるとユーザー名やパスワードを参照できなくなります。

遊び方

農村の茶番.exeを起動するとchormeでbgaに繋がります。

ログイン後アグリコラのゲームに参加,観戦するか,アグリコラのリプレイを見る際にやかましい音声が再生されます。音量には十分注意してください。

煽りセリフのリクエストなどありましたら教えていただけると実装するかもしれません。

ソースコード

音声の著作権の問題で以下のコードと音声ファイルやアイコン画像をpyinstallerでコンパイルしました。

import os
import sys
import pygame
import random
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.common.exceptions import StaleElementReferenceException
from selenium.common.exceptions import WebDriverException
import time

# pygame用の初期化
pygame.mixer.init()

# 音声再生パス指定関数
def resource_path(relative_path):
    """リソースファイルのパスを取得します。_MEIPASS変数が定義されている場合、そのパスを使用します。"""
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)

# ファイル内容を読み込む関数
def read_file_content(filename):
    """指定されたファイル名から内容を読み込んで返します。"""
    try:
        with open(filename, 'r', encoding='utf-8') as file:
            return file.read().strip()
    except FileNotFoundError:
        print(f"Error: {filename} not found.")
        return None

# ユーザーネームとパスワードのファイルから内容を読み込む
username = read_file_content('ユーザー名.txt')
password = read_file_content('パスワード.txt')

# 音声再生の関数
def play_sound_if_needed(current_content, previous_content, keywords, sound_files):
    """指定されたキーワードが現在のコンテンツに含まれていて、前のコンテンツと異なる場合に音声を再生します。"""
    if current_content != previous_content and any(keyword in current_content for keyword in keywords):
        try:
            chosen_sound_file = random.choice(sound_files)
            pygame.mixer.music.load(resource_path(chosen_sound_file))
            pygame.mixer.music.play()
            while pygame.mixer.music.get_busy():  # 再生が完了するまで待機
                time.sleep(1)
            return True
        except pygame.error:
            print(f"Failed to load {chosen_sound_file}, playing default sound.")
            pygame.mixer.music.load(resource_path('汎用.wav'))
            pygame.mixer.music.play()
            while pygame.mixer.music.get_busy():  # 再生が完了するまで待機
                time.sleep(1)
            return False
    return False

def is_browser_open(driver):
    """ブラウザのセッションがまだ有効かチェックします。"""
    try:
        # ドライバーがまだページを取得できるかどうかを確認する簡単なチェック
        driver.current_url
        return True
    except WebDriverException:
        return False

# Chrome オプションの設定
options = webdriver.ChromeOptions()
options.headless = False  # 音声再生が必要なので、ヘッドレスモードはオフ

# ChromeDriverManagerを使用してChromeDriverを設定
driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)

# 監視するページにアクセス
driver.get('https://boardgamearena.com/lobby')

# ログイン情報を入力してログイン処理を行う
if username and password:
    username_input = driver.find_element(By.CSS_SELECTOR, '#username_input')
    password_input = driver.find_element(By.CSS_SELECTOR, '#password_input')
    submit_button = driver.find_element(By.CSS_SELECTOR, '#submit_login_button')

    username_input.send_keys(username)  # ユーザー名を入力
    password_input.send_keys(password)  # パスワードを入力
    submit_button.click()  # ログインボタンをクリック
else:
    print("Username or password file is missing.")

previous_content = None  # 前回の特定の条件を満たす要素の内容を保存

try:
    while True:
        if not is_browser_open(driver):
            print("ブラウザが閉じられました。プログラムを終了します。")
            break

        try:
            log_elements = driver.find_elements(By.CSS_SELECTOR, '[id^="log_"]')
            found_element = None
            for element in log_elements:
                try:
                    text = element.text
                    if "に家族コマを置いた" in text or "アクションが使えるようになった" in text or "収穫の開始" in text:
                        found_element = element
                        break
                except StaleElementReferenceException:
                    continue  # エレメントが古くなっていればスキップ

            if found_element:
                current_content = found_element.text
                # 最初の文字が"は"であれば後続の処理をスキップ
                if current_content.startswith("は"):
                    continue  # 次のループへ移る
                # 踏んだ時の処理
                # ここに音声再生の処理を追加
                #踏んだ時の処理
            if play_sound_if_needed(current_content, previous_content, ["「窪地」","「粘土坑」"], ['泥踏み1.wav','泥踏み2.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「森林」","「小さな森」","「雑木林」"], ['木.wav','汎用.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「資材市場」"], ['石葦飯.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「葦原」"], ['葦原踏み1.wav','葦原踏み2.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「小劇場」","「漁」"], ['食料累積1.wav','食料累積2.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「農場拡充」"], ['増築増員だ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「集会所」"], ['集会所踏み1.wav','集会所踏み2.wav','集会所踏み3.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「小麦の種」"], ['小麦踏み.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「農地」"], ['畑踏み.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「農場拡充」"], ['増築増員だ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「授業」"], ['授業踏み1.wav','授業踏み2.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「日雇い労働者」"], ['日雇い踏み1.wav','日雇い踏み2.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「家畜市場」"], ['家畜市場踏み1.wav','家畜市場踏み2.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「羊市場」"], ['羊踏み.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「大きい進歩」"], ['大進歩.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「柵」"], ['柵.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「穀物活用」"], ['種パン.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「家の建て直し」"], ['改築大進歩.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「西の石切り場」"], ['石踏み1.wav','石踏み2.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「子供がほしい」"], ['子供踏み.wav','子供踏み2.wav','子供踏み3.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「猪市場」"], ['豚踏み.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「野菜の種」"], ['野菜踏み.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「東の石切り場」"], ['石踏み1.wav','石踏み2.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「牛市場」"], ['牛踏み.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「耕作」"], ['畑種.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「急いで子供がほしい」"], ['急いで子供がほしい.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["「農場の再開発」"], ['改築柵.wav']):
                previous_content = current_content
            #めくれた時の処理リプレイ
            elif play_sound_if_needed(current_content, previous_content, ["__羊市場__ "], ['羊めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__大進歩__ "], ['大進歩.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__柵__ "], ['柵.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__穀物活用__ "], ['種パン.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__家の建て直し__ "], ['改築大進歩.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__西の石切り場__ "], ['石めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__子供がほしい__ "], ['子供めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__猪市場__ "], ['豚めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__野菜の種__ "], ['野菜めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__東の石切り場__ "], ['石めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__牛市場__ "], ['牛めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__耕作__ "], ['畑種.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__急いで子供がほしい__ "], ['急いで子供がほしい.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["__農場の再開発__ "], ['改築柵.wav']):
                previous_content = current_content
            #めくれた時の処理リアルタイム
            elif play_sound_if_needed(current_content, previous_content, ["羊市場 is"], ['羊めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["大進歩 is"], ['大進歩.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["柵 is"], ['柵.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["穀物活用 is"], ['種パン.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["家の建て直し is"], ['改築大進歩.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["西の石切り場 is"], ['石めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["子供がほしい is"], ['子供めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["猪市場 is"], ['豚めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["野菜の種 is"], ['野菜めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["東の石切り場 is"], ['石めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["牛市場 is"], ['牛めくれ.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["耕作 is"], ['畑種.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["急いで子供がほしい is"], ['急いで子供がほしい.wav']):
                previous_content = current_content
            elif play_sound_if_needed(current_content, previous_content, ["農場の再開発 is"], ['改築柵.wav']):
                previous_content = current_content
            #収穫の開始
            elif play_sound_if_needed(current_content, previous_content, ["収穫の開始"], ['収穫の開始.wav']):
                previous_content = current_content

        except Exception as e:
            #print('ループ内エラー:', e)
            time.sleep(0)
        time.sleep(1)

except Exception as e:
    print('エラーが発生しました:', e)
    with open('エラー.txt', 'w', encoding='utf-8') as error_file:
        error_file.write(str(e))

finally:
    driver.quit()
    print("プログラムを終了します。")

※デバック用のコメントアウトは一部削除しています。


いじればオリジナルも作れるので試してみてください。

より古いバージョンをお求めの方は↓

あわせて読みたい
農村の茶番ダウンロード 【ダウンロード】 var0.0.3・ゲームプレイ時アクションカードが捲れた時の音声がならない問題を修正しました。 var0.0.3ダウンロード↓ https://drive.google.com/file/d...
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次