comparison CrossRealmAssist.lua @ 11:421508c17712

Started implementing new interface
author ShadowTheAge
date Tue, 10 Mar 2015 00:16:23 +0300
parents 9fa8442dd547
children 0deef890ec99
comparison
equal deleted inserted replaced
10:d1f39eeb8169 11:421508c17712
1 CrossRealmAssist = LibStub("AceAddon-3.0"):NewAddon("CrossRealmAssist", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0") 1 CrossRealmAssist = LibStub("AceAddon-3.0"):NewAddon("CrossRealmAssist", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0")
2 local AceGUI = LibStub("AceGUI-3.0") 2 local AceGUI = LibStub("AceGUI-3.0")
3 local addon = CrossRealmAssist; 3 local addon = CrossRealmAssist;
4 local wholib = LibStub:GetLibrary('LibWho-2.0'):Library() 4 local wholib = LibStub:GetLibrary('LibWho-2.0'):Library()
5 5
6 local hgroup, lfgContainer, currealm, partyrealm, recrealm, curRealmStat, homeRealm, realmSep, gui, leavebtn 6 local homeRealm, realmSep, gui, btRefresh, btQuick, btManual, lbRealm, lbStatus, playerName
7 7
8 local curRealmStat
8 local scanstate=0 9 local scanstate=0
9 local recentRealms={} 10 local recentRealms={}
10 local active=false 11 local active=false
11 12
12 local lfgGroups={ 13 local lfgGroups={
19 20
20 local lfgTabs 21 local lfgTabs
21 local curLfgGroup 22 local curLfgGroup
22 local sheduledScan 23 local sheduledScan
23 local wasInGroup 24 local wasInGroup
25 local wasInInstance
24 local lfgScanInProgress=false 26 local lfgScanInProgress=false
27
28 local function setupWidget(widget, parameters, x, y)
29 if parameters then
30 for key,value in pairs(parameters) do widget[key](widget,value) end
31 end
32 if y then
33 widget:SetPoint("TOPLEFT",widget:GetParent(),"TOPLEFT",x,-y)
34 end
35 return widget
36 end
37
38 local function ShowTooltip(widget)
39 GameTooltip:SetOwner(widget, widget.TooltipAnchor)
40 GameTooltip:ClearLines()
41 widget:TooltipFactory()
42 GameTooltip:Show()
43 end
44
45 local function HideTooltip(widget)
46 GameTooltip:Hide()
47 end
48
49 local function setupTooltip(widget, anchor, factory)
50 widget.TooltipAnchor = anchor;
51 widget.TooltipFactory = factory;
52 widget:SetScript("OnEnter", ShowTooltip)
53 widget:SetScript("OnLeave", HideTooltip)
54 end
25 55
26 function addon:OnInitialize() 56 function addon:OnInitialize()
27 57
28 end 58 end
29 59
33 for i=1,tabCount do 63 for i=1,tabCount do
34 local cat = lfgGroups[i] 64 local cat = lfgGroups[i]
35 table.insert(lfgTabs,{value=cat,text=(C_LFGList.GetCategoryInfo(cat))}) 65 table.insert(lfgTabs,{value=cat,text=(C_LFGList.GetCategoryInfo(cat))})
36 end 66 end
37 realmSep = _G.REALM_SEPARATORS 67 realmSep = _G.REALM_SEPARATORS
68 playerName = UnitName("player")
38 homeRealm = GetRealmName() 69 homeRealm = GetRealmName()
39 addon:RegisterChatCommand("cra", "Activate") 70 addon:RegisterChatCommand("cra", "Activate")
40 addon:RegisterChatCommand("crossrealmassist", "Activate") 71 addon:RegisterChatCommand("crossrealmassist", "Activate")
72
73 addon:ScheduleTimer("Activate", 0.5)
41 end 74 end
42 75
43 function addon:OnDisable() 76 function addon:OnDisable()
44 addon:Deactivate() 77 addon:Deactivate()
45 end 78 end
46 79
47 function addon:Activate() 80 function addon:Activate()
48 if active then return end 81 if active then return end
49 active=true 82 active=true
50 wasInGroup = IsInGroup() 83 wasInGroup = IsInGroup()
51 addon:CreateUI() 84 if not gui then addon:CreateUI() end
52 addon:ScanRealm() 85 addon:updateCurrentRealm();
53 addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "SheduleScan") 86 addon:ForceRefreshZone();
54 addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData") 87 gui:Show()
55 addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed") 88 addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "ForceRefreshZone")
56 addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo") 89 addon:RegisterEvent("SCENARIO_UPDATE", "ForceRefreshZone")
57 addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus") 90 --addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData")
91 --addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed")
92 --addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo")
93 --addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus")
58 end 94 end
59 95
60 function addon:Deactivate() 96 function addon:Deactivate()
61 if not active then return end 97 if not active then return end
62 active = false 98 active = false
63 scanstate = 0 99 scanstate = 0
64 lfgScanInProgress = false 100 lfgScanInProgress = false
65 gui:Release();
66 gui, lfgContainer, hgroup, currealm, partyrealm, recrealm, leavebtn = nil,nil,nil,nil,nil,nil,nil
67 addon:UnregisterEvent("ZONE_CHANGED_NEW_AREA") 101 addon:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
68 addon:UnregisterEvent("PLAYER_REGEN_ENABLED") 102 addon:UnregisterEvent("PLAYER_REGEN_ENABLED")
69 addon:UnregisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED") 103 addon:UnregisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED")
70 addon:UnregisterEvent("LFG_LIST_SEARCH_FAILED") 104 addon:UnregisterEvent("LFG_LIST_SEARCH_FAILED")
71 addon:UnregisterEvent("GROUP_ROSTER_UPDATE") 105 addon:UnregisterEvent("GROUP_ROSTER_UPDATE")
72 addon:UnregisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED") 106 addon:UnregisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED")
73 end 107 end
74 108
109 function addon:SetStatus(status)
110 if status then
111 lbStatus:SetText(status)
112 else
113 lbStatus:SetText("") -- TODO
114 end
115 end
116
75 function addon:CreateUI() 117 function addon:CreateUI()
76 gui = addon:AddUI(nil,"Window",{SetTitle="Cross Realm Assist",EnableResize=false,SetLayout="Flow"},true,{OnClose=addon.Deactivate}) 118 gui = setupWidget(CreateFrame("Frame",nil,nil,"InsetFrameTemplate3"), {SetFrameStrata="DIALOG",SetWidth=208,SetHeight=60,EnableMouse=true,SetMovable=true})
119 local title = setupWidget(CreateFrame("Frame",nil,gui), {SetWidth=190,SetHeight=18,EnableMouse=true,RegisterForDrag="LeftButton"}, 0, 6);
120 title:SetScript("OnDragStart", function() gui:StartMoving() end)
121 title:SetScript("OnDragStop", function() gui:StopMovingOrSizing() end)
122 gui:SetScript("OnHide", addon.Deactivate)
123 setupTooltip(title, "ANCHOR_TOP", addon.realmToolip)
124
125 lbRealm = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontNormal"), {SetWidth=200,SetHeight=18}, 0, 6)
126 lbStatus = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontHighlightSmallLeft"), {SetWidth=200,SetHeight=10}, 6, 23)
127
128 btQuick = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{EnableMouse=true,SetWidth=90,SetHeight=20,SetText="Quick join"},4,36)
129 btManual = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{EnableMouse=true,SetWidth=90,SetHeight=20,SetText="Manual join"},94,36)
130 setupWidget(CreateFrame("Button",nil,gui,"UIPanelCloseButton"),{EnableMouse=true,SetWidth=20,SetHeight=20},188,0)
131
132 btRefresh = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{EnableMouse=true,SetWidth=20,SetHeight=20},184,36)
133 btRefresh.icon:SetTexture("Interface/BUTTONS/UI-RefreshButton")
134 btRefresh.icon:SetTexCoord(0,1,0,1);
135 btRefresh:SetScript("OnClick",addon.RefreshZone)
136
137 gui:SetPoint("CENTER",0,0)
138
139 --[[gui = addon:AddUI(nil,"Window",{SetTitle="Cross Realm Assist",EnableResize=false,SetLayout="Flow"},true,{OnClose=addon.Deactivate})
77 140
78 local tabgroup = addon:AddUI(gui,"TabGroup",{SetFullHeight=true,SetTabs=lfgTabs,SetLayout="Fill"},true,{OnGroupSelected=addon.LfgScan}) 141 local tabgroup = addon:AddUI(gui,"TabGroup",{SetFullHeight=true,SetTabs=lfgTabs,SetLayout="Fill"},true,{OnGroupSelected=addon.LfgScan})
79 tabgroup:SelectTab(lfgGroups[1]) 142 tabgroup:SelectTab(lfgGroups[1])
80 lfgContainer = addon:AddUI(tabgroup,"ScrollFrame") 143 lfgContainer = addon:AddUI(tabgroup,"ScrollFrame")
81 144
101 hgroupc:SetPoint("TOPLEFT", gui.content, "TOPRIGHT", -200, 0) 164 hgroupc:SetPoint("TOPLEFT", gui.content, "TOPRIGHT", -200, 0)
102 hgroupc:SetPoint("BOTTOMRIGHT", gui.content, "BOTTOMRIGHT") 165 hgroupc:SetPoint("BOTTOMRIGHT", gui.content, "BOTTOMRIGHT")
103 166
104 if curRealmStat then addon:updateCurrentRealm() end 167 if curRealmStat then addon:updateCurrentRealm() end
105 addon:updatePartyInfo() 168 addon:updatePartyInfo()
106 addon:updateRecentRealms() 169 addon:updateRecentRealms()]]
107 end 170 end
108 171
109 -- LFG scanning routine 172 -- LFG scanning routine
110 173
111 function addon.refreshLfgCurrent() 174 --[[function addon.refreshLfgCurrent()
112 addon.LfgScan(nil,nil,curLfgGroup) 175 addon.LfgScan(nil,nil,curLfgGroup)
113 end 176 end
114 177
115 function addon.LfgScan(widget, callback, tab) 178 function addon.LfgScan(widget, callback, tab)
116 if not tab then return end 179 if not tab then return end
241 304
242 function addon:updateAppStatus(event, id, status, oldstatus) 305 function addon:updateAppStatus(event, id, status, oldstatus)
243 if status == "invited" then 306 if status == "invited" then
244 LFGListInviteDialog_Accept(LFGListInviteDialog) 307 LFGListInviteDialog_Accept(LFGListInviteDialog)
245 end 308 end
246 end 309 end]]
247 310
248 -- Zone scanning routine 311 -- Zone scanning routine
249 312
250 function addon:LeaveCombat() 313 function addon:LeaveCombat()
251 addon:UnregisterEvent("PLAYER_REGEN_ENABLED") 314 addon:UnregisterEvent("PLAYER_REGEN_ENABLED")
252 scanstate = 0 315 scanstate = 0
253 addon:ScanRealm(); 316 addon:ScanRealm();
317 end
318
319 function addon:ForceRefreshZone()
320 addon:RefreshZone(true)
321 end
322
323 function addon:RefreshZone(shedule)
324 local inst, instType = IsInInstance()
325 if (inst or instType ~= "none") then
326 lbRealm:SetText("Instanced zone")
327 curRealmStat = nil
328 btQuick:Disable()
329 else
330 btQuick:Enable()
331 if scanstate == 0 then
332 addon:ScanRealm()
333 elseif shedule == true and scanstate == 2 then
334 addon:SetStatus("Rescan sheduled...")
335 scanstate = 3
336 end
337 end
254 end 338 end
255 339
256 function addon:ScanRealm() 340 function addon:ScanRealm()
257 if scanstate > 0 then return end 341 if scanstate > 0 then return end
258 if InCombatLockdown() then 342 if InCombatLockdown() then
259 addon:RegisterEvent("PLAYER_REGEN_ENABLED","LeaveCombat") 343 addon:RegisterEvent("PLAYER_REGEN_ENABLED","LeaveCombat")
260 scanstate = 1 344 scanstate = 1
261 addon:AddLabel(currealm, "Scan sheduled after combat...", 3); 345 addon:SetStatus("Scan sheduled after combat...");
262 return 346 return
263 end 347 end
264 scanstate = 2 348 scanstate = 2
265 addon:AddLabel(currealm, "Scanning...", 3); 349 addon:SetStatus("Scanning current realm...");
266 local searchString = _G.WHO_TAG_ZONE .. '"' .. GetZoneText() .. '"'; 350 local searchString = _G.WHO_TAG_ZONE .. '"' .. GetZoneText() .. '"';
267 wholib:Who(searchString, {callback = "ScanResult", handler=addon}) 351 wholib:Who(searchString, {callback = "ScanResult", handler=addon})
268 end 352 end
269 353
270 function addon:ScanResult(query, results, complete) 354 function addon:ScanResult(query, results, complete)
271 local realms = {} 355 local realms = {}
272 for _, player in ipairs(results) do 356 for _, player in ipairs(results) do
273 addon:AddRealmStat(player.Name, realms); 357 addon:AddRealmStat(player.Name, realms);
274 end 358 end
275 curRealmStat = addon:GetRealmStat(realms); 359 curRealmStat = addon:GetRealmStat(realms);
360 curRealmStat.complete = complete
276 addon:updateCurrentRealm(); 361 addon:updateCurrentRealm();
277 local rescan = scanstate == 3 362 local rescan = scanstate == 3
278 scanstate = 0; 363 scanstate = 0;
279 if rescan then addon:ScanRealm() end 364 if rescan then addon:ScanRealm() end
280 end 365 end
281 366
282 function addon:AddRealmStat(name, realms) 367 function addon:AddRealmStat(name, realms)
283 local _, realm = strsplit(realmSep, name) -- TODO exclude self 368 if (name == playerName) then return end
369 local _, realm = strsplit(realmSep, name)
284 realm = realm or homeRealm 370 realm = realm or homeRealm
285 realms[realm] = (realms[realm] or 0) + 1 371 realms[realm] = (realms[realm] or 0) + 1
286 end 372 end
287 373
288 function addon:AddUnitIdStat(unitid, realms) 374 function addon:AddUnitIdStat(unitid, realms)
310 stat.realms = rcount; 396 stat.realms = rcount;
311 return stat; 397 return stat;
312 end 398 end
313 399
314 function addon:updateCurrentRealm() 400 function addon:updateCurrentRealm()
315 if not currealm then return end 401 addon:SetStatus();
316 currealm:ReleaseChildren() 402 if not curRealmStat or curRealmStat.realms < 1 then
317 if curRealmStat.players < 5 then 403 lbRealm:SetText("Unknown realm (No players)")
318 addon:AddLabel(currealm, "Not enough players", 0); 404 return;
319 end 405 end
320 local sureplayers = curRealmStat.players/2 406
321 local maybeplayers = math.max(curRealmStat.max/4, 3) 407 local bestRealm = curRealmStat[1]
322 local recentRealmUpdated = false 408 local prevThreshold = math.min(bestRealm.count/3,5)
409 local mixCount = 0
410 for i=2,curRealmStat.realms do
411 local data = curRealmStat[i]
412 if data.count >= prevThreshold then
413 mixCount = mixCount + 1
414 prevThreshold = math.min(data.count/3,5)
415 end
416 end
417 curRealmStat.threshold = prevThreshold
418
419 if (mixCount > 0) then
420 lbRealm:SetText("Mixed "..bestRealm.realm.." +"..mixCount)
421 else
422 lbRealm:SetText(bestRealm.realm)
423 end
424 end
425
426 function addon:realmToolip()
427 if not curRealmStat then return end
428 local players = curRealmStat.players;
429 local threshold = curRealmStat.threshold
430 GameTooltip:AddLine("Players in zone: "..players)
431 if not curRealmStat.complete then
432 GameTooltip:AppendText("+")
433 end
323 for i=1,curRealmStat.realms do 434 for i=1,curRealmStat.realms do
324 local data = curRealmStat[i] 435 local data = curRealmStat[i]
325 if data.count >= maybeplayers then 436 local percent = math.ceil(100 * data.count / players - 0.5) .. "%";
326 local realm = data.realm 437 if data.count >= threshold then
327 local rvalue = (data.count >= sureplayers) and 4 or 2 438 GameTooltip:AddDoubleLine(data.realm, percent, 0,1,0,0,1,0)
328 if (rvalue > (recentRealms[realm] or 0)) then 439 else
329 recentRealmUpdated = true 440 GameTooltip:AddDoubleLine(data.realm, percent, 0.5,0.5,0.5,0.5,0.5,0.5)
330 recentRealms[realm] = rvalue 441 end
331 end 442 end
332 end 443 end
333 end 444
334 addon:addLabels(currealm, curRealmStat, sureplayers, maybeplayers, 3, "Realm unknown"); 445 --[[function addon:addLabels(container, stats, epict, whitet, grayt, emptytext)
335 if recentRealmUpdated then
336 addon:UpdateCurrentLfgInfo()
337 addon:updateRecentRealms()
338 end
339 end
340
341 function addon:addLabels(container, stats, epict, whitet, grayt, emptytext)
342 if stats.realms == 0 then 446 if stats.realms == 0 then
343 addon:AddLabel(container, emptytext) 447 addon:AddLabel(container, emptytext)
344 else 448 else
345 local players = stats.players 449 local players = stats.players
346 local pleft = players; 450 local pleft = players;
380 recentRealms = {} 484 recentRealms = {}
381 addon:UpdateCurrentLfgInfo() 485 addon:UpdateCurrentLfgInfo()
382 addon:updateRecentRealms() 486 addon:updateRecentRealms()
383 end 487 end
384 488
385 function addon:SheduleScan()
386 if scanstate == 0 then
387 addon:ScanRealm()
388 elseif scanstate == 2 then
389 scanstate = 3
390 end
391 end
392
393 function addon:updatePartyInfo() 489 function addon:updatePartyInfo()
394 if not partyrealm then return end 490 if not partyrealm then return end
395 partyrealm:ReleaseChildren() 491 partyrealm:ReleaseChildren()
396 local realms = {} 492 local realms = {}
397 local inGroup = IsInGroup() 493 local inGroup = IsInGroup()
412 addon:UpdateCurrentLfgInfo() 508 addon:UpdateCurrentLfgInfo()
413 leavebtn:SetDisabled(not inGroup) 509 leavebtn:SetDisabled(not inGroup)
414 end 510 end
415 local partyStat = addon:GetRealmStat(realms); 511 local partyStat = addon:GetRealmStat(realms);
416 addon:addLabels(partyrealm, partyStat, partyStat.players/2, 2, 0, "Not in party"); 512 addon:addLabels(partyrealm, partyStat, partyStat.players/2, 2, 0, "Not in party");
417 end 513 end]]
418
419 -- Utils functions
420
421 function addon:AddUI(owner, type, parameters, manual, callbacks)
422 local ui = AceGUI:Create(type)
423 if parameters then
424 for key,value in pairs(parameters) do ui[key](ui,value) end
425 end
426 if callbacks then
427 for key,value in pairs(callbacks) do ui:SetCallback(key,value) end
428 end
429 if not manual then ui:SetFullWidth(true) end
430 if owner then owner:AddChild(ui) end
431 return ui
432 end
433
434 function addon:AddLabel(owner, text, color, icon)
435 local label = AceGUI:Create("Label")
436 label:SetText(text)
437 label:SetFullWidth(true)
438 if color ~= nil then
439 local r,g,b = GetItemQualityColor(color);
440 label:SetColor(r,g,b)
441 end
442 owner:AddChild(label)
443 return label
444 end
445
446 function addon:AddIcon(owner, image, size, visible, tooltip)
447 if visible ~= false then
448 local icon = addon:AddUI(owner,"Icon",{SetWidth=size,SetHeight=size},true)
449 icon:SetImage(image)
450 icon:SetImageSize(size,size)
451 if tooltip then
452 icon:SetUserData('tooltip',tooltip)
453 icon:SetCallback("OnEnter",addon.ShowTooltip)
454 icon:SetCallback("OnLeave",addon.HideTooltip)
455 end
456 else -- add placeholder
457 addon:AddUI(owner,"Label",{SetWidth=size,SetHeight=size},true)
458 end
459 end
460
461 function addon.ShowTooltip(widget)
462 GameTooltip:SetOwner(widget.frame, "ANCHOR_TOP")
463 local tooltip = widget:GetUserData('tooltip')
464 for i=1,#tooltip do
465 GameTooltip:AddLine(tooltip[i], 1, 1, 1)
466 end
467 GameTooltip:Show()
468 end
469
470 function addon.HideTooltip(widget)
471 GameTooltip:Hide()
472 end