Quantcast

FIXED: AddOn communication should now work properly.

F16Gaming [02-11-12 - 00:55]
FIXED: AddOn communication should now work properly.

Still needs testing with another Command-enabled client.
Filename
AddonComm.lua
ChatManager.lua
Events.lua
Events_Chat.lua
diff --git a/AddonComm.lua b/AddonComm.lua
index d116f1b..8694263 100644
--- a/AddonComm.lua
+++ b/AddonComm.lua
@@ -26,24 +26,59 @@ local CET = C.Extensions.Table
 local log = C.Logger

 C.AddonComm = {
-	Halted = false,
+	InGroup = false,
+	InGuild = false,
+	GroupMaster = true,
+	GuildMaster = true,
+	GroupChecked = false,
+	GuildChecked = false,
+	GroupRunning = false,
+	GuildRunning = false,
 	Type = {
 		VersionUpdate = "COMM_VU",
-		HandleCommand = "COMM_DO"
+		GroupUpdate = "COMM_GU",
+		GroupAdd = "COMM_GA",
+		GuildUpdate = "COMM_UG",
+		GuildAdd = "COMM_AG"
 	},
 	Format = {
 		VersionUpdate = "%s",
-		HandleCommand = "%s;&%s;&%s"
 	},
-	Last = {
-		Sender = nil,
-		Message = nil,
-		Channel = nil
-	}
+	GroupMembers = {},
+	GuildMembers = {}
 }

 local AC = C.AddonComm

+local CONTROLLER_WAIT = 5
+
+local GroupTimer = CreateFrame("Frame")
+local GuildTimer = CreateFrame("Frame")
+GroupTimer.Time = 0
+GuildTimer.Time = 0
+
+local function GroupTimerUpdate(frame, elapsed)
+	frame.Time = frame.Time + elapsed
+	if frame.Time >= CONTROLLER_WAIT then
+		frame.Time = 0
+		AC.GroupRunning = false
+		frame:SetScript("OnUpdate", nil)
+		log:Normal("No response from group, running updater...")
+		AC:UpdateGroup()
+	end
+end
+
+local function GuildTimerUpdate(frame, elapsed)
+	frame.Time = frame.Time + elapsed
+	if frame.Time >= CONTROLLER_WAIT then
+		frame.Time = 0
+		AC.GuildRunning = false
+		frame:SetScript("OnUpdate", nil)
+		log:Normal("No response from guild, running updater...")
+		AC:UpdateGuild()
+	end
+end
+
 function AC:Init()
 	--self:LoadSavedVars()
 	for _,v in pairs(self.Type) do
@@ -56,24 +91,57 @@ function AC:LoadSavedVars()
 end

 function AC:Receive(msgType, msg, channel, sender)
-	if sender == UnitName("player") then return end
+	if sender == UnitName("player") or not msg then return end
 	if msgType == self.Type.VersionUpdate then
 		local ver = tonumber(msg)
 		if type(ver) ~= "number" then return end
 		C:CheckVersion(ver)
