Skip to content

Latest commit

 

History

85 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ちゃんりば(ちゃんとリバーシ)

軽く一局打っても、その一局がちゃんと残り、ちゃんと振り返れて、次につながるAndroid向けリバーシアプリです。Supabase Auth・matchmaking・Realtime signaling・WebRTC DataChannelを使うオンライン対局と、対局後GameRecordをEdaxで解析するレビュー経路を実装しています。本アプリはEdax公式・公認アプリではありません。

開発環境

  • Android Studio Koala以降
  • JDK 17
  • Android SDK 36
  • Android NDK 27.3.13750724 (r27d LTS) / CMake 3.22.1
  • Kotlin 2.2.10 / Compose Compiler plugin / Compose 1.6.8

ビルドとテスト

./gradlew test
./gradlew lint
./gradlew :app:assembleDebug
./gradlew :app:assembleRelease
./gradlew :app:bundleRelease
pwsh ./scripts/check-boundaries.ps1
pwsh ./scripts/check-sql-security.ps1
pwsh ./scripts/check-release-contents.ps1
supabase start
supabase test db
supabase stop

# Emulator A/B smoke/E2E (credentials are environment variables, never committed)
./scripts/run-emulator-e2e.ps1 -StartSupabase -AutoPlay

Android Studioでルートを開いて同期し、app configurationを実行することもできます。リポジトリにはGradle Wrapperを含めています。

構成

詳細は ARCHITECTURE.mdIMPLEMENTATION_PLAN.md を参照してください。core:gameはAndroid/Supabase/WebRTC/Rating/Edaxを参照しない純粋Kotlinです。feature:matchanalysisへ依存せず、Reviewだけがanalysis:apiを参照します。

WebRTC SDKとSupabase SDKの具体実装は、それぞれtransport:webrtcdata:supabaseへ隔離します。matches.server_statusはサーバーが保証できる状態だけを保持し、AndroidのP2P session stateとは別物です。 WebRTC Android SDKはMaven Centralのio.github.webrtc-sdk:android:144.7559.09に固定しています。 SupabaseModuledata:supabase内でSDK clientとrepositoryを組み立て、appへは自前port interfaceだけを返します。

Supabase / Android configuration

The Android client reads supabase.url and supabase.anonKey from the untracked local.properties file, or SUPABASE_URL / SUPABASE_ANON_KEY from the environment. Missing values produce a visible configuration error and do not crash the app. Never place a service-role key in Android resources or BuildConfig.

Hosted疎通環境を同じ設定で作り直す手順は docs/SUPABASE_HOSTED_SETUP.md に記録しています。

  1. Supabase projectを作成します。
  2. supabase/migrations内のmigrationをファイル名順にすべてSupabase SQL EditorまたはSupabase CLIで適用します。
  3. Android側へservice-role keyを置かず、AuthユーザーのJWTと公開anon keyだけをアプリ設定へ渡します。
  4. 新規AuthユーザーはDB triggerでprofiles/ratingsへbootstrapされます。マッチングはenqueue_or_match()だけを使用し、公式Rating snapshotとTTLをDB側で管理します。
  5. 結果提出はsubmit_match_result(...)を使用します。2件目の提出時に同一transaction内で自動finalizeされ、finalize_match_v2(...)はreconciliation用に残します。参加者以外・二重Rating更新・不一致結果はDB側で拒否またはDISPUTEDになります。
  6. 公開プロフィールとdisplay_nameは初回公開版のDBから削除済みです。対局相手ratingは参加者限定のmatchmaking RPCが成立時snapshotだけを返します。

Cloudflare Admin

cloudflare-adminはアカウント削除を扱う信頼済み管理BFFです。service-role keyはWorker secretにだけ置き、ADMIN_TOKENもWorker secretに置きます。初回公開版に段級位申請・証明画像・verification管理機能はなく、関連DB/Storage/Worker経路も削除しています。

削除要求は10分ごとのWorker Cronまたは管理endpointから再実行できます。私有データ削除、Research identityのunlink、Supabase Auth Admin削除、完了記録の順に処理し、途中失敗を完了扱いしません。共有棋譜に必要な内部ID tombstoneは残りますが、表示名は保持しません。ブラウザやAndroidへservice-role keyを配布しません。

cd cloudflare-admin
npm install
npx wrangler secret put SUPABASE_SERVICE_ROLE_KEY
npx wrangler secret put ADMIN_TOKEN
npm run deploy

オンライン対局

MatchTransportのWebRTC DataChannel実装を使用します。Supabase RealtimeのPostgres Changesは、待機側へのparticipant限定match_notificationsと、SDP offer/answer用match_signalingだけに使用します。通知を受けた待機側は即座にmatchをclaimし、heartbeat pollingは通知失敗時のfallbackとして残します。P2P接続後に着手、時計、盤面、結果をRealtimeへ送信しません。実機2台では、Auth設定、同一Supabase project、TURN/STUN設定、2台のqueue参加、DataChannel成立、両者start ACK、双方の同一棋譜・hash、結果提出の順で確認します。

