diff --git a/AutoInvite.lua b/AutoInvite.lua index 37d8842..9a5f61f 100644 --- a/AutoInvite.lua +++ b/AutoInvite.lua @@ -15,9 +15,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <http://www.gnu.org/licenses/>. -if AutoInvite == nil then - AutoInvite = {} -end +AutoInvite = AutoInvite or {} AutoInvite.AddonId = "AutoInvite" ------------------------------------------------ @@ -34,69 +32,6 @@ AutoInvite.isCyrodiil = function(unit) return GetUnitZone(unit) == "Cyrodiil" end -AutoInvite.guildLookup = function(channel, acctName) - local guildId = 0 - if channel == CHAT_CHANNEL_GUILD_1 or channel == CHAT_CHANNEL_OFFICER_1 then guildId = GetGuildId(1) end - if channel == CHAT_CHANNEL_GUILD_2 or channel == CHAT_CHANNEL_OFFICER_2 then guildId = GetGuildId(2) end - if channel == CHAT_CHANNEL_GUILD_3 or channel == CHAT_CHANNEL_OFFICER_3 then guildId = GetGuildId(3) end - if channel == CHAT_CHANNEL_GUILD_4 or channel == CHAT_CHANNEL_OFFICER_4 then guildId = GetGuildId(4) end - if channel == CHAT_CHANNEL_GUILD_5 or channel == CHAT_CHANNEL_OFFICER_5 then guildId = GetGuildId(5) end - - if guildId == 0 then d("Error - couldn't invite on channel: " .. channel) end - - local aName - for i=1,GetNumGuildMembers(guildId) do - aName = GetGuildMemberInfo(guildId,i) - if aName == acctName then - local hasChar, charName, zone = GetGuildMemberCharacterInfo(guildId,i) - -- Might use zone check to NOT auto-invite people outside current zone if leader in Cyrodiil - - if not hasChar then - echo("Could not find player name for " .. acctName .. ". Please manually invite.") - return "" - end - - charName = charName:gsub("%^.+", "") - - if AutoInvite.cfg.cyrCheck then - dbg("In Cyrodiil? " .. b(AutoInvite.isCyrodiil()) .. " / Zone: " .. zone) - - if AutoInvite.isCyrodiil() and zone ~= "Cyrodiil" then - echo("Player " .. charName .. " is not in Cyrodiil but in " .. zone) - echo("Blocking invite to prevent crashes.") - return "" - end - end - - return charName - end - end -end - -AutoInvite.kickTable = {} -function AutoInvite.checkOffline() - local now = GetTimeStamp() - for i=1,GetGroupSize() do - local tag = GetGroupUnitTagByIndex(i) - if not IsUnitOnline(tag) then - AutoInvite.kickTable[GetUnitName(tag)] = now - end - end -end - ---Since KickByName doesn't seem to be working -function AutoInvite.kickByName(name) - AutoInvite.kickTable[name] = nil - for i=1,GetGroupSize() do - local tag = GetGroupUnitTagByIndex(i) - if GetUnitName(tag) == name then - GroupKick(tag) - return - end - end - d("No one named " .. name .. " found in group scan. Please manually kick.") -end - ------------------------------------------------ --- Event handlers ------------------------------------------------ @@ -157,108 +92,8 @@ function AutoInvite.disbandEvent() end -- tick function: called every 15s -function AutoInvite.kickCheck() - if not AutoInvite.cfg.autoKick then return end - local now = GetTimeStamp() - --d("Check kick") - for p,t in pairs(AutoInvite.kickTable) do - local offTime = GetDiffBetweenTimeStamps(now, t) - if offTime > AutoInvite.cfg.kickDelay then - echo(" KICK: " .. p .. " offline for " .. offTime) - AutoInvite.kickByName(p) - else - dbg(p .. " offline for " .. offTime .. " / " .. AutoInvite.cfg.kickDelay) - end - end -end - ------------------------------------------------- ---- Invite queue ------------------------------------------------- - --- FIFO invite queue -AutoInvite.toInvite = { - vals = {}, - front = 1, - back = 1, -} -local queue = AutoInvite.toInvite -function queue:size() - return queue.back - queue.front -end - -function queue:push(val) - local back = self.back - self.vals[back] = val - queue.back = back + 1 -end - -function queue:pop() - if self:size() == 0 then - return nil - end - local front = self.front - local retval = self.vals[front] - self.vals[front] = nil - self.front = front + 1 - return retval -end - -function queue:reset() - self.vals = {} - self.front = 1 - self.back = 1 -end - --- Key: name / Value: timestamp -AutoInvite.sentInvite = {} --- sentInvite not array form, so maintain count -AutoInvite.sentInvites = 0 - -function AutoInvite:processQueue() - local now = GetTimeStamp() - local effectiveCount = GetGroupSize() + self.sentInvites - local numInvites = math.min(queue:size(), self.cfg.maxSize - effectiveCount) - for _ = 1,numInvites do - local name = queue:pop() - self.sentInvites = self.sentInvites + 1 - self.sentInvite[name] = now - GroupInviteByName(name) - end -end - -function AutoInvite:checkSentInvites() - local now = GetTimeStamp() - - local members = {} - for i=1,GetGroupSize() do - local tag = GetGroupUnitTagByIndex(i) - members[GetUnitName(tag)] = true - end - - for name, time in pairs(self.sentInvite) do - if members[name] or GetDiffBetweenTimeStamps(now, time) < 15 then - self.sentInvite[name] = nil - AutoInvite.sentInvites = AutoInvite.sentInvites - 1 - end - end -end - -function AutoInvite:resetQueues() - self.toInvite = {} - queue:reset() -end - - -function AutoInvite:resetGroup() - self:resetQueues() - for i=1,GetGroupSize() do - local tag = GetGroupUnitTagByIndex(i) - local name = GetUnitName(tag) - table.insert(self.toInvite, name) - GroupDisband() - GroupLeave() --for group leader bug - end +function AutoInvite.tick() + AutoInvite.kickCheck() end ------------------------------------------------ @@ -280,7 +115,7 @@ AutoInvite.startListening = function() if not AutoInvite.enabled then AutoInvite.enabled = true AutoInvite.checkOffline() - EVENT_MANAGER:RegisterForUpdate("AutoInviteKickCheck", 1000, AutoInvite.kickCheck) + EVENT_MANAGER:RegisterForUpdate("AutoInviteKickCheck", 1000, AutoInvite.tick) EVENT_MANAGER:RegisterForEvent(AutoInvite.AddonId, EVENT_GROUP_DISBANDED) end @@ -295,37 +130,6 @@ AutoInvite.startListening = function() end ------------------------------------------------ ---- Command line ------------------------------------------------- - - --- print command usage -AutoInvite.help = function() - echo("AutoInvite - command '/ai <str>'. Usage") - echo(" '/ai foo' - autoInvite on 'foo' command'") - echo(" '/ai help' - show this menu") - echo(" '/ai' - turn off autoInvite (auto on group full)") - return -end - ---Main interaction switch -SLASH_COMMANDS["/ai"] = function(str) - if not str or str == "" or str == "help" then - if not AutoInvite.listening or str == "help" then - AutoInvite.help() - return - end - echo("Disabling AutoInvite") - AutoInvite.disable() - return - end - AutoInvite.cfg.watchStr = string.lower(str) - AutoInvite.startListening() - - AutoInviteUI.refresh() -end - ------------------------------------------------- --- Initialization ------------------------------------------------ AutoInvite.init = function() @@ -352,36 +156,3 @@ end EVENT_MANAGER:RegisterForEvent("AutoInviteInit", EVENT_PLAYER_ACTIVATED, AutoInvite.init) --- 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 -end diff --git a/AutoInvite.txt b/AutoInvite.txt index 5ac53d6..c326407 100644 --- a/AutoInvite.txt +++ b/AutoInvite.txt @@ -20,5 +20,9 @@ lib/LibAddonMenu-2.0/controls/header.lua lib/LibAddonMenu-2.0/controls/slider.lua lib/LibAddonMenu-2.0/controls/texture.lua +lua/cli.lua +lua/guild.lua +lua/kick.lua +lua/queue.lua AutoInviteUI.lua AutoInvite.lua diff --git a/lua/cli.lua b/lua/cli.lua new file mode 100644 index 0000000..ced5841 --- /dev/null +++ b/lua/cli.lua @@ -0,0 +1,85 @@ +-- This file is part of AutoInvite +-- +-- (C) 2014 Scott Yeskie (Sasky) +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. + +AutoInvite = AutoInvite or {} +------------------------------------------------ +--- Utility functions +------------------------------------------------ +local function b(v) if v then return "T" else return "F" end end +local function nn(val) if val == nil then return "NIL" else return val end end +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 + +-- print command usage +AutoInvite.help = function() + echo("AutoInvite - command '/ai <str>'. Usage") + echo(" '/ai foo' - autoInvite on 'foo' command'") + echo(" '/ai help' - show this menu") + echo(" '/ai' - turn off autoInvite (auto on group full)") + return +end + +--Main interaction switch +SLASH_COMMANDS["/ai"] = function(str) + if not str or str == "" or str == "help" then + if not AutoInvite.listening or str == "help" then + AutoInvite.help() + return + end + echo("Disabling AutoInvite") + AutoInvite.disable() + return + end + AutoInvite.cfg.watchStr = string.lower(str) + AutoInvite.startListening() + + AutoInviteUI.refresh() +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 +end diff --git a/lua/guild.lua b/lua/guild.lua new file mode 100644 index 0000000..38d77d6 --- /dev/null +++ b/lua/guild.lua @@ -0,0 +1,60 @@ +-- This file is part of AutoInvite +-- +-- (C) 2014 Scott Yeskie (Sasky) +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- 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 b(v) if v then return "T" else return "F" end end +local function nn(val) if val == nil then return "NIL" else return val end end +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 + +AutoInvite = AutoInvite or {} + +AutoInvite.guildLookup = function(channel, acctName) + local guildId = 0 + if channel == CHAT_CHANNEL_GUILD_1 or channel == CHAT_CHANNEL_OFFICER_1 then guildId = GetGuildId(1) end + if channel == CHAT_CHANNEL_GUILD_2 or channel == CHAT_CHANNEL_OFFICER_2 then guildId = GetGuildId(2) end + if channel == CHAT_CHANNEL_GUILD_3 or channel == CHAT_CHANNEL_OFFICER_3 then guildId = GetGuildId(3) end + if channel == CHAT_CHANNEL_GUILD_4 or channel == CHAT_CHANNEL_OFFICER_4 then guildId = GetGuildId(4) end + if channel == CHAT_CHANNEL_GUILD_5 or channel == CHAT_CHANNEL_OFFICER_5 then guildId = GetGuildId(5) end + + if guildId == 0 then d("Error - couldn't invite on channel: " .. channel) end + + local aName + for i=1,GetNumGuildMembers(guildId) do + aName = GetGuildMemberInfo(guildId,i) + if aName == acctName then + local hasChar, charName, zone = GetGuildMemberCharacterInfo(guildId,i) + if not hasChar then + echo("Could not find player name for " .. acctName .. ". Please manually invite.") + return "" + end + + charName = charName:gsub("%^.+", "") + + if AutoInvite.cfg.cyrCheck then + dbg("In Cyrodiil? " .. b(AutoInvite.isCyrodiil()) .. " / Zone: " .. zone) + + if AutoInvite.isCyrodiil() and zone ~= "Cyrodiil" then + echo("Player " .. charName .. " is not in Cyrodiil but in " .. zone) + echo("Blocking invite to prevent crashes.") + return "" + end + end + + return charName + end + end +end \ No newline at end of file diff --git a/lua/kick.lua b/lua/kick.lua new file mode 100644 index 0000000..83421da --- /dev/null +++ b/lua/kick.lua @@ -0,0 +1,57 @@ +-- This file is part of AutoInvite +-- +-- (C) 2014 Scott Yeskie (Sasky) +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. + +AutoInvite = AutoInvite or {} + +AutoInvite.kickTable = {} +function AutoInvite.checkOffline() + local now = GetTimeStamp() + for i=1,GetGroupSize() do + local tag = GetGroupUnitTagByIndex(i) + if not IsUnitOnline(tag) then + AutoInvite.kickTable[GetUnitName(tag)] = now + end + end +end + +--Since KickByName doesn't seem to be working +function AutoInvite.kickByName(name) + AutoInvite.kickTable[name] = nil + for i=1,GetGroupSize() do + local tag = GetGroupUnitTagByIndex(i) + if GetUnitName(tag) == name then + GroupKick(tag) + return + end + end + d("No one named " .. name .. " found in group scan. Please manually kick.") +end + +function AutoInvite.kickCheck() + if not AutoInvite.cfg.autoKick then return end + local now = GetTimeStamp() + --d("Check kick") + for p,t in pairs(AutoInvite.kickTable) do + local offTime = GetDiffBetweenTimeStamps(now, t) + if offTime > AutoInvite.cfg.kickDelay then + echo(" KICK: " .. p .. " offline for " .. offTime) + AutoInvite.kickByName(p) + else + dbg(p .. " offline for " .. offTime .. " / " .. AutoInvite.cfg.kickDelay) + end + end +end \ No newline at end of file diff --git a/lua/queue.lua b/lua/queue.lua new file mode 100644 index 0000000..90b0319 --- /dev/null +++ b/lua/queue.lua @@ -0,0 +1,107 @@ +-- This file is part of AutoInvite +-- +-- (C) 2014 Scott Yeskie (Sasky) +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. + +AutoInvite = AutoInvite or {} + +-- FIFO invite queue +local queue = { + vals = {}, + front = 1, + back = 1, +} + +function queue:size() + return queue.back - queue.front +end + +function queue:push(val) + local back = self.back + self.vals[back] = val + queue.back = back + 1 +end + +function queue:pop() + if self:size() == 0 then + return nil + end + local front = self.front + local retval = self.vals[front] + self.vals[front] = nil + self.front = front + 1 + return retval +end + +function queue:reset() + self.vals = {} + self.front = 1 + self.back = 1 +end + +-- Key: name / Value: timestamp +AutoInvite.sentInvite = {} +-- sentInvite not array form, so maintain count +AutoInvite.sentInvites = 0 + +function AutoInvite:processQueue() + local now = GetTimeStamp() + local effectiveCount = GetGroupSize() + self.sentInvites + local numInvites = math.min(queue:size(), self.cfg.maxSize - effectiveCount) + for _ = 1,numInvites do + local name = queue:pop() + self.sentInvites = self.sentInvites + 1 + self.sentInvite[name] = now + GroupInviteByName(name) + end +end + +function AutoInvite:checkSentInvites() + local now = GetTimeStamp() + + local members = {} + for i=1,GetGroupSize() do + local tag = GetGroupUnitTagByIndex(i) + members[GetUnitName(tag)] = true + end + + for name, time in pairs(self.sentInvite) do + if members[name] or GetDiffBetweenTimeStamps(now, time) < 15 then + self.sentInvite[name] = nil + AutoInvite.sentInvites = AutoInvite.sentInvites - 1 + end + end +end + +function AutoInvite:resetQueues() + queue:reset() +end + + +function AutoInvite:resetGroup() + self:resetQueues() + for i=1,GetGroupSize() do + local tag = GetGroupUnitTagByIndex(i) + local name = GetUnitName(tag) + table.insert(self.toInvite, name) + GroupDisband() + GroupLeave() --for group leader bug + end +end + +--Interface to queue +function AutoInvite:invitePlayer(name) + queue:push(name) +end \ No newline at end of file