-	elseif msgType == self.Type.HandleCommand then
-		local t = CES:Split(msg, ";&")
-		for i,v in ipairs(t) do log:Normal(i .. ": " .. tostring(v)) end
-		if #t < 3 then return end
-		local name = tostring(t[1])
-		local sent = tostring(t[2])
-		local chan = tostring(t[3])
-		if type(t[1]) ~= "string" or type(t[2]) ~= "string" or type(t[3]) ~= "string" then return end
-		log:Normal("Received HandleCommand from " .. sender)
-		self.Last.Sender = name
-		self.Last.Message = sent
-		self.Last.Channel = chan
-		--self.Halted = true
+	elseif msgType == self.Type.GroupUpdate then
+		if channel ~= "RAID" and channel ~= "PARTY" then return end
+		if self.GroupRunning then
+			GroupTimer:SetScript("OnUpdate", nil)
+			GroupTimer.Time = 0
+			self.GroupRunning = false
+		end
+		local t = CES:Split(msg, ";")
+		wipe(self.GroupMembers)
+		for _,v in ipairs(t) do
+			if v then
+				table.insert(self.GroupMembers, v)
+			end
+		end
+		log:Normal("Updated group members, controller: " .. self.GroupMembers[1])
+		self:UpdateGroup()
+	elseif msgType == self.Type.GroupAdd then
+		if channel ~= "WHISPER" or not GT:IsGroup() then return end
+		if self.GroupMembers[1] ~= UnitName("player") then return end
+		if not CET:HasValue(self.GroupMembers, msg) then
+			table.insert(self.GroupMembers, msg)
+		end
+		self:Send(self.Type.GroupUpdate, table.concat(self.GroupMembers, ";"), "RAID")
+	elseif msgType == self.Type.GuildUpdate then
+		if channel ~= "GUILD" then return end
+		if self.GuildRunning then
+			GuildTimer:SetScript("OnUpdate", nil)
+			GuildTimer.Time = 0
+			self.GuildRunning = false
+		end
+		local t = CES:Split(msg, ";")
+		wipe(self.GuildMembers)
+		for _,v in ipairs(t) do
+			if v then
+				table.insert(self.GuildMembers, v)
+			end
+		end
+		log:Normal("Updated guild members, controller: " .. self.GuildMembers[1])
+		self:UpdateGuild()
+	elseif msgType == self.Type.GuildAdd then
+		if channel ~= "WHISPER" then return end
+		if self.GuildMembers[1] ~= UnitName("player") then return end
+		if not CET:HasValue(self.GuildMembers, msg) then
+			table.insert(self.GuildMembers, msg)
+		end
+		self:Send(self.Type.GuildUpdate, table.concat(self.GuildMembers, ";"), "GUILD")
 	end
 end

@@ -84,30 +152,114 @@ function AC:Send(msgType, msg, channel, target)
 		return
 	end
 	SendAddonMessage(msgType, msg, channel, target)
-	if msgType == self.Type.HandleCommand then
+	if msgType ~= self.Type.VersionUpdate then
 		SendAddonMessage(self.Type.VersionUpdate, self.Format.VersionUpdate:format(C.VersionNum), channel)
 	end
 end

-function AC:Handled(msg, sender, channel)
-	if self.Halted then return false end
-	if channel == "WHISPER" then return true end
-	if self:IsHandled(msg, sender, channel) then return false end
-	self:Send(self.Type.HandleCommand, self.Format.HandleCommand:format(sender, msg, channel), channel)
-	return true
+function AC:UpdateGroup()
+	if not GT:IsGroup() then
+		self.InGroup = false
+		self.GroupChecked = false
+		self.GroupMaster = true
+		wipe(self.GroupMembers)
+		return
+	end
+	self:CheckGroupRoster()
+	if not self.InGroup then -- Just joined group
+		self.GroupMaster = false
+		if not self.GroupChecked then
+			self.GroupChecked = true
+			self.GroupRunning = true
+			log:Normal("Waiting for group response...")
+			GroupTimer:SetScript("OnUpdate", GroupTimerUpdate)
+			return
+		end
+		self.InGroup = true
+		if self.GroupMembers[1] == UnitName("player") or not self.GroupMembers[1] then
+			self.GroupMaster = true
+			self.GroupMembers[1] = UnitName("player")
+			self:Send(self.Type.GroupUpdate, table.concat(self.GroupMembers, ";"), "RAID")
+		else
+			self.GroupMaster = false
+			self:Send(self.Type.GroupAdd, UnitName("player"), "WHISPER", self.GroupMembers[1])
+		end
+	else -- Already in group
+		if self.GroupMembers[1] == UnitName("player") then
+			self.GroupMaster = true
+			self:Send(self.Type.GroupUpdate, table.concat(self.GroupMembers, ";"), "RAID")
+		else
+			self.GroupMaster = false
+		end
+	end
 end

