Quantcast

Added LuaDoc comments and cleaned up code.

F16Gaming [10-23-11 - 19:15]
Added LuaDoc comments and cleaned up code.

FIXED: Should no longer spam a player when !invme is used.
FIXED: Various missing ends etc. causing AddOn to fail loading.
ADDED: All different "Random X Dungeon" have now been added. Not tested.
Filename
ChatManager.lua
Command.lua
CommandManager.lua
EventHandler.lua
GroupTools.lua
Logger.lua
PlayerManager.lua
QueueManager.lua
String.lua
Table.lua
diff --git a/ChatManager.lua b/ChatManager.lua
index 37c0d0a..e02f33a 100644
--- a/ChatManager.lua
+++ b/ChatManager.lua
@@ -32,6 +32,10 @@ local PM = C.PlayerManager
 local CCM = C.CommandManager
 local CES = C.Extensions.String

+--- Get the channel to be used as a response channel based on event name.
+-- @param event Full name of the event.
+-- @returns The channel to be used as response channel.
+--
 function CM:GetRespondChannelByEvent(event)
 	local respondChannel = "SAY"
 	if event == "CHAT_MSG_BATTLEGROUND" then
@@ -68,10 +72,14 @@ function CM:GetRespondChannelByEvent(event)
 	return respondChannel
 end

+--- Initialize ChatManager.
+--
 function CM:Init()
 	self:LoadSavedVars()
 end

+--- Load saved variables.
+--
 function CM:LoadSavedVars()
 	if type(C.Settings.CHAT) ~= "table" then
 		C.Settings.CHAT = {}
@@ -85,6 +93,12 @@ function CM:LoadSavedVars()
 	end
 end

+--- Send a chat message.
+-- Will echo the msg param locally if LOCAL_ONLY setting is true.
+-- @param msg The message to send.
+-- @param channel The channel to send to.
+-- @param target Player or channel index to send message to.
+--
 function CM:SendMessage(msg, channel, target)
 	if not self.Settings.LOCAL_ONLY then
 		msg = ("[%s] %s"):format(C.Name, msg)
@@ -94,18 +108,37 @@ function CM:SendMessage(msg, channel, target)
 	end
 end

+--- Parse a message.
+-- @param msg The message to parse.
+-- @returns Table with the individual words.
+--
 function CM:ParseMessage(msg)
 	return CES:Split(msg)
 end

+--- Parse a command.
+-- @param cmd Command to parse.
+-- @returns Parsed command (without the command char)
+--
 function CM:ParseCommand(cmd)
 	return cmd:sub(2, cmd:len())
 end

+--- Check if a string is a command.
+-- @param msg String to check.
+-- @returns True if the string is a command, false otherwise.
+--
 function CM:IsCommand(msg)
 	return CES:StartsWith(msg, self.Settings.CMD_CHAR)
 end

+--- Handle a chat message.
+-- @param msg The message to handle.
+-- @param sender Player object of the player who sent the message.
+-- @param channel Channel the message was sent from.
+-- @param target Player or channel index.
+-- @param isBN True if battle.net message, false or nil otherwise.
+--
 function CM:HandleMessage(msg, sender, channel, target, isBN)
 	isBN = isBN or false
 	target = target or sender
diff --git a/Command.lua b/Command.lua
index 46fc594..94488eb 100644
--- a/Command.lua
+++ b/Command.lua
@@ -26,7 +26,6 @@ Command = {
 	Global = {},
 	Settings = {},
 	Events = {},
-	Modules = {}
 }

 local C = Command
@@ -35,6 +34,8 @@ local CM
 local PM
 local log

+--- Initialize method.
+--
 function C:Init()
 	Cmd = self.CommandManager
 	CM = self.ChatManager
@@ -44,6 +45,9 @@ function C:Init()
 	log.Settings.Debug = self.Settings.DEBUG
 end

+--- Load the saved variables.
+-- Also call Init() on modules that need it.
+--
 function C:LoadSavedVars()
 	if type(_G["COMMAND"]) ~= "table" then
 		_G["COMMAND"] = {}
@@ -67,35 +71,53 @@ function C:LoadSavedVars()
 	self.Global.VERSION = self.VarVersion
 end

+--- Control AddOn state.
+-- @param enabled Boolean indicating enabled or disabled state.
+--
 function C:SetEnabled(enabled)
 	self.Enabled = enabled
 end

+--- Enable AddOn.
+--
 function C:Enable()
 	self:SetEnabled(true)
 end

+--- Disable AddOn.
+--
 function C:Disable()
 	self:SetEnabled(false)
 end

+--- Toggle AddOn on and off.
+--
 function C:Toggle()
 	self:SetEnabled(not self.Enabled)
 end

+--- Control debugging state.
+-- @param enabled Boolean indicating enabled or disabled state.
+--
 function C:SetDebug(enabled)
 	self.Settings.DEBUG = enabled
 	log:SetDebug(enabled)
 end

+--- Enable debugging.
+--
 function C:EnableDebug()
 	self:SetDebug(true)
 end

+--- Disable debugging.
+--
 function C:DisableDebug()
 	self:SetDebug(false)
 end

+--- Toggle debugging.
+--
 function C:ToggleDebug()
 	self:SetDebug(not self.Settings.DEBUG)
 end
diff --git a/CommandManager.lua b/CommandManager.lua
index ec9475a..dd2a14a 100644
--- a/CommandManager.lua
+++ b/CommandManager.lua
@@ -37,6 +37,11 @@ function CM:Init()

 end

+--- Register a new command.
+-- @param command Table containing aliases for the command.
+-- @param access Number depicting the access level needed to execute command.
+-- @param func Function called to execute command. Called with params args, player and isChat.
+--
 function CM:Register(command, access, func)
 	if type(command) == "string" then
 		command = {command}
@@ -49,6 +54,10 @@ function CM:Register(command, access, func)
 	end
 end

+--- Gets the callback for a command by name.
+-- @param command Name of the command to get.
+-- @returns Callback for the command.
+--
 function CM:GetCommand(command)
 	if self.Commands[command] then
 		return self.Commands[command]
@@ -56,6 +65,14 @@ function CM:GetCommand(command)
 	return self.Commands.__DEFAULT__
 end

+--- Calls command with supplied args.
+-- @param command Command to call (name)
+-- @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)
+-- @returns If successfull, returns result, otherwise false.
+-- @returns Error message if not successful, otherwise nil.
+--
 function CM:HandleCommand(command, args, isChat, player)
 	local cmd = self:GetCommand(command)
 	if cmd then
