diff --git a/BattleNetTools.lua b/BattleNetTools.lua index 58a9776..98094ad 100644 --- a/BattleNetTools.lua +++ b/BattleNetTools.lua @@ -19,6 +19,7 @@ -- Upvalues local select = select +local tinsert = table.insert local tonumber = tonumber -- API Upvalues @@ -158,30 +159,50 @@ function BNT:GetFriendById(id) return ParseBNFriendResult(BNGetFriendInfoByID(id)) end -function BNT:GetFriendByName(name) +function BNT:GetFriendByName(name, startIndex) local n = BNGetNumFriends() if n <= 0 then return nil end - for i = 1, n do + for i = startIndex or 1, n do local friend = ParseBNFriendResult(BNGetFriendInfo(i)) if (friend.ToonName or ""):lower() == name:lower() then - return friend + return friend, i end end return nil end +function BNT:GetAllFriendsByName(name) + local result = {} + local friend, lastIndex + repeat + friend, lastIndex = self:GetFriendByName(name, (lastIndex or 0) + 1) + if friend then tinsert(result, friend) end + until friend == nil + return result +end + function BNT:GetToon(id) return ParseBNToonResult(BNGetToonInfo(id)) end -function BNT:GetToonByName(name) +function BNT:GetToonByName(name, startIndex) local numF = BNGetNumFriends() if numF <= 0 then return nil end - for i = 1, numF do + for i = startIndex or 1, numF do for t = 1, BNGetNumFriendToons(i) do local toon = ParseBNToonResult(BNGetFriendToonInfo(i, t)) - if not CES:IsNullOrEmpty(toon.Name) and toon.Name:lower() == name:lower() then return toon end + if not CES:IsNullOrEmpty(toon.Name) and toon.Name:lower() == name:lower() then return toon, i end end end return nil end + +function BNT:GetAllToonsByName(name) + local result = {} + local toon, lastIndex + repeat + toon, lastIndex = self:GetToonByName(name, (lastIndex or 0) + 1) + if toon then tinsert(result, toon) end + until toon == nil + return result +end diff --git a/ChatManager.lua b/ChatManager.lua index 0a0bb08..b39dc76 100644 --- a/ChatManager.lua +++ b/ChatManager.lua @@ -68,6 +68,7 @@ local PM = C.PlayerManager local L = C.LocaleManager local GT = C.GroupTools local AC = C.AddonComm +local BNT = C.BattleNetTools local CCM = C.CommandManager local CES = C.Extensions.String @@ -211,8 +212,19 @@ function CM:HandleMessage(msg, sender, channel, target, sourceChannel, isBN, pID table.insert(t, args[i]) end end - local player = PM:GetOrCreatePlayer(sender) - local result, arg, errArg = CCM:HandleCommand(cmd, t, sourceChannel, player) + local realm = GetRealmName() + local bnetInfo + if isBN then + local toon = BNT:GetToon(pID) + if toon then + realm = toon.Realm + end + bnetInfo = { + PresenceID = pID + } + end + local player = PM:GetOrCreatePlayer(sender, realm) + local result, arg, errArg = CCM:HandleCommand(cmd, t, sourceChannel, player, bnetInfo) if isBN then target = pID sender = pID diff --git a/Command.lua b/Command.lua index 6ae5665..fc40f17 100644 --- a/Command.lua +++ b/Command.lua @@ -58,6 +58,7 @@ local DM local SM local IM local CDM +local CRM local log --- Initialize Command. @@ -76,6 +77,7 @@ function C:Init() SM = self.SummonManager IM = self.InviteManager CDM = self.DuelManager + CRM = self.RoleManager log = self.Logger self:LoadSavedVars() log:Normal(L("ADDON_LOAD")) @@ -117,6 +119,7 @@ function C:LoadSavedVars() SM:Init() IM:Init() CDM:Init() + CRM:Init() Cmd:Init() log:SetDebug(self.Settings.DEBUG) self.Global.VERSION = self.VarVersion diff --git a/CommandManager.lua b/CommandManager.lua index 8ce386f..7d6f747 100644 --- a/CommandManager.lua +++ b/CommandManager.lua @@ -70,6 +70,7 @@ local DM = C.DeathManager local SM = C.SummonManager local IM = C.InviteManager local CDM = C.DuelManager +local CRM = C.RoleManager local Chat local CES = C.Extensions.String local CET = C.Extensions.Table @@ -167,10 +168,11 @@ end -- @param args Table with arguments for the command. -- @param isChat Is the command called from chat? -- @param player Player object of the calling player (if chat) +-- @param bnetInfo Information about the B.Net sender (if called from B.Net chat) -- @return If successfull, returns result, otherwise false. -- @return Error message if not successful, otherwise nil. -- -function CM:HandleCommand(command, args, isChat, player) +function CM:HandleCommand(command, args, isChat, player, bnetInfo) command = tostring(command):lower() local cmd = self:GetCommand(command) if cmd then @@ -181,7 +183,11 @@ function CM:HandleCommand(command, args, isChat, player) return false, "CM_ERR_NOACCESS", {player.Info.Name, cmd.Access, PM:GetAccess(player)} end end - return cmd.Call(args, player, isChat) + local result, arg, errArg = cmd.Call(args, player, isChat, bnetInfo) + if type(result) == "nil" then + return "CM_ERR_UNKNOWN" + end + return result, arg, errArg else return false, "CM_ERR_NOTREGGED", {tostring(command)} end @@ -205,7 +211,7 @@ function CM:GetHelp(cmd) end -CM:Register({"__DEFAULT__"}, PM.Access.Local, function(args, sender, isChat) +CM:Register({"__DEFAULT__"}, PM.Access.Local, function(args, sender, isChat, bnetInfo) if isChat then return "CM_DEFAULT_CHAT" end @@ -214,7 +220,7 @@ CM:Register({"__DEFAULT__"}, PM.Access.Local, function(args, sender, isChat) return "CM_DEFAULT_END" end, "CM_DEFAULT_HELP") -CM:Register({"help", "h"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"help", "h"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then if isChat then return "CM_DEFAULT_CHAT" @@ -224,7 +230,7 @@ CM:Register({"help", "h"}, PM.Access.Groups.User.Level, function(args, sender, i return CM:GetHelp(tostring(args[1]):lower()) end, "CM_HELP_HELP") -CM:Register({"commands", "cmds", "cmdlist", "listcmds", "listcommands", "commandlist"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"commands", "cmds", "cmdlist", "listcmds", "listcommands", "commandlist"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) local all if #args > 0 then all = args[1] == "all" @@ -233,11 +239,11 @@ CM:Register({"commands", "cmds", "cmdlist", "listcmds", "listcommands", "command return "RAW_TABLE_OUTPUT", CES:Fit(cmds, 240, ", ") -- Max length is 255, "[Command] " takes up 10. This leaves us with 5 characters grace. end, "CM_COMMANDS_HELP") -CM:Register({"version", "ver", "v"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"version", "ver", "v"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) return "CM_VERSION", {C.Version} end, "CM_VERSION_HELP") -CM:Register({"set", "s"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"set", "s"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then return false, "CM_SET_USAGE" end @@ -405,7 +411,7 @@ CM:Register({"set", "s"}, PM.Access.Groups.Admin.Level, function(args, sender, i return false, "CM_SET_USAGE" end, "CM_SET_HELP") -CM:Register({"locale", "loc"}, PM.Access.Local, function(args, sender, isChat) +CM:Register({"locale", "loc"}, PM.Access.Local, function(args, sender, isChat, bnetInfo) if isChat then return false, "CM_ERR_NOCHAT" end if #args <= 0 then return "CM_LOCALE_CURRENT", {L.Settings.LOCALE} @@ -432,7 +438,7 @@ CM:Register({"locale", "loc"}, PM.Access.Local, function(args, sender, isChat) return false, "CM_LOCALE_USAGE" end, "CM_LOCALE_HELP") -CM:Register({"mylocale", "ml"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"mylocale", "ml"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not isChat then return false, "CM_ERR_CHATONLY" end @@ -451,7 +457,7 @@ CM:Register({"mylocale", "ml"}, PM.Access.Groups.User.Level, function(args, send end end, "CM_MYLOCALE_HELP") -CM:Register({"lock", "lockdown"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"lock", "lockdown"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if type(args[1]) == "string" then return PM:SetLocked(PM:GetOrCreatePlayer(args[1]), true) else @@ -459,7 +465,7 @@ CM:Register({"lock", "lockdown"}, PM.Access.Groups.Admin.Level, function(args, s end end, "CM_LOCK_HELP") -CM:Register({"unlock", "open"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"unlock", "open"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if type(args[1]) == "string" then return PM:SetLocked(PM:GetOrCreatePlayer(args[1]), false) else @@ -467,7 +473,7 @@ CM:Register({"unlock", "open"}, PM.Access.Groups.Admin.Level, function(args, sen end end, "CM_UNLOCK_HELP") -CM:Register({"getaccess"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"getaccess"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if type(args[1]) == "string" then local player = PM:GetOrCreatePlayer(args[1]) return "CM_GETACCESS_STRING", {player.Info.Name, PM.Access.Groups[player.Info.Group].Level, player.Info.Group} @@ -476,7 +482,7 @@ CM:Register({"getaccess"}, PM.Access.Groups.User.Level, function(args, sender, i end end, "CM_GETACCESS_HELP") -CM:Register({"setaccess"}, PM.Access.Local, function(args, sender, isChat) +CM:Register({"setaccess"}, PM.Access.Local, function(args, sender, isChat, bnetInfo) if #args < 1 then return false, "CM_SETACCESS_USAGE" end @@ -488,7 +494,7 @@ CM:Register({"setaccess"}, PM.Access.Local, function(args, sender, isChat) end end, "CM_SETACCESS_HELP") -CM:Register({"owner"}, PM.Access.Local, function(args, sender, isChat) +CM:Register({"owner"}, PM.Access.Local, function(args, sender, isChat, bnetInfo) if isChat then return false, "CM_ERR_NOCHAT" end @@ -496,7 +502,7 @@ CM:Register({"owner"}, PM.Access.Local, function(args, sender, isChat) return PM:SetOwner(player) end, "CM_OWNER_HELP") -CM:Register({"admin"}, PM.Access.Groups.Owner.Level, function(args, sender, isChat) +CM:Register({"admin"}, PM.Access.Groups.Owner.Level, function(args, sender, isChat, bnetInfo) if isChat then return false, "CM_ERR_NOCHAT" end @@ -507,7 +513,7 @@ CM:Register({"admin"}, PM.Access.Groups.Owner.Level, function(args, sender, isCh return PM:SetAdmin(player) end, "CM_ADMIN_HELP") -CM:Register({"op"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"op"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if type(args[1]) == "string" then local player = PM:GetOrCreatePlayer(args[1]) return PM:SetOp(player) @@ -516,7 +522,7 @@ CM:Register({"op"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) end end, "CM_OP_HELP") -CM:Register({"user"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"user"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if type(args[1]) == "string" then local player = PM:GetOrCreatePlayer(args[1]) return PM:SetUser(player) @@ -525,7 +531,7 @@ CM:Register({"user"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) end end, "CM_USER_HELP") -CM:Register({"ban"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"ban"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then return false, "CM_BAN_USAGE" end @@ -533,7 +539,7 @@ CM:Register({"ban"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat return PM:BanUser(player) end, "CM_BAN_HELP") -CM:Register({"auth", "authenticate", "a"}, PM.Access.Local, function(args, sender, isChat) +CM:Register({"auth", "authenticate", "a"}, PM.Access.Local, function(args, sender, isChat, bnetInfo) if isChat and isChat ~= "WHISPER" then return false, "CM_ERR_NOCHAT" end if #args < 2 then return false, "CM_AUTH_USAGE" end local arg = tostring(args[1]):lower() @@ -558,72 +564,76 @@ CM:Register({"auth", "authenticate", "a"}, PM.Access.Local, function(args, sende return false, "CM_AUTH_USAGE" end, "CM_AUTH_HELP") -CM:Register({"authme", "authenticateme", "am"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"authme", "authenticateme", "am"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not isChat then return false, "CM_ERR_CHATONLY" end if #args <= 0 then return false, "CM_AUTHME_USAGE" end local pass = tostring(args[1]) return AM:Authenticate(sender.Info.Name, pass) end, "CM_AUTHME_HELP") -CM:Register({"accept", "acceptinvite", "acceptinv", "join", "joingroup"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"accept", "acceptinvite", "acceptinv", "join", "joingroup"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not IM:IsEnabled() or not IM:IsGroupEnabled() then return "CM_ERR_DISABLED" end return IM:AcceptGroupInvite() end, "CM_ACCEPTINVITE_HELP") -CM:Register({"decline", "declineinvite", "declineinv", "cancelinvite", "cancelinv"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"decline", "declineinvite", "declineinv", "cancelinvite", "cancelinv"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not IM:IsEnabled() or not IM:IsGroupEnabled() then return "CM_ERR_DISABLED" end return IM:DeclineGroupInvite() end, "CM_DECLINEINVITE_HELP") -CM:Register({"acceptguildinvite", "acceptginvite", "acceptguildinv", "acceptginv"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"acceptguildinvite", "acceptginvite", "acceptguildinv", "acceptginv"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not IM:IsEnabled() or not IM:IsGuildEnabled() then return "CM_ERR_DISABLED" end return IM:AcceptGuildInvite() end, "CM_ACCEPTGUILDINVITE_HELP") -CM:Register({"declineguildinvite", "declineginvite", "declineguildinv", "declineginv"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"declineguildinvite", "declineginvite", "declineguildinv", "declineginv"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not IM:IsEnabled() or not IM:IsGuildEnabled() then return "CM_ERR_DISABLED" end return IM:DeclineGuildInvite() end, "CM_DECLINEGUILDINVITE_HELP") -CM:Register({"invite", "inv"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"invite", "inv"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) + local pID + if bnetInfo then pID = bnetInfo.PresenceID end if type(args[1]) == "string" then local player = PM:GetOrCreatePlayer(args[1]) - return PM:Invite(player, sender) + return PM:Invite(player, sender, pID) else - return PM:Invite(sender, sender) + return PM:Invite(sender, sender, pID) end end, "CM_INVITE_HELP") -CM:Register({"inviteme", "invme"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"inviteme", "invme"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not isChat then return false, "CM_ERR_CHATONLY" end - return PM:Invite(sender, sender) + local pID + if bnetInfo then pID = bnetInfo.PresenceID end + return PM:Invite(sender, sender, pID) end, "CM_INVITEME_HELP") -CM:Register({"blockinvites", "blockinvite", "denyinvites", "denyinvite"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"blockinvites", "blockinvite", "denyinvites", "denyinvite"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not isChat then return false, "CM_ERR_CHATONLY" end return PM:DenyInvites(sender, isChat == "WHISPER" or isChat == "BNET") end, "CM_DENYINVITE_HELP") -CM:Register({"allowinvites", "allowinvite"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"allowinvites", "allowinvite"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not isChat then return false, "CM_ERR_CHATONLY" end return PM:AllowInvites(sender, isChat == "WHISPER" or isChat == "BNET") end, "CM_ALLOWINVITE_HELP") -CM:Register({"kick"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"kick"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then return false, "CM_KICK_USAGE" end @@ -637,28 +647,28 @@ CM:Register({"kick"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) return PM:Kick(player, sender, reason, override) end, "CM_KICK_HELP") -CM:Register({"kingme", "givelead"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"kingme", "givelead"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if not isChat then return false, "CM_ERR_CHATONLY" end return PM:PromoteToLeader(sender) end, "CM_KINGME_HELP") -CM:Register({"opme", "assistant", "assist"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"opme", "assistant", "assist"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if not isChat then return false, "CM_ERR_CHATONLY" end return PM:PromoteToAssistant(sender) end, "CM_OPME_HELP") -CM:Register({"deopme", "deassistant", "deassist"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"deopme", "deassistant", "deassist"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if not isChat then return false, "CM_ERR_CHATONLY" end return PM:DemoteAssistant(sender) end, "CM_DEOPME_HELP") -CM:Register({"leader", "lead"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"leader", "lead"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then return false, "CM_LEADER_USAGE" end @@ -666,7 +676,7 @@ CM:Register({"leader", "lead"}, PM.Access.Groups.Op.Level, function(args, sender return PM:PromoteToLeader(player) end, "CM_LEADER_HELP") -CM:Register({"promote"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"promote"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then return false, "CM_PROMOTE_USAGE" end @@ -674,7 +684,7 @@ CM:Register({"promote"}, PM.Access.Groups.Op.Level, function(args, sender, isCha return PM:PromoteToAssistant(player) end, "CM_PROMOTE_HELP") -CM:Register({"demote"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"demote"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then return false, "CM_DEMOTE_USAGE" end @@ -682,7 +692,7 @@ CM:Register({"demote"}, PM.Access.Groups.Op.Level, function(args, sender, isChat return PM:DemoteAssistant(player) end, "CM_DEMOTE_HELP") -CM:Register({"queue", "q"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"queue", "q"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then return false, "CM_QUEUE_USAGE" end @@ -703,7 +713,7 @@ CM:Register({"queue", "q"}, PM.Access.Groups.User.Level, function(args, sender, return QM:Queue(index) end, "CM_QUEUE_HELP") -CM:Register({"leavelfg", "cancellfg", "cancel", "leavelfd", "cancellfd"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"leavelfg", "cancellfg", "cancel", "leavelfd", "cancellfd"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not QM.QueuedByCommand then return false, "CM_LEAVELFG_FAIL" end @@ -712,7 +722,7 @@ end, "CM_LEAVELFG_HELP") -- So apparently Blizzard does not allow accepting invites without HW event... Making this command useless... -- I'm keeping this command here for the future, if there will ever be a way to make this work. -CM:Register({"acceptlfg", "acceptlfd", "joinlfg", "joinlfd"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"acceptlfg", "acceptlfd", "joinlfg", "joinlfd"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not C.Settings.DEBUG then return false, "CM_ERR_PERMDISABLED" end @@ -725,7 +735,7 @@ CM:Register({"acceptlfg", "acceptlfd", "joinlfg", "joinlfd"}, PM.Access.Groups.U return QM:Accept() end, "CM_ACCEPTLFG_HELP") -CM:Register({"convert", "conv"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"convert", "conv"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if GT:IsLFGGroup() then return false, "CM_CONVERT_LFG" elseif not GT:IsGroup() then @@ -754,18 +764,18 @@ CM:Register({"convert", "conv"}, PM.Access.Groups.Op.Level, function(args, sende return false, "CM_CONVERT_INVALID" end, "CM_CONVERT_HELP") -CM:Register({"list"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"list"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if not args[1] then return false, "CM_LIST_USAGE" end return PM:ListToggle(args[1]:lower()) end, "CM_LIST_HELP") -CM:Register({"listmode", "lm", "lmode"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"listmode", "lm", "lmode"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) return PM:ToggleListMode() end, "CM_LISTMODE_HELP") -CM:Register({"groupallow", "gallow"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"groupallow", "gallow"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if #args <= 1 then return false, "CM_GROUPALLOW_USAGE" end @@ -774,7 +784,7 @@ CM:Register({"groupallow", "gallow"}, PM.Access.Groups.Admin.Level, function(arg return PM:GroupAccess(group, cmd, true) end, "CM_GROUPALLOW_HELP") -CM:Register({"groupdeny", "gdeny", "deny"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"groupdeny", "gdeny", "deny"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if #args <= 1 then return false, "CM_GROUPDENY_USAGE" end @@ -783,7 +793,7 @@ CM:Register({"groupdeny", "gdeny", "deny"}, PM.Access.Groups.Admin.Level, functi return PM:GroupAccess(group, cmd, false) end, "CM_GROUPDENY_HELP") -CM:Register({"resetgroupaccess", "groupaccessreset", "removegroupaccess", "groupaccessremove", "rga", "gar"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"resetgroupaccess", "groupaccessreset", "removegroupaccess", "groupaccessremove", "rga", "gar"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if #args <= 1 then return false, "CM_RESETGROUPACCESS_USAGE" end @@ -792,7 +802,7 @@ CM:Register({"resetgroupaccess", "groupaccessreset", "removegroupaccess", "group return PM:GroupAccessRemove(group, cmd) end, "CM_RESETGROUPACCESS_HELP") -CM:Register({"userallow", "uallow"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"userallow", "uallow"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if #args <= 1 then return false, "CM_USERALLOW_USAGE" end @@ -801,7 +811,7 @@ CM:Register({"userallow", "uallow"}, PM.Access.Groups.Admin.Level, function(args return PM:PlayerAccess(player, cmd, true) end, "CM_USERALLOW_HELP") -CM:Register({"userdeny", "udeny"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"userdeny", "udeny"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if #args <= 1 then return false, "CM_USERDENY_USAGE" end @@ -810,7 +820,7 @@ CM:Register({"userdeny", "udeny"}, PM.Access.Groups.Admin.Level, function(args, return PM:PlayerAccess(player, cmd, false) end, "CM_USERDENY_HELP") -CM:Register({"resetuseraccess", "useraccessreset", "removeuseraccess", "useraccessremove", "rua", "uar"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat) +CM:Register({"resetuseraccess", "useraccessreset", "removeuseraccess", "useraccessremove", "rua", "uar"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat, bnetInfo) if #args <= 1 then return false, "CM_RESETUSERACCESS_USAGE" end @@ -819,21 +829,21 @@ CM:Register({"resetuseraccess", "useraccessreset", "removeuseraccess", "useracce return PM:PlayerAccessRemove(player, cmd) end, "CM_RESETUSERACCESS_HELP") -CM:Register({"toggle", "t"}, PM.Access.Local, function(args, sender, isChat) +CM:Register({"toggle", "t"}, PM.Access.Local, function(args, sender, isChat, bnetInfo) if isChat then return false, "CM_ERR_NOCHAT" end return C:Toggle() end, "CM_TOGGLE_HELP") -CM:Register({"toggledebug", "td", "debug", "d"}, PM.Access.Local, function(args, sender, isChat) +CM:Register({"toggledebug", "td", "debug", "d"}, PM.Access.Local, function(args, sender, isChat, bnetInfo) if isChat then return false, "CM_ERR_NOCHAT" end return C:ToggleDebug() end, "CM_TOGGLEDEBUG_HELP") -CM:Register({"readycheck", "rc"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"readycheck", "rc"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then if PM:GetAccess(sender) > PM.Access.Groups.Op.Level then return "CM_ERR_NOACCESS", {sender.Info.Name, PM.Access.Groups.Op.Level, PM:GetAccess(sender)} @@ -873,7 +883,7 @@ CM:Register({"readycheck", "rc"}, PM.Access.Groups.User.Level, function(args, se return false, "CM_READYCHECK_FAIL" end, "CM_READYCHECK_HELP") -CM:Register({"loot", "l"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"loot", "l"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if GT:IsLFGGroup() then return false, "CM_LOOT_LFG" end @@ -916,7 +926,7 @@ CM:Register({"loot", "l"}, PM.Access.Groups.Op.Level, function(args, sender, isC return false, usage end, "CM_LOOT_HELP") -CM:Register({"roll", "r"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"roll", "r"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if #args <= 0 then return RM:StartRoll(sender.Info.Name) end @@ -978,7 +988,7 @@ CM:Register({"roll", "r"}, PM.Access.Groups.Op.Level, function(args, sender, isC return false, "CM_LOOT_USAGE" end, "CM_LOOT_HELP") -CM:Register({"raidwarning", "rw", "raid_warning"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"raidwarning", "rw", "raid_warning"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not GT:IsRaid() then return false, "CM_RAIDWARNING_NORAID" elseif not GT:IsRaidLeaderOrAssistant() then @@ -999,7 +1009,7 @@ CM:Register({"raidwarning", "rw", "raid_warning"}, PM.Access.Groups.User.Level, return "CM_RAIDWARNING_SENT" end, "CM_RAIDWARNING_HELP") -CM:Register({"dungeondifficulty", "dungeondiff", "dd", "dungeonmode", "dm"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"dungeondifficulty", "dungeondiff", "dd"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if #args < 1 then return GT:GetDungeonDifficultyString() end @@ -1016,7 +1026,7 @@ CM:Register({"dungeondifficulty", "dungeondiff", "dd", "dungeonmode", "dm"}, PM. return GT:SetDungeonDifficulty(diff) end, "CM_DUNGEONMODE_HELP") -CM:Register({"raiddifficulty", "raiddiff", "rd", "raidmode", "rm"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"raiddifficulty", "raiddiff", "rd"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if #args < 1 then return GT:GetRaidDifficultyString() end @@ -1037,49 +1047,49 @@ CM:Register({"raiddifficulty", "raiddiff", "rd", "raidmode", "rm"}, PM.Access.Gr return GT:SetRaidDifficulty(diff) end, "CM_RAIDMODE_HELP") -CM:Register({"release", "rel"}, PM.Access.Groups.Op.Level, function(args, sender, isChat) +CM:Register({"release", "rel"}, PM.Access.Groups.Op.Level, function(args, sender, isChat, bnetInfo) if not DM:IsEnabled() or not DM:IsReleaseEnabled() then return false, "CM_ERR_DISABLED" end return DM:Release() end, "CM_RELEASE_HELP") -CM:Register({"resurrect", "ressurrect", "ress", "res"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"resurrect", "ressurrect", "ress", "res"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not DM:IsEnabled() or not DM:IsResurrectEnabled() then return false, "CM_ERR_DISABLED" end return DM:Resurrect() end, "CM_RESURRECT_HELP") -CM:Register({"acceptsummon", "as", "acceptsumm", "asumm"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"acceptsummon", "as", "acceptsumm", "asumm"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not SM:IsEnabled() then return false, "CM_ERR_DISABLED" end return SM:AcceptSummon() end, "CM_ACCEPTSUMMON_HELP") -CM:Register({"declinesummon", "ds", "declinesumm", "dsumm", "cancelsummon", "csumm"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"declinesummon", "ds", "declinesumm", "dsumm", "cancelsummon", "csumm"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not SM:IsEnabled() then return false, "CM_ERR_DISABLED" end return SM:DeclineSummon() end, "CM_DECLINESUMMON_HELP") -CM:Register({"acceptduel", "acceptd"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"acceptduel", "acceptd"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not CDM:IsEnabled() then return false, "CM_ERR_DISABLED" end return CDM:AcceptDuel() end, "CM_ACCEPTDUEL_HELP") -CM:Register({"declineduel", "declined"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"declineduel", "declined"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not CDM:IsEnabled() then return false, "CM_ERR_DISABLED" end return CDM:DeclineDuel() end, "CM_DECLINEDUEL_HELP") -CM:Register({"startduel", "startd", "challenge"}, PM.Access.Groups.User.Level, function(args, sender, isChat) +CM:Register({"startduel", "startd", "challenge"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) if not CDM:IsEnabled() then return false, "CM_ERR_DISABLED" end @@ -1089,6 +1099,40 @@ CM:Register({"startduel", "startd", "challenge"}, PM.Access.Groups.User.Level, f return CDM:Challenge(args[1]) end, "CM_STARTDUEL_HELP") +CM:Register({"role", "rm"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo) + if not CRM:IsEnabled() then + return false, "CM_ERR_DISABLED" + end + if #args < 1 then + return "CM_ROLE_CURRENT", {CRM.Roles[CRM:GetRole()]} + end + local arg = args[1]:lower() + if arg:match("^st") or arg:match("^i") then -- Start/Initiate/Issue + return CRM:Start() + elseif arg:match("^[sa]") then -- Set/Assign (Role) + if #args < 2 then + return false, "CM_ROLE_SET_USAGE" + end + local role = args[2]:lower() + if role:match("^[thd]") then + return CRM:SetRole(role) + end + return false, "CM_ROLE_SET_USAGE" + elseif arg:match("^c") then -- Confirm (Role) + if #args >= 2 then -- Role supplied as argument #2 + local role = args[2]:lower() + if role:match("^[thd]") then + return CRM:SetRole(role) + end + return false, "CM_ROLE_CONFIRM_USAGE" + else -- No role specified + -- Confirm the role last chosen by the player + return CRM:ConfirmRole() + end + end + return false, "CM_ROLE_USAGE" +end, "CM_ROLE_HELP") + for i,v in ipairs(CM.Slash) do _G["SLASH_" .. C.Name:upper() .. i] = "/" .. v end diff --git a/Events.lua b/Events.lua index 8e105d0..9d22211 100644 --- a/Events.lua +++ b/Events.lua @@ -36,6 +36,7 @@ local AC = C.AddonComm local DM = C.DeathManager local SM = C.SummonManager local IM = C.InviteManager +local RM = C.RoleManager local CDM = C.DuelManager --- Event handler for ADDON_LOADED @@ -155,3 +156,7 @@ end function C.Events.DUEL_REQUESTED(self, ...) CDM:OnDuel((select(1, ...))) end + +function C.Events.ROLE_POLL_BEGIN(self, ...) + RM:OnRoleCheck() +end diff --git a/GroupTools.lua b/GroupTools.lua index 1dd3104..a0f50b2 100644 --- a/GroupTools.lua +++ b/GroupTools.lua @@ -96,6 +96,14 @@ function GT:IsLFGGroup() return false end +--- Check if player is in a party. +-- (Returns false if raid) +-- @return True if player is in a party, false otherwise. +-- +function GT:IsParty() + return UnitExists("party1") and not self:IsRaid() and not self:IsLFGGroup() +end + --- Check if player is in a raid. -- @return True if the player is in a raid, false otherwise. -- diff --git a/Number.lua b/Number.lua new file mode 100644 index 0000000..9255041 --- /dev/null +++ b/Number.lua @@ -0,0 +1,45 @@ +--[[ + * Copyright (c) 2011-2012 by Adam Hellberg. + * + * This file is part of Command. + * + * Command 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 3 of the License, or + * (at your option) any later version. + * + * Command 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 Command. If not, see <http://www.gnu.org/licenses/>. +--]] + +-- Upvalues +local type = type + +local C = Command + +if type(C.Extensions) ~= "table" then + C.Extensions = {} +end + +C.Extensions.Number = { + type = "ext" -- For future use +} + +local L = C.LocaleManager +local CEN = C.Extensions.Number + +function CEN:FormatSeconds(seconds) + -- Return plain seconds if less than 60 seconds + if seconds < 60 then return ("%d %s"):format(seconds, L("SECONDS"):lower()) end + local minutes = floor(seconds / 60) -- Get number of minutes + local secs = tostring(seconds - minutes * 60) -- Get number of remaining seconds + if not secs:match("%d%d") then -- Check if seconds <= 9 + secs = "0" .. secs -- Prefix a zero to make it look better + end + return ("%d:%s"):format(minutes, secs) -- Return in m:ss format +end diff --git a/PlayerManager.lua b/PlayerManager.lua index d80559a..bfcede0 100644 --- a/PlayerManager.lua +++ b/PlayerManager.lua @@ -232,6 +232,18 @@ function PM:LoadSavedVars() end Players = self.Data.PLAYERS[GetRealmName()] List = self.Data.LIST + + self:UpdatePlayerData() +end + +function PM:UpdatePlayerData() + for realm,players in pairs(self.Data.PLAYERS) do + for name,player in pairs(players) do + if not player.Info.Realm then + player.Info.Realm = realm + end + end + end end function PM:ParseMessage(message) @@ -261,20 +273,22 @@ end -- @param name Name of player. -- @return Player from list of players if exists, otherwise a new player object. -- -function PM:GetOrCreatePlayer(name) +function PM:GetOrCreatePlayer(name, realm) name = (name or UnitName("player")):lower():gsub("^%l", string.upper) - if CET:HasKey(Players, name) then - return Players[name] + realm = realm or GetRealmName() + if CET:HasKey(self.Data.PLAYERS[realm], name) then + return self.Data.PLAYERS[realm][name] else local player = CET:Copy(Player) player.Info.Name = name + player.Info.Realm = realm if player.Info.Name == UnitName("player") then player.Info.Group = self.Access.Groups.Owner.Name else player.Info.Group = self.Access.Groups.User.Name end - Players[player.Info.Name] = player - log:Normal(L("PM_PLAYER_CREATE"):format(player.Info.Name)) + self.Data.PLAYERS[realm][player.Info.Name] = player + log:Normal(L("PM_PLAYER_CREATE"):format(player.Info.Name, player.Info.Realm)) return player end end @@ -283,8 +297,8 @@ end -- @param player Player object to update. -- function PM:UpdatePlayer(player) - Players[player.Info.Name] = player - log:Normal(L("PM_PLAYER_UPDATE"):format(player.Info.Name)) + self.Data.PLAYERS[player.Info.Realm][player.Info.Name] = player + log:Normal(L("PM_PLAYER_UPDATE"):format(player.Info.Name, player.Info.Realm)) end --- Completely remove a command from a group's access list. @@ -603,10 +617,11 @@ end -- Also sends a message to the invited player about the event. -- @param player Player object of player to invite. -- @param sender Player object of the inviting player. +-- @param pID Presence ID if this was an Invite(Me) command from B.Net chat -- @return String stating the result of the invite, false if error. -- @return Error message if unsuccessful, nil otherwise. -- -function PM:Invite(player, sender) +function PM:Invite(player, sender, pID) if not sender then sender = self:GetOrCreatePlayer(UnitName("player")) end if player.Info.Name == UnitName("player") then return false, "PM_INVITE_SELF" @@ -619,7 +634,11 @@ function PM:Invite(player, sender) if self.Invites[player.Info.Name] then return false, "PM_INVITE_ACTIVE", {player.Info.Name} elseif player.Info.Name == sender.Info.Name then - InviteUnit(player.Info.Name) + if player.Info.Realm == GetRealmName() or not pID then + InviteUnit(player.Info.Name) + else -- Invite(Me) command sent from B.Net chat + BNInviteFriend(pID) + end return "PM_INVITE_NOTIFYTARGET" elseif player.Settings.Invite then InviteUnit(player.Info.Name) diff --git a/RoleManager.lua b/RoleManager.lua new file mode 100644 index 0000000..7405ebf --- /dev/null +++ b/RoleManager.lua @@ -0,0 +1,215 @@ +--[[ + * Copyright (c) 2011-2012 by Adam Hellberg. + * + * This file is part of Command. + * + * Command 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 3 of the License, or + * (at your option) any later version. + * + * Command 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 Command. If not, see <http://www.gnu.org/licenses/>. +--]] + +-- Upvalues +local type = type + +-- API Upvalues +local CreateFrame = CreateFrame +local UnitSetRole = UnitSetRole +local UnitGetAvailableRoles = UnitGetAvailableRoles +local UnitGroupRolesAssigned = UnitGroupRolesAssigned + +local C = Command + +C.RoleManager = { + Roles = { + TANK = "CRM_TANK", + HEALER = "CRM_HEALER", + DAMAGER = "CRM_DAMAGE", + NONE = "CRM_UNDEFINED", + Tank = "TANK", + Healer = "HEALER", + Damage = "DAMAGER", + Undefined = "NONE" + }, + BlizzRoles = {} +} + +local L = C.LocaleManager +local RM = C.RoleManager +local GT = C.GroupTools +local CM +local CEN = C.Extensions.Number + +local DEFAULT_DELAY = 5 +local MAX_DELAY = 60 -- Arbitrary max delay, unknown if there is an existing delay + +function RM:Init() + CM = C.ChatManager + self:LoadSavedVars() +end + +function RM:LoadSavedVars() + if type(C.Global["ROLE_MANAGER"]) ~= "table" then + C.Global["ROLE_MANAGER"] = {} + end + + self.Settings = C.Global["ROLE_MANAGER"] + + if type(self.Settings.ENABLED) ~= "boolean" then + self.Settings.ENABLED = true + end + + if type(self.Settings.DELAY) ~= "number" then + self.Settings.DELAY = DEFAULT_DELAY + end +end + +function RM:OnRoleCheck() + if self.Settings.DELAY > 0 then + local frame = CreateFrame("Frame") + frame.Time = 0 + frame.Delay = self.Settings.DELAY + frame:SetScript("OnUpdate", function(self, elapsed) + self.Time = self.Time + elapsed + if self.Time >= self.Delay then + self:SetScript("OnUpdate", nil) + RM:Announce() + end + end) + else + self:Announce() + end +end + +function RM:Announce() + if not self:RolePollActive() then return end + local current = self:GetRole() + local msg + if current ~= self.Roles.Undefined then + msg = "CRM_ANNOUNCE_HASROLE" + else + msg = "CRM_ANNOUNCE_NOROLE" + end + CM:SendMessage(L(msg):format(L(self.Roles[current])), "SMART") +end + +function RM:SetRole(role) + if type(role) ~= "string" then + error("RoleManager.SetRole: Argument was of type [" .. type(role) .. "], expected [string].") + return nil + end + role = role:lower() + local result = self.Roles.Damage + if role:match("^t") then + result = self.Roles.Tank + elseif role:match("^h") then + result = self.Roles.Healer + end + if not self:CanBeRole(result) then + return false, "CRM_SET_INVALID", {L(self.Roles[result])} + end + UnitSetRole("player", result) + if self:RolePollActive() then + RolePollPopup:Hide() + end + return "CRM_SET_SUCCESS", {L(self.Roles[result])} +end + +function RM:GetRole() + local role = UnitGroupRolesAssigned("player") + if role == "TANK" then + return self.Roles.Tank + elseif role == "HEALER" then + return self.Roles.Healer + elseif role == "DAMAGER" then + return self.Roles.Damage + end + return self.Roles.Undefined +end + +function RM:ConfirmRole() + local role = self:GetRole() + if role == self.Roles.Undefined then + return false, "CRM_CONFIRM_NOROLE" + end + return self:SetRole(role) +end + +function RM:CanBeRole(role) + if type(role) ~= "string" then + error("RoleManager.CanBeRole: Argument was of type [" .. type(role) .. "], expected [string].") + return nil + end + role = role:lower() + local tank, healer, dps = UnitGetAvailableRoles("player") + if role:match("^t") then + return tank + elseif role:match("^h") then + return healer + end + return dps +end + +function RM:RolePollActive() + return RolePollPopup and RolePollPopup:IsShown() +end + +function RM:Start() + if self:RolePollActive() then + return false, "CRM_START_ACTIVE" + elseif (GT:IsParty() and GT:IsGroupLeader()) or (GT:IsRaid() and GT:IsRaidLeaderOrAssistant()) then + + else + return false, "CRM_START_NOPRIV" + end +end + +function RM:Enable() + self.Settings.ENABLED = true + return "CRM_ENABLED" +end + +function RM:Disable() + self.Settings.ENABLED = false + return "CRM_DISABLED" +end + +function RM:Toggle() + if self:IsEnabled() then + return self:Disable() + end + return self:Enable() +end + +function RM:IsEnabled() + return self.Settings.ENABLED +end + +function RM:GetDelay() + return CEN:FormatSeconds(self:GetRawDelay()) +end + +function RM:GetRawDelay() + return self.Settings.DELAY +end + +function RM:SetDelay(amount) + if amount < 0 then + amount = 0 + elseif amount > MAX_DELAY then + amount = MAX_DELAY + end + self.Settings.DELAY = amount + if amount > 0 then + return "CRM_SETDELAY_SUCCESS", {CEN:FormatSeconds(amount)} + end + return "CRM_SETDELAY_INSTANT" +end diff --git a/SummonManager.lua b/SummonManager.lua index 380f825..3a8c54a 100644 --- a/SummonManager.lua +++ b/SummonManager.lua @@ -35,28 +35,21 @@ local GetSummonConfirmTimeLeft = GetSummonConfirmTimeLeft local C = Command -C.SummonManager = {} +C.SummonManager = { + VarVersion = 1 +} local L = C.LocaleManager local SM = C.SummonManager local CM local GT = C.GroupTools +local CEN = C.Extensions.Number +local DEFAULT_DELAY = 5 local MAX_DELAY = 110 -- 1 minute 50 seconds, summons expire after 2 minutes (usually) local LastSummoner -local function FormatSeconds(seconds) - -- Return plain seconds if less than 60 seconds - if seconds < 60 then return ("%d %s"):format(seconds, L("SECONDS"):lower()) end - local minutes = floor(seconds / 60) -- Get number of minutes - local secs = tostring(seconds - minutes * 60) -- Get number of remaining seconds - if not secs:match("%d%d") then -- Check if seconds > 9 - secs = "0" .. secs -- Prefix a zero to make it look better - end - return ("%d:%s"):format(minutes, secs) -- Return in m:ss format -end - function SM:Init() CM = C.ChatManager LastSummoner = L("UNKNOWN") @@ -70,22 +63,28 @@ function SM:LoadSavedVars() self.Settings = C.Global["SUMMON_MANAGER"] + if not self.Settings.VERSION or self.Settings.VERSION < self.VarVersion then + wipe(self.Settings) + end + if type(self.Settings.ENABLED) ~= "boolean" then self.Settings.ENABLED = true end - if type(self.Settings.TIME) ~= "number" then - self.Settings.TIME = 0 + if type(self.Settings.DELAY) ~= "number" then + self.Settings.DELAY = DEFAULT_DELAY end + + self.Settings.VERSION = self.VarVersion end function SM:OnSummon() if self.DelayActive then return end - if self.Settings.TIME > 0 then + if self.Settings.DELAY > 0 then self.DelayActive = true local frame = CreateFrame("Frame") frame.Time = 0 -- Current time - frame.Delay = self.Settings.TIME -- Delay to wait + frame.Delay = self.Settings.DELAY -- Delay to wait frame:SetScript("OnUpdate", function(self, elapsed) self.Time = self.Time + elapsed if self.Time >= self.Delay then @@ -186,7 +185,7 @@ function SM:SetDelay(amount) end self.Settings.DELAY = amount if amount > 0 then - return "SM_SETDELAY_SUCCESS", {FormatSeconds(amount)} + return "SM_SETDELAY_SUCCESS", {CEN:FormatSeconds(amount)} end return "SM_SETDELAY_INSTANT" end diff --git a/load.xml b/load.xml index e52cdbb..4a6775c 100644 --- a/load.xml +++ b/load.xml @@ -23,6 +23,7 @@ <Script file="Table.lua" /> <Script file="String.lua" /> <Include file="LocaleLoader.xml" /> + <Script file="Number.lua" /> <Script file="Logger.lua" /> <Script file="BattleNetTools.lua" /> <Script file="GroupTools.lua" /> @@ -36,6 +37,7 @@ <Script file="SummonManager.lua" /> <Script file="InviteManager.lua" /> <Script file="DuelManager.lua" /> + <Script file="RoleManager.lua" /> <Script file="CommandManager.lua" /> <Script file="ChatManager.lua" /> <Script file="Events.lua" /> diff --git a/locales/enUS.lua b/locales/enUS.lua index fbb9852..b536361 100644 --- a/locales/enUS.lua +++ b/locales/enUS.lua @@ -90,6 +90,7 @@ local L = { -- CommandManager -- -------------------- + CM_ERR_UNKNOWN = "Unknown error occurred, please contact addon author.", CM_ERR_NOTALLOWED = "%s is not allowed to be used, %s.", CM_ERR_NOACCESS = "You do not have permission to use that command, %s. Required access level: %d. Your access level: %d.", CM_ERR_NOTREGGED = "%q is not a registered command.", @@ -303,6 +304,12 @@ local L = { CM_STARTDUEL_HELP = "Challenges another player to a duel.", CM_STARTDUEL_USAGE = "Usage: startduel <target>", + CM_ROLE_HELP = "Provides various commands for controlling role assignment.", + CM_ROLE_USAGE = "Usage: role start|set|confirm", + CM_ROLE_CURRENT = "My current role is %s.", + CM_ROLE_SET_USAGE = "Usage: role set tank|healer|dps", + CM_ROLE_CONFIRM_USAGE = "Usage: role confirm [tank|healer|dps]", + ------------ -- Events -- ------------ @@ -394,8 +401,8 @@ local L = { PM_KICK_NOPRIV = "Unable to kick %s from group. Not group leader or assistant.", PM_KICK_TARGETASSIST = "Unable to kick %s, assistants cannot kick other assistants from group.", - PM_PLAYER_CREATE = "Created player %q with default settings.", - PM_PLAYER_UPDATE = "Updated player %q.", + PM_PLAYER_CREATE = "Created player %q (%s) with default settings.", + PM_PLAYER_UPDATE = "Updated player %q (%s).", PM_GA_REMOVED = "%q removed from group %s.", PM_GA_EXISTSALLOW = "%q already has that command on the allow list.", @@ -583,6 +590,33 @@ local L = { CDM_DELAY_DISABLED = "Announce delay has been disabled, will now announce immediately.", ----------------- + -- RoleManager -- + ----------------- + + CRM_ENABLED = "RoleManager enabled.", + CRM_DISABLED = "RoleManager disabled.", + + + CRM_TANK = "Tank", + CRM_HEALER = "Healer", + CRM_DAMAGE = "DPS", + CRM_UNDEFINED = "Undefined", + + CRM_ANNOUNCE_HASROLE = "Role check started! Confirm my current role (%s) with !role confirm or set a new one with !role confirm tank|healer|dps", + CRM_ANNOUNCE_NOROLE = "Role check started! Set my role with !role confirm tank|healer|dps", + + CRM_SET_INVALID = "I cannot fulfill the role of %s, please specify another role.", + CRM_SET_SUCCESS = "Successfully set my role to %s!", + + CRM_CONFIRM_NOROLE = "No role set, confirmation needed with role confirm tank|healer|dps", + + CRM_START_ACTIVE = "A role check is already pending, please wait until it has ended.", + CRM_START_NOPRIV = "Unable to start role check, not leader or assistant.", + + CRM_STARTDELAY_SUCCESS = "RoleManager announce delay set to %s!", + CRM_STARTDELAY_INSTANT = "RoleManager now announces instantly.", + + ----------------- -- AuthManager -- ----------------- diff --git a/locales/svSE.lua b/locales/svSE.lua index 850648e..8854ca0 100644 --- a/locales/svSE.lua +++ b/locales/svSE.lua @@ -90,6 +90,7 @@ local L = { -- CommandManager -- -------------------- + CM_ERR_UNKNOWN = "Okänt fel inträffade, kontakta addonskapare.", CM_ERR_NOTALLOWED = "%s är inte tillåtet att användas, %s.", CM_ERR_NOACCESS = "Du har inte tillåtelse att använda det kommandot, %s. Behörighet som krävs: %d. Din behörighet: %d.", CM_ERR_NOTREGGED = "%q är inte ett registrerat kommando.", @@ -303,6 +304,12 @@ local L = { CM_STARTDUEL_HELP = "Challenges another player to a duel.", CM_STARTDUEL_USAGE = "Usage: startduel <target>", + CM_ROLE_HELP = "Provides various commands for controlling role assignment.", + CM_ROLE_USAGE = "Användning: role start|set|confirm", + CM_ROLE_CURRENT = "My current role is %s.", + CM_ROLE_SET_USAGE = "Användning: role set tank|healer|dps", + CM_ROLE_CONFIRM_USAGE = "Usage: role confirm [tank|healer|dps]", + ------------ -- Events -- ------------ @@ -394,8 +401,8 @@ local L = { PM_KICK_NOPRIV = "Unable to kick %s from group. Not group leader or assistant.", PM_KICK_TARGETASSIST = "Unable to kick %s, assistants cannot kick other assistants from group.", - PM_PLAYER_CREATE = "Created player %q with default settings.", - PM_PLAYER_UPDATE = "Updated player %q.", + PM_PLAYER_CREATE = "Created player %q (%s) with default settings.", + PM_PLAYER_UPDATE = "Updated player %q (%s).", PM_GA_REMOVED = "%q removed from group %s.", PM_GA_EXISTSALLOW = "%q already has that command on the allow list.", @@ -583,6 +590,33 @@ local L = { CDM_DELAY_DISABLED = "Announce delay has been disabled, will now announce immediately.", ----------------- + -- RoleManager -- + ----------------- + + CRM_ENABLED = "RoleManager enabled.", + CRM_DISABLED = "RoleManager disabled.", + + + CRM_TANK = "Tank", + CRM_HEALER = "Healer", + CRM_DAMAGE = "DPS", + CRM_UNDEFINED = "Undefined", + + CRM_ANNOUNCE_HASROLE = "Role check started! Confirm my current role (%s) with !role confirm or set a new one with !role confirm tank|healer|dps", + CRM_ANNOUNCE_NOROLE = "Role check started! Set my role with !role confirm tank|healer|dps", + + CRM_SET_INVALID = "I cannot fulfill the role of %s, please specify another role.", + CRM_SET_SUCCESS = "Successfully set my role to %s!", + + CRM_CONFIRM_NOROLE = "No role set, confirmation needed with role confirm tank|healer|dps", + + CRM_START_ACTIVE = "A role check is already pending, please wait until it has ended.", + CRM_START_NOPRIV = "Unable to start role check, not leader or assistant.", + + CRM_STARTDELAY_SUCCESS = "RoleManager announce delay set to %s!", + CRM_STARTDELAY_INSTANT = "RoleManager now announces instantly.", + + ----------------- -- AuthManager -- -----------------