-function AC:IsHandled(msg, sender, channel)
-	if channel == "WHISPER" then return false end
-	if tostring(msg) == self.Last.Message and tostring(sender) == self.Last.Sender and tostring(channel) == self.Last.Channel then
-		return true
+function AC:UpdateGuild()
+	if not IsInGuild() then
+		self.InGuild = false
+		self.GuildChecked = false
+		self.GuildMaster = true
+		wipe(self.GuildMembers)
+		return
+	end
+	self:CheckGuildRoster()
+	if not self.InGuild then -- Probably logged in and is getting guild update for the first time
+		self.GuildMaster = false
+		if not self.GuildChecked then
+			self.GuildChecked = true
+			self.GuildRunning = true
+			log:Normal("Waiting for guild response...")
+			GuildTimer:SetScript("OnUpdate", GuildTimerUpdate)
+			return
+		end
+		self.InGuild = true
+		if self.GuildMembers[1] == UnitName("player") or not self.GuildMembers[1] then
+			self.GuildMaster = true
+			self.GuildMembers[1] = UnitName("player")
+			self:Send(self.Type.GuildUpdate, table.concat(self.GuildMembers, ";"), "GUILD")
+		else
+			self.GuildMaster = false
+			self:Send(self.Type.GuildAdd, UnitName("player"), "WHISPER", self.GuildMembers[1])
+		end
+	else -- Already in guild
+		if self.GuildMembers[1] == UnitName("player") then
+			self.GuildMaster = true
+			self:Send(self.Type.GuildUpdate, table.concat(self.GuildMembers, ";"), "GUILD")
+		else
+			self.GuildMaster = false
+		end
+	end
+end
+
+function AC:CheckGroupRoster()
+	for i,v in ipairs(self.GroupMembers) do
+		if not GT:IsInGroup(v) then
+			table.remove(self.GroupMembers, i)
+		end
 	end
-	return false
 end

-function AC:Reset()
-	self.Last.Sender = nil
-	self.Last.Message = nil
-	self.Last.Channel = nil
-	self.Halted = false
+function AC:CheckGuildRoster()
+	local g = {}
+	for i=1, (select(1, GetNumGuildMembers())) do
+		local name = tostring((select(1, GetGuildRosterInfo(i))))
+		local online = (select(9, GetGuildRosterInfo(i)))
+		g[name] = online
+	end
+	for i,v in pairs(self.GuildMembers) do
+		if not g[v] then
+			table.remove(self.GuildMembers, i)
+		end
+	end
+end
+
+function AC:IsController(channel)
+	if channel == "RAID" or channel == "PARTY" then
+		self:CheckGroupRoster()
+		return self.GroupMembers[1] == UnitName("player")
+	elseif channel == "GUILD" then
+		self:CheckGuildRoster()
+		return self.GuildMembers[1] == UnitName("player")
+	end
+	return true
 end
diff --git a/ChatManager.lua b/ChatManager.lua
index e4a006c..214b3e1 100644
--- a/ChatManager.lua
+++ b/ChatManager.lua
@@ -161,13 +161,10 @@ end
 -- @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)
+function CM:HandleMessage(msg, sender, channel, target, sourceChannel, isBN)
 	isBN = isBN or false
 	target = target or sender
-	if isBN then
-		C.Logger:Normal("Battle.Net convos/whispers are not supported yet")
-		return
-	end
+	if isBN then return end
 	local raw = msg
 	msg = CES:Trim(msg)
 	local args = self:ParseMessage(msg)
@@ -176,8 +173,8 @@ function CM:HandleMessage(msg, sender, channel, target, isBN)
 	self.LastTarget = target
 	local cmd = self:ParseCommand(args[1])
 	if not CCM:HasCommand(cmd) then return end
-	if channel ~= "WHISPER" and not AC:Handled(raw, sender, channel) then
-		C.Logger:Normal("Request already handled by another instance of Command, aborting...")
+	if not AC:IsController(sourceChannel) then
+		C.Logger:Normal("Not controller instance for \124cff00FFFF" .. sourceChannel:lower() .. "\124r, aborting.")
 		return
 	end
 	local t = {}
@@ -187,13 +184,6 @@ function CM:HandleMessage(msg, sender, channel, target, isBN)
 		end
 	end

-	--[[
-	if channel ~= "WHISPER" and AC:IsHandled(msg, sender) then
-		C.Logger:Normal("Request already handled by other instance of Command, aborting...")
-		return
-	end
-	]]
-
 	local player = PM:GetOrCreatePlayer(sender)
 	local result, err = CCM:HandleCommand(cmd, t, true, player)
 	if result then
diff --git a/Events.lua b/Events.lua
index d8fddac..ec5a3c1 100644
--- a/Events.lua
+++ b/Events.lua
@@ -21,6 +21,7 @@ local C = Command

 local CM = C.ChatManager
 local QM = C.QueueManager
+local AC = C.AddonComm

 --[[
 function T.Events.CHAT_MSG_ADDON(event, ...)
@@ -80,3 +81,23 @@ end
 function C.Events.READY_CHECK_FINISHED(self, ...)
 	C.Data.ReadyCheckRunning = false
 end
+
+function C.Events.RAID_ROSTER_UPDATE(self, ...)
+	if AC.GroupRunning then return end
+	AC:UpdateGroup()
+end
+
+function C.Events.PARTY_MEMBERS_CHANGED(self, ...)
+	if AC.GroupRunning then return end
+	AC:UpdateGroup()
+end
+
+function C.Events.PARTY_LEADER_CHANGED(self, ...)
+	if AC.GroupRunning then return end
+	AC:UpdateGroup()
+end
+
+function C.Events.GUILD_ROSTER_UPDATE(self, ...)
+	if AC.GuildRunning then return end
+	AC:UpdateGuild()
+end
diff --git a/Events_Chat.lua b/Events_Chat.lua
index ae33714..93feea9 100644
--- a/Events_Chat.lua
+++ b/Events_Chat.lua
@@ -75,7 +75,7 @@ function C.Events.CHAT_MSG_GUILD(self, event, ...)
 	local chan = CM:GetRespondChannelByEvent(event)
 	local msg = (select(1, ...))
 	local sender = (select(2, ...))
-	CM:HandleMessage(msg, sender, chan)
+	CM:HandleMessage(msg, sender, chan, nil, "GUILD")
 end

 --- Event handler for CHAT_MSG_OFFICER.
@@ -88,7 +88,7 @@ function C.Events.CHAT_MSG_OFFICER(self, event, ...)
 	local chan = CM:GetRespondChannelByEvent(event)
 	local msg = (select(1, ...))
 	local sender = (select(2, ...))
-	CM:HandleMessage(msg, sender, chan)
+	CM:HandleMessage(msg, sender, chan, nil, "GUILD")
 end

 --- Event handler for CHAT_MSG_PARTY.
@@ -101,7 +101,7 @@ function C.Events.CHAT_MSG_PARTY(self, event, ...)
 	local chan = CM:GetRespondChannelByEvent(event)
 	local msg = (select(1, ...))
 	local sender = (select(2, ...))
-	CM:HandleMessage(msg, sender, chan)
+	CM:HandleMessage(msg, sender, chan, nil, "PARTY")
 end

 --- Event handler for CHAT_MSG_PARTY_LEADER.
@@ -114,7 +114,7 @@ function C.Events.CHAT_MSG_PARTY_LEADER(self, event, ...)
 	local chan = CM:GetRespondChannelByEvent(event)
 	local msg = (select(1, ...))
 	local sender = (select(2, ...))
-	CM:HandleMessage(msg, sender, chan)
+	CM:HandleMessage(msg, sender, chan, nil, "PARTY")
 end

 --- Event handler for CHAT_MSG_RAID.
@@ -127,7 +127,7 @@ function C.Events.CHAT_MSG_RAID(self, event, ...)
 	local chan = CM:GetRespondChannelByEvent(event)
 	local msg = (select(1, ...))
 	local sender = (select(2, ...))
-	CM:HandleMessage(msg, sender, chan)
+	CM:HandleMessage(msg, sender, chan, nil, "RAID")
 end

 --- Event handler for CHAT_MSG_RAID_LEADER.
@@ -140,7 +140,7 @@ function C.Events.CHAT_MSG_RAID_LEADER(self, event, ...)
 	local chan = CM:GetRespondChannelByEvent(event)
 	local msg = (select(1, ...))
 	local sender = (select(2, ...))
-	CM:HandleMessage(msg, sender, chan)
+	CM:HandleMessage(msg, sender, chan, nil, "RAID")
 end

 --- Event handler for CHAT_MSG_RAID_WARNING.
@@ -153,7 +153,7 @@ function C.Events.CHAT_MSG_RAID_WARNING(self, event, ...)
 	local chan = CM:GetRespondChannelByEvent(event)
 	local msg = (select(1, ...))
 	local sender = (select(2, ...))
-	CM:HandleMessage(msg, sender, chan)
+	CM:HandleMessage(msg, sender, chan, nil, "RAID")
 end

 --[[
@@ -176,7 +176,7 @@ function C.Events.CHAT_MSG_WHISPER(self, event, ...)
 	local msg = (select(1, ...))
 	local sender = (select(2, ...))
 	local target = sender
-	CM:HandleMessage(msg, sender, chan, target)
+	CM:HandleMessage(msg, sender, chan, target, "WHISPER")
 end

 --[[