PageRenderTime 536ms CodeModel.GetById 60ms app.highlight 344ms RepoModel.GetById 80ms app.codeStats 1ms

/Tukui/modules/datatext/friend.lua

http://github.com/Asphyxia/Tukui
Lua | 335 lines | 282 code | 40 blank | 13 comment | 99 complexity | a0235fcdcb4060b1fedcbfd863db1032 MD5 | raw file
  1--------------------------------------------------------------------
  2-- FRIEND
  3--------------------------------------------------------------------
  4local T, C, L = unpack(select(2, ...)) -- Import Functions/Constants, Config, Locales
  5
  6if not C["datatext"].friends or C["datatext"].friends == 0 then return end
  7
  8-- create a popup
  9StaticPopupDialogs.SET_BN_BROADCAST = {
 10	text = BN_BROADCAST_TOOLTIP,
 11	button1 = ACCEPT,
 12	button2 = CANCEL,
 13	hasEditBox = 1,
 14	editBoxWidth = 350,
 15	maxLetters = 127,
 16	OnAccept = function(self) BNSetCustomMessage(self.editBox:GetText()) end,
 17	OnShow = function(self) self.editBox:SetText(select(3, BNGetInfo()) ) self.editBox:SetFocus() end,
 18	OnHide = ChatEdit_FocusActiveWindow,
 19	EditBoxOnEnterPressed = function(self) BNSetCustomMessage(self:GetText()) self:GetParent():Hide() end,
 20	EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end,
 21	timeout = 0,
 22	exclusive = 1,
 23	whileDead = 1,
 24	hideOnEscape = 1,
 25	preferredIndex = 3,
 26}
 27
 28local Stat = CreateFrame("Frame")
 29Stat:EnableMouse(true)
 30Stat:SetFrameStrata("MEDIUM")
 31Stat:SetFrameLevel(3)
 32
 33local Text  = TukuiInfoLeft:CreateFontString(nil, "OVERLAY")
 34Text:SetFont(C.media.pixelfont, C["datatext"].fontsize, "MONOCHROMEOUTLINE")
 35Text:SetShadowOffset(T.mult, -T.mult)
 36T.PP(C["datatext"].friends, Text)
 37
 38local menuFrame = CreateFrame("Frame", "TukuiFriendRightClickMenu", UIParent, "UIDropDownMenuTemplate")
 39local menuList = {
 40	{ text = OPTIONS_MENU, isTitle = true,notCheckable=true},
 41	{ text = INVITE, hasArrow = true,notCheckable=true, },
 42	{ text = CHAT_MSG_WHISPER_INFORM, hasArrow = true,notCheckable=true, },			
 43	{ text = PLAYER_STATUS, hasArrow = true, notCheckable=true,
 44		menuList = {
 45			{ text = "|cff2BC226"..AVAILABLE.."|r", notCheckable=true, func = function() if IsChatAFK() then SendChatMessage("", "AFK") elseif IsChatDND() then SendChatMessage("", "DND") end end },
 46			{ text = "|cffE7E716"..DND.."|r", notCheckable=true, func = function() if not IsChatDND() then SendChatMessage("", "DND") end end },
 47			{ text = "|cffFF0000"..AFK.."|r", notCheckable=true, func = function() if not IsChatAFK() then SendChatMessage("", "AFK") end end },
 48		},
 49	},
 50	{ text = BN_BROADCAST_TOOLTIP, notCheckable=true, func = function() StaticPopup_Show("SET_BN_BROADCAST") end },
 51}
 52
 53local function GetTableIndex(table, fieldIndex, value)
 54	for k,v in ipairs(table) do
 55		if v[fieldIndex] == value then return k end
 56	end
 57	return -1
 58end
 59
 60local function inviteClick(self, arg1, arg2, checked)
 61	menuFrame:Hide()
 62	InviteUnit(arg1)
 63end
 64
 65local function whisperClick(self,arg1,arg2,checked)
 66	menuFrame:Hide() 
 67	SetItemRef( "player:"..arg1, ("|Hplayer:%1$s|h[%1$s]|h"):format(arg1), "LeftButton" )		 
 68end
 69
 70local levelNameString = "|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r"
 71local clientLevelNameString = "%s (|cff%02x%02x%02x%d|r |cff%02x%02x%02x%s|r%s) |cff%02x%02x%02x%s|r"
 72local levelNameClassString = "|cff%02x%02x%02x%d|r %s%s%s"
 73local worldOfWarcraftString = "World of Warcraft"
 74local battleNetString = "Battle.NET"
 75local wowString = "WoW"
 76local totalOnlineString = FRIENDS_LIST_ONLINE .. ": %s/%s"
 77local tthead, ttsubh, ttoff = {r=0.4, g=0.78, b=1}, {r=0.75, g=0.9, b=1}, {r=.3,g=1,b=.3}
 78local activezone, inactivezone = {r=0.3, g=1.0, b=0.3}, {r=0.65, g=0.65, b=0.65}
 79local displayString = string.join("", "%s: ", "|cffffffff", T.datacolor.."%d|r")
 80local statusTable = { "[AFK]", "[DND]", "" }
 81local groupedTable = { "|cffaaaaaa*|r", "" } 
 82local friendTable, BNTable = {}, {}
 83local totalOnline, BNTotalOnline = 0, 0
 84
 85local function BuildFriendTable(total)
 86	totalOnline = 0
 87	wipe(friendTable)
 88	local name, level, class, area, connected, status, note
 89	for i = 1, total do
 90		name, level, class, area, connected, status, note = GetFriendInfo(i)
 91		for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end
 92		
 93		friendTable[i] = { name, level, class, area, connected, status, note }
 94		if connected then totalOnline = totalOnline + 1 end
 95	end
 96	table.sort(friendTable, function(a, b)
 97		if a[1] and b[1] then
 98			return a[1] < b[1]
 99		end
100	end)
101end
102
103local function UpdateFriendTable(total)
104	totalOnline = 0
105	local name, level, class, area, connected, status, note
106	for i = 1, #friendTable do
107		name, level, class, area, connected, status, note = GetFriendInfo(i)
108		for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end
109		
110		-- get the correct index in our table		
111		index = GetTableIndex(friendTable, 1, name)
112		-- we cannot find a friend in our table, so rebuild it
113		if index == -1 then
114			BuildFriendTable(total)
115			break
116		end
117		-- update on-line status for all members
118		friendTable[index][5] = connected
119		-- update information only for on-line members
120		if connected then
121			friendTable[index][2] = level
122			friendTable[index][3] = class
123			friendTable[index][4] = area
124			friendTable[index][6] = status
125			friendTable[index][7] = note
126			totalOnline = totalOnline + 1
127		end
128	end
129end
130
131local function BuildBNTable(total)
132	BNTotalOnline = 0
133	wipe(BNTable)
134	local _, presenceID, givenName, surname, toonName, toonID, client, isOnline, isAFK, isDND, noteText, realmName, faction, race, class, zoneName, level
135	for i = 1, total do
136		presenceID, givenName, surname, toonName, toonID, client, isOnline, _, isAFK, isDND, _, noteText = BNGetFriendInfo(i)
137		_, _, _, realmName, _, faction, race, class, _, zoneName, level = BNGetToonInfo(presenceID)
138		for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end
139		
140		BNTable[i] = { presenceID, givenName, surname, toonName, toonID, client, isOnline, isAFK, isDND, noteText, realmName, faction, race, class, zoneName, level }
141		if isOnline then BNTotalOnline = BNTotalOnline + 1 end
142	end
143	table.sort(BNTable, function(a, b)
144		if a[2] and b[2] then
145			if a[2] == b[2] then return a[3] < b[3] end
146			return a[2] < b[2]
147		end
148	end)
149end
150
151local function UpdateBNTable(total)
152	BNTotalOnline = 0
153	local presenceID, givenName, surname, toonName, toonID, client, isOnline, isAFK, isDND, noteText
154	local _, realmName, faction, race, class, zoneName, level
155	for i = 1, #BNTable do
156		-- get guild roster information
157		presenceID, givenName, surname, toonName, toonID, client, isOnline, _, isAFK, isDND, _, noteText = BNGetFriendInfo(i)
158		_, _, _, realmName, _, faction, race, class, _, zoneName, level = BNGetToonInfo(presenceID)
159		for k,v in pairs(LOCALIZED_CLASS_NAMES_MALE) do if class == v then class = k end end
160		
161		-- get the correct index in our table		
162		index = GetTableIndex(BNTable, 1, presenceID)
163		-- we cannot find a BN member in our table, so rebuild it
164		if index == -1 then
165			BuildBNTable(total)
166			return
167		end
168		-- update on-line status for all members
169		BNTable[index][7] = isOnline
170		-- update information only for on-line members
171		if isOnline then
172			BNTable[index][2] = givenName
173			BNTable[index][3] = surname
174			BNTable[index][4] = toonName
175			BNTable[index][5] = toonID
176			BNTable[index][6] = client
177			BNTable[index][8] = isAFK
178			BNTable[index][9] = isDND
179			BNTable[index][10] = noteText
180			BNTable[index][11] = realmName
181			BNTable[index][12] = faction
182			BNTable[index][13] = race
183			BNTable[index][14] = class
184			BNTable[index][15] = zoneName
185			BNTable[index][16] = level
186			
187			BNTotalOnline = BNTotalOnline + 1
188		end
189	end
190end
191
192Stat:SetScript("OnMouseUp", function(self, btn)
193	if btn ~= "RightButton" then return end
194	
195	GameTooltip:Hide()
196	
197	local menuCountWhispers = 0
198	local menuCountInvites = 0
199	local classc, levelc
200	
201	menuList[2].menuList = {}
202	menuList[3].menuList = {}
203	
204	if totalOnline > 0 then
205		for i = 1, #friendTable do
206			if (friendTable[i][5]) then
207				menuCountInvites = menuCountInvites + 1
208				menuCountWhispers = menuCountWhispers + 1
209
210				classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[friendTable[i][3]], GetQuestDifficultyColor(friendTable[i][2])
211				if classc == nil then classc = GetQuestDifficultyColor(friendTable[i][2]) end
212
213				menuList[2].menuList[menuCountInvites] = {text = format(levelNameString,levelc.r*255,levelc.g*255,levelc.b*255,friendTable[i][2],classc.r*255,classc.g*255,classc.b*255,friendTable[i][1]), arg1 = friendTable[i][1],notCheckable=true, func = inviteClick}
214				menuList[3].menuList[menuCountWhispers] = {text = format(levelNameString,levelc.r*255,levelc.g*255,levelc.b*255,friendTable[i][2],classc.r*255,classc.g*255,classc.b*255,friendTable[i][1]), arg1 = friendTable[i][1],notCheckable=true, func = whisperClick}
215			end
216		end
217	end
218	
219	if BNTotalOnline > 0 then
220		local realID, playerFaction, grouped
221		for i = 1, #BNTable do
222			if (BNTable[i][7]) then
223				realID = (BATTLENET_NAME_FORMAT):format(BNTable[i][2], BNTable[i][3])
224				menuCountWhispers = menuCountWhispers + 1
225				menuList[3].menuList[menuCountWhispers] = {text = realID, arg1 = realID,notCheckable=true, func = whisperClick}
226
227				if select(1, UnitFactionGroup("player")) == "Horde" then playerFaction = 0 else playerFaction = 1 end
228				if BNTable[i][6] == wowString and BNTable[i][11] == T.myrealm and playerFaction == BNTable[i][12] then
229					classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[BNTable[i][14]], GetQuestDifficultyColor(BNTable[i][16])
230					if classc == nil then classc = GetQuestDifficultyColor(BNTable[i][16]) end
231
232					if UnitInParty(BNTable[i][4]) or UnitInRaid(BNTable[i][4]) then grouped = 1 else grouped = 2 end
233					menuCountInvites = menuCountInvites + 1
234					menuList[2].menuList[menuCountInvites] = {text = format(levelNameString,levelc.r*255,levelc.g*255,levelc.b*255,BNTable[i][16],classc.r*255,classc.g*255,classc.b*255,BNTable[i][4]), arg1 = BNTable[i][4],notCheckable=true, func = inviteClick}
235				end
236			end
237		end
238	end
239
240	EasyMenu(menuList, menuFrame, "cursor", 0, 0, "MENU", 2)
241end)
242
243local function Update(self, event)
244	if event == "BN_FRIEND_INFO_CHANGED" or "BN_FRIEND_ACCOUNT_ONLINE" or "BN_FRIEND_ACCOUNT_OFFLINE" or "BN_TOON_NAME_UPDATED"
245			or "BN_FRIEND_TOON_ONLINE" or "BN_FRIEND_TOON_OFFLINE" or "PLAYER_ENTERING_WORLD" then
246		local BNTotal = BNGetNumFriends()
247		if BNTotal == #BNTable then
248			UpdateBNTable(BNTotal)
249		else
250			BuildBNTable(BNTotal)
251		end
252	end
253	
254	if event == "FRIENDLIST_UPDATE" or "PLAYER_ENTERING_WORLD" then
255		local total = GetNumFriends()
256		if total == #friendTable then
257			UpdateFriendTable(total)
258		else
259			BuildFriendTable(total)
260		end
261	end
262
263	Text:SetFormattedText(displayString, FRIENDS, totalOnline + BNTotalOnline)
264	self:SetAllPoints(Text)
265end
266
267Stat:SetScript("OnMouseDown", function(self, btn) if btn == "LeftButton" then ToggleFriendsFrame(1) end end)
268Stat:SetScript("OnEnter", function(self)
269	if InCombatLockdown() then return end
270		
271	local totalonline = totalOnline + BNTotalOnline
272	local totalfriends = #friendTable + #BNTable
273	local zonec, classc, levelc, realmc, grouped
274	if totalonline > 0 then
275		local anchor, panel, xoff, yoff = T.DataTextTooltipAnchor(Text)
276		GameTooltip:SetOwner(panel, anchor, xoff, yoff)
277		GameTooltip:ClearLines()
278		GameTooltip:AddDoubleLine(FRIENDS_LIST, format(totalOnlineString, totalonline, totalfriends),tthead.r,tthead.g,tthead.b,tthead.r,tthead.g,tthead.b)
279		if totalOnline > 0 then
280			GameTooltip:AddLine(' ')
281			GameTooltip:AddLine(worldOfWarcraftString)
282			for i = 1, #friendTable do
283				if friendTable[i][5] then
284					if GetRealZoneText() == friendTable[i][4] then zonec = activezone else zonec = inactivezone end
285					classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[friendTable[i][3]], GetQuestDifficultyColor(friendTable[i][2])
286					if classc == nil then classc = GetQuestDifficultyColor(friendTable[i][2]) end
287					
288					if UnitInParty(friendTable[i][1]) or UnitInRaid(friendTable[i][1]) then grouped = 1 else grouped = 2 end
289					GameTooltip:AddDoubleLine(format(levelNameClassString,levelc.r*255,levelc.g*255,levelc.b*255,friendTable[i][2],friendTable[i][1],groupedTable[grouped]," "..friendTable[i][6]),friendTable[i][4],classc.r,classc.g,classc.b,zonec.r,zonec.g,zonec.b)
290				end
291			end
292		end
293		if BNTotalOnline > 0 then
294			GameTooltip:AddLine(' ')
295			GameTooltip:AddLine(battleNetString)
296
297			local status = 0
298			for i = 1, #BNTable do
299				if BNTable[i][7] then
300					if BNTable[i][6] == wowString then
301						if (BNTable[i][8] == true) then status = 1 elseif (BNTable[i][9] == true) then status = 2 else status = 3 end
302	
303						classc, levelc = (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[BNTable[i][14]], GetQuestDifficultyColor(BNTable[i][16])
304						if classc == nil then classc = GetQuestDifficultyColor(BNTable[i][16]) end
305						
306						if UnitInParty(BNTable[i][4]) or UnitInRaid(BNTable[i][4]) then grouped = 1 else grouped = 2 end
307						GameTooltip:AddDoubleLine(format(clientLevelNameString, BNTable[i][6],levelc.r*255,levelc.g*255,levelc.b*255,BNTable[i][16],classc.r*255,classc.g*255,classc.b*255,BNTable[i][4],groupedTable[grouped], 255, 0, 0, statusTable[status]),BNTable[i][2].." "..BNTable[i][3],238,238,238,238,238,238)
308						if IsShiftKeyDown() then
309							if GetRealZoneText() == BNTable[i][15] then zonec = activezone else zonec = inactivezone end
310							if GetRealmName() == BNTable[i][11] then realmc = activezone else realmc = inactivezone end
311							GameTooltip:AddDoubleLine("  "..BNTable[i][15], BNTable[i][11], zonec.r, zonec.g, zonec.b, realmc.r, realmc.g, realmc.b)
312						end
313					else
314						GameTooltip:AddDoubleLine("|cffeeeeee"..BNTable[i][6].." ("..BNTable[i][4]..")|r", "|cffeeeeee"..BNTable[i][2].." "..BNTable[i][3].."|r")
315					end
316				end
317			end
318		end
319		GameTooltip:Show()
320	else 
321		GameTooltip:Hide() 
322	end
323end)
324
325Stat:RegisterEvent("BN_FRIEND_ACCOUNT_ONLINE")
326Stat:RegisterEvent("BN_FRIEND_ACCOUNT_OFFLINE")
327Stat:RegisterEvent("BN_FRIEND_INFO_CHANGED")
328Stat:RegisterEvent("BN_FRIEND_TOON_ONLINE")
329Stat:RegisterEvent("BN_FRIEND_TOON_OFFLINE")
330Stat:RegisterEvent("BN_TOON_NAME_UPDATED")
331Stat:RegisterEvent("FRIENDLIST_UPDATE")
332Stat:RegisterEvent("PLAYER_ENTERING_WORLD")
333
334Stat:SetScript("OnLeave", function() GameTooltip:Hide() end)
335Stat:SetScript("OnEvent", Update)