view Admin.lua @ 102:21567b74fcc7

Notes and corrections
author John@Doomsday
date Thu, 03 May 2012 09:05:24 -0400
parents 5914125bb4ea
children d3ea0ab1428d
line wrap: on
line source
local bsk=bsk
local _G=_G
local table=table 
local pairs=pairs
local setmetatable=setmetatable
local ipairs=ipairs
local string=string
local sformat=string.format
local strsplit=strsplit
local tostring=tostring
local type=type
local unpack=unpack
local getn=getn
setfenv(1,bsk)

adminList = {}

local function GuildRosterUpdate()
    local guildInfoText = _G.GetGuildInfoText()
    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
        l = string.trim(l or "")
        r = string.trim(r or "")
        if l == "BSKADMIN" then -- found a juicy line. may contain multiple, comma or space delimited
            local admins = {strsplit(", ",r)}
            for _,a in pairs(admins) do
                a = string.trim(a or "")
                if a ~= "" then
                    newAdminList[a] = true
                end
            end
        end
    end

    if _G.next(adminList) ~= nil then -- had old admins. don't want to spam on initial load
        -- diff new vs old
        for a in pairs(adminList) do
            if not newAdminList[a] then
                print("Admin removed:", a)
            end
        end
        for a in pairs(newAdminList) do
            if not adminList[a] then
                print("Admin added:",a)
            end
        end
    end
    adminList = newAdminList

    if adminList[_G.UnitName("player")] then -- I'm an admin!
        admin = true
        bsk.db.profile.admin = true
        RegisterAdminChannels()
    else
        admin = false
        bsk.db.profile.admin = false
        UnregisterAdminChannels()
    end
end

function RemoteAdminUpdateReceived(sender,remoteAdminStatusTable)
    if not admin then return end

    local rs = 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
        local dbs = db.profile.adminStatus[i] or {}
        local ics = packet[i] or {}

        -- 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
        end
    end
end

function InitializeAdmin()
    if not event then
        _G.error("BSK: Improper order of initialization")
    end

    if admin then -- if at last login I was an admin ...

        -- note that we're not transmitting anything here. we'll do that once we
        -- know for certain we're an admin

        -- cache the onload status in case it changes in memory later
        onloadAdminStatus = {}
        tcopy(onloadAdminStatus,db.profile.adminStatus)

        -- update our own entry - safe because comms shouldn't have happened yet
        me = _G.UnitName("player")
        if not onloadAdminStatus then onloadAdminStatus = {} end
        if not onloadAdminStatus[me] then onloadAdminStatus[me] = {} end
        onloadAdminStatus[me].base = db.profile.time or 0
        onloadAdminStatus[me].changes= {}
        for _,v in ipairs(db.profile.changes) do
            table.insert(onloadAdminStatus[me].changes,v.time) -- only timestamps
        end

    else -- otherwise store a blank slate
        onloadAdminStatus = {}
        db.profile.adminStatus = nil
    end

    
    event:RegisterEvent("GUILD_ROSTER_UPDATE",GuildRosterUpdate)
    _G.GuildRoster() -- will eventually force the event to fire
end