Quantcast

Lots of additions, changes and fixes.

F16Gaming [03-26-12 - 23:26]
Lots of additions, changes and fixes.

Battle.Net whisper handling improved!
New commands: acceptinvite, raidwarning.
New subcommand: set groupinvite
Added feature: Informs users who invite the player that !acceptinvite is available (default OFF, configurable delay before sending message).
Filename
BattleNetTools.lua
ChatManager.lua
Command.lua
CommandManager.lua
Events.lua
Events_Chat.lua
PlayerManager.lua
load.xml
diff --git a/BattleNetTools.lua b/BattleNetTools.lua
new file mode 100644
index 0000000..d3a0301
--- /dev/null
+++ b/BattleNetTools.lua
@@ -0,0 +1,162 @@
+--[[
+	* 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/>.
+--]]
+
+local C = Command
+
+C.BattleNetTools = {
+
+}
+
+local BNT = C.BattleNetTools
+local CET = C.Extensions.Table
+
+local Friend = {
+	PresenceID = 0,
+	GivenName = "",
+	SurName = "",
+	ToonName = "",
+	ToonID = 0,
+	Client = "",
+	IsOnline = false,
+	LastOnline = 0,
+	IsAFK = false,
+	IsDND = false,
+	BroadcastText = "",
+	NoteText = "",
+	IsFriend = false,
+	BroadcastTime = 0,
+	Unknown = false
+}
+
+local Toon = {
+	Unknown = false,
+	Name = "",
+	Client = "",
+	Realm = "",
+	RealmID = "",
+	Faction = -1,
+	FactionString = "",
+	Race = "",
+	Class = "",
+	Unknown2 = "",
+	Zone = "",
+	Level = 0,
+	GameText = "",
+	BroadcastText = "",
+	BroadcastTime = "",
+	Unknown3 = false,
+	Unknown4 = 0
+}
+
+local function ParseBNFriendResult(...)
+	local argc = select("#", ...)
+	if argc ~= 15 then
+		error("ParseBNFriendResult expected 15 arguments, got " .. argc)
+		return nil
+	end
+	local id, gName, sName, tName, tId, client, online, last, afk, dnd, bText, note, friend, bTime, u = ...
+	local f = CET:Copy(Friend)
+	f.PresenceID = id
+	f.GivenName = gName
+	f.SurName = sName
+	f.ToonName = tName
+	f.ToonID = tID
+	f.Client = client
+	f.IsOnline = online
+	f.LastOnline = last
+	f.IsAFK = afk
+	f.IsDND = dnd
+	f.BroadcastText = bText
+	f.NoteText = note
+	f.IsFriend = friend
+	f.BroadcastTime = bTime
+	f.Unknown = u
+	return f
+end
+
+local function ParseBNToonResult(...)
+	local argc = select("#", ...)
+	if argc ~= 16 then
+		error("ParseBNToonResult expected 16 arguments, got " .. argc)
+		return nil
+	end
+	local u, name, client, realm, realmId, faction, race, class, u2, zone, lvl, text, bText, bTime, u3, u4 = ...
+	local t = CET:Copy(Toon)
+	t.Unknown = u
+	t.Name = name
+	t.Client = client
+	t.Realm = realm
+	t.RealmID = realmId
+	t.Faction = faction
+	if t.Faction == 0 then
+		t.FactionString = "Horde"
+	elseif t.Faction == 1 then
+		t.FactionString = "Alliance"
+	end
+	t.Race = race
+	t.Class = class
+	t.Unknown2 = u2
+	t.Zone = zone
+	t.Level = tonumber(lvl)
+	t.GameText = text
+	t.BroadcastText = bText
+	t.BroadcastTime = bTime
+	t.Unknown3 = u3
+	t.Unknown4 = u4
+	return t
+end
+
+function BNT:GetFriend(index)
+	if index < 1 or index > BNGetNumFriends() then
+		return nil
+	end
+	return ParseBNFriendResult(BNGetFriendInfo(index))
+end
+
+function BNT:GetFriendById(id)
+	return ParseBNFriendResult(BNGetFriendInfoByID(id))
+end
+
+function BNT:GetFriendByName(name)
+	local n = BNGetNumFriends()
+	if n <= 0 then return nil end
+	for i = 1, n do
+		local friend = ParseBNFriendResult(BNGetFriendInfo(i))
+		if friend.ToonName:lower() == name:lower() then
+			return friend
+		end
+	end
+	return nil
+end
+
+function BNT:GetToon(id)
+	return ParseBNToonResult(BNGetToonInfo(id))
+end
+
+function BNT:GetToonByName(name)
+	local numF = BNGetNumFriends()
+	if numF <= 0 then return nil end
+	for i = 1, numF do
+		for t = 1, BNGetNumFriendToons(i) do
+			local toon = ParseBNToonResult(BNGetFriendToonInfo(i, t))
+			if toon.Name:lower() == name:lower() then return toon end
+		end
+	end
+	return nil
+end
diff --git a/ChatManager.lua b/ChatManager.lua
index f6c9592..a940ca9 100644
--- a/ChatManager.lua
+++ b/ChatManager.lua
@@ -191,7 +191,7 @@ function CM:SetCmdChar(char)
 	if type(char) ~= "string" then
 		return false, "Command char has to be of type string."
 	end
