Merge branch 'master' of ssh://git.lapikud.ee:202/renkar/tipibot
# Conflicts: # bot.py
This commit is contained in:
48
README.md
48
README.md
@@ -10,8 +10,9 @@ Discord bot for the TipiLAN community. Manages member roles and nicknames via Go
|
||||
2. [Member Management](#member-management)
|
||||
3. [Admin Commands](#admin-commands)
|
||||
4. [Birthday System](#birthday-system)
|
||||
5. [TipiCOIN Economy](#tipicoin-economy)
|
||||
6. [Project Structure](#project-structure)
|
||||
5. [Tournament Team Roles](#tournament-team-roles)
|
||||
6. [TipiCOIN Economy](#tipicoin-economy)
|
||||
7. [Project Structure](#project-structure)
|
||||
|
||||
---
|
||||
|
||||
@@ -107,6 +108,8 @@ cp .env.example .env
|
||||
| `PB_ECONOMY_COLLECTION_DEV` | PocketBase collection used by `BOT_PROFILE=dev` |
|
||||
| `PB_ECONOMY_COLLECTION_ECONOMY` | PocketBase collection used by `BOT_PROFILE=economy` |
|
||||
| `PB_ECONOMY_COLLECTION` | Legacy fallback collection (optional) |
|
||||
| `TEAM_SHEET_ID` | Tournament registration spreadsheet (separate from the member sheet). Unset = team sync off |
|
||||
| `TEAM_DIVIDER_<GAME>_<YEAR>` | Divider role that a sheet section's teams get positioned under - see [Tournament team roles](#tournament-team-roles) |
|
||||
|
||||
### 6. Install & Run
|
||||
|
||||
@@ -168,6 +171,7 @@ Admins (bot lacks permission to modify them) are silently skipped and still mark
|
||||
|---|---|---|
|
||||
| `/check` | Manage Roles | Refreshes sheet data, backfills missing User IDs, syncs nicknames + roles for every member, reports stats |
|
||||
| `/member @user` | Manage Roles | Shows a member's full sheet data + calculated age |
|
||||
| `/teamsync` | Bot admin | Reloads the tournament registration sheet, grants/removes team roles, and repositions them under their dividers. See [Tournament Team Roles](#tournament-team-roles) |
|
||||
| `/sync` | Manage Guild | Re-registers slash commands with Discord |
|
||||
| `/restart` | Manage Guild | Gracefully restarts the bot process; posts ✅ in the same channel when back up |
|
||||
| `/shutdown` | Manage Guild | Shuts the bot down cleanly without restarting |
|
||||
@@ -220,6 +224,46 @@ If a member joins and their birthday is within `BIRTHDAY_WINDOW_DAYS` days, a bi
|
||||
|
||||
---
|
||||
|
||||
## Tournament Team Roles
|
||||
|
||||
Runs on the **economy** profile only, driven by the separate `TEAM_SHEET_ID` spreadsheet. It is independent of the member roster - players are matched straight from the registration sheet by Discord username, and never need a row in the member sheet.
|
||||
|
||||
Re-runs automatically **every hour**, and on demand via `/teamsync` (admin).
|
||||
|
||||
### What it does
|
||||
|
||||
- Grants each registered player the role named after their team, creating that role if it doesn't exist yet
|
||||
- Removes team roles they no longer hold (switched teams, dropped out)
|
||||
- Positions every team role directly beneath its game's divider role
|
||||
- **Only role names present in the sheet are ever added, removed, or moved** - no unrelated role is at risk
|
||||
|
||||
### Divider placement
|
||||
|
||||
The registration sheet stacks several game sections per tab, each under a merged title row:
|
||||
|
||||
```
|
||||
[merged] TipiLAN 2026 CS2 Registration Log
|
||||
No | Team Name | Lineup (nickname, citizenship) | ...
|
||||
1 | GENESIS | kapa (EST), neaQ (EST) | ...
|
||||
```
|
||||
|
||||
Set one `TEAM_DIVIDER_*` variable per section to say where those teams belong:
|
||||
|
||||
```bash
|
||||
TEAM_DIVIDER_CS2_2026="====== COUNTER-STRIKE 2 2026 ======"
|
||||
TEAM_DIVIDER_LOL_2026="===== LEAGUE OF LEGENDS 2026 ====="
|
||||
```
|
||||
|
||||
- **The key suffix** is matched against the section's title row. Every underscore-separated part must appear in it as a whole word, so `CS2_2026` matches only the 2026 CS2 block, while a plain `CS2` would match that game in any year. When several keys match, the most specific one (most parts) wins.
|
||||
- **The value** is the *exact* Discord role name, decoration included. Copy it from Server Settings → Roles.
|
||||
- Sections matching no key still get their team roles - they just aren't repositioned.
|
||||
|
||||
Teams are ordered alphabetically downwards under their divider. Every sync re-checks placement, so roles that predate this feature get pulled into place on the next run.
|
||||
|
||||
> The bot can only move roles **below its own** role. Drag the TipiBOT role above your dividers, or placement is skipped and reported as an error.
|
||||
|
||||
---
|
||||
|
||||
## TipiCOIN Economy
|
||||
|
||||
All economy data is stored in **PocketBase** (`economy_users` collection - see `core/pb_client.py`). The currency is **TipiCOIN** (⬡), displayed as a custom Discord emoji configured in `core/economy/store.py → COIN`.
|
||||
|
||||
Reference in New Issue
Block a user