Mercurial > wow > breuesk
comparison 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 |
comparison
equal
deleted
inserted
replaced
104:9aa2dcbbdc87 | 105:c6c748a5823b |
---|---|
13 local getn=getn | 13 local getn=getn |
14 setfenv(1,bsk) | 14 setfenv(1,bsk) |
15 | 15 |
16 adminList = {} | 16 adminList = {} |
17 | 17 |
18 local lastZoneTime = 0 | |
19 local function ZoneChanged() | |
20 lastZoneTime = _G.time() | |
21 end | |
18 local function GuildRosterUpdate() | 22 local function GuildRosterUpdate() |
19 local guildInfoText = _G.GetGuildInfoText() | 23 local guildInfoText = _G.GetGuildInfoText() |
24 if lastZoneTime+5 > _G.time() then return end -- silly workaround - GGIT() returns "" when you zone in | |
20 local newAdminList = {} | 25 local newAdminList = {} |
21 for line in guildInfoText:gmatch("[^\r\n]+") do | 26 for line in guildInfoText:gmatch("[^\r\n]+") do |
22 local l,r = line:match("(.*):(.*)") -- could use wow strsplit had I known about it before writing this | 27 local l,r = line:match("(.*):(.*)") -- could use wow strsplit had I known about it before writing this |
23 l = string.trim(l or "") | 28 l = string.trim(l or "") |
24 r = string.trim(r or "") | 29 r = string.trim(r or "") |
65 end | 70 end |
66 | 71 |
67 function RemoteAdminUpdateReceived(sender,remoteAdminStatusTable) | 72 function RemoteAdminUpdateReceived(sender,remoteAdminStatusTable) |
68 if not admin then return end | 73 if not admin then return end |
69 | 74 |
70 local rs = remoteAdminStatusTable | 75 local rs,base,changes = unpack(remoteAdminStatusTable) |
71 local events = {} -- record all timestamps seen in this update | |
72 for i,_ in pairs(adminList) do -- update each admin's entry in your own DB | 76 for i,_ in pairs(adminList) do -- update each admin's entry in your own DB |
73 | 77 |
74 -- grab the db copy and the incoming copy for that admin | 78 if i ~= me then |
75 if not db.profile.adminStatus then db.profile.adminStatus = {} end | 79 -- grab the db copy and the incoming copy for that admin |
76 local dbs = db.profile.adminStatus[i] or {base=0, changes={}} | 80 if not db.profile.adminStatus then db.profile.adminStatus = {} end |
77 local ics = rs[i] or {base=0, changes={}} | 81 local dbs = db.profile.adminStatus[i] or {base=0, changes={}} |
78 | 82 local ics = rs[i] or {base=0, changes={}} |
79 -- figure out which is better and keep that one | 83 |
80 -- winning criteria: | 84 -- figure out which is better and keep that one |
81 -- * broadcast was actually from that person (ie best | 85 -- winning criteria: |
82 -- verification possible) | 86 -- * broadcast was actually from that person (ie best |
83 -- * newer base | 87 -- verification possible) |
84 -- * same base, more entries | 88 -- * newer base |
85 -- * todo: see if date last observed is a better option | 89 -- * same base, more entries |
86 | 90 -- * todo: see if date last observed is a better option |
87 if i==sender then | 91 |
88 db.profile.adminStatus[i] = ics | 92 if i==sender then |
89 elseif ics.base > dbs.base or (ics.base==dbs.base and getn(ics.changes) > getn(dbs.changes)) then | 93 db.profile.adminStatus[i] = ics |
90 db.profile.adminStatus[i] = ics | 94 elseif ics.base > dbs.base or (ics.base==dbs.base and getn(ics.changes) > getn(dbs.changes)) then |
91 end | 95 db.profile.adminStatus[i] = ics |
92 end | 96 end |
93 | 97 end |
94 local rss = rs[sender] | 98 end |
95 | 99 |
96 -- now figure out what I'm missing - and ask for it! | 100 if changes and getn(changes)>0 then |
97 | 101 IntegrateChangeDiff(base,changes) |
98 -- construct a hash table of all entries that the sender has / should have | 102 end |
99 local entries = {} | 103 |
100 for i,v in pairs(rs) do | 104 -- trim if the replies said it's safe |
101 if v.changes then | 105 |
102 for j,k in pairs(v.changes) do | 106 local trimPoint = db.profile.time |
103 entries[k.time] = true | 107 -- come up with a tentative starting point (max base) |
104 end | 108 for i,v in pairs(db.profile.adminStatus) do |
105 end | 109 if v.base > trimPoint then trimPoint = v.base end |
106 end | 110 end |
107 -- now go back and scrub my own keys from that list | 111 |
112 local pointer = {} | |
113 -- fast forward pointers *past* the trimPoint in each list | |
114 for p,l in pairs(db.profile.adminStatus) do | |
115 pointer[p] = 1 | |
116 for i,v in ipairs(l.changes) do | |
117 if v <= trimPoint then | |
118 pointer[p] = i+1 -- "past" the trim point - might point to nil | |
119 else | |
120 break | |
121 end | |
122 end | |
123 end | |
124 print("pointers") | |
125 PrintTable(pointer) | |
126 | |
108 for i,v in ipairs(db.profile.changes) do | 127 for i,v in ipairs(db.profile.changes) do |
109 entries[v.time] = nil | 128 if v.time > trimPoint then -- advance to the trim point estimate before doing anything |
110 end | 129 -- into uncharted territory, let's see how far we can push it |
111 -- what's left is what I need to ask for | 130 local continue = true |
112 local request = {} | 131 for p,t in pairs(pointer) do |
113 for i,v in pairs(entries) do | 132 local dbpapct = db.profile.adminStatus[p].changes[t] |
114 if v then table.insert(request,i) end | 133 if dbpapct and dbpapct==v.time then |
115 end | 134 pointer[p] = pointer[p]+1 |
116 table.sort(request) | 135 else |
117 Comm:RequestSpecificChanges(request,sender) | 136 continue=false |
118 | 137 break |
119 for | 138 end |
120 -- specifically leaving this broken. note to self. | 139 trimPoint = v.time |
121 -- this still isn't good enough. it doesn't communicate an admin's | 140 end |
122 -- present working state. like if they had put in new changes since | 141 if not continue then break end |
123 -- loading up. or learned of some changes to fill in an old gap | 142 end |
143 end | |
144 print("pointers") | |
145 PrintTable(pointer) | |
146 if trimPoint > db.profile.time then | |
147 | |
148 -- protect trimming back to beginning of previous month so we're not | |
149 -- trimming like madmen | |
150 local ct = _G.date("*t",_G.time()) | |
151 ct.month = ct.month-1 | |
152 if ct.month < 1 then ct.month = 12 end | |
153 ct.day = 1 | |
154 ct.hour = 1 | |
155 ct.minute = 0 | |
156 ct.sec = 0 | |
157 local ts = _G.time(ct) | |
158 print("I think I can trim to",trimPoint,ts) | |
159 TrimLists(ts) | |
160 else | |
161 print("no bother trimming",trimPoint) | |
162 end | |
124 end | 163 end |
125 | 164 |
126 function InitializeAdmin() | 165 function InitializeAdmin() |
127 if not event then | 166 if not event then |
128 _G.error("BSK: Improper order of initialization") | 167 _G.error("BSK: Improper order of initialization") |
151 onloadAdminStatus = {} | 190 onloadAdminStatus = {} |
152 db.profile.adminStatus = nil | 191 db.profile.adminStatus = nil |
153 end | 192 end |
154 | 193 |
155 event:RegisterEvent("GUILD_ROSTER_UPDATE",GuildRosterUpdate) | 194 event:RegisterEvent("GUILD_ROSTER_UPDATE",GuildRosterUpdate) |
195 event:RegisterEvent("ZONE_CHANGED_NEW_AREA",ZoneChanged) | |
196 event:RegisterEvent("ZONE_CHANGED_INDOORS",ZoneChanged) | |
197 event:RegisterEvent("ZONE_CHANGED",ZoneChanged) | |
156 _G.GuildRoster() -- will eventually force the event to fire | 198 _G.GuildRoster() -- will eventually force the event to fire |
157 | 199 |
158 if me == "Breuemama" then -- debugging only | 200 if me == "Breuemama" then -- debugging only |
159 GuildRosterUpdate() | 201 GuildRosterUpdate() |
160 end | 202 end |