-	char = char:lower()
+	char = char:lower():sub(1, 1)
 	self.Settings.CMD_CHAR = char
 	return "Successfully set the command char to: " .. char
 end
diff --git a/Command.lua b/Command.lua
index e58e9f5..7900732 100644
--- a/Command.lua
+++ b/Command.lua
@@ -32,7 +32,7 @@
 Command = {
 	Name = "Command",
 	Version = GetAddOnMetadata("Command", "Version"),
-	VersionNum = 6, -- Increment on every release
+	VersionNum = 7, -- Increment on every release
 	VersionChecked = false, -- Prevent spam of "New Version" notice
 	Loaded = false,
 	VarVersion = 2,
@@ -91,6 +91,12 @@ function C:LoadSavedVars()
 	if type(self.Settings.ENABLED) ~= "bolean" then
 		self.Settings.ENABLED = true
 	end
+	if type(self.Settings.GROUP_INVITE_ANNOUNCE) ~= "boolean" then
+		self.Settings.GROUP_INVITE_ANNOUNCE = false
+	end
+	if type(self.Settings.GROUP_INVITE_ANNOUNCE_DELAY) ~= "number" then
+		self.Settings.GROUP_INVITE_ANNOUNCE_DELAY = 0
+	end
 	CM:Init()
 	PM:Init()
 	RM:Init()
@@ -167,3 +173,42 @@ end
 function C:ToggleDebug()
 	return self:SetDebug(not self.Settings.DEBUG)
 end
+
+function C:SetGroupInvite(enabled)
+	self.Settings.GROUP_INVITE_ANNOUNCE = enabled
+	if self.Settings.GROUP_INVITE_ANNOUNCE then
+		return "Group Invite (Announce) enabled."
+	end
+	return "Group Invite (Announce) disabled."
+end
+
+function C:EnableGroupInvite()
+	return self:SetGroupInvite(true)
+end
+
+function C:DisableGroupInvite()
+	return self:SetGroupInvite(false)
+end
+
+function C:ToggleGroupInvite()
+	return self:SetGroupInvite(not self.Settings.GROUP_INVITE_ANNOUNCE)
+end
+
+function C:SetGroupInviteDelay(time)
+	if type(time) ~= "number" then
+		return false, "Delay has to be a number."
+	end
+	time = math.ceil(time)
+	if time > 50 then
+		return false, "Delay cannot be greater than 50 seconds."
+	end
+	self.Settings.GROUP_INVITE_ANNOUNCE_DELAY = time
+	if self.Settings.GROUP_INVITE_ANNOUNCE_DELAY > 0 then
+		return "Group Invite (Announce) delay set to " .. self.Settings.GROUP_INVITE_ANNOUNCE_DELAY .. " seconds."
+	end
+	return "Group Invite (Announce) delay disabled."
+end
+
+function C:DisableGroupInviteDelay()
+	return self:SetGroupInviteDelay(0)
+end
diff --git a/CommandManager.lua b/CommandManager.lua
index 48859a5..e172353 100644
--- a/CommandManager.lua
+++ b/CommandManager.lua
@@ -180,7 +180,7 @@ CM:Register({"version", "ver", "v"}, PM.Access.Groups.User.Level, function(args,
 end, "Print the version of Command")

 CM:Register({"set", "s"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat)
-	local usage = "Usage: set cmdchar"
+	local usage = "Usage: set cmdchar|groupinvite"
 	if #args <= 0 then
 		return false, usage
 	end
@@ -190,6 +190,20 @@ CM:Register({"set", "s"}, PM.Access.Groups.Admin.Level, function(args, sender, i
 			return false, "No command character specified."
 		end
 		return Chat:SetCmdChar(args[2])
+	elseif args[1]:match("^g") then -- Group invite (announce)
+		if #args < 2 then
+			return false, "Usage: set groupinvite enable|disable|<time>"
+		end
+		args[2] = args[2]:lower()
+		local time = tonumber(args[2])
+		if time then
+			return C:SetGroupInviteDelay(time)
+		elseif args[2]:match("^[eay]") then -- Enable
+			return C:EnableGroupInvite()
+		elseif args[2]:match("^[dn]") then -- Disable
+			return C:DisableGroupInvite()
+		end
+		return false, "Usage: set groupinvite enable|disable|<time>"
 	end
 	return false, usage
 end, "Control the settings of Command.")
@@ -277,6 +291,16 @@ CM:Register({"ban"}, PM.Access.Groups.Admin.Level, function(args, sender, isChat
 	return PM:BanUser(player)
 end, "Ban a player.")

+CM:Register({"acceptinvite", "acceptinv", "join", "joingroup"}, PM.Access.Groups.User.Level, function(args, sender, isChat)
+	if not StaticPopup_Visible("PARTY_INVITE") then
+		return false, "No pending invites active."
+	elseif GT:IsInGroup() then
+		return false, "I am already in a group." -- This shouldn't happen
+	end
+	AcceptGroup()
+	return "Accepted group invite!"
+end, "Accepts a pending group invite.")
+
 CM:Register({"invite", "inv"}, PM.Access.Groups.User.Level, function(args, sender, isChat)
 	if type(args[1]) == "string" then
 		local player = PM:GetOrCreatePlayer(args[1])
@@ -657,7 +681,13 @@ CM:Register({"raidwarning", "rw", "raid_warning"}, PM.Access.Groups.User.Level,
 	elseif #args <= 0 then
 		return false, "Usage: raidwarning <message>"
 	end
-	Chat:SendMessage(args[1], "RAID_WARNING")
+	local msg = args[1]
+	if #args > 1 then
+		for i = 2, #args do
+			msg = msg .. " " .. args[i]
+		end
+	end
+	Chat:SendMessage(msg, "RAID_WARNING")
 	return "Sent raid warning."
 end, "Sends a raid warning.")

diff --git a/Events.lua b/Events.lua
index ec5a3c1..555ddf8 100644
--- a/Events.lua
+++ b/Events.lua
@@ -87,7 +87,22 @@ function C.Events.RAID_ROSTER_UPDATE(self, ...)
 	AC:UpdateGroup()
 end

+function C.Events.PARTY_INVITE_REQUEST(self, ...)
+	if not self.Settings.GROUP_INVITE_ANNOUNCE then return end
+	local sender = (select(1, ...))
+	local msg = "Type !acceptinvite to make me accept the group invite."
+	if self.Settings.GROUP_INVITE_ANNOUNCE_DELAY > 0 then
+		local f=CreateFrame("Frame")f.T=0;f.L=self.Settings.GROUP_INVITE_ANNOUNCE_DELAY;f.S=sender;f.M=msg
+		f:SetScript("OnUpdate",function(s,e)s.T=s.T+e;if(s.T>s.L)then s:SetScript("OnUpdate",nil)if(StaticPopup_Visible("PARTY_INVITE"))then CM:SendMessage(s.M,"WHISPER",s.S)end;end;end)
+	else
+		CM:SendMessage(msg, "WHISPER", sender)
+	end
+end
+
 function C.Events.PARTY_MEMBERS_CHANGED(self, ...)
+	if StaticPopup_Visible("PARTY_INVITE") then
+		StaticPopup_Hide("PARTY_INVITE")
+	end
 	if AC.GroupRunning then return end
 	AC:UpdateGroup()
 end
diff --git a/Events_Chat.lua b/Events_Chat.lua
index 1fa26d7..9eb6ac7 100644
--- a/Events_Chat.lua
+++ b/Events_Chat.lua
@@ -20,6 +20,7 @@
 local C = Command
 local CM = C.ChatManager
 local AC = C.AddonComm
+local BNT = C.BattleNetTools

 function C.Events.CHAT_MSG_SYSTEM(self, event, ...)
 	if C.RollManager.Running then
@@ -64,11 +65,11 @@ function C.Events.CHAT_MSG_BN_WHISPER(self, event, ...)
 	local chan = "BNET"
 	local msg = (select(1, ...))
 	local id = (select(13, ...))
-	local _, name, client, realm, _, faction, _, _, _, _, _, _, _, _ = BNGetToonInfo(id)
-	if not name or client:lower() ~= "wow" then return end
-	if faction == 0 then faction = "horde" elseif faction == 1 then faction = "alliance" end
-	if realm:lower() == GetRealmName():lower() and faction == (select(1, UnitFactionGroup("player"))):lower() then
-		CM:HandleMessage(msg, name, chan, id, chan, true, id)
+	local toon = BNT:GetToon(id)
+	if not toon then return end
+	if toon.Client ~= BNET_CLIENT_WOW then return end
+	if toon.Realm:lower() == GetRealmName():lower() and toon.FactionString:lower() == (select(1, UnitFactionGroup("player"))):lower() then
+		CM:HandleMessage(msg, toon.Name, chan, id, chan, true, id)
 	end
 end

diff --git a/PlayerManager.lua b/PlayerManager.lua
index 1494f1b..afdab53 100644
--- a/PlayerManager.lua
+++ b/PlayerManager.lua
@@ -23,6 +23,7 @@ local MODE_WHITELIST = 1
 local C = Command
 local CM
 local GT = C.GroupTools
+local BNT = C.BattleNetTools
 local CCM
 local CET = C.Extensions.Table
 local log
@@ -366,11 +367,9 @@ end
 -- @return True if BN friend, false otherwise.
 --
 function PM:IsBNFriend(player)
-	if BNGetNumFriends() <= 0 then return false end
-	for i=1,BNGetNumFriends() do
-		local char, client = (select(4, BNGetFriendInfo(i))), (select(6, BNGetFriendInfo(i)))
-		if char == player.Info.Name and client == "WoW" then return true end
-	end
+	local friend = BNT:GetFriendByName(player.Info.Name)
+	if not friend then return false end
+	if friend.Client == BNET_CLIENT_WOW then return true end
 	return false
 end

diff --git a/load.xml b/load.xml
index 3f79a87..19f2c8e 100644
--- a/load.xml
+++ b/load.xml
@@ -23,6 +23,7 @@
 	<Script file="Table.lua" />
 	<Script file="String.lua" />
 	<Script file="Logger.lua" />
+	<Script file="BattleNetTools.lua" />
 	<Script file="GroupTools.lua" />
 	<Script file="PlayerManager.lua" />
 	<Script file="QueueManager.lua" />