/Tukui/modules/datatext/friend.lua

http://github.com/Asphyxia/Tukui · Lua · 335 lines · 298 code · 24 blank · 13 comment · 46 complexity · a0235fcdcb4060b1fedcbfd863db1032 MD5 · raw file

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