Files
P42_godDaemons/GPS/arenaAgentLoader.js
T

83 lines
2.7 KiB
JavaScript

export class ArenaAgentLoader {
constructor(arenaCnx, arenaStorage, debug = false) {
this.cnx = arenaCnx
this.arenaStorage = arenaStorage
this.debug = debug
}
async loadAgents(expectedIds = null) {
// TODO: when arena mesh is sharded, iterate all arena Redis connections and merge agent ids
const agentIds = await this.#listAgentIds(expectedIds)
const agents = []
const errors = []
for(const agentId of agentIds) {
const result = await this.#loadAgentFromHash(agentId)
if(!result.ok) {
errors.push(result.err)
continue
}
agents.push(result.agent)
}
if(errors.length) return({ ok: false, err: errors.join('; '), agents: [] })
return({ ok: true, agents })
}
#parseHashField(raw) {
if(raw == null) return(null)
if(typeof(raw) === 'object') return(raw)
try { return(JSON.parse(raw)) }
catch { return(null) }
}
#isVector(v) {
return(
v &&
typeof(v) === 'object' &&
typeof(v.x) === 'number' &&
typeof(v.y) === 'number' &&
typeof(v.z) === 'number'
)
}
async #listAgentIds(expectedIds = null) {
if(Array.isArray(expectedIds) && expectedIds.length) return([...expectedIds])
return(await this.cnx.redisSmembers(this.arenaStorage.agentsIndexKey))
}
async #loadAgentFromHash(agentId) {
const key = this.arenaStorage.agentHashKey.replace(/\[UID\]/g, agentId)
const positionRaw = await this.cnx.redisHget(key, 'position')
const vectorRaw = await this.cnx.redisHget(key, 'vector')
let position = this.#parseHashField(positionRaw)
let vector = this.#parseHashField(vectorRaw)
if(!this.#isVector(vector)) {
const segmentRaw = await this.cnx.redisHget(key, 'segment')
const segment = this.#parseHashField(segmentRaw)
if(segment) {
if(!this.#isVector(vector) && this.#isVector(segment.vector)) vector = segment.vector
if(!this.#isVector(position) && this.#isVector(segment.position)) position = segment.position
}
}
if(!this.#isVector(vector)) return({ ok: false, err: `Invalid or missing vector for ${agentId}` })
if(!this.#isVector(position)) position = { x: 0, y: 0, z: 0 }
return({
ok: true,
agent: {
id: agentId,
position: { ...position },
vector: { ...vector },
since: 0,
generation: 1,
},
})
}
}