ESOUI SVN TaosGroupInvite

[/] [trunk/] [TaosGroupInvite/] [logic/] [InviteHandler.lua] - Rev 8

Compare with Previous | Blame | View Log

--[[
        Addon: Taos Group Invite
        Author: TProg Taonnor
        Created by @Taonnor
]]--

--[[
        Local variables
]]--
local LOG_ACTIVE = true
local _logger = nil

local REFRESHRATE = 1000 -- ms; RegisterForUpdate is in miliseconds

--[[
        Table TGI_InviteHandler
]]--
TGI_InviteHandler = {}
TGI_InviteHandler.__index = TGI_InviteHandler

--[[
        Table Members
]]--
TGI_InviteHandler.Name = "TGI-InviteHandler"
TGI_InviteHandler.IsRunning = false
TGI_InviteHandler.CurrentInviteString = ""
TGI_InviteHandler.AutoKickList = {}
TGI_InviteHandler.RegroupList = {}

--[[
        Sets invite string and start/stop automatic invite
]]--
function TGI_InviteHandler.SetInviteString(inviteString)
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.SetInviteString")
        _logger:logDebug("inviteString", inviteString)
    end

    if (TGI_InviteHandler.IsRunning) then
        if (inviteString == TGI_InviteHandler.CurrentInviteString) then
            -- Stop
            TGI_InviteHandler.StopInvite()
        else
            -- Change string
            TGI_InviteHandler.CurrentInviteString = inviteString

            if (TGI_SettingsHandler.SavedVariables.AutoKick) then
                d(zo_strformat("Automatisches Einladen mit <<1>> und Autokick aktiv.", TGI_InviteHandler.CurrentInviteString))
            else
                d(zo_strformat("Automatisches Einladen mit <<1>> aktiv.", TGI_InviteHandler.CurrentInviteString))
            end
        end
    else
        -- Change string
        TGI_InviteHandler.CurrentInviteString = inviteString

        -- Start
        TGI_InviteHandler.StartInvite()
    end
end

--[[
        Starts inviting of players in base of CurrentInviteString
]]--
function TGI_InviteHandler.StartInvite()
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.StartInvite")
    end
    
    -- Set IsRunning
    TGI_InviteHandler.IsRunning = true

    -- Register listening on chat
    EVENT_MANAGER:RegisterForEvent(TGI_InviteHandler.Name, EVENT_CHAT_MESSAGE_CHANNEL, TGI_InviteHandler.OnNewChatMessage)

    -- Start auto kick if activated
    if (TGI_SettingsHandler.SavedVariables.AutoKick) then
        TGI_InviteHandler.StartAutoKick()
        d(zo_strformat("Automatisches Einladen mit <<1>> und Autokick aktiv.", TGI_InviteHandler.CurrentInviteString))
    else
        d(zo_strformat("Automatisches Einladen mit <<1>> aktiv.", TGI_InviteHandler.CurrentInviteString))
    end
end

--[[
        Stops inviting of players and resets CurrentInviteString
]]--
function TGI_InviteHandler.StopInvite()
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.StopInvite")
    end

    -- Unregister listening on chat
    EVENT_MANAGER:UnregisterForEvent(TGI_InviteHandler.Name, EVENT_CHAT_MESSAGE_CHANNEL)

    -- Resets invite string
    TGI_InviteHandler.CurrentInviteString = ""

    -- Stop auto kick
    TGI_InviteHandler.StopAutoKick()

    -- Set IsRunning
    TGI_InviteHandler.IsRunning = false

    d("Automatisches Einladen deaktiviert.")
end

