feat(rust): NPC profiles and placements pages, the profile leaderboard (runicnpc stage 4)
Admin: Rust NPC profiles (the form RunicNPC reads, per server, shared or fleet, each server's push state and refusals, replaced profiles with Restore) and Rust NPC placements (the live map: click to place, pins for every placement; edit, rename, respawn, remove). The live map takes a pick handler and pins, unchanged for the public page. Public: the leaderboard ranks by a profile's kills (D250), and opening a row shows that player's kills by profile (D252); the killfeed names a RunicNPC NPC by its own name. Player: your own kills by profile. Titles: a rule on a profile's kills picks the profile. npcs.test.js covers the profile checks, adoption, the push, the picker and verb, the triggers, kill crediting, titles and placements (481 server tests). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -56,6 +56,15 @@ export const servers = {
|
||||
// gets; then what moves on it, already cut down to this viewer on the server.
|
||||
map: (id) => req(`/public/rust/servers/${encodeURIComponent(id)}/map`),
|
||||
mapLive: (id) => req(`/public/rust/servers/${encodeURIComponent(id)}/map/live`),
|
||||
|
||||
// RunicNPC (runicnpc stage 4). The profiles a leaderboard can rank by, one
|
||||
// profile's ranking counted as the profile says (D247, D250), and one
|
||||
// player's kills by profile, for an opened leaderboard row (D252).
|
||||
npcProfiles: (id) => req(`/public/rust/servers/${encodeURIComponent(id)}/npc-profiles`),
|
||||
npcLeaderboard: (id, { profile, wipe = null, limit = null } = {}) =>
|
||||
req(`/public/rust/servers/${encodeURIComponent(id)}/npc-leaderboard${query({ profile, wipe, limit })}`),
|
||||
npcKills: (id, steamId, { wipe = null } = {}) =>
|
||||
req(`/public/rust/servers/${encodeURIComponent(id)}/players/${encodeURIComponent(steamId)}/npc-kills${query({ wipe })}`),
|
||||
}
|
||||
|
||||
// One clan. Its roster comes back only for a viewer inside the operator's roster
|
||||
@@ -94,6 +103,11 @@ export const playerServers = {
|
||||
list: () => req('/player/rust/servers'),
|
||||
}
|
||||
|
||||
// Your own kills of each RunicNPC profile, current wipes, across your linked accounts (D252).
|
||||
export const playerNpcKills = {
|
||||
list: () => req('/player/rust/npc-kills'),
|
||||
}
|
||||
|
||||
// R1's identity link, from the signed-in player's side.
|
||||
//
|
||||
// **The code is the whole of what goes up.** The site has no idea which server
|
||||
@@ -220,6 +234,28 @@ export const adminZones = {
|
||||
remove: (id) => req(`/admin/rust/zones/presets/${encodeURIComponent(id)}`, { method: 'DELETE' }),
|
||||
}
|
||||
|
||||
// ── admin · NPCs (runicnpc stage 4) ─────────────────────────────────────────
|
||||
//
|
||||
// The site's RunicNPC profiles (per server, shared or fleet), pushed to each
|
||||
// server; and each server's placements, which live on the server (D222), so
|
||||
// every placement call is a live round trip that fails while the game is off.
|
||||
const npcServer = (serverId) => `/admin/rust/npcs/servers/${encodeURIComponent(serverId)}`
|
||||
export const adminNpcs = {
|
||||
read: () => req('/admin/rust/npcs'),
|
||||
create: (body) => req('/admin/rust/npcs/profiles', { method: 'POST', body }),
|
||||
update: (id, body) => req(`/admin/rust/npcs/profiles/${encodeURIComponent(id)}`, { method: 'PUT', body }),
|
||||
remove: (id) => req(`/admin/rust/npcs/profiles/${encodeURIComponent(id)}`, { method: 'DELETE' }),
|
||||
restore: (id) => req(`/admin/rust/npcs/profiles/${encodeURIComponent(id)}/restore`, { method: 'POST' }),
|
||||
push: (serverId) => req(`${npcServer(serverId)}/push`, { method: 'POST' }),
|
||||
placements: (serverId) => req(`${npcServer(serverId)}/placements`),
|
||||
place: (serverId, body) => req(`${npcServer(serverId)}/placements`, { method: 'POST', body }),
|
||||
setPlacement: (serverId, id, body) => req(`${npcServer(serverId)}/placements/${encodeURIComponent(id)}`, { method: 'PUT', body }),
|
||||
removePlacement: (serverId, id) => req(`${npcServer(serverId)}/placements/${encodeURIComponent(id)}`, { method: 'DELETE' }),
|
||||
renamePlacement: (serverId, id, to) =>
|
||||
req(`${npcServer(serverId)}/placements/${encodeURIComponent(id)}/rename`, { method: 'POST', body: { to } }),
|
||||
respawnPlacement: (serverId, id) => req(`${npcServer(serverId)}/placements/${encodeURIComponent(id)}/respawn`, { method: 'POST' }),
|
||||
}
|
||||
|
||||
// ── admin · mod configuration (R18) ───────────────────────────────────────
|
||||
//
|
||||
// Every call here is a LIVE round trip to a game host, which makes this the only
|
||||
@@ -301,6 +337,8 @@ export default {
|
||||
adminConfig,
|
||||
adminVisibility,
|
||||
adminZones,
|
||||
adminNpcs,
|
||||
playerNpcKills,
|
||||
adminUserLinks,
|
||||
adminUserPermissions,
|
||||
BASE,
|
||||
|
||||
Reference in New Issue
Block a user