Commit Graph

26 Commits

Author SHA1 Message Date
clxud 246a29f695 Extract website to SREBOT-web repo: remove web/, move seasons/locales/constants to repo root, fix imports 2026-07-02 02:45:22 +00:00
deploy c0214eaaae fix(recap): speed up /card lookup, fix stale completed-season cache, add Place Finished
- /card player lookup was a leading-wildcard substring match with a Python
  ulower() UDF over 6.16M player_games_hist rows — a full scan measured at
  27s live before the ~2s render. Add a prefix fast-path
  (nick LIKE 'name%' COLLATE NOCASE) that uses the existing NOCASE index
  (~1ms), falling back to the ulower substring scan only when the prefix
  finds nothing. Same fix applied to _resolve_player_uids_batch (compare/stats).
  Lookup: 27,205ms -> 1ms.

- Completed-season recap cache served ANY cached PNG forever, including files
  rendered mid-season (frozen at whatever point they were last viewed). Only
  serve from cache when the file's mtime is after season end; otherwise
  re-render. Fixed in both BOT/utils.py and web/server.js (shared cache).

- Replace squadron card "Rating change" with "Place finished" (#rank / total),
  derived by ranking clans by final total_score among those active in-season.

- Add (CARD)/(RECAP) timing logs for prod observability.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 19:20:26 +00:00
deploy 61236a8267 fix: tolerate season-reset payloads in /sq-info and stop duplicate error embeds
obtain_clan_new_points treated a missing `astat` or `member_ratings` block as
"squadron unavailable or deleted". After a season reset the game API omits those
blocks for inactive/unranked squadrons even though the clan and its roster still
exist, so /sq-info wrongly reported real squadrons (e.g. DSPL, 513th) as
nonexistent. Require a `members` roster to consider the payload valid (genuinely
deleted clans return CLAN_IS_NOT_EXISTS JSON handled upstream) and default both
stat blocks to zero, so the squadron renders at 0 points instead of erroring.

permission_fail was invoked twice per error because discord.py dispatches to
both the command-local `@cmd.error` handler and the global `@tree.error`
handler. Combined with a public defer, this produced a duplicated error message
(one public, one ephemeral). Guard on interaction.extras so the embed is sent
at most once per interaction.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 12:28:22 +00:00
NotSoToothless 0f8f22df29 update for spectra changes (#1363) 2026-06-29 11:05:51 -07:00
NotSoToothless 48f96ca8ff Auto merge dev → main (#1332)
* feat(tssbot): build_match_logs + match_logs persistence

* feat(tssbot): create match_logs table and write logs at ingest

* feat(tssbot): one-time match_logs backfill script

* feat(srebot): persist chat/battle logs to match_logs (parity, no backfill)

* feat(tssbot): Battle/Chat Log buttons on Discord scoreboards
2026-06-18 01:02:59 -07:00
NotSoToothless deb4e0fb12 update renderer to have cap status also tickets (#1325) 2026-06-14 22:36:06 -07:00
NotSoToothless 4b75ce1533 Auto merge dev → main (#1324)
* update game files

* update files and capture raw spectra payload
2026-06-14 21:11:57 -07:00
NotSoToothless 9d950c413f blacklist DSPL 💔 2 (#1294) 2026-06-01 13:31:49 -07:00
NotSoToothless 38726d6340 blacklist DSPL 💔 (#1293) 2026-06-01 13:16:43 -07:00
NotSoToothless cb0a18f748 move venv to shared (#1291) 2026-05-31 01:43:19 -07:00
NotSoToothless 37c3e66d75 update blacklists (#1290) 2026-05-30 10:23:03 -07:00
NotSoToothless 54c06bd275 lets get this party starteddddd (#1287) 2026-05-30 08:45:32 -07:00
deploy 14430d3850 simplify: strip first/last char for squadron tag normalization
WT tags are always exactly one decorator char on each side, so a
simple s[1:-1] is clearer than a regex strip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:33:28 +00:00
deploy c0755ec243 fix: strip leading/trailing non-alphanumeric chars in _normalize_squadron_tag
The old regex [^A-Za-z0-9_-] whitelisted dashes and underscores, so
-DSPLA- and _APS_ passed through untouched. All downstream code that
reads team["squadron"] then saw the raw tag instead of the bare short
name, causing NULL clan_ids in player_games_hist/match_summary and
broken lookups throughout. Fixing at the source means every consumer
gets a clean name without individual patches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:24:25 +00:00
deploy 5d972d7314 fix: resolve_clans drops unresolved placeholders to allow tag fallback
Squads with dash-wrapped tags (e.g. -DSPLA-) store the full tag in the
replay's team.squadron field rather than the bare short name. The short
lookup fails and returns a placeholder whose short_name blocks the tag
lookup, leaving squadron_long as "<unresolved>" and producing no point
diffs on scoreboards. Fix: only include successfully resolved clans
(clan_id is not None) in results and resolved_shorts so the tag pass
still runs for any failed short lookup. Affects all 186 dash-tagged squads.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 16:42:23 +00:00
NotSoToothless 96aa75be57 fuck u (#1283) 2026-05-28 06:37:08 -07:00
NotSoToothless 8760c63759 update tss and sre replay area (#1269) 2026-05-25 21:24:56 -07:00
NotSoToothless 9c6ca3bcd7 compress the mf (#1267) 2026-05-24 19:44:12 -07:00
NotSoToothless f6f4e33a65 update to handle new structure from spectra, no more gobs (#1266) 2026-05-23 17:16:53 -07:00
NotSoToothless 2d5adfcbe0 fix leave alarm (#1265) 2026-05-21 23:22:10 -07:00
NotSoToothless ff379c7843 move some commands to standard (#1256) 2026-05-16 16:04:37 -07:00
NotSoToothless 55ab213e76 limit by UID and server (#1252) 2026-05-15 03:05:48 -07:00
NotSoToothless 311ae875fb limit by UID and server (#1251) 2026-05-15 02:56:55 -07:00
NotSoToothless 3fb15d6282 consolidate runtime env into .env, drop ecosystem env blocks (#1229)
- Make .env the single source of truth for runtime config. Remove all
  `env:` blocks from SREBOT/ecosystem.config.js and TSSBOT/ecosystem.config.js
  so values can't silently shadow .env. Both ecosystem files load .env via
  `require('dotenv').config()` and PM2 inherits the resolved environment.

- Rename SREBOT_STORAGE_VOL_PATH → STORAGE_VOL_PATH across all readers
  (BOT/utils.py, BOT/receiver_bridge.py, BOT/render_recap.py, server.js,
  web/server.js, dateindex.js, scripts/*, srebot.service, tests/, README,
  and both .env files). STORAGE is shared between SREBOT and TSSBOT, so the
  variable shouldn't carry one bot's prefix.

- Rename per-process PORT env vars to disambiguated names so .env can be
  the source of truth without collisions:
    PORT (api)     → SREBOT_API_PORT     (server.js)
    PORT (web)     → SREBOT_WEB_PORT     (web/server.js)
    WEBHOOK_PORT   → SREBOT_WEBHOOK_PORT (github_webhook_updater.py)
  SREBOT_EXTERNAL_HOST/PORT/UPSTREAM_URL were already uniquely named;
  they just move from ecosystem env to .env.

- TSSBOT/.env: drop GITHUB_WEBHOOK_SECRET (only srebot-webhook consumes it)
  and the stale SREBOT_DEPLOY_PATH. SREBOT/.env: also drop the obsolete
  SREBOT_DEPLOY_PATH (ecosystem now hardcodes __dirname).

- ecosystem.config.js no longer references SREBOT_DEPLOY_PATH; deploy path
  is always __dirname of the ecosystem file.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 00:07:34 -07:00
NotSoToothless 39ef90b3fd Auto merge dev → main (#1225)
* fix BOT.data_parser import in render_recap.py

render_recap.py runs as a subprocess (Path(__file__).parent.parent on
sys.path) and used `from BOT.data_parser import ...`. After the SHARED
move, data_parser is no longer in the BOT package. Add BOTS/SHARED to
sys.path and switch to the absolute `from data_parser import ...`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* centralize SHARED sys.path bootstrap in BOT/__init__.py

Drop per-file `sys.path.insert(SHARED)` bandaids from BOT/scoreboard.py,
gob.py, utils.py, and game_api.py. The bootstrap now happens exactly
once when the BOT package is imported (via BOT/__init__.py), which is
implicit for any `from BOT.X import …` / `import BOT.X` and any
`python -m BOT.x` invocation.

`SHARED_DIR` is exposed as a public name on the BOT package; siblings
import it via `from . import SHARED_DIR` for building asset paths
(MAPS, ICONS, FONTS, vromfs) instead of recomputing the location.

render_recap.py is the one subprocess entry point that runs as
__main__, so it keeps a minimal bootstrap: add SREBOT to sys.path
then `import BOT` to fire the package init once.

Also move pyrightconfig.json to the BOTS monorepo root so pyright
resolves data_parser and third-party imports regardless of which
subproject the editor opens from.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 23:42:47 -07:00
FURRO404 2b399fdb81 add SREBOT, SHARED, TSSBOT contents (fixup for #1223)
PR #1223 only staged the deletions of the old paths because the new
top-level directories were still untracked when the commit was authored.
This commit adds the actual restructured tree: SREBOT/ (existing bot),
SHARED/ (vromfs, data_parser, ICONS/MAPS/FONTS, DAGOR_FILES,
update_game_files), and TSSBOT/ (skeleton).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 23:17:02 -07:00