Add native gameplay outcomes, recovery verification, and realm diagnostics
Core tests / core (push) Successful in 40s

This commit is contained in:
Codex
2026-09-22 21:18:32 -04:00
parent 9d586f4c44
commit 290926f33f
18 changed files with 264 additions and 21 deletions
+36
View File
@@ -0,0 +1,36 @@
-- Bounded native gameplay counters. Flush once a minute, never per loot item.
AuthDBExecute([[CREATE TABLE IF NOT EXISTS azerothai_outcomes (
guid INT UNSIGNED PRIMARY KEY,quests INT UNSIGNED NOT NULL DEFAULT 0,
abandoned INT UNSIGNED NOT NULL DEFAULT 0,loot_events INT UNSIGNED NOT NULL DEFAULT 0,
loot_items INT UNSIGNED NOT NULL DEFAULT 0,party_kills INT UNSIGNED NOT NULL DEFAULT 0,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)]])
local pending={}
local function add(p,key,amount)
if not p:IsPlayerbot() then return end
local guid=p:GetGUIDLow()
local row=pending[guid] or {quests=0,abandoned=0,loot_events=0,loot_items=0,party_kills=0}
row[key]=row[key]+(amount or 1);pending[guid]=row
end
RegisterPlayerEvent(54,function(_,p) add(p,'quests') end)
RegisterPlayerEvent(38,function(_,p) add(p,'abandoned') end)
RegisterPlayerEvent(32,function(_,p,item,count) add(p,'loot_events');add(p,'loot_items',count) end)
RegisterPlayerEvent(7,function(_,p,killed)
if not p:IsPlayerbot() then return end
local g=p:GetGroup();if not g then return end
for _,other in pairs(g:GetMembers()) do
if other~=p and other:IsPlayerbot() and not other:IsDead() and other:IsInCombat()
and other:GetVictim() and other:GetVictim():GetGUID()==killed:GetGUID() and p:GetDistance(other)<=35 then
add(p,'party_kills');break
end
end
end)
local function flush()
for guid,r in pairs(pending) do
AuthDBExecute('INSERT INTO azerothai_outcomes(guid,quests,abandoned,loot_events,loot_items,party_kills) VALUES ('..guid..','..r.quests..','..r.abandoned..','..r.loot_events..','..r.loot_items..','..r.party_kills..') ON DUPLICATE KEY UPDATE quests=quests+VALUES(quests),abandoned=abandoned+VALUES(abandoned),loot_events=loot_events+VALUES(loot_events),loot_items=loot_items+VALUES(loot_items),party_kills=party_kills+VALUES(party_kills),updated_at=NOW()')
end
pending={}
end
CreateLuaEvent(flush,60000,0)
-- Native profiler JSON is generated every five minutes; enabling it is an operator setting.
CreateLuaEvent(function()RunCommand('playerbots pmon tick')end,300000,0)
PrintInfo('[AzerothAI] Gameplay counters enabled; one-minute flush, five-minute profiler export')
+22 -1
View File
@@ -1,6 +1,6 @@
-- Conservative recovery for managed residents with fresh quest/explore intent.
-- Native position/progress is sampled independently of dashboard summaries.
local intents, observations = {}, {}
local intents, observations, pendingResults = {}, {}, {}
local LIMIT = 600
local COOLDOWN = 1800
local function sqltext(s)
@@ -10,6 +10,25 @@ AuthDBExecute([[CREATE TABLE IF NOT EXISTS azerothai_recovery_log (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,guid INT UNSIGNED NOT NULL,
name VARCHAR(64) NOT NULL,at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
detail VARCHAR(255) NOT NULL,INDEX(guid,at))]])
AuthDBExecute([[CREATE TABLE IF NOT EXISTS azerothai_recovery_results (
attempt_id BIGINT UNSIGNED PRIMARY KEY,status VARCHAR(24) NOT NULL,
checked_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,detail VARCHAR(255) NOT NULL)]])
local function checkResults(now)
for guid,r in pairs(pendingResults) do
local p=GetPlayerByName(r.name);local status,detail
if not p or not p:IsPlayerbot() or p:GetGUIDLow()~=guid or p:GetAccountId()~=r.account or p:IsDead() then
status='unverified';detail='Resident unavailable before verification'
elseif p:GetMapId()~=r.map or p:GetLevel()~=r.level or (p:GetX()-r.x)^2+(p:GetY()-r.y)^2+(p:GetZ()-r.z)^2>25 then
status='resumed';detail='Native movement or level progress observed after recovery'
elseif now-r.at>=180 then
status='no_progress';detail='No movement or level progress observed within three minutes'
end
if status then
AuthDBExecute('INSERT IGNORE INTO azerothai_recovery_results(attempt_id,status,detail) SELECT id,'..sqltext(status)..','..sqltext(detail)..' FROM azerothai_recovery_log WHERE guid='..guid..' AND UNIX_TIMESTAMP(at)='..r.at..' ORDER BY id DESC LIMIT 1')
pendingResults[guid]=nil
end
end
end
function AzerothAISetRecoveryIntents(rows)
local nextIntents={}
for _,r in ipairs(rows) do
@@ -31,6 +50,7 @@ local function safe(p,a)
end
local function sample()
local now=os.time()
checkResults(now)
for guid,r in pairs(intents) do
local p=GetPlayerByName(r.name)
if now-r.at>120 or not p or not p:IsPlayerbot() or p:GetGUIDLow()~=guid or p:GetAccountId()~=r.account then
@@ -55,6 +75,7 @@ local function sample()
local moved=a:DoSpecificAction('move random',true)
local detail=(staleFlight and 'Cleared stale flight; ' or '')..'AI replanned; walking request='..tostring(moved)
AuthDBExecute('INSERT INTO azerothai_recovery_log(guid,name,detail) VALUES ('..guid..','..sqltext(r.name)..','..sqltext(detail)..')')
pendingResults[guid]={name=r.name,account=r.account,at=now,x=x,y=y,z=z,map=map,level=level}
PrintInfo('[AzerothAI recovery] '..r.name..': '..detail)
end
old.since=now