Minor bugfixes, release prep

Sasky [09-18-14 - 05:33]
Minor bugfixes, release prep
- Add check for sent invites
- Group list update adjustment
Filename
AutoInvite.lua
AutoInvite.txt
lang/en.lua
lua/cli.lua
lua/guild.lua
lua/queue.lua
ui/ai_enabled_fragment.lua
ui/ai_options_fragment.lua
ui/half_grouplist.lua
ui/half_grouplist.xml
diff --git a/AutoInvite.lua b/AutoInvite.lua
index bcdd83e..6cb3116 100644
--- a/AutoInvite.lua
+++ b/AutoInvite.lua
@@ -50,7 +50,7 @@ AutoInvite.callback = function(_, messageType, from, message)

 	if string.lower(message) == AutoInvite.cfg.watchStr and from ~= nil and from ~= "" then
 		if (messageType >= CHAT_CHANNEL_GUILD_1 and messageType <= CHAT_CHANNEL_OFFICER_5) or messageType == CHAT_CHANNEL_WHISPER then
-			from = AutoInvite.accountNameLookup(messageType, from)
+            from = AutoInvite.accountNameLookup(messageType, from)
 			if from == "" or from == nil then return end
         end

@@ -84,6 +84,7 @@ AutoInvite.offlineEvent = function(_, unitTag, connectStatus)
         dbg(unitTag .. "/" .. unitName .. " has disconnected")
         AutoInvite.kickTable[unitName] = GetTimeStamp()
     end
+    MINI_GROUP_LIST:updateSingle(name)
 end

 function AutoInvite.disbandEvent()
@@ -173,6 +174,7 @@ AutoInvite.init = function()

     AutoInvite.listening = false
     AutoInvite.enabled = false
+    AutoInvite.player = GetUnitName("player")
     AutoInviteUI.init()
 end

diff --git a/AutoInvite.txt b/AutoInvite.txt
index 08e1311..dbe9c9a 100644
--- a/AutoInvite.txt
+++ b/AutoInvite.txt
@@ -1,6 +1,6 @@
-## APIVersion: 100008
+## APIVersion: 100009
 ## Title: AutoInvite
-## Version: 1.5.1
+## Version: 2.0.0
 ## Author: Sasky
 ## SavedVariables: AutoInviteSettings
 ## OptionalDependsOn: LibAddonMenu-2.0
diff --git a/lang/en.lua b/lang/en.lua
index f57ca0e..9bdcb2f 100644
--- a/lang/en.lua
+++ b/lang/en.lua
@@ -17,4 +17,5 @@

 ZO_CreateStringId("SI_AUTO_INVITE", "Auto Invite")
 ZO_CreateStringId("SI_AUTO_INVITE_STOP", "Stop AutoInvite")
+ZO_CreateStringId("SI_AUTO_INVITE_NO_GROUP_MESSAGE", "Group is empty")
 --ZO_CreateStringId("", "")
\ No newline at end of file
diff --git a/lua/cli.lua b/lua/cli.lua
index ced5841..35bcdb5 100644
--- a/lua/cli.lua
+++ b/lua/cli.lua
@@ -51,35 +51,15 @@ SLASH_COMMANDS["/ai"] = function(str)
 end

 -- Debug commands
-SLASH_COMMANDS["/aik"] = function()
-    local now = GetTimeStamp()
-    --d("Current timestamp: " .. GetTimeStamp())
-    --d("Offline players:")
-    for p,t in pairs(AutoInvite.kickTable) do
-        local offTime = now - t
-        if offTime > 300 then
-            dbg("  KICK: " .. p .. " offline for " .. now - t)
-        else
-            dbg("  " .. p .. " offline for " .. now - t)
-        end
-    end
-end
-
 SLASH_COMMANDS["/aidebug"] = function()
     echo("|cFF0000Beginning debug mode for AutoInvite.")
     AutoInvite.debug = true
 end