--[[
        Callback of EVENT_CHAT_MESSAGE_CHANNEL, handles text from chat against InviteString
]]--
function TGI_InviteHandler.OnNewChatMessage(eventCode, channelType, fromName, text, isCustomerService, fromDisplayName)
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.OnNewChatMessage")
        --_logger:logDebug("channelType;text;fromDisplayName", channelType, text, fromDisplayName)
    end

    -- Ignore text in group chat
    if (channelType ~= CHAT_CHANNEL_PARTY) then
        -- Only if text is CurrentInviteString
        if (text == TGI_InviteHandler.CurrentInviteString) then
            -- Ignore messages from yourself
            if (GetDisplayName() ~= fromDisplayName) then
                -- Only if you are leader
                if (IsUnitSoloOrGroupLeader("player")) then
                    local currentGroupSize = GetGroupSize()
                    local maxGroupSize = TGI_SettingsHandler.SavedVariables.MaxGroupSize

                    -- Check against configurated maxGroupSize
                    if (currentGroupSize < maxGroupSize) then
                        -- Invite player
                        d(zo_strformat("Schicke Einladung zu <<1>>.", fromDisplayName))
                        GroupInviteByName(fromDisplayName)
                    else
                        if (LOG_ACTIVE) then _logger:logDebug("Ignore invite. " .. tostring(currentGroupSize) .. " >= " .. tostring(maxGroupSize)) end
                    end
                else
                    if (LOG_ACTIVE) then _logger:logDebug("Ignore invite. You are not leader") end
                end
            else
                if (LOG_ACTIVE) then _logger:logDebug("Ignore invite. GetDisplayName() == fromDisplayName") end
            end
        else
            if (LOG_ACTIVE) then _logger:logDebug("Ignore invite. text ~= CurrentInviteString") end
        end
    else
        if (LOG_ACTIVE) then _logger:logDebug("Ignore invite. Group chat.") end
    end
end

--[[
        Starts auto kicking members in group
]]--
function TGI_InviteHandler.StartAutoKick()
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.StartAutoKick")
    end

    -- Register listening offline/online status
    EVENT_MANAGER:RegisterForEvent(TGI_InviteHandler.Name, EVENT_GROUP_MEMBER_CONNECTED_STATUS, TGI_InviteHandler.OnGroupMemberConnected)

    -- Start timer
        EVENT_MANAGER:RegisterForUpdate(TGI_InviteHandler.Name, REFRESHRATE, TGI_InviteHandler.OnTimedUpdate)

    -- Check group for offline members and add them to list
    for i = 1, GetGroupSize() do
        local unitTag = GetGroupUnitTagByIndex(i)
        if (IsUnitOnline(unitTag) == false) then
            local newElementId = #TGI_InviteHandler.AutoKickList + 1
            local unitTimeStamp = GetTimeStamp()

            TGI_InviteHandler.AutoKickList[newElementId] = {}
            TGI_InviteHandler.AutoKickList[newElementId].unitTag = unitTag
            TGI_InviteHandler.AutoKickList[newElementId].unitTimeStamp = unitTimeStamp
        end
    end
end

--[[
        Stops auto kicking members in group
]]--
function TGI_InviteHandler.StopAutoKick()
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.StopAutoKick")
    end

    -- Stop timer
        EVENT_MANAGER:UnregisterForUpdate(TGI_InviteHandler.Name)

    -- Unregister listening offline/online status
    EVENT_MANAGER:UnregisterForEvent(TGI_InviteHandler.Name, EVENT_GROUP_MEMBER_CONNECTED_STATUS)

    -- Clear auto kick list
    for i = #TGI_InviteHandler.AutoKickList, 1, -1 do
        table.remove(TGI_InviteHandler.AutoKickList, i)
    end
end

--[[
        Called on refresh of timer
]]--
function TGI_InviteHandler.OnTimedUpdate(eventCode)
    if (LOG_ACTIVE) then 
        --_logger:logTrace("TGI_InviteHandler.OnTimedUpdate")
    end

    -- Only if you are grouped and leader
    if (IsUnitGrouped("player") and IsUnitGroupLeader("player")) then
        -- Check all offline players and kick if > timeout
        local timeout = TGI_SettingsHandler.SavedVariables.AutoKickTimeout

        for i = #TGI_InviteHandler.AutoKickList, 1, -1 do
            local unitTimestamp = TGI_InviteHandler.AutoKickList[i].unitTimeStamp
            local currentTimestamp = GetTimeStamp()
            local difference = currentTimestamp - unitTimestamp

            if (difference > timeout) then
                local unitName = GetUnitDisplayName(TGI_InviteHandler.AutoKickList[i].unitTag)
                if (LOG_ACTIVE) then _logger:logDebug(zo_strformat("Remove player from list <<1>>", unitName)) end

                -- Still offline?
                if (IsUnitOnline(TGI_InviteHandler.AutoKickList[i].unitTag) == false) then
                    -- Kick
                    d(zo_strformat("Spieler <<1>> wurde automatisch gekickt.", unitName))
                    GroupKick(TGI_InviteHandler.AutoKickList[i].unitTag)
                end
                
                -- Remove
                table.remove(TGI_InviteHandler.AutoKickList, i)
            end
        end
    end
