fix(rust): the last fixes' small ones (W3 W6 W7/W11 W8 W10 W13-W18)
Stage 2 of PLAN_LAST_FIXES (docs#366). - W7/W11: an "is it loaded" refusal is confirmed live before it is given. New liveStatus.js asks the sidecar once (boot.refreshOne, as a poll tick would), at most once per server per 5 s and waiting at most 3 s, then reads the stored status again. Used by Economics (step and staff page), Backpacks, Dangerous Treasures, Guarded Crate, RaidableBases, ZoneDomes, TruePVE and RunicNPC. - W3: a world call answered `already-out` (the bridge half comes in stage 3) succeeds as called 0, saying a Travelling Vendor is already out. - W6: "A locked crate dropped by a Chinook is being hacked." - W8: a RaidableBases profile's audit row names RaidableBases, not "@data". - W10: the backpack sizes picker lists each size once, naming its servers. - W13: a RaidableBases name both servers describe differently shows each server's own description. - W14: each RaidableBases note after the first starts its own sentence. - W15: a staff deposit refused at Economics' limit answers 409. - W16: a payment's failedNote explains only the reasons that happened. - W17: the sync state counts player grants that did not land (waitingToLand), and the Permissions page says "in sync · 1 waits for their player to join" instead of plain "in sync". - W18: Guarded Crate's kept note drops the "30 minutes" it could not know. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -43,6 +43,7 @@ const { serverFor, transportError, pluginError } = require('./eventLeases')
|
||||
const { BUDGET_MS, location, revert, reconcile } = require('./eventWorld')
|
||||
const { gridOf } = require('./worldEvents')
|
||||
const { reportOf, helperPatched } = require('./raidableBases')
|
||||
const live = require('./liveStatus')
|
||||
const serversDb = require('./model/servers/servers.db')
|
||||
const mapDb = require('./model/map/map.db')
|
||||
|
||||
@@ -107,10 +108,19 @@ function byValue(entries) {
|
||||
const out = new Map()
|
||||
for (const { value, label, server } of entries) {
|
||||
const key = value.toLowerCase()
|
||||
if (!out.has(key)) out.set(key, { value, label, servers: [] })
|
||||
if (!out.get(key).servers.includes(server)) out.get(key).servers.push(server)
|
||||
if (!out.has(key)) out.set(key, { value, labels: new Map() })
|
||||
// Labels compare ignoring case, as the names do.
|
||||
const labels = out.get(key).labels
|
||||
const said = label.toLowerCase()
|
||||
if (!labels.has(said)) labels.set(said, { label, servers: [] })
|
||||
if (!labels.get(said).servers.includes(server)) labels.get(said).servers.push(server)
|
||||
}
|
||||
return [...out.values()].map((e) => ({ value: e.value, label: `${e.label} — ${e.servers.join(', ')}` }))
|
||||
// One name, one row. Where servers describe it differently (a profile Hard on
|
||||
// one and Expert on another), each server's own words, not the first's (W13).
|
||||
return [...out.values()].map((e) => ({
|
||||
value: e.value,
|
||||
label: [...e.labels.values()].map(({ label, servers }) => `${label} — ${servers.join(', ')}`).join('; '),
|
||||
}))
|
||||
}
|
||||
|
||||
const OPTION_SOURCES = [
|
||||
@@ -371,8 +381,15 @@ const raidSpawn = {
|
||||
if (!found.ok) return found
|
||||
const name = found.server.name || found.server.id
|
||||
|
||||
const report = reportOf(await serversDb.rbReportFor(found.server.id).catch(() => null))
|
||||
const missing = missingOn(report, name, parsed.wire, parsed.spot)
|
||||
// Confirmed live before it refuses: the stored status lags a restart (W7).
|
||||
const { report, missing } = await live.confirmed(
|
||||
found.server,
|
||||
async () => {
|
||||
const read = reportOf(await serversDb.rbReportFor(found.server.id).catch(() => null))
|
||||
return { report: read, missing: missingOn(read, name, parsed.wire, parsed.spot) }
|
||||
},
|
||||
(r) => Boolean(r.missing),
|
||||
)
|
||||
if (missing) return { ok: false, retry: false, error: missing }
|
||||
|
||||
if (verify) {
|
||||
@@ -421,7 +438,8 @@ const raidSpawn = {
|
||||
if (data.repeat) notes.push('answered from the first attempt; nothing new was spawned')
|
||||
if (data.x === undefined) notes.push('RaidableBases picks the spot; the map shows it once the base opens')
|
||||
if (data.despawns !== 'teardown') notes.push(OWN_TIMER)
|
||||
if (notes.length) detail.note = notes.join('. ')
|
||||
// Each note after the first starts a sentence (W14).
|
||||
if (notes.length) detail.note = notes.map((n, i) => (i ? n[0].toUpperCase() + n.slice(1) : n)).join('. ')
|
||||
|
||||
// Only a base the helper made the run's is a resource teardown can take back.
|
||||
if (!data.id) return { ok: true, detail }
|
||||
|
||||
Reference in New Issue
Block a user