ログイン後のホームには本人のサーバー管理ratings.current_ratingを表示します。対局画面には成立時に保存した相手rating snapshotだけを表示し、ニックネーム、メールアドレス、UUIDをプレイヤー名として表示しません。

applicationId = com.shinpstudio.chanriva をGoogle Play公開用の正式IDとして使用します。repository名と内部package/DB識別子のothelloは、公開ブランドではなく既存の技術識別子として変更していません。

Emulator A/Bの再現手順と、emulatorで完了できる項目・物理端末に残る項目は docs/DEVICE_TEST.mdを参照してください。build/e2e/には secretを含めないXML、スクリーンショット、対象tagのlogcatを保存できます。

matchesのCREATED leaseは5分のsignaling用です。DataChannel成立後、両participantがack_match_startedを一度呼び、クライアントがget_match_start_stateで両者ACKを確認してからPLAYINGへ進みます。両者ACK後はP2P開始事実と24時間のbounded play leaseを記録します。PENDING_RESULTのactive reservationは5分で、30日保持の監査用submissionとは分離しています。期限切れはABANDONEDへ遷移してからreservationを解放します。matchmaking hot pathはcaller-scoped reconciliationとqueue expiryだけを行い、stale matchとterminal recordの全体cleanupはmaintenance pathで実行します。Supabase Cron/pg_cronを使う場合は、service role相当で次を1時間ごとに実行します。

select public.cleanup_stale_created_matches();
select public.cleanup_expired_pending_results();
select public.cleanup_expired_started_matches();
select public.cleanup_terminal_matches();

Edax / OSS

対局後Reviewの解析エンジンにはEdax 4.6を使用します。upstream commitは14f048c05ddfa385b6bf954a9c2905bbe677e9d3へ固定し、Kotlin -> analysis:api -> analysis:edax -> JNI -> native Edaxで統合しています。Android app全体はGNU GPL version 3で配布します。ライセンス全文はLICENSE、著作権・第三者dependency表示はNOTICE.md、固定ソース・patch・再構築手順はthird_party/edax/UPSTREAM.mddocs/EDAX_BUILD.mdを参照してください。

Edaxの評価データ(eval.dat等)とOpening Bookは、権利をEdax本体と分離して扱い、APK/AABにもrepositoryにも同梱しません。評価データは設定 -> 解析から、Edax公式GitHub Releasesのv4.4 eval.7zからeval.datだけを自動設定するか、ユーザーが正当に取得・所有するファイルをStorage Access Frameworkで選んで、アプリprivate storageへコピーできます。ダウンロード・展開・検証に成功するまで既存データは置き換えません。評価データ未設定時は偽の値を表示しません。Bookは任意で、未設定またはbook miss時は通常のEdax探索を使います。詳しい導線はhttps://chanriva.shinp-studio.com/edaxを使用します。

Reviewでは実戦開始局面、任意ply、最終局面、保存前variation局面を解析でき、現在手番の全合法手へ予測終局石差を盤面上表示します。完全読みのexact、深さ依存のheuristic、import済みBook由来のbookを区別します。解析は明示操作時だけ単一background workerで実行し、ply変更・variation変更・画面離脱・新規解析でcancel/stale-result破棄を行います。

対応ABIはarm64-v8aと開発用x86_64だけです。Edaxを含む全native libraryとAPK packagingは16 KiB page-size alignmentをrelease検査します。feature:matchcore:gameはanalysis/JNI/Edaxへ依存せず、ranked/live DataChannel経路から解析へ到達できません。

公開前に残る判断と実機確認

  • ユーザー判断: repository renameの要否、Google Playの公開version・価格・対象年齢・配信国、公開support email、TURN provider、Play App Signingとtesting/publication。
  • 物理端末: arm64 native実性能、Edaxの持続性能・thermal・battery、Wi-Fi↔mobile/mobile↔mobile、carrier NAT/CGNAT/symmetric NAT、STUN-only成功率とTURN必要率、network handover、メーカー固有background挙動。

launcher icon、アプリ内Privacy Policy導線、公開Privacy Policy(https://chanriva.shinp-studio.com/privacy)、アプリ不要のWeb削除受付(https://chanriva.shinp-studio.com/account-deletion)は実装済みです。signed release / Play生成APKでの最終runtime確認はPlay App Signing後の別ゲートです。

現在のICE設定はPublic STUNのみです。Emulator A/B成功はTURN不要の根拠にはせず、物理ネットワーク試験後に導入判断します。有料サービスを前提にした設定は含めていません。

About

Android online Othello MVP foundation

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages