Quantcast

Major changes to PlayerManager and some other fixes.

F16Gaming [10-28-11 - 16:24]
Major changes to PlayerManager and some other fixes.

ADDED: Ability to use the blacklist, whitelist, allow/deny lists (both user and group).
ADDED: Ability to toggle debug mode.
FIXED: PlayerManager.HasAccess should work better now.
FIXED: Now checks for enabled state before calling event handlers.
FIXED: The convert command should now check if player is group leader before attempting to convert.
FIXED: Enabled variable is now a saved variable.
CHANGED: Saved Var version increased.
Filename
Command.lua
CommandManager.lua
EventHandler.lua
PlayerManager.lua
diff --git a/Command.lua b/Command.lua
index 0e673df..1342a28 100644
--- a/Command.lua
+++ b/Command.lua
@@ -32,8 +32,7 @@
 Command = {
 	Name = "Command",
 	Version = GetAddOnMetadata("Command", "Version"),
-	VarVersion = 1,
-	Enabled = true,
+	VarVersion = 2,
 	Global = {},
 	Settings = {},
 	Events = {},
@@ -64,6 +63,7 @@ function C:LoadSavedVars()
 		_G["COMMAND"] = {}
 	elseif type(_G["COMMAND"]["VERSION"]) == "number" then
 		if _G["COMMAND"]["VERSION"] < self.VarVersion then
+			log:Normal("Saved Variables out of date, resetting...")
 			wipe(_G["COMMAND"])
 			_G["COMMAND"] = {}
 		end
@@ -76,6 +76,9 @@ function C:LoadSavedVars()
 	if type(self.Settings.DEBUG) ~= "boolean" then
 		self.Settings.DEBUG = false
 	end
+	if type(self.Settings.ENABLED) ~= "bolean" then
+		self.Settings.ENABLED = true
+	end
 	CM:Init()
 	PM:Init()
 	Cmd:Init()
@@ -86,7 +89,7 @@ end
 -- @param enabled Boolean indicating enabled or disabled state.
 --
 function C:SetEnabled(enabled)
-	self.Enabled = enabled
+	self.Settings.ENABLED = enabled
 end

 --- Enable AddOn.
diff --git a/CommandManager.lua b/CommandManager.lua
index 61b8e1c..c59472d 100644
--- a/CommandManager.lua
+++ b/CommandManager.lua
@@ -265,6 +265,9 @@ CM:Register({"convert", "conv"}, PM.Access.Groups.Op.Level, function(args, sende
 	if not GT:IsGroup() then
 		return false, "Cannot convert if not in a group."
 	end
+	if not GT:IsGroupLeader() then
+		return false, "Cannot convert group, not leader."
+	end
 	if #args <= 0 then
 		return false, "Usage: convert party||raid."
 	end
@@ -289,6 +292,67 @@ CM:Register({"convert", "conv"}, PM.Access.Groups.Op.Level, function(args, sende
 	end
 end)

+CM:Register({"list"}, PM.Access.Admin, function(args, sender, isChat)
+	if not args[1] then
+		return false, "Missing argument: command name"
+	end
+	return PM:List(args[1]:lower())
+end)
+
+CM:Register({"groupallow", "gallow"}, PM.Access.Admin, function(args, sender, isChat)
+	if #args <= 1 then
+		return false, "Usage: groupallow <groupname> <commandname>"
+	end
+	local group = args[1]:gsub("^%l", string.upper)
+	local cmd = args[2]:lower()
+	return PM:GroupAccess(group, cmd, true)
+end)
+
+CM:Register({"groupdeny", "deny"}, PM.Access.Admin, function(args, sender, isChat)
+	if #args <= 1 then
+		return false, "Usage: groupdeny <groupname> <commandname>"
+	end
+	local group = args[1]:gsub("^%1", string.upper)
+	local cmd = args[2]:lower()
+	return PM:GroupAccess(group, cmd, false)
+end)
+
+CM:Register({"resetgroupaccess", "groupaccessreset", "removegroupaccess", "groupaccessremove", "rga", "gar"}, PM.Access.Admin, function(args, sender, isChat)
+	if #args <= 1 then
+		return false, "Usage: resetgroupaccess <groupname> <commandname>"
+	end
+	local group = args[1]:gsub("^%1", string.upper)
+	local cmd = args[2]:lower()
+	return PM:GroupAccessRemove(group, cmd)
+end)
+
+CM:Register({"userallow", "uallow"}, PM.Access.Admin, function(args, sender, isChat)
+	if #args <= 1 then
+		return false, "Usage: userallow <playername> <commandname>"
+	end
+	local player = PM:GetOrCreatePlayer(args[1])
+	local cmd = args[2]:lower()
+	return PM:PlayerAccess(player, cmd, true)
+end)
+
+CM:Register({"userdeny", "udeny"}, PM.Access.Admin, function(args, sender, isChat)
+	if #args <= 1 then
+		return false, "Usage: userdeny <playername> <commandname>"
+	end
+	local player = PM:GetOrCreatePlayer(args[1])
+	local cmd = args[2]:lower()
+	return PM:PlayerAccess(player, cmd, false)
+end)
+
+CM:Register({"resetuseraccess", "useraccessreset", "removeuseraccess", "useraccessremvoe", "rua", "uar"}, PM.Access.Admin, function(args, sender, isChat)
+	if #args <= 1 then
+		return false, "Usage: resetuseraccess <playername> <commandname>."
+	end
+	local player = PM:GetOrCreatePlayer(args[1])
+	local cmd = args[2]:lower()
+	return PM:PlayerAccessRemove(player, cmd)
+end)
+
 CM:Register({"toggle", "t"}, PM.Access.Local, function(args, sender, isChat)
 	if isChat then
 		return false, "This command is not allowed to be used from the chat."
@@ -296,6 +360,13 @@ CM:Register({"toggle", "t"}, PM.Access.Local, function(args, sender, isChat)
 	return C:Toggle()
 end)

+CM:Register({"toggledebug", "td", "debug", "d"}, PM.Access.Local, function(args, sender, isChat)
+	if isChat then
+		return false, "This command is not allowed to be used from the chat."
+	end
+	return C:ToggleDebug()
+end)
+
 for i,v in ipairs(CM.Slash) do
 	_G["SLASH_" .. C.Name:upper() .. i] = "/" .. v
 end
diff --git a/EventHandler.lua b/EventHandler.lua
index 6db1696..8fcfb81 100644
--- a/EventHandler.lua
+++ b/EventHandler.lua
@@ -27,6 +27,7 @@ local CES = C.Extensions.String
 -- @param ... Event arguments.
 --
 function C:OnEvent(frame, event, ...)
+	if not self.Settings.ENABLED then return end
 	if not self.Events[event] then return end
 	if CES:StartsWith(event, "CHAT_MSG_") then
 		self.Events[event](self, event, ...)
diff --git a/PlayerManager.lua b/PlayerManager.lua
index 76051cf..3872f56 100644
--- a/PlayerManager.lua
+++ b/PlayerManager.lua
@@ -42,7 +42,7 @@ C.PlayerManager = {
 			Owner = {
 				Level = 0,
 				Name = "Owner",
-				Allow = {"*"},
+				Allow = {},
 				Deny = {}
 			},
 			Admin = {
@@ -67,7 +67,7 @@ C.PlayerManager = {
 				Level = 4,
 				Name = "Banned",
 				Allow = {},
-				Deny = {"*"}
+				Deny = {}
 			}
 		}
 	},
@@ -145,6 +145,25 @@ function PM:LoadSavedVars()
 	if type(C.Global["PLAYER_MANAGER"]["LIST"]) ~= "table" then
 		C.Global["PLAYER_MANAGER"]["LIST"] = {}
 	end
+	if type(C.Global["PLAYER_MANAGER"]["GROUP_PERMS"]) ~= "table" then
+		C.Global["PLAYER_MANAGER"]["GROUP_PERMS"] = {}
+		for k,v in pairs(self.Access.Groups) do
+			C.Global["PLAYER_MANAGER"]["GROUP_PERMS"][k] = {
+				Allow = {},
+				Deny = {}
+			}
+			for _,v in pairs(self.Access.Groups[k].Allow) do
+				table.insert(C.Global["PLAYER_MANAGER"]["GROUP_PERMS"][k].Allow, v)
+			end
+			for _,v in pairs(self.Access.Groups[k].Deny) do
+				table.insert(C.Global["PLAYER_MANAGER"]["GROUP_PERMS"][k].Deny, v)
+			end
+		end
+	end
+	for k,v in pairs(C.Global["PLAYER_MANAGER"]["GROUP_PERMS"]) do
+		self.Access.Groups[k].Allow = v.Allow
+		self.Access.Groups[k].Deny = v.Deny
+	end
 	Players = C.Global["PLAYER_MANAGER"]["PLAYERS"]
 	List = C.Global["PLAYER_MANAGER"]["LIST"]
 end
@@ -167,10 +186,67 @@ function PM:GetOrCreatePlayer(name)
 	end
 end

+--- Completely remove a command from a group's access list.
+-- Removed from both the allow and deny list.
+-- @param group Name of group to modify.
+-- @param command Name of command to remove.
+-- @return String stating that the command has been removed or false if error.
+-- @return Error message is unsuccessful, otherwise nil.
+--
+function PM:GroupAccessRemove(group, command)
+	group = group:gsub("^%l", string.upper)
+	if not command then return false, "No Command specified" end
+	for i,v in pairs(self.Access.Groups[k].Allow) do
+		if v == command then table.remove(self.Access.Groups[k].Allow, i) end
+	end
+	for i,v in pairs(self.Access.Groups[k].Deny) do
+		if v == command then table.remove(self.Access.Groups[k].Deny, i) end
+	end
+	return ("%q removed from group %s."):format(command, group)
+end
+
+--- Modify the access of a command for a specific group.
+-- @param group Name of group to modify.
+-- @param command Name of command to allow or deny.
+-- @param allow True to allow command, false to deny.
+-- @return String stating the result, or false if error.
+-- @return Error message if unsuccessful, otherwise nil.
+--
+function PM:GroupAccess(group, command, allow)
+	if not command then return false, "No command specified" end
+	local mode = "allowed"
+	if allow then
+		if CET:HasValue(self.Access.Groups[group].Deny, command) then
+			for i,v in ipairs(player.Access.Deny) do
+				if v == command then table.remove(player.Access.Deny, i) end
+			end
+		end
+		if CET:HasValue(self.Access.Groups[group].Allow, command) then
+			return false, ("%q already has that command on the allow list."):format(group)
+		end
+		table.insert(self.Access.Groups[group].Allow, command)
+		mode = "allowed"
+	else
+		if CET:HasValue(self.Access.Groups[group].Allow, command) then
+			for i,v in pairs(self.Access.Groups[group].Allow) do
+				if v == command then table.remove(self.Access.Groups[group].Allow, i) end
+			end
+		end
+		if CET:HasValue(self.Access.Groups[group].Deny, command) then
+			return false, ("%q already has that command on the deny list."):format(group)
+		end
+		table.insert(self.Access.Groups[group].Deny, command)
+		mode = "denied"
+	end
+	return ("%q is now %s for %s"):format(command, mode, group)
+end
+
 --- Completely remove a command from a player's access list.
 -- Removes from both the allow and deny list.
 -- @param player Player object of the player to modify.
 -- @param command Name of command to remove.
+-- @return String stating that the command has been removed or false if error.
+-- @return Error message is unsuccessful, otherwise nil.
 --
 function PM:PlayerAccessRemove(player, command)
 	if not command then return false, "No command specified" end
@@ -218,7 +294,7 @@ function PM:PlayerAccess(player, command, allow)
 		mode = "denied"
 	end
 	self:UpdatePlayer(player)
-	return ("%q is now %s for %q"):format(command, mode, player.Info.Name)
+	return ("%q is now %s for %s"):format(command, mode, player.Info.Name)
 end

 --- Update a player and subsequently save them.
@@ -243,8 +319,8 @@ function PM:IsFriend(player)
 end

 --- Check if supplied player is on the player's BN friends list.
--- Note: If the BN friend is currently offline, this will return false regardless.
--- Which means, disconnected BN friends can be kicked.
+-- Note: If the BN friend is currently offline while his character is online, this will return false regardless.
+-- Which means, BN friends that are disconnected from Battle.Net but still in the group are treated as normal users.
 -- @param player Player object of the player to check.
 -- @return True if BN friend, false otherwise.
 --
@@ -294,14 +370,12 @@ function PM:HasAccess(player, command)
 	end
 	local hasAccess = self:GetAccess(player) <= command.Access
 	local group = self.Access.Groups[player.Info.Group]
-	if CET:HasValue(group.Allow, command.Name) or CET:HasValue(player.Access.Allow, command.Name) then hasAccess = true end
-	if CET:HasValue(group.Deny, command.Name) or CET:HasValue(player.Access.Deny, command.Name) then hasAccess = false end
-	if CET:HasKey(List, command.Name) then
-		if (List[command.Name] and self:GetListMode() == MODE_BLACKLIST) or (not List[command.Name] and self:GetListMode() == MODE_WHITELIST) then
-			hasAccess = false
-		else
-			hasAccess = true
-		end
+	if CET:HasValue(group.Allow, command.Name) then hasAccess = true end
+	if CET:HasValue(group.Deny, command.Name) then hasAccess = false end
+	if CET:HasValue(player.Access.Allow, command.Name) then hasAccess = true end
+	if CET:HasValue(player.Access.Deny, command.Name) then hasAccess = false end
+	if (List[command.Name] and self:GetListMode() == MODE_BLACKLIST) or (not List[command.Name] and self:GetListMode() == MODE_WHITELIST) then
+		hasAccess = false
 	end
 	if player.Info.Name == UnitName("player") then hasAccess = true end
 	return hasAccess
@@ -498,18 +572,44 @@ function PM:PromoteToAssistant(player)
 	return false, "Unknown error occurred"
 end

+--- Check if a certain command is on the blacklist/whitelist.
+-- @param command Name of command to check.
+--
+function PM:IsListed(command)
+	return List[command]
+end
+
+--- Dynamically add or remove an item from the list.
+-- @param command Name of command to list.
+--
+function PM:List(command)
+	List[command] = not self:IsListed(command)
+end
+
 --- Add a command to the blacklist/whitelist.
 -- @param command Name of command to add.
+-- @return String stating that the command was added.
 --
 function PM:ListAdd(command)
 	List[command] = true
+	local mode = "blacklist"
+	if self:GetListMode() == MODE_WHITELIST then
+		mode = "whitelist"
+	end
+	return ("Added %s to %s."):format(command, mode)
 end

 --- Remove a command from the blacklist/whitelist.
 -- @param command Name of command to remove.
+-- @return String stating that the command was removed.
 --
 function PM:ListRemove(command)
 	List[command] = false
+	local mode = "blacklist"
+	if self:GetListMode() == MODE_WHITELIST then
+		mode = "whitelist"
+	end
+	return ("Removed %s from %s."):format(command, mode)
 end

 --- Toggle the list between being a blacklist and being a whitelist.