comparison Lists.lua @ 8:b05fcb225c4a

player -> person fix trim bug when trimming all shortened IDs for persons list keys
author John@Yosemite-PC
date Wed, 07 Mar 2012 00:18:05 -0500
parents 241986f7066c
children daed0597deba
comparison
equal deleted inserted replaced
7:241986f7066c 8:b05fcb225c4a
41 -- ordering. Then the next 5, etc. 41 -- ordering. Then the next 5, etc.
42 -- 42 --
43 -- Handling conflicts: 43 -- Handling conflicts:
44 -- 44 --
45 45
46 -- todo: list-of-lists must not use int indices. those will lead to peril.
46 bsk.lists = {} 47 bsk.lists = {}
47 bsk.players = {} 48 bsk.persons = {}
48 49
49 local RaidList = {} 50 local raidList = {}
50 local ReserveList = {} 51 local reserveList = {}
51 local activeList = 0 -- temporary 52 local activeListKey = 1 -- temporary
53 local personsReverse = {}
52 54
53 local tinsert = table.insert 55 local tinsert = table.insert
54 local sformat = string.format 56 local sformat = string.format
55 local getn = table.getn 57 local getn = table.getn
56 58
75 bsk:PrintTable(bsk.lists) 77 bsk:PrintTable(bsk.lists)
76 end 78 end
77 function bsk:PrintChanges() 79 function bsk:PrintChanges()
78 bsk:PrintTable(bsk.db.profile.changes) 80 bsk:PrintTable(bsk.db.profile.changes)
79 end 81 end
80 function bsk:PrintPlayers() 82 function bsk:PrintPersons()
81 bsk:PrintTable(bsk.players) 83 bsk:PrintTable(bsk.persons)
82 end 84 end
83 function bsk:PrintTable(table, depth) 85 function bsk:PrintTable(table, depth)
84 depth = depth or "" 86 depth = depth or ""
85 if not table then return end 87 if not table then return end
86 for i,v in pairs(table) do 88 for i,v in pairs(table) do
100 end 102 end
101 103
102 --}}} 104 --}}}
103 105
104 function bsk:CreateWorkingStateFromChanges(changes) 106 function bsk:CreateWorkingStateFromChanges(changes)
105 local playerBase = self.db.profile.players 107 local personsBase = self.db.profile.persons
106 local listBase = self.db.profile.listBase 108 local listBase = self.db.profile.listBase
107 109
108 -- copy the base to the working state 110 -- copy the base to the working state
109 wipe(bsk.lists) 111 wipe(bsk.lists)
110 wipe(bsk.players) 112 wipe(bsk.persons)
113 wipe(personsReverse)
114
111 bsk:tcopy(bsk.lists,listBase) 115 bsk:tcopy(bsk.lists,listBase)
112 bsk:tcopy(bsk.players,playerBase) 116 bsk:tcopy(bsk.persons,personsBase)
113 117
114 -- now just go through the changes list applying each 118 -- now just go through the changes list applying each
115 for i,v in ipairs(changes) do 119 for i,v in ipairs(changes) do
116 bsk:ProcessChange(v) 120 bsk:ProcessChange(v)
117 end 121 end
173 -- timestamp check. Issue warnings for anyone with a clock that's more than 177 -- timestamp check. Issue warnings for anyone with a clock that's more than
174 -- X seconds out of sync with the others. Seriously, why isn't NTP a standard 178 -- X seconds out of sync with the others. Seriously, why isn't NTP a standard
175 -- setting on all operating systems ... 179 -- setting on all operating systems ...
176 180
177 function bsk:ProcessChange(change) 181 function bsk:ProcessChange(change)
178 if change.action == "AddPlayer" then 182 if change.action == "AddPerson" then
179 bsk:DoAddPlayer(change) 183 bsk:DoAddPerson(change)
180 elseif change.action == "CreateList" then 184 elseif change.action == "CreateList" then
181 bsk:DoCreateList(change) 185 bsk:DoCreateList(change)
182 elseif change.action == "AddPlayerToList" then 186 elseif change.action == "AddPersonToList" then
183 bsk:DoAddPlayerToList(change) 187 bsk:DoAddPersonToList(change)
184 elseif change.action == "SuicidePlayer" then 188 elseif change.action == "SuicidePerson" then
185 bsk:DoSuicidePlayer(change) 189 bsk:DoSuicidePerson(change)
186 else 190 else
187 bsk:Print("Unknown message encountered") 191 bsk:Print("Unknown message encountered")
188 bsk:PrintTable(change) 192 bsk:PrintTable(change)
189 assert(false) 193 assert(false)
190 end 194 end
206 -- routines. 210 -- routines.
207 -- 211 --
208 -- Note that "undo" has no special voodoo to it. It's basically a change that 212 -- Note that "undo" has no special voodoo to it. It's basically a change that
209 -- reverses the prior change on the stack. 213 -- reverses the prior change on the stack.
210 214
211 -- Players list 215 -- persons list
212 function bsk:DoAddPlayer(change) 216 function bsk:DoAddPerson(change)
213 assert(change) 217 assert(change)
214 assert(change.arg.guid) 218 assert(change.arg.id)
215 local arg = change.arg 219 local arg = change.arg
216 -- require admin 220 -- require admin
217 local players = bsk.players 221 local persons = bsk.persons
218 local name = arg.name 222 local name = arg.name
219 local guid = arg.guid 223 local id = arg.id
220 assert(players[guid]==nil) 224 assert(persons[id]==nil)
221 players[guid] = name 225 persons[id] = {main=name}
222 players.time=change.time 226 persons.time=change.time
227 personsReverse[name] = id
223 return true 228 return true
224 end 229 end
225 230
226 function bsk:AddPlayer(name) 231 function bsk:AddPerson(name)
227 local players = bsk.players 232 local persons = bsk.persons
228 local guid = UnitGUID(name) 233 local guid = UnitGUID(name)
229 -- TODO: check guid to be sure it's a player 234 -- TODO: check guid to be sure it's a player
230 if not guid then 235 if not guid then
231 self:Print(sformat("Could not add player %s - they must be in range or group",name)) 236 self:Print(sformat("Could not add player %s - they must be in range or group",name))
232 return 237 return
233 end 238 end
234 if players[guid] and players[guid] ~= name then 239 local id = string.sub(guid,6) -- skip at least 0x0580 ...
235 self:Print(sformat("Namechange detected for %s - new is %s, please rename the existing entry", players[guid], name)) 240 id = id:gsub("^0*(.*)","%1") -- nom all leading zeroes remaining
241
242 if persons[id] and persons[id] ~= name then
243 self:Print(sformat("Namechange detected for %s - new is %s, please rename the existing entry", persons[id], name))
236 return 244 return
237 end 245 end
238 if players[guid] ~= nil then 246 if persons[id] ~= nil then
239 self:Print(sformat("%s is already in the players list; disregarding", name)) 247 self:Print(sformat("%s is already in the persons list; disregarding", name))
240 return 248 return
241 end 249 end
242 local change = {action="AddPlayer",arg={name=name,guid=guid}} 250 local change = {action="AddPerson",arg={name=name,id=id}}
243 if bsk:DoAddPlayer(change) then 251 if bsk:DoAddPerson(change) then
244 bsk:CreateChange(change) 252 bsk:CreateChange(change)
245 end 253 end
246 end 254 end
247 255
248 function bsk:DoCreateList(change) 256 function bsk:DoCreateList(change)
266 if bsk:DoCreateList(change) then 274 if bsk:DoCreateList(change) then
267 bsk:CommitChange(change) 275 bsk:CommitChange(change)
268 end 276 end
269 end 277 end
270 278
271 function bsk:DoAddPlayerToList(change) 279 function bsk:DoAddPersonToList(change)
272 local listIndex = change.arg.listIndex 280 local listIndex = change.arg.listIndex
273 local slist = change.arg.slist 281 local slist = change.arg.slist
274 local list = bsk.lists[listIndex] 282 local list = bsk.lists[listIndex]
275 283
276 if #slist == 1 then -- end of list insertion - just one person 284 if #slist == 1 then -- end of list insertion - just one person
281 return false 289 return false
282 end 290 end
283 return true 291 return true
284 end 292 end
285 293
286 function bsk:AddPlayerToList(name,list) 294 function bsk:AddPersonToList(name,list)
287 -- require admin 295 -- require admin
288 local listIndex = bsk:GetListIndex(list) 296 local listIndex = bsk:GetListIndex(list)
289 local slist = {name} -- TODO: support adding to elsewhere besides the end 297 local id = personsReverse[name]
290 local change = {action="AddPlayerToList",arg={name=name,listIndex=listIndex,slist=slist}} 298 local slist = {id} -- TODO: support adding to elsewhere besides the end
299 local change = {action="AddPersonToList",arg={id=id,listIndex=listIndex,slist=slist}}
291 bsk:StartChange(change) 300 bsk:StartChange(change)
292 if bsk:DoAddPlayerToList(change) then 301 if bsk:DoAddPersonToList(change) then
293 bsk:CommitChange(change) 302 bsk:CommitChange(change)
294 end 303 end
295 end 304 end
296 305
297 function bsk:DoRemovePlayer(change) 306 function bsk:DoRemovePerson(change)
298 307
299 -- return true 308 -- return true
300 end 309 end
301 310
302 function bsk:RemovePlayer(name) 311 function bsk:RemovePerson(name)
303 -- from both players and lists 312 -- from both persons and lists
304 end 313 end
305 314
306 function bsk:DoSuicidePlayer(change) 315 function bsk:DoSuicidePerson(change)
307 local listIndex = change.arg.listIndex 316 local listIndex = change.arg.listIndex
308 local list = bsk.lists[listIndex] 317 local list = bsk.lists[listIndex]
309 local slist = shallowCopy(change.arg.list) 318 local slist = shallowCopy(change.arg.list)
310 -- the goal here is to rotate the suicide list by 1 319 -- the goal here is to rotate the suicide list by 1
311 -- then we can just mash it on top of the intersection between the original 320 -- then we can just mash it on top of the intersection between the original
326 --bsk:Print("After") 335 --bsk:Print("After")
327 --bsk:PrintTable(list) 336 --bsk:PrintTable(list)
328 return true 337 return true
329 end 338 end
330 339
331 function bsk:SuicidePlayer(name,list) 340 function bsk:SuicidePerson(name,list)
332 -- require admin 341 -- require admin
333 bsk:PopulateRaidList() 342 bsk:PopulateRaidList()
334 local listIndex = bsk:GetListIndex(list) 343 local listIndex = bsk:GetListIndex(list)
335 local slist=bsk:GetSuicideList(name,bsk.lists[listIndex]) 344 local slist=bsk:GetSuicideList(name,bsk.lists[listIndex])
336 local change = {action="SuicidePlayer",arg={names=names,list=slist,listIndex=listIndex}} 345 local change = {action="SuicidePerson",arg={names=names,list=slist,listIndex=listIndex}}
337 bsk:StartChange(change) 346 bsk:StartChange(change)
338 if bsk:DoSuicidePlayer(change) then 347 if bsk:DoSuicidePerson(change) then
339 bsk:CommitChange(change) 348 bsk:CommitChange(change)
340 end 349 end
341 end 350 end
342 351
343 function bsk:TrimLists(time) 352 function bsk:TrimLists(time)
363 372
364 -- apply first half 373 -- apply first half
365 bsk:CreateWorkingStateFromChanges(before) 374 bsk:CreateWorkingStateFromChanges(before)
366 375
367 -- save this state permanently; trim the changes permanently 376 -- save this state permanently; trim the changes permanently
368 bsk:tcopy(bsk.db.profile.players,bsk.players) 377 bsk:tcopy(bsk.db.profile.persons,bsk.persons)
369 bsk:tcopy(bsk.db.profile.listBase,bsk.lists) 378 bsk:tcopy(bsk.db.profile.listBase,bsk.lists)
370 while bsk.db.profile.changes[1].time <= time do 379 while bsk.db.profile.changes ~= nil and bsk.db.profile.changes[1] ~= nil and bsk.db.profile.changes[1].time <= time do
371 table.remove(bsk.db.profile.changes,1) 380 table.remove(bsk.db.profile.changes,1)
372 end 381 end
373 382
374 -- using the trimmed list and the new bases, recreate the working state 383 -- using the trimmed list and the new bases, recreate the working state
375 bsk:CreateWorkingStateFromChanges(bsk.db.profile.changes) 384 bsk:CreateWorkingStateFromChanges(bsk.db.profile.changes)
376 end 385 end
377 386
378 --}}} 387 --}}}
379 -- Higher order actions (ie calls other Doers){{{ 388 -- Higher order actions (ie calls other Doers){{{
380 function bsk:AddMissingPlayers() 389 function bsk:AddMissingPersons()
381 bsk:PopulateRaidList() 390 bsk:PopulateRaidList()
382 local t = {} 391 local t = {}
383 for i,v in pairs(bsk.players) do 392 for _,v in pairs(bsk.persons) do
384 t[v] = true 393 t[v.main] = true
385 end 394 -- TODO: also add alts here
386 for i,v in pairs(RaidList) do 395 end
396 for i,_ in pairs(raidList) do
387 if t[i] == nil then 397 if t[i] == nil then
388 bsk:Print(sformat("Player %s is missing from the players list - adding",i)) 398 bsk:Print(sformat("Person %s is missing from the persons list - adding",i))
389 bsk:AddPlayer(i) 399 bsk:AddPerson(i)
390 end 400 end
391 end 401 end
392 -- TODO: batch into a single op - no need to spam 25 messages in a row 402 -- TODO: batch into a single op - no need to spam 25 messages in a row
393 end 403 end
394 function bsk:PopulateListRandom(index) 404 function bsk:PopulateListRandom(index)
396 bsk:PopulateRaidList() 406 bsk:PopulateRaidList()
397 local list = bsk.lists[index] 407 local list = bsk.lists[index]
398 408
399 local t = {} 409 local t = {}
400 --for i = 1,#list do 410 --for i = 1,#list do
401 -- if not (RaidList(list[i]) or ReserveList(list[i])) then 411 -- if not (raidList(list[i]) or reserveList(list[i])) then
402 -- tinsert(t,) 412 -- tinsert(t,)
403 -- end 413 -- end
404 --end 414 --end
405 end 415 end
406 --}}} 416 --}}}
407 417
408 -- "Soft" actions- ie things that cause nonpermanent state {{{ 418 -- "Soft" actions- ie things that cause nonpermanent state {{{
409 419
410 -- reserves 420 -- reserves
411 function bsk:AddReserve(name) 421 function bsk:AddReserve(name)
412 ReserveList[name]=true 422 reserveList[name]=true
413 -- TODO: communicate to others. don't store this in any way. 423 -- TODO: communicate to others. don't store this in any way.
414 end 424 end
415 425
416 function bsk:RemoveReserve(name) 426 function bsk:RemoveReserve(name)
417 ReserveList[name]=false 427 reserveList[name]=false
418 -- TODO: communicate to others. don't store this in any way. 428 -- TODO: communicate to others. don't store this in any way.
419 end 429 end
420 430
421 431
422 --function bsk:GetActiveList() 432 --function bsk:GetActiveList()
437 end 447 end
438 function bsk:PopulateRaidList() 448 function bsk:PopulateRaidList()
439 local inParty = GetNumPartyMembers() 449 local inParty = GetNumPartyMembers()
440 local inRaid = GetNumRaidMembers() 450 local inRaid = GetNumRaidMembers()
441 451
442 wipe(RaidList) 452 wipe(raidList)
443 if inRaid > 0 then 453 if inRaid > 0 then
444 for i = 1, inRaid do 454 for i = 1, inRaid do
445 RaidList[UnitName(rID[i])]=true 455 raidList[UnitName(rID[i])]=true
446 end 456 end
447 elseif inParty > 0 then 457 elseif inParty > 0 then
448 for i = 1, inParty do 458 for i = 1, inParty do
449 RaidList[UnitName(pID[i])]=true 459 raidList[UnitName(pID[i])]=true
450 end 460 end
451 -- Now add yourself as the last party member 461 -- Now add yourself as the last party member
452 RaidList[UnitName("player")]=true 462 raidList[UnitName("player")]=true
453 else 463 else
454 -- You're alone 464 -- You're alone
455 RaidList[UnitName("player")]=true 465 raidList[UnitName("player")]=true
456 end 466 end
457 end 467 end
458 468
459 -- undo rules! 469 -- undo rules!
460 -- only the most recent event can be undone 470 -- only the most recent event can be undone
473 local pushing = false 483 local pushing = false
474 for i = 1, #list do 484 for i = 1, #list do
475 if list[i] == name then 485 if list[i] == name then
476 pushing = true 486 pushing = true
477 end 487 end
478 if pushing and (RaidList[list[i]] or ReserveList[list[i]]) then 488 if pushing and (raidList[list[i]] or reserveList[list[i]]) then
479 tinsert(ret,list[i]) 489 tinsert(ret,list[i])
480 end 490 end
481 end 491 end
482 return ret 492 return ret
483 end 493 end