@@ -142,7 +159,7 @@ CM:Register({"inviteme", "invme"}, PM.Access.Groups.User.Level, function(args, s
 	if not isChat then
 		return false, "This command can only be used from the chat."
 	end
-	return PM:Invite(sender)
+	return PM:Invite(sender, true)
 end)

 CM:Register({"kick"}, PM.Access.Groups.Op.Level, function(args, sender, isChat)
@@ -247,6 +264,13 @@ CM:Register({"convert", "conv"}, PM.Access.Groups.Op.Level, function(args, sende
 	end
 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."
+	end
+	return C:Toggle()
+end)
+
 for i,v in ipairs(CM.Slash) do
 	_G["SLASH_" .. C.Name:upper() .. i] = "/" .. v
 end
@@ -254,7 +278,7 @@ end
 SlashCmdList[C.Name:upper()] = function(msg, editBox)
 	msg = CES:Trim(msg)
 	local args = CES:Split(msg)
-	cmd = args[1]
+	local cmd = args[1]
 	local t = {}
 	if #args > 1 then
 		for i=2,#args do
diff --git a/EventHandler.lua b/EventHandler.lua
index 35e862a..5b109dd 100644
--- a/EventHandler.lua
+++ b/EventHandler.lua
@@ -20,6 +20,11 @@
 local C = Command
 local CES = C.Extensions.String

+--- Handles events.
+-- @param frame The frame on which the event was registered.
+-- @param event Full name of the event.
+-- @param ... Event arguments.
+--
 function C:OnEvent(frame, event, ...)
 	if not self.Events[event] then return end
 	if CES:StartsWith(event, "CHAT_MSG_") then
diff --git a/GroupTools.lua b/GroupTools.lua
index bf5e50b..fba7fd9 100644
--- a/GroupTools.lua
+++ b/GroupTools.lua
@@ -23,22 +23,41 @@ C.GroupTools = {}

 local GT = C.GroupTools

+--- Check if player is in a group.
+-- @returns True if player is in group, false otherwise.
+--
 function GT:IsGroup()
 	return UnitExists("party1")
 end

+--- Check if the player is in an LFG group.
+-- @returns True if the player is in an LFG group, false otherwise.
+--
 function GT:IsLFGGroup()
 	return (select(1, GetLFGMode())) == "lfgparty"
+end

+--- Check if player is in a raid.
+-- @returns True if the player is in a raid, false otherwise.
+--
 function GT:IsRaid()
 	return UnitInRaid("player")
 end

+--- Check if the unit is the group leader.
+-- @param name Name/Unit to check, defaults to player.
+-- @returns True if unit is group leader, false otherwise.
+--
 function GT:IsGroupLeader(name)
 	name = name or "player"
 	return UnitIsPartyLeader(name) -- or (name == "player" and not self:IsGroup())
 end

+--- Check if the group is full.
+-- NOTE: Only checks for 5 players in a party and 40 players in a raid.
+-- DOES NOT respect 10 and 25 man raids.
+-- @returns True if the group is full, false otherwise.
+--
 function GT:IsGroupFull()
 	local num = 0
 	local max = 40
@@ -52,6 +71,10 @@ function GT:IsGroupFull()
 	return false
 end

+--- Check if the unit is raid leader or assistant.
+-- @param name Unit to check, defaults to player.
+-- @returns True if the unit is raid leader or assistant, false otherwise.
+--
 function GT:IsRaidLeaderOrAssistant(name)
 	name = name or "player"
 	if not self:IsRaid() then return false end
@@ -64,11 +87,19 @@ function GT:IsRaidLeaderOrAssistant(name)
 	return false
 end

+--- Check if unit is raid assistant.
+-- @param name Unit to check, defaults to player.
+-- @returns True if assistant, false otherwise.
+--
 function GT:IsRaidAssistant(name)
 	name = name or "player"
 	return UnitIsRaidOfficer(name)
 end

+--- Check if the unit is in the player's group.
+-- @param name Unit/Player Name to check.
+-- @returns True if the unit is in group, false otherwise.
+--
 function GT:IsInGroup(name)
 	if self:IsRaid() then
 		for i=1,GetNumRaidMembers() do
diff --git a/Logger.lua b/Logger.lua
index 6e9f154..bbf8292 100644
--- a/Logger.lua
+++ b/Logger.lua
@@ -1 +1 @@
---[[
	* Copyright (c) 2011 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/>.
--]]

Command.Logger = {
	Level = {
		Debug = 0,
		Normal = 1,
		Warning = 2,
		Error = 3
	},
	Settings = {
		Debug = false,
		Format = "%s%s: %s",
		Prefix = {
			Main = "\124cff00FF00[Command]\124r",
			Debug = " \124cffBBBBFFDebug\124r",
			Normal = "",
			Warning = " \124cffFFFF00Warning\124r",
			Error = " \124cffFF0000ERROR\124r"
		}
	}
}

local Logger = Command.Logger

------------------------
-- MAIN LOGGER MODULE --
------------------------

function Logger:Print(msg, level)
	local prefix
	if level == self.Level.Debug then
		if not self.Settings.Debug then return end
		prefix = self.Settings.Prefix.Debug
	elseif level == self.Level.Normal then
		prefix = self.Settings.Prefix.Normal
	elseif level == self.Level.Warning then
		prefix = self.Settings.Prefix.Warning
	elseif level == self.Level.Error then
		prefix = self.Settings.Prefix.Error
	else
		error(("Undefined logger level passed (%q)"):format(tostring(level)))
		return
	end
	DEFAULT_CHAT_FRAME:AddMessage(self.Settings.Format:format(self.Settings.Prefix.Main, prefix, msg))
end

function Logger:Debug(msg)
	self:Print(msg, self.Level.Debug)
end

function Logger:Normal(msg)
	self:Print(msg, self.Level.Normal)
end

function Logger:Warning(msg)
	self:Print(msg, self.Level.Warning)
end

function Logger:Error(msg)
	self:Print(msg, self.Level.Error)
end

function Logger:SetDebug(enabled)
	self.Settings.Debug = enabled
end

function Logger:EnableDebug()
	self:SetDebug(true)
end

function Logger:DisableDebug()
	self:SetDebug(false)
end

function Logger:ToggleDebug()
	self:SetDebug(not self.Settings.Debug)
end
\ No newline at end of file
+--[[
	* Copyright (c) 2011 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/>.
--]]

Command.Logger = {
	Level = {
		Debug = 0,
		Normal = 1,
		Warning = 2,
		Error = 3
	},
	Settings = {
		Debug = false,
		Format = "%s%s: %s",
		Prefix = {
			Main = "\124cff00FF00[Command]\124r",
			Debug = " \124cffBBBBFFDebug\124r",
			Normal = "",
			Warning = " \124cffFFFF00Warning\124r",
			Error = " \124cffFF0000ERROR\124r"
		}
	}
}

local Logger = Command.Logger

------------------------
-- MAIN LOGGER MODULE --
------------------------

--- Print a log message at the specified level.
-- @param msg Message to pring.
-- @param level One of the levels defined in Logger.Level.
--
function Logger:Print(msg, level)
	local prefix
	if level == self.Level.Debug then
		if not self.Settings.Debug then return end
		prefix = self.Settings.Prefix.Debug
	elseif level == self.Level.Normal then
		prefix = self.Settings.Prefix.Normal
	elseif level == self.Level.Warning then
		prefix = self.Settings.Prefix.Warning
	elseif level == self.Level.Error then
		prefix = self.Settings.Prefix.Error
	else
		error(("Undefined logger level passed (%q)"):format(tostring(level)))
		return
	end
	DEFAULT_CHAT_FRAME:AddMessage(self.Settings.Format:format(self.Settings.Prefix.Main, prefix, msg))
end

--- Print a debug message.
-- @param msg Message to print.
--
function Logger:Debug(msg)
	self:Print(msg, self.Level.Debug)
end

--- Print a normal message
-- @param msg Message to print.
--
function Logger:Normal(msg)
	self:Print(msg, self.Level.Normal)
end

--- Print a warning message.
-- @param msg Message to pring.
--
function Logger:Warning(msg)
	self:Print(msg, self.Level.Warning)
end

--- Print an error message.
-- @param msg Message to print.
--
function Logger:Error(msg)
	self:Print(msg, self.Level.Error)
end


--- Control the debug state.
-- Setting debugging to enabled will make debug messages able to be printed.
-- @param enabled Boolean indicating enabled or disabled state.
--
function Logger:SetDebug(enabled)
	self.Settings.Debug = enabled
end

--- Enable debugging.
--
function Logger:EnableDebug()
	self:SetDebug(true)
end

--- Disable debugging.
--
function Logger:DisableDebug()
	self:SetDebug(false)
end

--- Toggle debugging.
--
function Logger:ToggleDebug()
	self:SetDebug(not self.Settings.Debug)
end
\ No newline at end of file
diff --git a/PlayerManager.lua b/PlayerManager.lua
index 9c9bdcb..3143349 100644
--- a/PlayerManager.lua
+++ b/PlayerManager.lua
@@ -83,12 +83,16 @@ local Player = {
 	}
 }

+--- Initialize the player manager.
+--
 function PM:Init()
 	log = C.Logger
 	CM = C.ChatManager
 	self:LoadSavedVars()
 end

+--- Load saved variables.
+--
 function PM:LoadSavedVars()
 	if type(C.Global["PLAYER_MANAGER"]) ~= "table" then
 		C.Global["PLAYER_MANAGER"] = {}
@@ -106,6 +110,10 @@ function PM:LoadSavedVars()
 	List = C.Global["PLAYER_MANAGER"]["LIST"]
 end

+--- Get or create a player.
+-- @param name Name of player.
+-- @returns Player from list of players if exists, otherwise a new player object.
+--
 function PM:GetOrCreatePlayer(name)
 	name = name:gsub("^%l", string.upper)
 	if CET:HasKey(Players, name) then
@@ -120,6 +128,11 @@ function PM:GetOrCreatePlayer(name)
 	end
 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.
+--
 function PM:PlayerAccessRemove(player, command)
 	if not command then return false, "No command specified" end
 	for i,v in pairs(player.Access.Allow) do
@@ -132,6 +145,13 @@ function PM:PlayerAccessRemove(player, command)
 	return ("%q removed from %s"):format(command, player.Info.Name)
 end

+--- Modify the access of a command for a specific player.
+-- @param player Player object of the player to modify.
+-- @param command Name of command to allow or deny.
+-- @param allow True to allow command, false to deny.
+-- @returns String stating the result, or false if error.
+-- @returns Error message if unsuccessful, otherwise nil.
+--
 function PM:PlayerAccess(player, command, allow)
 	if not command then return false, "No command specified" end
 	local mode = "allowed"
@@ -162,11 +182,18 @@ function PM:PlayerAccess(player, command, allow)
 	return ("%q is now %s for %q"):format(command, mode, player.Info.Name)
 end

+--- Update a player and subsequently save them.
+-- @param player Player object to update.
+--
 function PM:UpdatePlayer(player)
 	Players[player.Info.Name] = player
 	log:Normal(("Updated player %q."):format(player.Info.Name))
 end

+--- Check if supplied player is on the player's friends list.
+-- @param player Player object of the player to check.
+-- @return True if friend, false otherwise.
+--
 function PM:IsFriend(player)
 	if GetNumFriends() <= 0 then return false end
 	for i=1,GetNumFriends() do
@@ -176,6 +203,10 @@ function PM:IsFriend(player)
 	return false
 end

+--- Check if supplied player is on the player's BN friends list.
+-- @param player Player object of the player to check.
+-- @return True if BN friend, false otherwise.
+--
 function PM:IsBNFriend(player)
 	if BNGetNumFriends() <= 0 then return false end
 	for i=1,BNGetNumFriends() do
@@ -185,6 +216,10 @@ function PM:IsBNFriend(player)
 	return false
 end

+--- Check if the supplied player is in the player's guild.
+-- @param player Player object of the player to check.
+-- @returns True if in guild, false otherwise.
+--
 function PM:IsInGuild(player)
 	if not IsInGuild() then return false end
 	if GetNumGuildMembers() <= 1 then return false end
@@ -195,10 +230,19 @@ function PM:IsInGuild(player)
 	return false
 end

+--- Get the current access level of supplied player.
+-- @param player Player to check.
+-- @returns Access level of the player.
+--
 function PM:GetAccess(player)
 	return self.Access.Groups[player.Info.Group].Level
 end

+--- Check if player has access to command.
+-- @param player Player object of the player to check.
+-- @param command Command object of the command to check.
+-- @returns True if player has access, false otherwise.
+--
 function PM:HasAccess(player, command)
 	if player.Info.Name == UnitName("player") then return true end
 	if (self:IsInGuild(player) or self:IsBNFriend(player) or GT:IsRaidAssistant(player.Info.Name)) and command.Access >= self.Access.Groups.Op.Level then
@@ -219,6 +263,12 @@ function PM:HasAccess(player, command)
 	return hasAccess
 end

+--- Set the access group of supplied player.
+-- @param player Player to modify.
+-- @param group Group name to set the player to.
+-- @returns String stating the result of the operation, false if error.
+-- @returns Error message if unsuccessful, nil otherwise.
+--
 function PM:SetAccessGroup(player, group)
 	group = group:gsub("^%l", string.upper)
 	if player.Info.Name == UnitName("player") then
@@ -232,27 +282,56 @@ function PM:SetAccessGroup(player, group)
 	return ("Set the access level of %q to %d (%s)"):format(player.Info.Name, PM:GetAccess(player), player.Info.Group)
 end

+--- Give player Owner access.
+-- @param player Player to modify.
+-- @see Command.PlayerManager.SetAccessGroup
+--
 function PM:SetOwner(player)
 	return self:SetAccessGroup(player, self.Access.Groups.Owner.Name)
 end

+--- Give player Admin access.
+-- @param player Player to modify.
+-- @see Command.PlayerManager.SetAccessGroup
+--
 function PM:SetAdmin(player)
 	return self:SetAccessGroup(player, self.Access.Groups.Admin.Name)
 end

+--- Give player Op access.
+-- @param player Player to modify.
+-- @see Command.PlayerManager.SetAccessGroup
+--
 function PM:SetOp(player)
 	return self:SetAccessGroup(player, self.Access.Groups.Op.Name)
 end

+--- Give player User access.
+-- @param player Player to modify.
+-- @see Command.PlayerManager.SetAccessGroup
+--
 function PM:SetUser(player)
 	return self:SetAccessGroup(player, self.Access.Groups.User.Name)
 end

+--- Ban player.
+-- What this really does is set the access level to "Banned", effectively blocking the player from using any commands.
+-- Unless there is a command that requires access level "Banned". (Could be used for appeal commands).
+-- @param player Player to modify.
+-- @see Command.PlayerManager.SetAccessGroup
+--
 function PM:BanUser(player)
 	return self:SetAccessGroup(player, self.Access.Groups.Banned.Name)
 end

-function PM:Invite(player)
+--- Invite a player to group.
+-- Also sends a message to the invited player about the event.
+-- @param player Player object of player to invite.
+-- @param isSelf True if player is inviting themselves, nil or false otherwise.
+-- @returns String stating the result of the invite, false if error.
+-- @returns Error message if unsuccessful, nil otherwise.
+--
+function PM:Invite(player, isSelf)
 	if player.Info.Name == UnitName("player") then
 		return false, "Cannot invite myself to group."
 	elseif GT:IsInGroup(player.Info.Name) then
@@ -262,12 +341,21 @@ function PM:Invite(player)
 	end
 	if GT:IsGroupLeader() or GT:IsRaidLeaderOrAssistant() or not GT:IsGroup() then
 		InviteUnit(player.Info.Name)
-		CM:SendMessage(("You have been invited to the group, %s."):format(player.Info.Name), "WHISPER", player.Info.Name)
-		return ("Invited %s to group."):format(player.Info.Name)
+		if isSelf then
+			return "Invited you to the group."
+		else
+			CM:SendMessage(("You have been invited to the group, %s."):format(player.Info.Name), "WHISPER", player.Info.Name)
+			return ("Invited %s to group."):format(player.Info.Name)
+		end
 	end
 	return false, ("Unable to invite %s to group. Not group leader or assistant."):format(player.Info.Name)
 end

+--- Kick a player from the group.
+-- @param player Player object of the player to kick.
+-- @returns String stating the result of the kick, false if error.
+-- @returns Error message if unsuccessful, nil otherwise.
+--
 function PM:Kick(player)
 	if player.Info.Name == UnitName("player") then
 		return false, "Cannot kick myself."
@@ -283,6 +371,11 @@ function PM:Kick(player)
 	return false, ("Unable to kick %s from group. Not group leader or assistant."):format(player.Info.Name)
 end

+--- Promote a player to group leader.
+-- @param player Player object of the player to promote.
+-- @returns String stating the result of the promotion, false if error.
+-- @returns Error message if unsuccessful, nil otherwise.
+--
 function PM:PromoteToLeader(player)
 	if player.Info.Name == UnitName("player") then
 		return false, "Cannot promote myself to leader."
@@ -298,6 +391,11 @@ function PM:PromoteToLeader(player)
 	return false, "Unknown error occurred."
 end

+--- Promote player to assistant.
+-- @param player Player object of the player to promote.
+-- @returns String stating the result of the promotion, false if error.
+-- @returns Error message if unsuccessful, nil otherwise.
+--
 function PM:PromoteToAssistant(player)
 	if player.Info.Name == UnitName("player") then
 		return false, "Cannot promote myself to assistant."
@@ -315,14 +413,23 @@ function PM:PromoteToAssistant(player)
 	return false, "Unknown error occurred"
 end

+--- Add a command to the blacklist/whitelist.
+-- @param command Name of command to add.
+--
 function PM:ListAdd(command)
 	List[command] = true
 end

+--- Remove a command from the blacklist/whitelist.
+-- @param command Name of command to remove.
+--
 function PM:ListRemove(command)
 	List[command] = false
 end

+--- Toggle the list between being a blacklist and being a whitelist.
+-- @see Command.PlayerManager.SetListMode
+--
 function PM:ToggleListMode()
 	if self:GetListMode() == MODE_BLACKLIST then
 		return self:SetListMode(MODE_WHITELIST)
@@ -331,6 +438,10 @@ function PM:ToggleListMode()
 	end
 end

+--- Set the mode of the list.
+-- @param mode Mode to change to, MODE_WHITELIST for whitelist and MODE_BLACKLIST for blacklist.
+-- @returns String stating what mode the list is in.
+--
 function PM:SetListMode(mode)
 	if mode == MODE_WHITELIST then
 		C.Global["PLAYER_MANAGER"]["LIST_MODE"] = MODE_WHITELIST
@@ -341,6 +452,8 @@ function PM:SetListMode(mode)
 	end
 end

+--- Gets the current mode of the list.
+--
 function PM:GetListMode()
 	return C.Global["PLAYER_MANAGER"]["LIST_MODE"]
 end
diff --git a/QueueManager.lua b/QueueManager.lua
index d946f01..48d63cf 100644
--- a/QueueManager.lua
+++ b/QueueManager.lua
@@ -30,9 +30,59 @@ C.QueueManager = {
 local types = {
 	ClassicRandom = {
 		Alias = {
-
-		}
-	}
+			"classic",
+			"vanilla",
+			"classicrandom",
+			"random"
+		},
+		Id = 258
+	},
+	TBCRandom = {
+		Alias = {
+			"tbc",
+			"burningcrusade",
+			"tbcrandom",
+			"burningcrusaderandom",
+			"theburningcrusade",
+			"randomtbc"
+		},
+		Id = 259
+	},
+	TBCHeroic = {
+		Alias = {
+			"tbchc",
+			"tbcheroic",
+			"tbcrandomhc",
+			"tbcrandomheroic",
+			"randomtbchc",
+			"randomtbcheroic"
+		},
+		Id = 260
+	},
+	LKRandom = {
+		Alias = {
+			"lk",
+			"wotlk",
+			"lkrandom",
+			"wotlkrandom",
+			"lichking",
+			"wrathofthelichking"
+		},
+		Id = 261
+	},
+	LKHeroic = {
+		Alias = {
+			"lkhc",
+			"wotlkhc",
+			"hclk",
+			"hcwotlk",
+			"lkhcrandom",
+			"hclkrandom",
+			"wotlkhcrandom",
+			"hcwotlkrandom"
+		},
+		Id = 262
+	},
 	CataclysmRandom = {
 		Alias = {
 			"cata",
@@ -71,18 +121,35 @@ local types = {
 			"hallowseve",
 			"hallows",
 			"hallow",
-			"halloweve"
+			"halloweve",
+			"halloween"
 		},
 		Id = 285
+	},
+	BestChoice = {
+		Alias = {
+			"best",
+			"bestchoice",
+			"auto",
+			"choice"
+		},
+		Id = function() return GetRandomDungeonBestChoice() end
 	}
 }

 local QM = C.QueueManager

+--- Gets the numeric index of a dungoen for use with SetLFGDungeon.
+-- @param alias Name/Alias of the dungeon.
+-- @returns Index of the dungeon if dungeon was found, false otherwise.
+--
 function QM:GetIndex(alias)
 	for _,v in pairs(types) do
 		for _,d in pairs(v.Alias) do
 			if alias:lower() == d then
+				if type(v.Id) == "function" then
+					return v.Id()
+				end
 				return v.Id
 			end
 		end
@@ -90,8 +157,12 @@ function QM:GetIndex(alias)
 	return false
 end

+--- Queue for the dungeon with supplied index.
+-- @param index Index of dungeon to queue for.
+-- @returns String stating that rolecheck has started.
+--
 function QM:Queue(index)
-	_, t, h, d = GetLFGRoles()
+	local _, t, h, d = GetLFGRoles()
 	if not t and not h and not d then
 		d = true
 	end
@@ -106,18 +177,28 @@ function QM:Queue(index)
 	return ("Starting queue for %s, please select your role(s)... Type !cancel to cancel."):format(tostring(QM.Current))
 end

+--- Cancel the queueing/rolechecking.
+-- @returns String stating that queue has been cancelled.
+--
 function QM:Cancel()
 	self.QueuedByCommand = false
 	LeaveLFG()
 	return "Left the LFG queue."
 end

+--- Causes player to accept a pending LFG invite.
+-- @returns String stating that the invite was accepted.
+--
 function QM:Accept()
 	self.QueuedByCommand = false
 	AcceptProposal()
 	return "Accepted LFG invite."
 end

+--- Announce the current status of LFG to group.
+-- @param _ Not used
+-- @param elapsed Time elapsed since last time OnUpdate fired.
+--
 function QM:Announce(_, elapsed)
 	self.Time = self.Time + elapsed
 	if self.Time >= 0.25 then
@@ -137,6 +218,9 @@ function QM:Announce(_, elapsed)
 	end
 end

+--- Trigger method to announce status.
+-- This is because the status of LFG is not available straight after LFG_UPDATE event is fired.
+--
 function QM:AnnounceStatus()
 	if self.Running then return end
 	self.Running = true
diff --git a/String.lua b/String.lua
index 4b7aa41..75f3d03 100644
--- a/String.lua
+++ b/String.lua
@@ -25,18 +25,34 @@ Command.Extensions.String = {}

 local CES = Command.Extensions.String

+--- Check if a string starts with a specific string.
+-- @param s String to be checked.
+-- @param target String to search for at beginning of s.
+--
 function CES:StartsWith(s, target)
 	return s:sub(1, target:len()) == target
 end

+--- Check if a string ends with a specific string.
+-- @param s String to be checked.
+-- @param target Stromg to search for at end of s.
+--
 function CES:EndsWith(s, target)
 	return target == '' or s:sub(-target:len()) == target
 end

+--- Trim a string, removing whitespace at the beginning of it.
+-- @param s String to be trimmed.
+-- @returns The trimmed string.
+--
 function CES:Trim(s)
 	return (s:gsub("^%s*(.-)%s*$", "%1"))
 end

+--- Split a string with space as delimiter.
+-- @param s String to be split.
+-- @returns Table containing the individual words.
+--
 function CES:Split(s)
 	local t = {}
 	for token in string.gmatch(s, "[^%s]+") do
diff --git a/Table.lua b/Table.lua
index 14f6625..9765109 100644
--- a/Table.lua
+++ b/Table.lua
@@ -25,6 +25,11 @@ Command.Extensions.Table = {}

 local CET = Command.Extensions.Table

+--- Check if a table has the supplied key.
+-- @param tbl Table to check.
+-- @param key Key to search for.
+-- @returns True if the key was found, false otherwise.
+--
 function CET:HasKey(tbl, key)
 	for k,_ in pairs(tbl) do
 		if k == key then return true end
@@ -32,6 +37,10 @@ function CET:HasKey(tbl, key)
 	return false
 end

+--- Check if a table contains the supplied value.
+-- @param tbl Table to check.
+-- @param value Value to search for.
+-- @returns True if the value was found, false otherwise.
 function CET:HasValue(tbl, value)
 	for _,v in pairs(tbl) do
 		if v == value then return true end
@@ -40,6 +49,11 @@ function CET:HasValue(tbl, value)
 end

 -- Thanks to ITSBTH for the table copy function
+--- Create a copy of a table.
+-- @param tbl Table to copy.
+-- @param cache Cache used for recursion.
+-- @returns A copy of the supplied table without references.
+--
 function CET:Copy(tbl, cache)
 	if type(tbl) ~= "table" then return tbl end
 	cache = cache or {}