feat(rust): NPC profile and placement routes, the event picker, triggers and titles (runicnpc stage 4)
Admin: /admin/rust/npcs for profiles (create, change, delete, restore a replaced one, push now) and each server's placements (list, add from a map point, change, remove, rename, respawn). Public: the profiles a leaderboard ranks by, one profile's ranking counted as the profile says (D247, D250), and one player's kills by profile (D252). Player: your own kills by profile. The Place NPCs step offers the site's profiles first, then Rust's own (D243). rust.npc.died and rust.npc.health are triggers a phase can wait on. A title rule can rank a profile's kills. Swagger fragment, engagement and route manifests regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
const core = require('../../core')
|
||||
|
||||
const links = require('../../model/links/links.model')
|
||||
const npcs = require('../../model/npcs/npcs.model')
|
||||
const npcsDb = require('../../model/npcs/npcs.db')
|
||||
const permissions = require('../../model/permissions/permissions.model')
|
||||
const servers = require('../../model/servers/servers.model')
|
||||
|
||||
@@ -36,6 +38,22 @@ async function listServers(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
/** GET /player/rust/npc-kills — the caller's kills of each NPC profile, current wipes (D252). */
|
||||
async function ownNpcKills(req, res) {
|
||||
try {
|
||||
const held = await links.listForUser(req.user.id)
|
||||
const rows = await npcsDb.ownKills(held.map((l) => String(l.steamId)).filter(Boolean))
|
||||
const labels = new Map()
|
||||
for (const serverId of new Set(rows.map((r) => r.serverId))) {
|
||||
for (const p of await npcs.boardProfiles(serverId)) labels.set(`${serverId} ${p.name}`, p.label)
|
||||
}
|
||||
res.json({ kills: rows.map((r) => ({ ...r, label: labels.get(`${r.serverId} ${r.profile}`) || r.profile })) })
|
||||
} catch (err) {
|
||||
log.error('failed to read a player’s NPC kills', { error: err.message })
|
||||
res.status(500).json({ message: 'Failed to read your NPC kills' })
|
||||
}
|
||||
}
|
||||
|
||||
/** GET /player/rust/links — the Steam accounts the caller holds. */
|
||||
async function listLinks(req, res) {
|
||||
try {
|
||||
@@ -168,4 +186,4 @@ async function listPermissions(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { listServers, listLinks, confirmLink, removeLink, listPermissions }
|
||||
module.exports = { listServers, listLinks, confirmLink, removeLink, listPermissions, ownNpcKills }
|
||||
|
||||
@@ -58,6 +58,15 @@ const linkLimiter = rateLimit({
|
||||
message: 'Too many link attempts. Please try again later.',
|
||||
})
|
||||
|
||||
playerRustRouter.get(
|
||||
'/npc-kills',
|
||||
// #swagger.tags = ['Player · Rust']
|
||||
// #swagger.summary = 'Your kills of each NPC profile'
|
||||
// #swagger.description = 'The caller’s kills of RunicNPC’s NPCs, by server and profile, in each server’s current wipe, across every Steam account they have linked (docs/runicnpc/PLAN.md stage 4, D252). Empty with no linked account. Requires a session.'
|
||||
/* #swagger.responses[200] = { description: 'The kills', content: { "application/json": { schema: { $ref: "#/components/schemas/RustNpcOwnKills" } } } } */
|
||||
rust.ownNpcKills,
|
||||
)
|
||||
|
||||
playerRustRouter.get(
|
||||
'/servers',
|
||||
// #swagger.tags = ['Player · Rust']
|
||||
|
||||
Reference in New Issue
Block a user