Document VRC OSC setup
This commit is contained in:
@@ -1,241 +1,167 @@
|
||||
修正版。仕様はこう整理すると実装しやすい。
|
||||
# VRC_OSC
|
||||
|
||||
# VRC_LOG event.toml 監視仕様
|
||||
VRChat の OSC パラメータを受けて、Discord ミュート、VRChat ログ監視、OCR、翻訳を実行するローカルツール。
|
||||
|
||||
## 1. 目的
|
||||
## 起動
|
||||
|
||||
VRChatログから現在インスタンスの入退室を拾い、必要最低限だけ表示する。
|
||||
PowerShell から起動する。
|
||||
|
||||
表示対象は以下のみ。
|
||||
```powershell
|
||||
bin\vrc_osc.ps1
|
||||
```
|
||||
|
||||
- ワールド入室
|
||||
- guest の現在人数
|
||||
- guest の join / leave
|
||||
- staff の join / leave
|
||||
Python から直接起動する場合。
|
||||
|
||||
staff は表示するが guest 人数にはカウントしない。
|
||||
```powershell
|
||||
python src\bin\vrc_osc.py
|
||||
```
|
||||
|
||||
---
|
||||
OSC は `127.0.0.1:9001` で待ち受ける。
|
||||
|
||||
## 2. event.toml
|
||||
## 設定ファイル
|
||||
|
||||
実設定は `config/config.toml` に置く。このファイルは Git に入れない。
|
||||
|
||||
雛形は `config/config.example.toml`。
|
||||
|
||||
```toml
|
||||
[self]
|
||||
name = "自分のVRChat表示名"
|
||||
|
||||
[staff]
|
||||
names = [
|
||||
"StaffUserA",
|
||||
"StaffUserB"
|
||||
"StaffUserA"
|
||||
]
|
||||
|
||||
[guest]
|
||||
names = [
|
||||
"GuestUserA",
|
||||
"GuestUserB",
|
||||
"GuestUserC"
|
||||
"GuestUserB"
|
||||
]
|
||||
|
||||
[notice]
|
||||
missing_count = 3
|
||||
```
|
||||
|
||||
注意。
|
||||
`self.name` は Discord 自動ミュート判定に使う。
|
||||
|
||||
nofice ではなく notice にする。
|
||||
意味は「通知設定」。
|
||||
`staff.names` は表示対象だが guest 人数には含めない。
|
||||
|
||||
3. カウント仕様
|
||||
3.1 guest人数
|
||||
`guest.names` は guest 人数の母数と在室判定に使う。
|
||||
|
||||
guest人数は event.toml の [guest].names にいるユーザーだけを数える。
|
||||
`notice.missing_count` は「あと何人以内で全員集合か」の通知範囲。例えば guest が 23 人で `missing_count = 3` の場合、20〜22 人のときに未入室 guest を出す。
|
||||
|
||||
staff は数えない。
|
||||
## 秘密情報
|
||||
|
||||
現在Guest: 1/22
|
||||
`.env` に置く。このファイルは Git に入れない。
|
||||
|
||||
意味。
|
||||
雛形は `.env.example`。
|
||||
|
||||
現在いるguest数 / guest登録総数
|
||||
3.2 自分の入室順は関係ない
|
||||
```env
|
||||
DISCORD_WEBHOOK_URL=
|
||||
VRCHAT_USERNAME=
|
||||
VRCHAT_PASSWORD=
|
||||
```
|
||||
|
||||
自分がインスタンスに何番目に入ったかは使わない。
|
||||
`DISCORD_WEBHOOK_URL` は VRC ログ結果の Discord Webhook 通知に使う。
|
||||
|
||||
現在インスタンス内で発生した join / leave を時系列で処理し、最終的な在室状態から人数を出す。
|
||||
`VRCHAT_USERNAME` / `VRCHAT_PASSWORD` は `src/getUser.py` を使う場合だけ必要。
|
||||
|
||||
4. ログ範囲
|
||||
## OSC パラメータ
|
||||
|
||||
解析対象は昼12:00以降。
|
||||
Avatar Parameters 側の名前と一致させる。
|
||||
|
||||
実行時刻が 01:00 の場合。
|
||||
| Parameter | 動作 |
|
||||
| --- | --- |
|
||||
| `DiscordSend` | 押した瞬間に Discord の mute hotkey を送る |
|
||||
| `vrc_log` | VRC ログ監視の on/off |
|
||||
| `ocrEnabled` | VRChat 画面を撮って OCR |
|
||||
| `translation` | OCR して日本語翻訳 |
|
||||
|
||||
前日 12:00 以降
|
||||
## VRC ログ監視
|
||||
|
||||
実行時刻が 13:00 の場合。
|
||||
`vrc_log` を押すと、現在の VRChat ログを一度解析して Discord Webhook に送る。その後はログファイル末尾を追い、新しい join / leave / world 系ログが追記されたタイミングで即再解析する。
|
||||
|
||||
当日 12:00 以降
|
||||
以前のような `output_log = 10` の秒数ポーリング設定は使わない。
|
||||
|
||||
11:59以前のインスタンスは切り捨てる。
|
||||
解析対象は昼 12:00 以降。実行時刻が昼 12:00 前なら前日 12:00 以降を見る。
|
||||
|
||||
5. インスタンス仕様
|
||||
インスタンスが変わったら在室状態はリセットする。
|
||||
|
||||
昼12:00以降に検出した最新のワールド / インスタンスだけを対象にする。
|
||||
|
||||
インスタンスが変わったら、参加状態はリセットする。
|
||||
|
||||
6. 表示仕様
|
||||
6.1 ワールド入室
|
||||
|
||||
ワールドに入った時だけ表示。
|
||||
出力例。
|
||||
|
||||
```text
|
||||
ワールド入室: Midnight Rooftop
|
||||
現在Guest: 1/22
|
||||
現在Guest: 0/3
|
||||
[01:20] [join] GuestUserA 1/3
|
||||
[01:21] [join] GuestUserB 2/3
|
||||
[01:25] [leave] GuestUserA 1/3
|
||||
[01:26] [join] [staff] StaffUserA 1/3
|
||||
```
|
||||
|
||||
ワールド名が取れない場合。
|
||||
notice 条件に入った場合。
|
||||
|
||||
ワールド入室: wrld_xxx
|
||||
現在Guest: 1/22
|
||||
7. join / leave 表示仕様
|
||||
7.1 guest join
|
||||
[01:20] GuestUserA join 2/22
|
||||
7.2 guest leave
|
||||
[01:25] GuestUserA leave 1/22
|
||||
7.3 staff join
|
||||
|
||||
staff は人数カウントしない。
|
||||
|
||||
[staff] StaffUserA join 1/22
|
||||
7.4 staff leave
|
||||
|
||||
staff が抜けても guest人数は変わらない。
|
||||
|
||||
[staff] StaffUserA leave 1/22
|
||||
8. notice 判定
|
||||
|
||||
notice.missing_count = 3 の場合、guest登録総数から3人以内の不足になったら、今いないguest名を出す。
|
||||
|
||||
例。
|
||||
|
||||
guest登録総数が23人。
|
||||
missing_count が3。
|
||||
|
||||
通知対象人数は以下。
|
||||
|
||||
20人
|
||||
21人
|
||||
22人
|
||||
|
||||
つまり、
|
||||
|
||||
23 - 3 = 20
|
||||
|
||||
なので、guest現在人数が 20〜22 の間なら不足者を表示する。
|
||||
|
||||
9. notice 表示例
|
||||
|
||||
guest総数23人、notice=3。
|
||||
|
||||
9.1 20人になった場合
|
||||
現在Guest: 20/23
|
||||
```text
|
||||
現在Guest: 2/3
|
||||
未入室Guest:
|
||||
- GuestUserA
|
||||
- GuestUserB
|
||||
- GuestUserC
|
||||
9.2 21人になった場合
|
||||
現在Guest: 21/23
|
||||
未入室Guest:
|
||||
- GuestUserA
|
||||
- GuestUserB
|
||||
9.3 22人になった場合
|
||||
現在Guest: 22/23
|
||||
未入室Guest:
|
||||
- GuestUserA
|
||||
9.4 23人になった場合
|
||||
```
|
||||
|
||||
表示しない。
|
||||
## Discord 自動ミュート
|
||||
|
||||
9.5 23人から22人に減った場合
|
||||
常時 self monitor が VRChat ログの新規追記だけを見る。
|
||||
|
||||
再度表示する。
|
||||
新しく追記されたログの中で、自分の最後のイベントが `OnPlayerJoined` なら Discord を mute、`OnPlayerLeft` なら unmute する。
|
||||
|
||||
現在Guest: 22/23
|
||||
未入室Guest:
|
||||
- GuestUserA
|
||||
9.6 19人以下になった場合
|
||||
過去ログ全体の最後が self leave / join だっただけでは反応しない。
|
||||
|
||||
表示しない。
|
||||
`setDiscordMuted()` にはロックがあり、同時実行で mute hotkey が連続送信されないようにしている。
|
||||
|
||||
理由。
|
||||
## OCR / 翻訳
|
||||
|
||||
23 - 3 = 20
|
||||
`ocrEnabled` は VRChat ウィンドウを撮影して PaddleOCR にかける。結果はクリップボードへコピーする。
|
||||
|
||||
なので、20人未満は通知範囲外。
|
||||
`translation` は OCR 結果を翻訳し、翻訳結果をクリップボードへコピーする。
|
||||
|
||||
10. notice 条件
|
||||
## runtime
|
||||
|
||||
通知する条件。
|
||||
新規の実行ログは基本的に以下へまとめる。
|
||||
|
||||
total_guest - notice <= current_guest < total_guest
|
||||
```text
|
||||
runtime/runtime.log
|
||||
runtime/latest_ocr.png
|
||||
runtime/latest_screenshot.png
|
||||
```
|
||||
|
||||
例。
|
||||
`runtime/` は Git に入れない。
|
||||
|
||||
23 - 3 <= current_guest < 23
|
||||
OCR text、翻訳 text、VRC ログ結果は `runtime/runtime.log` に追記する。
|
||||
|
||||
つまり。
|
||||
画像は最新ファイルに上書きする。日時別ファイルを増やさない。
|
||||
|
||||
20 <= current_guest < 23
|
||||
## ユーザー名照合
|
||||
|
||||
通知しない条件。
|
||||
`src/vrc_log/member_name_matcher.py` は TOML 登録名と VRChat 表示名を安全な順番で紐づける補助実装。
|
||||
|
||||
current_guest == total_guest
|
||||
current_guest < total_guest - notice
|
||||
11. 最終出力例
|
||||
ワールド入室: Midnight Rooftop
|
||||
現在Guest: 1/22
|
||||
[staff] StaffUserA join 1/22
|
||||
[01:20] GuestUserA join 2/22
|
||||
[01:21] GuestUserB join 3/22
|
||||
[01:22] GuestUserC join 4/22
|
||||
[01:25] GuestUserB leave 3/22
|
||||
[staff] StaffUserA leave 3/22
|
||||
照合順。
|
||||
|
||||
notice条件に入った場合。
|
||||
1. 完全一致
|
||||
2. 正規化一致
|
||||
3. 高信頼 fuzzy
|
||||
4. guest のみ低信頼 fuzzy
|
||||
5. pending / ambiguous / unmatched
|
||||
|
||||
現在Guest: 20/23
|
||||
未入室Guest:
|
||||
- GuestUserA
|
||||
- GuestUserB
|
||||
- GuestUserC
|
||||
12. 実装時の内部状態
|
||||
world_name
|
||||
world_id
|
||||
instance_id
|
||||
guest_total
|
||||
guest_present_set
|
||||
staff_present_set
|
||||
current_guest_count
|
||||
notice_missing_count
|
||||
完全一致・正規化一致で確定した名前は fuzzy 候補から除外する。
|
||||
|
||||
ユーザー分類。
|
||||
## Git に入れないもの
|
||||
|
||||
if name in staff:
|
||||
role = "staff"
|
||||
elif name in guest:
|
||||
role = "guest"
|
||||
else:
|
||||
role = "other"
|
||||
以下はローカル専用。
|
||||
|
||||
other は表示しない。
|
||||
guest人数にも含めない。
|
||||
- `.env`
|
||||
- `config/config.toml`
|
||||
- `runtime/`
|
||||
- `__pycache__/`
|
||||
- `*.pyc`
|
||||
- `.vrchat_cookie.txt`
|
||||
|
||||
13. Discord通知も同じ最小表示
|
||||
|
||||
Discordには以下だけ送る。
|
||||
|
||||
ワールド入室: Midnight Rooftop
|
||||
現在Guest: 1/22
|
||||
[staff] StaffUserA join 1/22
|
||||
[01:20] GuestUserA join 2/22
|
||||
[01:25] GuestUserA leave 1/22
|
||||
|
||||
notice時だけ追加。
|
||||
|
||||
未入室Guest:
|
||||
- GuestUserA
|
||||
- GuestUserB
|
||||
秘密情報を含む可能性があるものはコミットしない。
|
||||
|
||||
Reference in New Issue
Block a user