Mercurial > wow > breuesk
diff Admin.lua @ 105:c6c748a5823b tip
Collaborative list trimming 80% functional
Updates for the zone-in problem
author | John@Yosemite-PC |
---|---|
date | Sun, 06 May 2012 08:33:34 -0400 |
parents | d3ea0ab1428d |
children |
line wrap: on
line diff
--- a/Admin.lua Sun May 06 08:30:15 2012 -0400 +++ b/Admin.lua Sun May 06 08:33:34 2012 -0400 @@ -15,8 +15,13 @@ adminList = {} +local lastZoneTime = 0 +local function ZoneChanged() + lastZoneTime = _G.time() +end local function GuildRosterUpdate() local guildInfoText = _G.GetGuildInfoText() + if lastZoneTime+5 > _G.time() then return end -- silly workaround - GGIT() returns "" when you zone in local newAdminList = {} for line in guildInfoText:gmatch("[^\r\n]+") do local l,r = line:match("(.*):(.*)") -- could use wow strsplit had I known about it before writing this @@ -67,60 +72,94 @@ function RemoteAdminUpdateReceived(sender,remoteAdminStatusTable) if not admin then return end - local rs = remoteAdminStatusTable - local events = {} -- record all timestamps seen in this update + local rs,base,changes = unpack(remoteAdminStatusTable) for i,_ in pairs(adminList) do -- update each admin's entry in your own DB - -- grab the db copy and the incoming copy for that admin - if not db.profile.adminStatus then db.profile.adminStatus = {} end - local dbs = db.profile.adminStatus[i] or {base=0, changes={}} - local ics = rs[i] or {base=0, changes={}} + if i ~= me then + -- grab the db copy and the incoming copy for that admin + if not db.profile.adminStatus then db.profile.adminStatus = {} end + local dbs = db.profile.adminStatus[i] or {base=0, changes={}} + local ics = rs[i] or {base=0, changes={}} - -- figure out which is better and keep that one - -- winning criteria: - -- * broadcast was actually from that person (ie best - -- verification possible) - -- * newer base - -- * same base, more entries - -- * todo: see if date last observed is a better option + -- figure out which is better and keep that one + -- winning criteria: + -- * broadcast was actually from that person (ie best + -- verification possible) + -- * newer base + -- * same base, more entries + -- * todo: see if date last observed is a better option - if i==sender then - db.profile.adminStatus[i] = ics - elseif ics.base > dbs.base or (ics.base==dbs.base and getn(ics.changes) > getn(dbs.changes)) then - db.profile.adminStatus[i] = ics + if i==sender then + db.profile.adminStatus[i] = ics + elseif ics.base > dbs.base or (ics.base==dbs.base and getn(ics.changes) > getn(dbs.changes)) then + db.profile.adminStatus[i] = ics + end end end - local rss = rs[sender] + if changes and getn(changes)>0 then + IntegrateChangeDiff(base,changes) + end - -- now figure out what I'm missing - and ask for it! + -- trim if the replies said it's safe - -- construct a hash table of all entries that the sender has / should have - local entries = {} - for i,v in pairs(rs) do - if v.changes then - for j,k in pairs(v.changes) do - entries[k.time] = true + local trimPoint = db.profile.time + -- come up with a tentative starting point (max base) + for i,v in pairs(db.profile.adminStatus) do + if v.base > trimPoint then trimPoint = v.base end + end + + local pointer = {} + -- fast forward pointers *past* the trimPoint in each list + for p,l in pairs(db.profile.adminStatus) do + pointer[p] = 1 + for i,v in ipairs(l.changes) do + if v <= trimPoint then + pointer[p] = i+1 -- "past" the trim point - might point to nil + else + break end end end - -- now go back and scrub my own keys from that list + print("pointers") + PrintTable(pointer) + for i,v in ipairs(db.profile.changes) do - entries[v.time] = nil + if v.time > trimPoint then -- advance to the trim point estimate before doing anything + -- into uncharted territory, let's see how far we can push it + local continue = true + for p,t in pairs(pointer) do + local dbpapct = db.profile.adminStatus[p].changes[t] + if dbpapct and dbpapct==v.time then + pointer[p] = pointer[p]+1 + else + continue=false + break + end + trimPoint = v.time + end + if not continue then break end + end end - -- what's left is what I need to ask for - local request = {} - for i,v in pairs(entries) do - if v then table.insert(request,i) end + print("pointers") + PrintTable(pointer) + if trimPoint > db.profile.time then + + -- protect trimming back to beginning of previous month so we're not + -- trimming like madmen + local ct = _G.date("*t",_G.time()) + ct.month = ct.month-1 + if ct.month < 1 then ct.month = 12 end + ct.day = 1 + ct.hour = 1 + ct.minute = 0 + ct.sec = 0 + local ts = _G.time(ct) + print("I think I can trim to",trimPoint,ts) + TrimLists(ts) + else + print("no bother trimming",trimPoint) end - table.sort(request) - Comm:RequestSpecificChanges(request,sender) - - for - -- specifically leaving this broken. note to self. - -- this still isn't good enough. it doesn't communicate an admin's - -- present working state. like if they had put in new changes since - -- loading up. or learned of some changes to fill in an old gap end function InitializeAdmin() @@ -153,6 +192,9 @@ end event:RegisterEvent("GUILD_ROSTER_UPDATE",GuildRosterUpdate) + event:RegisterEvent("ZONE_CHANGED_NEW_AREA",ZoneChanged) + event:RegisterEvent("ZONE_CHANGED_INDOORS",ZoneChanged) + event:RegisterEvent("ZONE_CHANGED",ZoneChanged) _G.GuildRoster() -- will eventually force the event to fire if me == "Breuemama" then -- debugging only