end

--[[
        Called on EVENT_GROUP_MEMBER_CONNECTED_STATUS
]]--
function TGI_InviteHandler.OnGroupMemberConnected(eventCode, unitTag, isOnline)
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.OnGroupMemberConnected")
        _logger:logDebug("unitTag;isOnline", unitTag, isOnline)
    end

    local found = false

    for i = #TGI_InviteHandler.AutoKickList, 1, -1 do
        if (TGI_InviteHandler.AutoKickList[i].unitTag == unitTag) then
            -- If online, remove; otherwise update
            if (isOnline) then
                table.remove(TGI_InviteHandler.AutoKickList, i)
            else
                TGI_InviteHandler.AutoKickList[i].unitTimeStamp = GetTimeStamp()
            end

            found = true
            break -- found
        end
    end

    -- If not found, add
    if (found == false) then
        -- Do not add if isOnline
        if (isOnline == false) then
            local newElementId = #TGI_InviteHandler.AutoKickList + 1
            local unitTimeStamp = GetTimeStamp()

            TGI_InviteHandler.AutoKickList[newElementId] = {}
            TGI_InviteHandler.AutoKickList[newElementId].unitTag = unitTag
            TGI_InviteHandler.AutoKickList[newElementId].unitTimeStamp = unitTimeStamp
        end
    end
end

--[[
        Starts regroup process
]]--
function TGI_InviteHandler.Regroup()
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.Regroup")
    end

    -- Only if you are grouped and leader
    if (IsUnitGrouped("player") and IsUnitGroupLeader("player")) then
        -- Get group display names
        for i = 1, GetGroupSize() do
            local unitTag = GetGroupUnitTagByIndex(i)
            local unitDisplayName = GetUnitDisplayName(unitTag)

            -- Ignore yourself
            if (GetDisplayName() ~= unitDisplayName) then
                local newElementId = #TGI_InviteHandler.RegroupList + 1
                TGI_InviteHandler.RegroupList[newElementId] = unitDisplayName
            end
        end
    
        -- Stop AutoKick, because group will reinvited
        TGI_InviteHandler.StopAutoKick()

        -- Disband group
        GroupDisband()

        -- Start regroup process
        zo_callLater(TGI_InviteHandler.PerformRegroup(), REFRESHRATE)
    else
        if (LOG_ACTIVE) then _logger:logDebug("Ignore invite. You are not leader or grouped.") end
    end
end

--[[
        Performs regroup process
]]--
function TGI_InviteHandler.PerformRegroup()
    if (LOG_ACTIVE) then 
        _logger:logTrace("TGI_InviteHandler.PerformRegroup")
    end

    -- Perform invite and clear
    for i = #TGI_InviteHandler.RegroupList, 1, -1 do
        -- Invite player
        d(zo_strformat("Schicke Einladung zu <<1>>.", TGI_InviteHandler.RegroupList[i]))
        GroupInviteByName(TGI_InviteHandler.RegroupList[i])

        -- Clear entry
        table.remove(TGI_InviteHandler.RegroupList, i)
    end

    -- Start auto kick if activated
    if (TGI_SettingsHandler.SavedVariables.AutoKick) then
        TGI_InviteHandler.StartAutoKick()
    end
end

--[[
        Initialize initializes TGI_InviteHandler
]]--
function TGI_InviteHandler.Initialize(logger)
    if (LOG_ACTIVE) then logger:logTrace("TGI_InviteHandler.Initialize") end

    _logger = logger
end

Compare with Previous | Blame