Reconcile dashboard online presence against complete live roster
This commit is contained in:
+23
-5
@@ -72,6 +72,24 @@ function observedHardcoreDeath(s:State,b:Bot,observation:Observation){
|
||||
export async function applyAuthoritativeAleEvent(store:StateStore,kind:string,payload:Record<string,unknown>){
|
||||
let s=await store.load();
|
||||
const revision=s.revision;
|
||||
// Complete world snapshots own presence once available; historical events
|
||||
// must never bring disconnected residents back online.
|
||||
if(kind==='player.snapshot' && payload.roster===true){
|
||||
const at=payload.observedAt;
|
||||
const guids=payload.characterGuids;
|
||||
if(typeof at!=='number'||!Number.isFinite(at)||!Array.isArray(guids)||!guids.every(g=>Number.isInteger(g)&&g>0))throw new Error('Invalid authoritative roster');
|
||||
if(at<=(s.aleRosterAt??0))return {matched:false,stale:true};
|
||||
const online=new Set(guids);
|
||||
for(const bot of s.bots){
|
||||
if(bot.status==='dead'||bot.status==='retired')continue;
|
||||
const present=bot.autonomy?.managed && online.has(bot.autonomy.characterGuid);
|
||||
bot.status=present?'online':'offline';
|
||||
bot.simulationBand=present?'background':'dormant';
|
||||
}
|
||||
s.aleRosterAt=at;
|
||||
await store.save(s,revision);
|
||||
return {matched:true,roster:true};
|
||||
}
|
||||
if(kind==='bridge.ready'){
|
||||
let changed=false;
|
||||
for(const bot of s.bots){
|
||||
@@ -103,7 +121,7 @@ export async function applyAuthoritativeAleEvent(store:StateStore,kind:string,pa
|
||||
const isZaku=name.toLowerCase()==='zaku';
|
||||
b={
|
||||
id:isZaku?'hero-zaku':`live-${crypto.randomUUID()}`,
|
||||
name,role,race,level,zone,status:'online',
|
||||
name,role,race,level,zone,status:s.aleRosterAt?'offline':'online',
|
||||
tier:isZaku?'hero':'resident',mortal:true,plotArmorHpFloor:isZaku?1:0,
|
||||
simulationBand:'background',
|
||||
routine:{wakeHour:isZaku?10:7,sleepHour:isZaku?3:23,preferredZones:[zone]},
|
||||
@@ -137,19 +155,19 @@ export async function applyAuthoritativeAleEvent(store:StateStore,kind:string,pa
|
||||
if(zone)b.zone=zone;
|
||||
|
||||
if(kind==='player.login'){
|
||||
b.status='online';
|
||||
if(!s.aleRosterAt)b.status='online';
|
||||
b.simulationBand='foreground';
|
||||
event(s,'lifecycle',`${b.name} logged into the authoritative AzerothCore world.`,b.id);
|
||||
}else if(kind==='player.logout'){
|
||||
b.status='offline';
|
||||
if(!s.aleRosterAt)b.status='offline';
|
||||
b.simulationBand='dormant';
|
||||
event(s,'lifecycle',`${b.name} logged out of the authoritative AzerothCore world.`,b.id);
|
||||
}else if(kind==='player.zone'||kind==='player.map'){
|
||||
if(b.status==='offline')b.status='online';
|
||||
if(!s.aleRosterAt&&b.status==='offline')b.status='online';
|
||||
b.simulationBand='foreground';
|
||||
event(s,'lifecycle',`${b.name} is now in ${b.zone} (authoritative ALE observation).`,b.id);
|
||||
}else if(kind==='player.snapshot'){
|
||||
if(b.status==='offline')b.status='online';
|
||||
if(!s.aleRosterAt&&b.status==='offline')b.status='online';
|
||||
if(b.simulationBand==='dormant')b.simulationBand='background';
|
||||
}else if(kind==='player.level'){
|
||||
const text=`I reached level ${b.level} while living in ${b.zone}.`;
|
||||
|
||||
Reference in New Issue
Block a user