尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证A RoleLogic plugin that grants Discord roles based on a member's Roblox account or in-game progression.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗A RoleLogic plugin that grants Discord roles based on a member's Roblox account or in-game progression.
Members link their Roblox account once. The plugin then assigns Discord roles automatically based on a single configurable condition per role link. Conditions span three categories:
/games page. Every reported stat is keyed by a free-form name (e.g. level, timePlayed, guild_score, isVIP) and exposed as Custom Numeric / Boolean / String role conditions.Per-game stats can reach the plugin in two ways:
POST /ingest/{universe_id}/stats with an X-Ingest-Secret header. The shipped Studio plugin under studio-plugin/ does this in 60s batches./games admin page; no in-game code change required.Bulk syncs use RoleLogic's chunked-upload API and scale to the documented 30M-per-role ceiling.
All endpoints are nested under /roblox-player-role.
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /register | Token {api_token} | RoleLogic registers a guild/role pair |
GET | /config | Token {api_token} | Returns the form schema (with current values) |
POST | /config | Token {api_token} | Saves a new condition; triggers a debounced bulk re-sync |
DELETE | /config | Token {api_token} | Deletes the role link |
GET | /verify | none | Linking page (Discord → Roblox OAuth) |
GET | /verify/login | none | Redirects to the Auth Gateway for Discord sign-in |
GET | /verify/roblox | rl_session cookie | Begins the Roblox OAuth (PKCE) flow |
GET | /verify/callback | rl_session cookie | Roblox OAuth callback |
POST | /verify/unlink | rl_session cookie | Drops the Roblox link, clears all roles |
GET | /players/{guild_id} | rl_session cookie | Verified-player list for a guild |
GET | /games | rl_session cookie | Game-creator admin dashboard |
POST | /games | rl_session cookie | Register a Roblox universe (returns ingest_secret once) |
POST | /games/{universe_id}/regenerate-secret | rl_session cookie | Rotate the ingest secret |
{BASE_URL}/verify/callback. Request scopes openid profile. (premium, verification are optional but populate the matching condition fields.).env.example → .env, fill it in. Generate TOKEN_ENCRYPTION_KEY with openssl rand -hex 32.compose.yml).docker compose up -d --build (or cargo run --release).The Auth Gateway service must be reachable at AUTH_GATEWAY_URL and share the same SESSION_SECRET and INTERNAL_API_KEY as configured here.
Once a server admin has set up at least one role link with a game condition pointing at your universe, register the universe at {BASE_URL}/games. From there you can:
studio-plugin/dist/Roblox-Player-Role.rbxm after rojo build). It batches every 60s and POSTs stats from leaderstats to the webhook. Paste your webhook URL + secret into the Configuration instance the plugin creates.ServerScriptService script.Stat payload shape (push):
{
"players": [
{
"user_id": "12345",
"stats": {
"level": 7,
"wins": 3,
"losses": 1,
"currency": 5000,
"timePlayed": 120,
"guild_score": 42,
"isVIP": true
}
}
]
}
stats is a flat key→value map. Keys are arbitrary; the server stores the whole object as the player's custom blob and exposes each key in the role-condition stat dropdown. Partial updates shallow-merge: keys you don't send are left untouched.
add_user / remove_user path with for_each_concurrent(10).SELECT discord_id WHERE … against denormalized columns + JSONB GIN indices, then push the qualifying list via RoleLogicClient::replace_users_scalable. That client transparently switches to the chunked start_upload → append_chunk (100k per chunk) → commit_upload flow above the single-PUT limit, atomic on commit. Pre-flights against the documented 30M-per-role ceiling.PlayerSyncEvent 4096, ConfigSyncEvent 256). Producers use try_send to apply backpressure rather than block.cargo test runs unit tests for condition_eval (every supported field) and schema::parse_config.
src/
├── main.rs — Router, AppState, channel + worker wiring
├── config.rs — Env loading
├── db.rs — PgPool, migrations
├── error.rs — AppError + IntoResponse
├── schema.rs — /config form schema + parse_config
├── models/ — Condition, ConditionField, PlayerStats
├── routes/ — RoleLogic contract, verification, players, games, ingest, health
├── services/ — roblox_api, roblox_oauth, roblox_open_cloud, rolelogic, condition_eval, sync, auth_gateway, session, crypto
└── tasks/ — player_sync_worker, config_sync_worker, refresh_worker, opencloud_poll_worker
migrations/ — 001 base / 002 user_cache / 003 game_universes / 004 player_game_stats
studio-plugin/ — Rojo source for the shipped .rbxm
See .claude/BLUEPRINT.md for cross-plugin conventions.
POST/games/{universe_id}/open-cloud |
rl_session cookie |
| Save / disable Open Cloud DataStore polling |
POST | /games/{universe_id}/delete | rl_session cookie | Delete the universe + cached stats |
POST | /ingest/{universe_id}/stats | X-Ingest-Secret header | Push per-player stats (max 100 players, 60 req/min/universe) |
GET | /health | none | Liveness + dependency check |