-SLASH_COMMANDS["/aikick"] = function()
-    local now = GetTimeStamp()
-    d("Offline players:")
-    for p,t in pairs(AutoInvite.kickTable) do
-        local offTime = now - t
-        if offTime > AutoInvite.cfg.kickDelay then
-            echo("  KICK: " .. p .. " offline for " .. now - t)
-            GroupKickByName(p)
-        else
-            dbg("  " .. p .. " offline for " .. now - t)
-        end
-    end
+SLASH_COMMANDS["/airesponse"] = function()
+    EVENT_MANAGER:RegisterForEvent(AutoInvite.AddonId, EVENT_GROUP_INVITE_RESPONSE, AutoInvite.inviteResponse)
+end
+
+SLASH_COMMANDS["/airg"] = function()
+    AutoInvite:resetGroup()
 end
diff --git a/lua/guild.lua b/lua/guild.lua
index 6032f8a..9ea4898 100644
--- a/lua/guild.lua
+++ b/lua/guild.lua
@@ -29,7 +29,6 @@ function AutoInvite.executeNameLookup(hasChar, charName, zone)
     end

     charName = charName:gsub("%^.+", "")
-
     if AutoInvite.cfg.cyrCheck then
         dbg("In Cyrodiil? " .. b(AutoInvite.isCyrodiil()) .. " / Zone: " .. zone)

@@ -72,7 +71,7 @@ function AutoInvite.accountNameLookup(channel, acctName)
     if channel == CHAT_CHANNEL_GUILD_5 or channel == CHAT_CHANNEL_OFFICER_5 then guildId = GetGuildId(5) end

     if guildId > 0 then
-        AutoInvite.guildLookup(guildId, acctName)
+        return AutoInvite.guildLookup(guildId, acctName)
     else
         --Came in on whisper channel, so try friends then move to all guilds
         local charName = AutoInvite.friendLookup(acctName)
@@ -84,6 +83,6 @@ function AutoInvite.accountNameLookup(channel, acctName)
             if charName then return charName end
         end

-        d("Error - couldn't invite on channel: " .. channel)
+        echo("Error - couldn't invite on channel: " .. channel)
     end
 end
\ No newline at end of file
diff --git a/lua/queue.lua b/lua/queue.lua
index f33aa97..2287d89 100644
--- a/lua/queue.lua
+++ b/lua/queue.lua
@@ -33,10 +33,10 @@ function queue:size()
 end

 function queue:push(val)
-    AI_SmallGroupListing:updateSingle(val)
     local back = self.back
     self.vals[back] = val
     self.back = back + 1
+    MINI_GROUP_LIST:updateSingle(val)
 end

 function queue:pop()
@@ -62,16 +62,26 @@ AutoInvite.sentInvite = {}
 AutoInvite.sentInvites = 0

 function AutoInvite:processQueue()
+    local sentCount = AutoInvite.sentInvites
     local now = GetTimeStamp()
-    local effectiveCount = GetGroupSize() + self.sentInvites
+    for name,time in pairs(self.sentInvite) do
+        if GetDiffBetweenTimeStamps(now, time) > 30 then
+            AutoInvite.sentInvite[name] = nil
+            sentCount = sentCount - 1
+        end
+    end
+
+    local effectiveCount = GetGroupSize() + sentCount
     local numInvites =  math.min(queue:size(), self.cfg.maxSize - effectiveCount)
     for _ = 1,numInvites do
         local name = queue:pop()
-        self.sentInvites = self.sentInvites + 1
+        sentCount = sentCount + 1
         self.sentInvite[name] = now
         GroupInviteByName(name)
-        AI_SmallGroupListing:updateSingle(name)
+        MINI_GROUP_LIST:updateSingle(name)
     end
+
+    AutoInvite.sentInvites = math.max(sentCount, 0)
 end

 function AutoInvite:IsInviteSent(name)
@@ -121,7 +131,8 @@ function AutoInvite:resetGroup()
         GroupDisband()
         GroupLeave() --for group leader bug
     end
