feat(rust): chat titles, BetterChat group styles, the voice and popups (phase 17)
PLAN.md §33, D134-D143. Protocol 12. - Chat titles (D135-D137): per-server rules (stat, top N, text, colour) that rank the current wipe, and a mode (first | all | up to N). Worked out once in model/titles and read three ways: pushed whole to the game by a new titleSync loop (on change, restart or wipe), and on every leaderboard row as `titles`. Admin: PUT /servers/:id/titles. - Group styles (D138, D139): a site group may carry all twelve BetterChat fields (rust_perm_group_chat). They ride perm.sync with `expect` from the pushed ledger, which gains a value column; a field changed in game is a `chat-field` drift row with the game's value, adopted into the style or put back. A withdrawn style is one `chat-group` retirement, never for `default`, cleared from the ledger only once BetterChat removed it. - The voice (D140): one fleet setting naming a styled group; news and rust.announce chat lines carry its format and the plugin says them with no sender. Admin: GET/PUT /voice. - Popups (D141, D142): rust.announce gains `delivery` (still version 1, from rust.options.delivery); each server gains news_delivery beside the news switch; `popup-unavailable` is not retried. - GET /servers/:id/integrations reads, live, which optional mods a server has loaded. README lists BetterChat and PopupNotifications as optional. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -927,3 +927,65 @@ ALTER TABLE rust_servers ADD COLUMN IF NOT EXISTS wipe_time CHAR(5) NULL;
|
||||
ALTER TABLE rust_servers ADD COLUMN IF NOT EXISTS wipe_tz VARCHAR(64) NULL;
|
||||
ALTER TABLE rust_servers ADD COLUMN IF NOT EXISTS wipe_anchor DATE NULL;
|
||||
ALTER TABLE rust_servers ADD COLUMN IF NOT EXISTS wipe_once_at DATETIME NULL;
|
||||
|
||||
-- ── The optional mods (phase 17, protocol 12) ─────────────────────────────
|
||||
--
|
||||
-- Chat titles (D135): an operator's rules, per server, in their own order. A
|
||||
-- rule ranks the CURRENT wipe by one stat and gives its top N a title. The
|
||||
-- titles themselves are not stored: they are computed from the standings each
|
||||
-- time they are pushed or shown, so nothing rolls them over at a wipe and
|
||||
-- nothing can go stale (`model/titles`).
|
||||
--
|
||||
-- stat `kills` · `npckills` · `playtime`
|
||||
-- top_n 1–10
|
||||
-- text at most 24 characters, with `[ ] < > { }` stripped on save so an
|
||||
-- operator's title can carry no markup of its own (§33.4)
|
||||
-- color `#rrggbb`
|
||||
-- position the operator's order, which is also precedence (D136)
|
||||
CREATE TABLE IF NOT EXISTS rust_title_rules (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
server_id VARCHAR(64) NOT NULL,
|
||||
position INT NOT NULL DEFAULT 0,
|
||||
stat VARCHAR(16) NOT NULL,
|
||||
top_n TINYINT NOT NULL DEFAULT 1,
|
||||
text VARCHAR(24) NOT NULL,
|
||||
color CHAR(7) NOT NULL DEFAULT '#ffaa55',
|
||||
KEY idx_rust_title_rules_server (server_id, position),
|
||||
CONSTRAINT fk_rust_title_rules_server
|
||||
FOREIGN KEY (server_id) REFERENCES rust_servers (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- How many titles one player shows (D136): `first` the first rule they meet,
|
||||
-- `all`, or `upto` `title_max` of them. A word this build does not know reads
|
||||
-- as `first`, the fewest.
|
||||
ALTER TABLE rust_servers ADD COLUMN IF NOT EXISTS title_mode VARCHAR(8) NOT NULL DEFAULT 'first';
|
||||
ALTER TABLE rust_servers ADD COLUMN IF NOT EXISTS title_max TINYINT NOT NULL DEFAULT 2;
|
||||
|
||||
-- Where a news post goes on this server when `announce_news` is on (D142):
|
||||
-- `chat` or `popup`. A popup needs PopupNotifications, which is optional
|
||||
-- (D141), and a server without it refuses with a reason.
|
||||
ALTER TABLE rust_servers ADD COLUMN IF NOT EXISTS news_delivery VARCHAR(8) NOT NULL DEFAULT 'chat';
|
||||
|
||||
-- A group's BetterChat style (D138): all twelve fields or none, one row each,
|
||||
-- as the text BetterChat's own `chat group set` takes. A style is authored with
|
||||
-- the group and dies with it; the push, the drift and the removal (D139) are the
|
||||
-- permission mirror's, like everything else about a group.
|
||||
CREATE TABLE IF NOT EXISTS rust_perm_group_chat (
|
||||
group_name VARCHAR(64) NOT NULL,
|
||||
field VARCHAR(32) NOT NULL,
|
||||
value VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (group_name, field),
|
||||
CONSTRAINT fk_rust_perm_group_chat_group
|
||||
FOREIGN KEY (group_name) REFERENCES rust_perm_groups (name) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- What a pushed style field HELD when it landed (kind `chat-field`, subject the
|
||||
-- group, object the field). Every other ledger row is a fact with no value — a
|
||||
-- grant is held or it is not — and a field is not: the value is what tells a
|
||||
-- field this site set from one somebody changed by hand (§33.2). NULL on every
|
||||
-- other kind.
|
||||
ALTER TABLE rust_perm_pushed ADD COLUMN IF NOT EXISTS value VARCHAR(255) NULL;
|
||||
|
||||
-- The value a changed field holds in the game, for a `chat-field` drift row.
|
||||
-- NULL on every other kind: a foreign grant is its own description.
|
||||
ALTER TABLE rust_perm_drift ADD COLUMN IF NOT EXISTS detail VARCHAR(255) NULL;
|
||||
|
||||
Reference in New Issue
Block a user