feat(rust): chat titles rank twenty-three conditions, and admins name the categories (PLAN_REDESIGNS §5, D172-D175, D209)
- Schema: fourteen title columns on rust_player_wipe_stats (the two best_* distances move by GREATEST, the rest are sums), rust_weapon_kills (kills by weapon prefab name) and rust_title_categories (the admin's title per category). purge.sql drops the two tables. - Ingest: player.tally's new fields, in one statement per frame, none for an older plugin's frame. - Titles: 23 categories plus playtime, each naming where it is read from (a sum, a MAX, npc_kills - animal_kills in signed arithmetic, or a named list). The bow/melee/blade/revolver/wood/ore/plants lists are one file, applied when a title is read. "NPC kills" ranks human NPCs only (D209). - A rule's text may be empty, meaning the category's title: the rule's own, then the admin's, then the default. Typed-only-markup is still refused. A rename forgets every server's cached answer. - Admin API: GET /admin/rust/title-categories and PUT /admin/rust/title-categories/:stat (empty text resets); the server list returns them too. Swagger fragment and routes.manifest.json regenerated (63 routes, against the pinned core). - Screen: every category in the rule form, the category's title as a placeholder, and a Category titles section with Save and Reset. The weapon lists are unverified until the rig probe runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -1303,7 +1303,7 @@
|
||||
"Admin · Rust"
|
||||
],
|
||||
"summary": "Set a server’s chat titles",
|
||||
"description": "Replaces the server’s title rules and how many titles a player shows. A rule ranks the CURRENT wipe by `kills`, `npckills` or `playtime` and gives its top N (1–10) a title; only a stat above zero counts, so a fresh wipe gives no titles. Rules are in precedence order, at most ten. `mode` is `first` (the first rule a player meets), `all`, or `upto` `max` (1–5). The titles are shown in game by BetterChat when it is loaded — they are pushed whether or not it is, and it shows them as soon as it is — and on the web and app leaderboards. A 400 carries one sentence per problem in `errors`.",
|
||||
"description": "Replaces the server’s title rules and how many titles a player shows. A rule ranks the CURRENT wipe by one of the title categories (`RustTitleSettings`) and gives its top N (1–10) a title; only a stat above zero counts, so a fresh wipe gives no titles. A rule’s `text` may be empty, meaning the category’s title (the admin’s, else the module’s default); `playtime` has no default and needs its own. A text that was typed but is only markup is refused. Rules are in precedence order, at most ten. `mode` is `first` (the first rule a player meets), `all`, or `upto` `max` (1–5). The titles are shown in game by BetterChat when it is loaded — they are pushed whether or not it is, and it shows them as soon as it is — and on the web and app leaderboards. A 400 carries one sentence per problem in `errors`.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
@@ -1341,6 +1341,89 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/admin/rust/title-categories": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Admin · Rust"
|
||||
],
|
||||
"summary": "The chat-title categories and their titles",
|
||||
"description": "Every category a title rule can rank that has a shipped title (PLAN_REDESIGNS §5, D172), with its label, the module’s default, the admin’s own title if they set one, and `current`, what a rule with no text of its own shows. The admin’s title is for the whole site (D175).",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The categories",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RustTitleCategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/admin/rust/title-categories/{stat}": {
|
||||
"put": {
|
||||
"tags": [
|
||||
"Admin · Rust"
|
||||
],
|
||||
"summary": "Rename a chat-title category, or reset it",
|
||||
"description": "Sets the site’s own title for one category (D175): at most 24 characters, markup characters taken out as a rule’s are. An empty `text` resets the category to the module’s default. Every rule of this category with no text of its own shows the new title on every server from the next push; a rule that carries its own text keeps it. Answers the whole list.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "stat",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The category id, for example animalkills"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Saved; answers every category"
|
||||
},
|
||||
"400": {
|
||||
"description": "The title is too long, or only markup"
|
||||
},
|
||||
"404": {
|
||||
"description": "No such category"
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error"
|
||||
}
|
||||
},
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string",
|
||||
"maxLength": 24,
|
||||
"example": "Hunter"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/admin/rust/visibility": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -3506,12 +3589,37 @@
|
||||
"example": [
|
||||
"kills",
|
||||
"npckills",
|
||||
"animalkills",
|
||||
"bowkills",
|
||||
"meleekills",
|
||||
"bladekills",
|
||||
"revolverkills",
|
||||
"headshots",
|
||||
"pvpdistance",
|
||||
"pvedistance",
|
||||
"apckills",
|
||||
"helikills",
|
||||
"wood",
|
||||
"ore",
|
||||
"plants",
|
||||
"attire",
|
||||
"weapons",
|
||||
"built",
|
||||
"repaired",
|
||||
"healed",
|
||||
"rockets",
|
||||
"explosives",
|
||||
"missions",
|
||||
"playtime"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "The category the rule ranks (PLAN_REDESIGNS §5). `npckills` is human NPCs only (D209); `pvpdistance` and `pvedistance` rank the longest single kill; `playtime` has no default title."
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
"example": "kills"
|
||||
@@ -3552,7 +3660,7 @@
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "The title. `[`, `]`, `<`, `>`, `{` and `}` are taken out on save, so a title carries no markup of its own."
|
||||
"example": "The title. `[`, `]`, `<`, `>`, `{` and `}` are taken out on save, so a title carries no markup of its own. Empty means the category’s title (D175), except for `playtime`."
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
@@ -3583,6 +3691,122 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"RustTitleCategory": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "object"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "One chat-title category (PLAN_REDESIGNS §5.5, D175) and the title a rule of it shows when the rule has none of its own."
|
||||
},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"stat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
"example": "animalkills"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
"example": "Animal kills"
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "The module’s shipped title."
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
"example": "Beastbane"
|
||||
}
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"nullable": {
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "The admin’s own title for the whole site, or null."
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
"example": "Hunter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"current": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "What shows: `text` when set, else `default`."
|
||||
},
|
||||
"example": {
|
||||
"type": "string",
|
||||
"example": "Hunter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "string"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"example": "date-time"
|
||||
},
|
||||
"nullable": {
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"RustIntegrations": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user