-    self:processQueue()
+
+    zo_callLater(function() AutoInvite:processQueue() end, 2000)
 end

 local responseCodes = {
@@ -140,8 +151,8 @@ local responseCodes = {

 local responseCodeInGroup = {
     [GROUP_INVITE_RESPONSE_ACCEPTED] = true,
-    [GROUP_INVITE_RESPONSE_ALREADY_GROUPED] = true, --Maybe
-    [GROUP_INVITE_RESPONSE_CONSIDERING_OTHER] = true, --Maybe
+    [GROUP_INVITE_RESPONSE_ALREADY_GROUPED] = false, --Maybe
+    [GROUP_INVITE_RESPONSE_CONSIDERING_OTHER] = false, --Maybe
     [GROUP_INVITE_RESPONSE_DECLINED] = false,
     [GROUP_INVITE_RESPONSE_GROUP_FULL] = false,
     [GROUP_INVITE_RESPONSE_IGNORED] = false,
@@ -159,13 +170,13 @@ function AutoInvite.inviteResponse(_, name, responseCode)
         AutoInvite.sentInvite[name] = nil
         AutoInvite.sentInvites = math.max(AutoInvite.sentInvites - 1, 0)

-        if not responseCodeInGroup[responseCode] then
-            AI_SmallGroupListing:removeSingle(name)
-        end
+        MINI_GROUP_LIST:updateSingle(name)
     end
 end

 --Interface to queue
 function AutoInvite:invitePlayer(name)
-    queue:push(name)
+    if name ~= self.player then
+        queue:push(name)
+    end
 end
\ No newline at end of file
diff --git a/ui/ai_enabled_fragment.lua b/ui/ai_enabled_fragment.lua
index 0bd13a5..b28d223 100644
--- a/ui/ai_enabled_fragment.lua
+++ b/ui/ai_enabled_fragment.lua
@@ -16,7 +16,7 @@
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.

 AutoInviteUI = AutoInviteUI or {}
-local ui = {}
+local ui = AutoInviteUI
 local wm = WINDOW_MANAGER

 function AutoInviteUI:CreateEnabledFragment()
diff --git a/ui/ai_options_fragment.lua b/ui/ai_options_fragment.lua
index f28f050..45cd503 100644
--- a/ui/ai_options_fragment.lua
+++ b/ui/ai_options_fragment.lua
@@ -16,7 +16,7 @@
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.

 AutoInviteUI = AutoInviteUI or {}
-local ui = {}
+local ui = AutoInviteUI
 local wm = WINDOW_MANAGER

 function AutoInviteUI:CreateOptionFragment()
@@ -26,6 +26,14 @@ function AutoInviteUI:CreateOptionFragment()
     ui.scroll = ui.main -- For using LAM controls
     ui.data = {}

+    ui.refreshList = wm:CreateControlFromVirtual(nil, ui.main, "ZO_DefaultButton")
+    ui.refreshList:SetAnchor(TOPRIGHT, ui.main, TOPRIGHT, -365, 5)
+    ui.refreshList:SetWidth(160)
+    ui.refreshList:SetText("Refresh List")
+    ui.refreshList:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+    ui.refreshList:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+    ui.refreshList:SetHandler("OnClicked", function() MINI_GROUP_LIST:RefreshData() end)
+
     ui.max = LAMCreateControl.slider(ui, {
         type = "slider",
         name = "Max group size",
@@ -37,7 +45,7 @@ function AutoInviteUI:CreateOptionFragment()
         default = 24,
         --width = "half"
     })
-    ui.max:SetAnchor(TOPRIGHT, ui.main, TOPRIGHT, 0, 25)
+    ui.max:SetAnchor(TOPRIGHT, ui.main, TOPRIGHT, 0, 55)

     ui.restart = LAMCreateControl.checkbox(ui, {
         type = "checkbox",
@@ -82,6 +90,22 @@ function AutoInviteUI:CreateOptionFragment()
     })
     ui.kickTime:SetAnchor(TOPLEFT, ui.kick, BOTTOMLEFT, 0, 25)

+    ui.regroup = wm:CreateControlFromVirtual(nil, ui.main, "ZO_DefaultButton")
+    ui.regroup:SetAnchor(TOPLEFT, ui.kickTime, BOTTOMLEFT, 70, 70)
+    ui.regroup:SetWidth(160)
+    ui.regroup:SetText("Re-form Group")
+    ui.regroup:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+    ui.regroup:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+    ui.regroup:SetHandler("OnClicked", function() AutoInvite:resetGroup() end)
+
+--    ui.queueTrigger = wm:CreateControlFromVirtual(nil, ui.main, "ZO_DefaultButton")
+--    ui.queueTrigger:SetAnchor(TOPLEFT, ui.regroup, TOPRIGHT, 20, 0)
+--    ui.queueTrigger:SetWidth(160)
+--    ui.queueTrigger:SetText("Trigger Queue")
+--    ui.queueTrigger:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+--    ui.queueTrigger:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+--    ui.queueTrigger:SetHandler("OnClicked", function() AutoInvite:processQueue() end)
+
     ui.note = LAMCreateControl.description(ui, {
         type = "description",
         title = "Slash Commands",
diff --git a/ui/half_grouplist.lua b/ui/half_grouplist.lua
index 3a6dc0d..e44e1a4 100644
--- a/ui/half_grouplist.lua
+++ b/ui/half_grouplist.lua
@@ -14,9 +14,11 @@
 --
 -- You should have received a copy of the GNU General Public License
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+local function dbg(msg) if AutoInvite.debug then d("|c999999" .. msg) end end
+local function echo(msg) CHAT_SYSTEM.primaryContainer.currentBuffer:AddMessage("|CFFFF00"..msg) end

 local AI_SmallGroupListing = ZO_SortFilterList:Subclass()
-local AI_GROUP_LIST_ENTRIES = {}
+AI_GROUP_LIST_ENTRIES = {}

 local AI_GROUP_DATA = 1

@@ -37,32 +39,39 @@ function AI_SmallGroupListing:New(control)
     local manager = ZO_SortFilterList.New(self, control)

     ZO_ScrollList_AddDataType(manager.list, AI_GROUP_DATA, "AI_SmallGroupListRow", 30, function(control, data) manager:SetupEntry(control, data) end)
-    --ZO_ScrollList_EnableHighlight(manager.list, "ZO_ThinListHighlight")
+    ZO_ScrollList_EnableHighlight(manager.list, "ZO_ThinListHighlight")

-    manager:SetEmptyText(GetString(SI_GROUP_LIST_PANEL_NO_GROUP_MESSAGE))
-    --manager:SetAlternateRowBackgrounds(true)
+    manager:SetEmptyText(GetString(SI_AUTO_INVITE_NO_GROUP_MESSAGE))
+    manager.emptyRow:ClearAnchors()
+    manager.emptyRow:SetAnchor(TOPLEFT, manager.control, TOPLEFT, 15, 100)
+    manager.emptyRow:SetWidth(300)
+    manager:SetAlternateRowBackgrounds(true)
     manager:RefreshData()

     manager.sortHeaderGroup:SelectHeaderByKey("displayName")

-    --For updates, tie into the GROUP_MANAGER logic rather than run equivalent events
-    local hookedMasterList = false
-    ZO_PreHook(GROUP_LIST, "BuildMasterList", function(...)
-        d("Hooked BuildMasterList")
-        hookedMasterList = true
+    local function Update()
         manager:RefreshData()
-        return true
-    end)
+    end
+
+--    local function UpdateSingle(name)
+--        manager:updateSingle(name)
+--    end

     ZO_PreHook(GROUP_LIST, "FilterScrollList", function(...)
-        d("Hooked FilterScrollList")
+        dbg("Hooked FilterScrollList")
         if not hookedMasterList then
-            manager:FilterScrollList()
+            manager:RefreshData()
         end
-        hookedMasterList = false
-        return true
+        --hookedMasterList = false /script AutoInvite:invitePlayer("Dynaxia Artria")
     end)

+--    control:RegisterForEvent(EVENT_GROUP_MEMBER_LEFT, Update)
+    control:RegisterForEvent(EVENT_GROUP_MEMBER_JOINED, Update)
+--    control:RegisterForEvent(EVENT_GROUP_MEMBER_KICKED, Update)
+--    control:RegisterForEvent(EVENT_GROUP_DISBANDED, Update)
+--    control:RegisterForEvent(EVENT_PLAYER_ACTIVATED, Update)
+
     AI_SMALL_GROUP_LIST_FRAGMENT = ZO_FadeSceneFragment:New(AI_SmallGroupList)

     return manager
@@ -76,7 +85,8 @@ function AI_SmallGroupListing:updateSingle(name)

     if AI_GROUP_LIST_ENTRIES[name] then
         AI_GROUP_LIST_ENTRIES[name]:Update()
-    else
+    elseif name then
+        dbg("Name " .. name .. " not found.")
        AI_GROUP_LIST_ENTRIES[name] = AI_SLG_Entry.New(name)
     end

@@ -84,7 +94,7 @@ function AI_SmallGroupListing:updateSingle(name)
 end

 function AI_SmallGroupListing:removeSingle(name)
-    d("Calling AI_SmallGroupListing:updateSingle()")
+    dbg("Calling AI_SmallGroupListing:updateSingle()")
     AI_GROUP_LIST_ENTRIES[name] = nil
     self:RefreshFilters()
 end
@@ -137,15 +147,9 @@ local function addTestCase(name, status, arg)
 end

 function AI_SmallGroupListing:BuildMasterList()
-    d("Calling AI_SmallGroupListing:BuildMasterList()")
+    dbg("Calling AI_SmallGroupListing:BuildMasterList()")
     AI_GROUP_LIST_ENTRIES = {}

-    for i=1,GetGroupSize() do
-        local tag = GetGroupUnitTagByIndex(i)
-        local name = GetUnitName(tag)
-        AI_GROUP_LIST_ENTRIES[name] = AI_SLG_Entry.New(name, tag)
-    end
-
     for name,time in pairs(AutoInvite.sentInvite) do
         AI_GROUP_LIST_ENTRIES[name] = AI_SLG_Entry.NewDefined(name, STATUS_ORDERING.SENT, time)
     end
@@ -154,15 +158,21 @@ function AI_SmallGroupListing:BuildMasterList()
         AI_GROUP_LIST_ENTRIES[name] = AI_SLG_Entry.NewDefined(name, STATUS_ORDERING.QUEUE)
     end

-    addTestCase("Zaniira", 1)
-    addTestCase("Ravlor", 2)
-    addTestCase("Sasky", 1)
-    addTestCase("Jinsa", 3)
-    addTestCase("Sascii", 4)
+    for i=1,GetGroupSize() do
+        local tag = GetGroupUnitTagByIndex(i)
+        local name = GetUnitName(tag)
+        AI_GROUP_LIST_ENTRIES[name] = AI_SLG_Entry.New(name, tag)
+    end
+
+--    addTestCase("Zaniira", 1)
+--    addTestCase("Ravlor", 2)
+--    addTestCase("Sasky", 1)
+--    addTestCase("Jinsa", 3)
+--    addTestCase("Sascii", 4)
 end

 function AI_SmallGroupListing:FilterScrollList()
-    d("Calling AI_SmallGroupListing:FilterScrollList()")
+    dbg("Calling AI_SmallGroupListing:FilterScrollList()")
     -- No filtering. Copy over from master list
     local scrollData = ZO_ScrollList_GetDataList(self.list)
     ZO_ClearNumericallyIndexedTable(scrollData)
@@ -173,30 +183,22 @@ function AI_SmallGroupListing:FilterScrollList()
 end

 function AI_SmallGroupListing:SortScrollList()
-    d("Calling AI_SmallGroupListing:SortScrollList()")
+    dbg("Calling AI_SmallGroupListing:SortScrollList()")
     if(self.currentSortKey ~= nil and self.currentSortOrder ~= nil) then
         local scrollData = ZO_ScrollList_GetDataList(self.list)
         table.sort(scrollData, self.CompareMembers)
     end
 end

-AI_SLG_Entry = {__index = AI_SLG_Entry}
-
-function AI_SLG_Entry.New(name, tag)
-    local self = setmetatable({}, AI_SLG_Entry)
-    self.status = STATUS_ORDERING.UNKNOWN
-    self.displayName = name
-    self.unitName = tag
-    self:update()
-    return self
-end
+AI_SLG_Entry = {}
+AI_SLG_Entry.__index = AI_SLG_Entry

 --For debugging
 function AI_SLG_Entry.NewDefined(name, status, arg)
     local self = setmetatable({}, AI_SLG_Entry)
     self.status = status
     self.displayName = name
-    function self.update() end --No-op
+    function self.Update() end --No-op

     if status == STATUS_ORDERING.queue then
         self.position = arg
@@ -207,11 +209,10 @@ function AI_SLG_Entry.NewDefined(name, status, arg)
     return self
 end

-function AI_SLG_Entry:update()
-    local name = self.displayName
+function AI_SLG_Entry:Update()
+    local name = self.displayName or ""
     local tag = self.unitName
     if GetUnitName(tag) == name then
-        d(name .. " in group")
         local offline = AutoInvite.kickTable[name]
         if IsUnitOnline(tag) then
             self.status = STATUS_ORDERING.ONLINE
@@ -220,23 +221,31 @@ function AI_SLG_Entry:update()
             self.time = offline
         end
     else
-        d(name .. " not in group")
         local sent = AutoInvite:IsInviteSent(name)
         if sent then
-            d(name .. " sent")
             self.status = STATUS_ORDERING.SENT
             self.time = sent
         else
             local queue = AutoInvite:IsInQueue(name)
             if queue then
-                d(name .. " in queue")
                 self.status = STATUS_ORDERING.QUEUE
                 --self.position = queue
+            else
+                dbg("Unknown status for " .. name)
+                AI_GROUP_LIST_ENTRIES[name] = nil
             end
         end
     end
 end

+function AI_SLG_Entry.New(name, tag)
+    local self = setmetatable({}, AI_SLG_Entry)
+    self.status = STATUS_ORDERING.UNKNOWN
+    self.displayName = name
+    self.unitName = tag
+    self:Update()
+    return self
+end

 --Global XML Handlers
 -----------------------
@@ -269,3 +278,9 @@ end
 function AI_SmallGroupListing_OnInitialized(self)
     MINI_GROUP_LIST = AI_SmallGroupListing:New(self)
 end
+
+--[[
+/script MINI_GROUP_LIST:RefreshData()
+/script MINI_GROUP_LIST:BuildMasterList()
+/script AutoInvite:invitePlayer("Streak Muldune")
+ ]]
\ No newline at end of file
diff --git a/ui/half_grouplist.xml b/ui/half_grouplist.xml
index adc6242..56eb0fc 100644
--- a/ui/half_grouplist.xml
+++ b/ui/half_grouplist.xml
@@ -88,7 +88,7 @@

                 <Control name="$(parent)List" inherits="ZO_ScrollList">
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Headers" relativePoint="BOTTOMLEFT" offsetY="3"/>
-                    <Anchor point="BOTTOMRIGHT" offsetX="-35" offsetY="-32"/>
+                    <Anchor point="BOTTOMRIGHT" relativeTo="$(parent)" relativePoint="BOTTOMLEFT" offsetX="360" offsetY="-32"/>
                 </Control>
             </Controls>
         </TopLevelControl>