BNet.lua

BNet.lua (8.1.5.29981; unchanged since 8.1.0.28724)
  1. local BN_TOAST_TYPE_ONLINE = 1;
  2. local BN_TOAST_TYPE_OFFLINE = 2;
  3. local BN_TOAST_TYPE_BROADCAST = 3;
  4. local BN_TOAST_TYPE_PENDING_INVITES = 4;
  5. local BN_TOAST_TYPE_NEW_INVITE = 5;
  6. local BN_TOAST_TYPE_CLUB_INVITATION = 6;
  7.  
  8. BNET_CLIENT_WOW = "WoW";
  9. BNET_CLIENT_SC2 = "S2";
  10. BNET_CLIENT_D3 = "D3";
  11. BNET_CLIENT_WTCG = "WTCG";
  12. BNET_CLIENT_APP = "App";
  13. BNET_CLIENT_HEROES = "Hero";
  14. BNET_CLIENT_OVERWATCH = "Pro";
  15. BNET_CLIENT_CLNT = "CLNT";
  16. BNET_CLIENT_SC = "S1";
  17. BNET_CLIENT_DESTINY2 = "DST2";
  18. BNET_CLIENT_COD = "VIPR";
  19.  
  20. --Name can be a realID or plain battletag with no 4 digit number (e.g. Murky McGrill or LichKing).
  21. function BNet_GetBNetIDAccount(name)
  22.   return GetAutoCompletePresenceID(name);
  23. end
  24.  
  25. --Name must be a character name from your friends list.
  26. function BNet_GetBNetIDAccountFromCharacterName(name)
  27.   local _, numBNetOnline = BNGetNumFriends();
  28.   for i = 1, numBNetOnline do
  29.     local opaqueID, displayName, battleTag, _, characterName = BNGetFriendInfo(i);
  30.     if ( (characterName and strcmputf8i(name, characterName) == 0) ) then
  31.       return opaqueID;
  32.     end
  33.   end
  34. end
  35.  
  36. -- BNET toast
  37.  
  38. BNToastMixin = {}
  39.  
  40. function BNToastMixin:OnLoad()
  41.   self.BNToastEvents = {
  42.     showToastOnline = { "BN_FRIEND_ACCOUNT_ONLINE" },
  43.     showToastOffline = { "BN_FRIEND_ACCOUNT_OFFLINE" },
  44.     showToastClubInvitation = { "CLUB_INVITATION_ADDED_FOR_SELF" },
  45.     showToastBroadcast = { "BN_CUSTOM_MESSAGE_CHANGED" },
  46.     showToastFriendRequest = { "BN_FRIEND_INVITE_ADDED", "BN_FRIEND_INVITE_LIST_INITIALIZED" },
  47.   };
  48.  
  49.   self.BNToasts = {};
  50.   self.DoubleLine:SetSpacing(3);
  51.   self:RegisterEvent("VARIABLES_LOADED");
  52.   self:RegisterEvent("BN_DISCONNECTED");
  53.   self:RegisterEvent("BN_BLOCK_FAILED_TOO_MANY");
  54.  
  55.   local alertSystem = ChatAlertFrame:AddAutoAnchoredSubSystem(self);
  56.   ChatAlertFrame:SetSubSystemAnchorPriority(alertSystem, 1);
  57. end
  58.  
  59. function BNToastMixin:OnEvent(event, ...)
  60.   if ( event == "BN_DISCONNECTED" ) then
  61.     self:ClearToasts();
  62.   elseif ( event == "BN_BLOCK_FAILED_TOO_MANY" ) then
  63.     self:BlockFailed(...);
  64.   elseif ( event == "BN_FRIEND_ACCOUNT_ONLINE" ) then
  65.     self:AddToast(BN_TOAST_TYPE_ONLINE, ...);
  66.   elseif ( event == "BN_FRIEND_ACCOUNT_OFFLINE" ) then
  67.     self:AddToast(BN_TOAST_TYPE_OFFLINE, ...);
  68.   elseif ( event == "BN_CUSTOM_MESSAGE_CHANGED" ) then
  69.     self:OnCustomMessageChanged(...);
  70.   elseif ( event == "BN_FRIEND_INVITE_ADDED" ) then
  71.     self:AddToast(BN_TOAST_TYPE_NEW_INVITE);
  72.   elseif ( event == "CLUB_INVITATION_ADDED_FOR_SELF" ) then
  73.     self:AddToast(BN_TOAST_TYPE_CLUB_INVITATION, ...);
  74.   elseif ( event == "BN_FRIEND_INVITE_LIST_INITIALIZED" ) then
  75.     self:AddToast(BN_TOAST_TYPE_PENDING_INVITES, ...);
  76.   elseif( event == "VARIABLES_LOADED" ) then
  77.     self:OnVariablesLoaded();
  78.   end
  79. end
  80.  
  81. function BNToastMixin:OnHide()
  82.   self:CheckShowToast();
  83. end
  84.  
  85. function BNToastMixin:OnEnter()
  86.   AlertFrame_PauseOutAnimation(self);
  87.  
  88.   if self.toastType == BN_TOAST_TYPE_BROADCAST and self.BottomLine:IsTruncated() then
  89.     self.TooltipFrame.Text:SetText(self.BottomLine:GetText());
  90.     self.TooltipFrame:Show();
  91.   end
  92. end
  93.  
  94. function BNToastMixin:OnLeave()
  95.   AlertFrame_ResumeOutAnimation(self);
  96.   self.TooltipFrame:Hide();
  97. end
  98.  
  99. function BNToastMixin:OnClick()
  100.   local toastType = self.toastType;
  101.   local toastData = self.toastData;
  102.  
  103.   self:Hide(); -- will trigger next toast
  104.  
  105.   if toastType == BN_TOAST_TYPE_NEW_INVITE or toastType == BN_TOAST_TYPE_PENDING_INVITES then
  106.     if not FriendsFrame:IsShown() then
  107.       ToggleFriendsFrame(FRIEND_TAB_FRIENDS);
  108.     end
  109.  
  110.     if GetCVarBool("friendInvitesCollapsed") then
  111.       FriendsListFrame_ToggleInvites();
  112.     end
  113.  
  114.     FriendsTabHeaderTab1:Click();
  115.   elseif toastType == BN_TOAST_TYPE_ONLINE or toastType == BN_TOAST_TYPE_BROADCAST then
  116.     local bnetIDAccount, accountName = BNGetFriendInfoByID(toastData);
  117.     if accountName then --This player may have been removed from our friends list, so we may not have a name.
  118.       ChatFrame_SendBNetTell(accountName);
  119.     end
  120.   elseif toastType == BN_TOAST_TYPE_CLUB_INVITATION then
  121.     Communities_LoadUI();
  122.     ShowUIPanel(CommunitiesFrame);
  123.     CommunitiesFrame:SelectClub(toastData.club.clubId);
  124.   end
  125. end
  126.  
  127. function BNToastMixin:ClearToasts()
  128.   table.wipe(self.BNToasts);
  129. end
  130.  
  131. function BNToastMixin:BlockFailed(blockType)
  132.   if ( blockType == "RID" ) then
  133.     StaticPopup_Show("BN_BLOCK_FAILED_TOO_MANY_RID");
  134.   elseif ( blockType == "CID" ) then
  135.     StaticPopup_Show("BN_BLOCK_FAILED_TOO_MANY_CID");
  136.   end
  137. end
  138.  
  139. function BNToastMixin:OnCustomMessageChanged(toastData)
  140.   if toastData then
  141.     self:AddToast(BN_TOAST_TYPE_BROADCAST, toastData);
  142.   end
  143. end
  144.  
  145. function BNToastMixin:OnVariablesLoaded()
  146.   self:SetToastDuration(GetCVar("toastDuration"));
  147.   self:SetToastsEnabled(GetCVarBool("showToastWindow"));
  148. end
  149.  
  150. function BNToastMixin:EnableToasts()
  151.   for cvar, events in pairs(self.BNToastEvents) do
  152.     if GetCVarBool(cvar) then
  153.       for eventIndex, event in ipairs(events) do
  154.         self:RegisterEvent(event);
  155.       end
  156.     end
  157.   end
  158. end
  159.  
  160. function BNToastMixin:DisableToasts()
  161.   self:ClearToasts();
  162.   self:Hide();
  163.  
  164.   for cvar, events in pairs(self.BNToastEvents) do
  165.     for eventIndex, event in ipairs(events) do
  166.       self:UnregisterEvent(event);
  167.     end
  168.   end
  169. end
  170.  
  171. function BNToastMixin:UpdateToastEvent(cvar, value)
  172.   if GetCVarBool("showToastWindow") then
  173.     local events = self.BNToastEvents[cvar];
  174.     if events and value == "1" then
  175.       for eventIndex, event in pairs(events) do
  176.         self:RegisterEvent(event);
  177.       end
  178.     else
  179.       for eventIndex, event in pairs(events) do
  180.         self:UnregisterEvent(event);
  181.       end
  182.     end
  183.   end
  184. end
  185.  
  186. function BNToastMixin:SetToastsEnabled(enabled)
  187.   if enabled then
  188.     self:EnableToasts();
  189.   else
  190.     self:DisableToasts();
  191.   end
  192. end
  193.  
  194. function BNToastMixin:SetToastDuration(duration)
  195.   self.duration = duration;
  196. end
  197.  
  198. function BNToastMixin:ShowToast()
  199.   local toast = tremove(self.BNToasts, 1);
  200.   local toastType, toastData = toast.toastType, toast.toastData;
  201.  
  202.   local self = BNToastFrame;
  203.   local topLine = self.TopLine;
  204.   local middleLine = self.MiddleLine;
  205.   local bottomLine = self.BottomLine;
  206.   local doubleLine = self.DoubleLine;
  207.  
  208.   topLine:Hide();
  209.   middleLine:Hide();
  210.   bottomLine:Hide();
  211.   doubleLine:Hide();
  212.  
  213.   if ( toastType == BN_TOAST_TYPE_NEW_INVITE ) then
  214.     self.IconTexture:SetTexCoord(0.75, 1, 0, 0.5);
  215.     doubleLine:Show();
  216.     doubleLine:SetText(BN_TOAST_NEW_INVITE);
  217.     doubleLine:SetMaxLines(0);
  218.   elseif ( toastType == BN_TOAST_TYPE_PENDING_INVITES ) then
  219.     self.IconTexture:SetTexCoord(0.75, 1, 0, 0.5);
  220.     doubleLine:Show();
  221.     doubleLine:SetFormattedText(BN_TOAST_PENDING_INVITES, toastData);
  222.   elseif ( toastType == BN_TOAST_TYPE_ONLINE ) then
  223.     local bnetIDAccount, accountName, battleTag, isBattleTag, characterName, bnetIDGameAccount, client = BNGetFriendInfoByID(toastData);
  224.     -- don't display a toast if we didn't get the data in time
  225.     if ( not accountName ) then
  226.       return;
  227.     end
  228.  
  229.     if (battleTag) then
  230.       characterName = BNet_GetValidatedCharacterName(characterName, battleTag, client) or "";
  231.       characterName = BNet_GetClientEmbeddedTexture(client, 14, 14, 0, -1)..characterName;
  232.       middleLine:SetFormattedText(characterName);
  233.       middleLine:SetTextColor(FRIENDS_BNET_NAME_COLOR.r, FRIENDS_BNET_NAME_COLOR.g, FRIENDS_BNET_NAME_COLOR.b);
  234.       middleLine:Show();
  235.     end
  236.  
  237.     self.IconTexture:SetTexCoord(0, 0.25, 0.5, 1);
  238.     topLine:Show();
  239.     topLine:SetText(FRIENDS_BNET_NAME_COLOR:WrapTextInColorCode(accountName));
  240.     bottomLine:Show();
  241.     bottomLine:SetText(FRIENDS_GRAY_COLOR:WrapTextInColorCode(BN_TOAST_ONLINE));
  242.   elseif ( toastType == BN_TOAST_TYPE_OFFLINE ) then
  243.     local bnetIDAccount, accountName = BNGetFriendInfoByID(toastData);
  244.     -- don't display a toast if we didn't get the data in time
  245.     if ( not accountName ) then
  246.       return;
  247.     end
  248.     self.IconTexture:SetTexCoord(0, 0.25, 0.5, 1);
  249.     topLine:Show();
  250.     topLine:SetFormattedText(FRIENDS_BNET_NAME_COLOR:WrapTextInColorCode(accountName));
  251.     bottomLine:Show();
  252.     bottomLine:SetText(BN_TOAST_OFFLINE);
  253.     bottomLine:SetTextColor(FRIENDS_GRAY_COLOR.r, FRIENDS_GRAY_COLOR.g, FRIENDS_GRAY_COLOR.b);
  254.     doubleLine:Hide();
  255.     middleLine:Hide();
  256.   elseif ( toastType == BN_TOAST_TYPE_BROADCAST ) then
  257.     local bnetIDAccount, accountName, battleTag, isBattleTag, characterName, bnetIDGameAccount, client, isOnline, lastOnline, isAFK, isDND, messageText = BNGetFriendInfoByID(toastData);
  258.     if ( not messageText or messageText == "" ) then
  259.       return;
  260.     end
  261.     BNToastFrameIconTexture:SetTexCoord(0, 0.25, 0, 0.5);
  262.     topLine:Show();
  263.     topLine:SetText(accountName);
  264.     topLine:SetTextColor(FRIENDS_BNET_NAME_COLOR.r, FRIENDS_BNET_NAME_COLOR.g, FRIENDS_BNET_NAME_COLOR.b);
  265.     bottomLine:Show();
  266.     bottomLine:SetText(messageText);
  267.     bottomLine:SetTextColor(FRIENDS_GRAY_COLOR.r, FRIENDS_GRAY_COLOR.g, FRIENDS_GRAY_COLOR.b);
  268.     doubleLine:Hide();
  269.     middleLine:Hide();
  270.   elseif ( toastType == BN_TOAST_TYPE_CLUB_INVITATION ) then
  271.     self.IconTexture:SetTexCoord(0.5, 0.75, 0, 0.5);
  272.     doubleLine:Show();
  273.     local clubName = "";
  274.     if toastData.club.clubType == Enum.ClubType.BattleNet then
  275.       clubName = BATTLENET_FONT_COLOR:WrapTextInColorCode(toastData.club.name);
  276.     else
  277.       clubName = NORMAL_FONT_COLOR:WrapTextInColorCode(toastData.club.name);
  278.     end
  279.     doubleLine:SetText(BN_TOAST_NEW_CLUB_INVITATION:format(clubName));
  280.     doubleLine:SetMaxLines(2);
  281.   end
  282.  
  283.   if (middleLine:IsShown() and bottomLine:IsShown()) then
  284.     bottomLine:SetPoint("TOPLEFT", middleLine, "BOTTOMLEFT", 0, -4);
  285.     self:SetHeight(63);
  286.   else
  287.     bottomLine:SetPoint("TOPLEFT", topLine, "BOTTOMLEFT", 0, -4);
  288.     self:SetHeight(50);
  289.   end
  290.  
  291.   PlaySound(SOUNDKIT.UI_BNET_TOAST);
  292.   self.toastType = toastType;
  293.   self.toastData = toastData;
  294.   AlertFrame_ShowNewAlert(self);
  295. end
  296.  
  297. function BNToastMixin:CheckShowToast()
  298.   if #self.BNToasts > 0 then
  299.     self:ShowToast();
  300.   end
  301. end
  302.  
  303. function BNToastMixin:AddToast(toastType, toastData)
  304.   self:RemoveToast(toastType, toastData);
  305.   tinsert(self.BNToasts, { toastType = toastType, toastData = toastData });
  306.   self:ShowToast();
  307. end
  308.  
  309. function BNToastMixin:RemoveToast(toastType, toastData)
  310.   for toastIndex, toast in ipairs(self.BNToasts) do
  311.     if toast.toastType == toastType and toast.toastData == toastData then
  312.       tremove(self.BNToasts, toastIndex);
  313.       break;
  314.     end
  315.   end
  316. end
  317.  
  318. --This is used to track time played for an alert in Korea
  319.  
  320. BNetTimeAlertMixin = {};
  321.  
  322. function BNetTimeAlertMixin:OnLoad()
  323.   self:RegisterEvent("SESSION_TIME_ALERT");
  324.  
  325.   local alertSystem = ChatAlertFrame:AddAutoAnchoredSubSystem(self);
  326.   ChatAlertFrame:SetSubSystemAnchorPriority(alertSystem, 2);
  327. end
  328.  
  329. function BNetTimeAlertMixin:OnEvent(event, ...)
  330.   if not self:IsShown() then
  331.     self:Start(...);
  332.   end
  333. end
  334.  
  335. function BNetTimeAlertMixin:Start(time)
  336.   self:SetExternallyManagedOutroAnimation(true); -- Initially this needs to display for a set amount of time, after which the alert system takes over and fades it out.
  337.   AlertFrame_ShowNewAlert(self);
  338.   self.timer = time / 1000;
  339. end
  340.  
  341. function BNetTimeAlertMixin:OnUpdate(elapsed)
  342.   if self.timer then
  343.     self.timer = self.timer - elapsed;
  344.     if self.timer < 0 then
  345.       self:SetExternallyManagedOutroAnimation(false);
  346.       AlertFrame_PlayOutroAnimation(self);
  347.       self.timer = nil;
  348.     end
  349.   end
  350.  
  351.   -- As long as this frame is shown, continue to update
  352.   self.Text:SetFormattedText(TIME_PLAYED_ALERT, SecondsToTime(GetSessionTime(), true, true));
  353.   self:SetHeight(self.Text:GetStringHeight() + 20);
  354. end
  355.  
  356. function BNet_GetClientEmbeddedTexture(client, width, height, xOffset, yOffset)
  357.   width = width or 0;
  358.   height = height or width;
  359.   xOffset = xOffset or 0;
  360.   yOffset = yOffset or 0;
  361.  
  362.   local textureString;
  363.   if ( client == BNET_CLIENT_WOW ) then
  364.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-WOW";
  365.   elseif ( client == BNET_CLIENT_SC2 ) then
  366.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-SC2";
  367.   elseif ( client == BNET_CLIENT_D3 ) then
  368.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-D3";
  369.   elseif ( client == BNET_CLIENT_WTCG ) then
  370.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-WTCG";
  371.   elseif ( client == BNET_CLIENT_HEROES ) then
  372.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-HotS";
  373.   elseif ( client == BNET_CLIENT_OVERWATCH ) then
  374.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-Overwatch";
  375.   elseif ( client == BNET_CLIENT_SC ) then
  376.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-SC";
  377.   elseif ( client == BNET_CLIENT_DESTINY2 ) then
  378.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-Destiny2";
  379.   elseif ( client == BNET_CLIENT_COD ) then
  380.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-CallOfDutyBlackOps4";
  381.   else
  382.     textureString = "Interface\\ChatFrame\\UI-ChatIcon-Battlenet";
  383.   end
  384.   return string.format("|T%s:%d:%d:%d:%d|t", textureString, width, height, xOffset, yOffset);
  385. end
  386.  
  387. function BNet_GetClientTexture(client)
  388.   if ( client == BNET_CLIENT_WOW ) then
  389.     return "Interface\\FriendsFrame\\Battlenet-WoWicon";
  390.   elseif ( client == BNET_CLIENT_SC2 ) then
  391.     return "Interface\\FriendsFrame\\Battlenet-Sc2icon";
  392.   elseif ( client == BNET_CLIENT_D3 ) then
  393.     return "Interface\\FriendsFrame\\Battlenet-D3icon";
  394.   elseif ( client == BNET_CLIENT_WTCG ) then
  395.     return "Interface\\FriendsFrame\\Battlenet-WTCGicon";
  396.   elseif ( client == BNET_CLIENT_HEROES ) then
  397.     return "Interface\\FriendsFrame\\Battlenet-HotSicon";
  398.   elseif ( client == BNET_CLIENT_OVERWATCH ) then
  399.     return "Interface\\FriendsFrame\\Battlenet-Overwatchicon";
  400.   elseif ( client == BNET_CLIENT_SC ) then
  401.     return "Interface\\FriendsFrame\\Battlenet-SCicon";
  402.   elseif ( client == BNET_CLIENT_DESTINY2 ) then
  403.     return "Interface\\FriendsFrame\\Battlenet-Destiny2icon";
  404.   elseif ( client == BNET_CLIENT_COD ) then
  405.     return "Interface\\FriendsFrame\\Battlenet-CallOfDutyBlackOps4icon";
  406.   else
  407.     return "Interface\\FriendsFrame\\Battlenet-Battleneticon";
  408.   end
  409. end
  410.  
  411. -- if we don't have a character name or it's for a game that doesn't have toons like Heroes, use the battletag
  412. function BNet_GetValidatedCharacterName(characterName, battleTag, client)
  413.   if ( not characterName or characterName == "" or client == BNET_CLIENT_HEROES ) then
  414.     if ( battleTag and battleTag ~= "" ) then
  415.       local symbol = string.find(battleTag, "#");
  416.       if ( symbol ) then
  417.         return string.sub(battleTag, 1, symbol - 1);
  418.       else
  419.         return battleTag;
  420.       end
  421.     else
  422.       return nil;
  423.     end
  424.   end
  425.   return characterName;
  426. end