Battle For Azeroth Addon Changes

UI and Macro
The COMBAT_LOG_EVENT & COMBAT_LOG_EVENT_UNFILTERED events no longer have any event payload. In order to get the information passed down previously with these events, please use the CombatLogGetCurrentEventInfo function.

Can anyone provide what CombatLogGetCurrentEventInfo returns? is it the same event info as the old code? Internet searching has provided me with a big fat goose egg so far...
nevermind i found something/figured it out
MainMenuBarLeftEndCap:Hide() and MainMenuBarRightEndCap:Hide() seem to be broken now. Are these depreicated?

Previously they got rid of the gryphons at the right and left ends of the action bars.
nvm, I figured it out myself:

MainMenuBarArtFrame.LeftEndCap:Hide();
In last week’s new build of the Battle For Azeroth Beta, we added SendLoggedAddonMessage.

SendLoggedAddonMessage allows players using your addon to report other players for abuse. The message must be valid UTF-8, and its constraints are identical to SendAddonMessage.
In what way does SendLoggedAddonMessage() differ?

What constitues "abuse" in this context?

Does it send only to Blizzard or does it send as SendAddonMessage does, but sends a COPY to Blizzard?

Why "using my addon" as a limitation?

I'm very confused by this.
05/30/2018 10:49 AMPosted by Ythisens
In last week’s new build of the Battle For Azeroth Beta, we added SendLoggedAddonMessage.

SendLoggedAddonMessage allows players using your addon to report other players for abuse. The message must be valid UTF-8, and its constraints are identical to SendAddonMessage.
Does this mean you're finally enforcing things handled by addons, such as the contents of RP profiles?

Or did I misunderstand its intention?
05/30/2018 11:12 AMPosted by Ezkanji
05/30/2018 10:49 AMPosted by Ythisens
In last week’s new build of the Battle For Azeroth Beta, we added SendLoggedAddonMessage.

SendLoggedAddonMessage allows players using your addon to report other players for abuse. The message must be valid UTF-8, and its constraints are identical to SendAddonMessage.
Does this mean you're finally enforcing things handled by addons, such as the contents of RP profiles?

Or did I misunderstand its intention?
I just thought of something neat (sort of).

If the "report" goes to the addon developer somehow, that developer could develop a blacklist, distributed with the addon, that would shut off the addon for individual players if he wanted. Not "remote control" so much as internal code that says "If the player is x on y server, return" in the main loop with no functional code executed. That test could be abstracted to presence in a tContains(blacklistTable, player_realm_string).

In order to prevent folks bypassing it, you could also a) embed it in the main code and b) save the data in some non-human-readable form in the table and only bring it back to readable code at runtime.

Hmmmmm.
05/30/2018 11:22 AMPosted by Ehiztari
I just thought of something neat (sort of).

If the "report" goes to the addon developer somehow, that developer could develop a blacklist, distributed with the addon, that would shut off the addon for individual players if he wanted. Not "remote control" so much as internal code that says "If the player is x on y server, return" in the main loop with no functional code executed. That test could be abstracted to presence in a tContains(blacklistTable, player_realm_string).

In order to prevent folks bypassing it, you could also a) embed it in the main code and b) save the data in some non-human-readable form in the table and only bring it back to readable code at runtime.

Hmmmmm.
I think the idea is neat, but I don't think it's fair to give authors the ability to pick and choose who cannot use their addon so freely... and I highly, highly doubt the messages have a way to redirect to the authors. I think they technically have that capability already, they just don't get "reports" like you suggested to properly manage a blacklist outside of their own personal grudges.

That aside, even obfuscated I don't think it would be hard to break the blacklist functionality, unless you're completely inexperienced with even the basics of programming. Blacklisting would need to protect people on the receiving end (i.e. denying incoming messages from people in the blacklist) rather than the mod rendering itself unusable for the person blacklisted.

But beyond that, honestly I already feel that addons are opt-in as is, and I find that Blizzard starting to govern their usage by the players is a step too far (and unnecessary, given how long we've gone without it). Unlike typical chat channels, the solution to not seeing things you don't want to see in an addon is by not using that addon.

But my opinion on the matter is irrelevant, its intended usage and implications should be clarified.
05/30/2018 11:45 AMPosted by Ezkanji
That aside, even obfuscated I don't think it would be hard to break the blacklist functionality, unless you're completely inexperienced with even the basics of programming.
Challenge accepted! (grin)
05/30/2018 11:45 AMPosted by Ezkanji
Blacklisting would need to protect people on the receiving end (i.e. denying incoming messages from people in the blacklist) rather than the mod rendering itself unusable for the person blacklisted.
If I got a report that someone was misusing an addon of mine and was giving it a bad name, I'd for sure kill the addon by user/realm with no guilt. The only way they'd be able to avoid having problems is if they didn't update and I might be able to find a way round that (there's a mechanism in some addons that send a nag if you're out of date - I could probably hijack that to shut the addon off if you're out of date). Not to say they couldn't rewrite my addon, but I'm pretty sure I could embed actual functionality in there as well somewhere and they'd have to find a way to take the stuff they don't want out and leave the stuff they do want in.
05/30/2018 11:45 AMPosted by Ezkanji
Blizzard starting to govern their usage by the players is a step too far (and unnecessary, given how long we've gone without it).
They're already doing that. Look at what happened to the ability to use coordinates this last xpac - some folks abused it - Blizzard nuked the whole suite of API functions that support it.
05/30/2018 11:45 AMPosted by Ezkanji
But my opinion on the matter is irrelevant, its intended usage and implications should be clarified.
100% agree - I have no idea what Blizzard intends with this and can't find it written up anywhere. I wish they'd post back with some context for this function. Mostly, I'm just blue-skying her.

Much of what I mentioned could be done predatorily as well - suppose you created a killer UI that made PVP much easier and more effective but stayed in-bounds on the rules.

You could embed code in it (even now) that disabled or scrambled certain functionality if the target was one of a list of toons (presumably yours and your friends).

I wouldn't ever actually do that (other than perhaps to Puddin - Earthen Ring as a joke, but he's got a pretty good sense of humor), but it's possible NOW. I just had a momentary hope that "abuse reporting" meant to an account associated with the creation of the addon.
So what is returned by GetSpellInfo() now? And for UnitBuff(), if it can't query by spell name, does it accept spell ID instead? (If there are obvious answers, sorry, I am trying to update an abandoned addon and am new to lua script)
Addon dev here that uses this API for syncing data between users of my addon ( "Guild Roster Manager" ).

I have not yet been invited to the beta so I am a little behind with the new APIs and I was just holding out for the PTR, but in regards to "SendLoggedAddonMessage" the explanation seems somewhat confusing to me.

The ReportPlayer( "typeReport" , "pending" , "comment" ) already functions in this capacity... so I can say ReportPlayer("cheater" , SetPendingReportTarget("target"), "Was fly hacking just now") in the Lua code... accept the confirmation.

But, this comment of yours, "SendLoggedAddonMessage allows players using your addon to report other players for abuse," makes this confusing to me. Why do I need addon to addon talk to send abuse complaints? I can only assume it has to do with some kind of addon abuse? Is it possible to get context here?

Also, is this in any relation to the previous, "SendAddonMessageLogged" API?
05/30/2018 10:49 AMPosted by Ythisens
SendLoggedAddonMessage allows players using your addon to report other players for abuse. The message must be valid UTF-8, and its constraints are identical to SendAddonMessage.

What constitutes "valid UTF-8" in Blizzard's definition? All byte sequences in the 0x01-0x7f range, plus valid UTF-8 characters comprised of bytes outside that range? Or are you restricting this to printable-only?

If it's printable only, please consider changing that to permit all non-NUL bytes. (Perhaps instead note that only components of messages made of printable characters can be checked for abuse?) Pre-existing protocols where abuse is likeliest to be found make fairly extensive use of ASCII control codes, and even just getting every addon using those protocols to change is a daunting task, let alone also getting the users to update.
If I got a report that someone was misusing an addon of mine and was giving it a bad name, I'd for sure kill the addon by user/realm with no guilt. The only way they'd be able to avoid having problems is if they didn't update and I might be able to find a way round that (there's a mechanism in some addons that send a nag if you're out of date - I could probably hijack that to shut the addon off if you're out of date). Not to say they couldn't rewrite my addon, but I'm pretty sure I could embed actual functionality in there as well somewhere and they'd have to find a way to take the stuff they don't want out and leave the stuff they do want in.
I suppose if you intentionally write spaghetti-code so that major features have to pass through the blacklisting feature somehow, that would be a way to make inexperienced players unable to fix the addon if they were blacklisted. But that would also require obfuscating the blacklist itself... which technically goes against the addon policy. I'm actually curious now what a functioning blacklist that is both difficult to break by novice programmers and abides by the addon development policy would look like.

Either way, I feel like that's a tremendous amount of effort for very little return that will probably backfire eventually when something in the API changes and suddenly everything breaks because it was all filtered through the blacklist system.

But this is an agree-to-disagree situation anyway. I'm of the opinion that an addon becomes a community resource once its published, and that the addon author shouldn't have the right to pick and choose who should use it. Believe me, there's a number of people I'd love to deny usage of my PvP mod, but even if I could implement an effective blacklist, I don't think I would let my grudges get the better of me.

They're already doing that. Look at what happened to the ability to use coordinates this last xpac - some folks abused it - Blizzard nuked the whole suite of API functions that support it.
Let me clarify, I meant usage of content of such mods (such as someone's totally questionable fanfic they posted in a roleplaying addon profile). Obviously mods themselves allowing for game-breaking behavior such as the drawing on the 3D space (hello ICC) or DBM's positional radar are arguably problems.

I'm just not convinced that someone who willingly chose to download a 3rd party addon that subjects them to all manner of things written by the best and worst minds of the community, should be upset if they see something they don't approve of on that 3rd party addon.

05/30/2018 04:00 PMPosted by Arkaan
But, this comment of yours, "SendLoggedAddonMessage allows players using your addon to report other players for abuse," makes this confusing to me. Why do I need addon to addon talk to send abuse complaints? I can only assume it has to do with some kind of addon abuse? Is it possible to get context here?
My best guess is what I've mentioned a few times so far - addons send data that actually gets logged on Blizzard's end so someone can report the contents of said data for abuse. Again, example being something inappropriate written in a roleplayer's character profile.

If it's not that, then I have absolutely no idea.
I don't know if this will help any addon authors, but for my addon I created a wrapper function for Blizzard API to help with cross version compatibility.

Basically what it does is if a function has been changed it calls a function in the wrapper which modifies the output, so for example with the 8.0 functions where return values were dropped it drops the values also in 7.3.5 so the returns are consistent between both. Functions like UnitAura which no longer accept spellName on 8.0 if it detects a string parameter it will loop through the auras on the unit and match it to the spell name, and then return the use the API call for that aura's index instead of the spell name.

If the API call has not been changed then it just returns the current API return values.

Please use the code however you like, it will require that your addons be updated to 8.0 compatibility but then they will work on both 8.0 and 7.3.5 exactly the same.

-- Pulls back the Addon-Local Variables and store them locally.
local addonName, addonTable = ...;
local addon = _G[addonName];

-- Store local copies of Blizzard API and other addon global functions and variables
local GetBuildInfo = GetBuildInfo;
local select, setmetatable, table, type, unpack = select, setmetatable, table, type, unpack;

addonTable.CURRENT_WOW_VERSION = select(4, GetBuildInfo());

local Prototype = {
-- API Version History
-- 8.0 - No longer supports canceling by spell name.
CancelUnitBuff = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
local unitID, ID = ...;

if type(ID) == "string" then
for counter = 1, 40 do
local auraName = UnitBuff(unitID, counter);

if ID == auraName then
return CancelUnitBuff(unitID, counter);
end
end
else
return CancelUnitBuff(...);
end
else
return CancelUnitBuff(...);
end
end,

-- API Version History
-- 8.0 - Function Removed
FindBaseSpellNameByName = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
error("FindBaseSpellNameByName API Function has been removed. Please report this error!");
else
return FindBaseSpellNameByName(...);
end
end,

-- API Version History
-- 8.0 - Function Removed
FindSpellOverrideNameByName = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
error("FindSpellOverrideNameByName API Function has been removed. Please report this error!");
else
return FindSpellOverrideNameByName(...);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (nameSubtext).
GetItemSpell = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return GetItemSpell(...);
else
local parameters = { GetItemSpell(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Dropped first two parameters (name, and nameSubtext).
GetMacroSpell = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return GetMacroSpell(...);
else
local parameters = { GetMacroSpell(...) };

table.remove(parameters, 2);
table.remove(parameters, 1);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (nameSubtext).
GetPetActionInfo = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return GetPetActionInfo(...);
else
local parameters = { GetPetActionInfo(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Second parameter changed from spell name to spell ID.
GetPossessInfo = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return GetPossessInfo(...);
else
local parameters = { GetPossessInfo(...) };
local _, _, _, _, _, _, spellID = GetSpellInfo(parameters[2]);

parameters[2] = spellID;

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (name).
GetShapeshiftFormInfo = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return GetShapeshiftFormInfo(...);
else
local parameters = { GetShapeshiftFormInfo(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - No longer returns trade skill link as second parameter (use GetSpellTradeSkillLink)
GetSpellLink = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return GetSpellLink(...);
else
local parameters = { GetSpellLink(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (nameSubtext).
GetTrainerServiceInfo = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return GetTrainerServiceInfo(...);
else
local parameters = { GetTrainerServiceInfo(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Function Removed
SearchGuildRecipes = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
error("SearchGuildRecipes API Function has been removed. Please report this error!");
else
return SearchGuildRecipes(...);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (nameSubtext).
-- - Also, no longer supports querying by spell name.
UnitAura = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
local unitID, ID = ...;

if type(ID) == "string" then
for counter = 1, 40 do
local auraName = UnitAura(unitID, counter);

if ID == auraName then
return UnitAura(unitID, counter);
end
end
else
return UnitAura(...);
end
else
local parameters = { UnitAura(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (nameSubtext).
-- - Also, no longer supports querying by spell name.
UnitBuff = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
local unitID, ID = ...;

if type(ID) == "string" then
for counter = 1, 40 do
local auraName = UnitBuff(unitID, counter);

if ID == auraName then
return UnitBuff(unitID, counter);
end
end
else
return UnitBuff(...);
end
else
local parameters = { UnitBuff(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (nameSubtext).
UnitCastingInfo = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return UnitCastingInfo(...);
else
local parameters = { UnitCastingInfo(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (nameSubtext).
UnitChannelInfo = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
return UnitChannelInfo(...);
else
local parameters = { UnitChannelInfo(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,

-- API Version History
-- 8.0 - Dropped second parameter (nameSubtext).
-- - Also, no longer supports querying by spell name.
UnitDebuff = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
local unitID, ID = ...;

if type(ID) == "string" then
for counter = 1, 40 do
local auraName = UnitDebuff(unitID, counter);

if ID == auraName then
return UnitDebuff(unitID, counter);
end
end
else
return UnitDebuff(...);
end
else
local parameters = { UnitDebuff(...) };

table.remove(parameters, 2);

return unpack(parameters);
end
end,
};

local MT = {
__index = function(table, key)
local classPrototype = Prototype[key];

if classPrototype then
if type(classPrototype) == "function" then
return function(...)
return classPrototype(...);
end
else
return classPrototype;
end
else
return function(...)
return _G[key](...);
end
end
end,
};

addon.APIWrapper = setmetatable({}, MT);


To use this wrapper instead of calling Blizzard API calls directly, simply call them via the wrapper so: GetTime() would become addon.APIWrapper.GetTime();

The advantage of this is that in future patches as more functions are changed the wrapper can just easily be extended to accomodate the new changes, ensuring your addon always gets consistent returns. As I said, hope this helps someone.

The previous posted code, brings all 7.3.5 functions to return the same as 8.0, however so there is less code changes needed in an addon you could always change the 8.0 returns to match the 7.3.5. The following is a changed GetMacroSpell wrapper function that makes 8.0 call to the function return 3 variables just like the 7.3.5 function.

-- API Version History
-- 8.0 - Dropped first two parameters (name, and nameSubtext).
GetMacroSpell = function(...)
if addonTable.CURRENT_WOW_VERSION >= 80000 then
local parameters = { GetMacroSpell(...) };

table.insert(parameters, 1, "dummyReturn");
table.insert(parameters, 2, "dummyReturn");

return unpack(parameters);
else
return GetMacroSpell(...);
end
end,
06/06/2018 09:43 PMPosted by Shibou
I don't know if this will help any addon authors, but for my addon I created a wrapper function for Blizzard API to help with cross version compatibility.


This has helped me immensely, thank you for sharing it =)
05/30/2018 04:37 PMPosted by Itarater
What constitutes "valid UTF-8" in Blizzard's definition? All byte sequences in the 0x01-0x7f range, plus valid UTF-8 characters comprised of bytes outside that range? Or are you restricting this to printable-only?

I checked the beta finally and it's basically a worst-case scenario for C_ChatInfo.SendAddonMessageLogged(), meaning it's completely useless and poorly implemented.

First, it appears to be limited to printable characters only and silently fails (!) when non-printable characters are included. So "valid UTF-8" is incorrect, as UTF-8 explicitly includes ASCII control codes as valid characters. It also will require changes to pre-existing protocols to even consider using it.

Second, there's no method to tell if a received message was sent using C_ChatInfo.SendAddonMessageLogged() or C_ChatInfo.SendAddonMessage(). The triggered event is the same and has identical parameters either way, meaning a bad actor can just find-and-replace all instances of "SendAddonMessageLogged" with "SendAddonMessage" in their addons folder and be completely free of consequence.

So this is completely worthless. It requires rewrites of protocols to avoid non-printable UTF-8, and completely botches the intended purpose by not even distinguishing itself from the unlogged variant, rewarding bad actors who just (very easily) modify any addon source to avoid consequences.

So A+ for finally bothering to try combating abuses over addons, but F for the actual implementation. It's unusable.
Thanks for the feedback. While we have to limit the SendLoggedAddonMessage to UTF-8 that is viewable in WoW, we are adding a CHAT_MSG_ADDON_LOGGED event.
While we have to limit the SendAddonMessageLogged to UTF-8 that is viewable in WoW, we are adding a CHAT_MSG_ADDON_LOGGED event.

Good that it'll be at least partly usable.

However, I'm not following why you have to limit it to printable-only. That seems like a choice, not a requirement. The game client, as-is, replaces non-printable characters in the chat box with the "?" glyph (I think it's the ASCII 0x3F glyph rather than U+FFFD, but that's good enough). A similar technique used for the GM log viewing tools would seem a more logical approach, rather than requiring rewrites of long-standing protocols and serializers that use non-printable characters.

Sure, a protocol designed in bad faith could incorporate binary compression to avoid scrutiny, but this could just as easily be done by just not using the logged function at all. A protocol designed in good faith would only use non-printable characters where necessary for the protocol overhead, meaning all of the potentially-abusive content would be present in plain text anyway, even if there's a scattering of U+FFFD characters when being read in a raw format.

Though I guess with a separate event, at least it's possible to work around with only wasting processing power and bandwidth. I imagine the best way to handle it would be to wrap a quoted-printable filter around the logged function/event returns.
06/12/2018 11:47 AMPosted by Lore
While we have to limit the SendLoggedAddonMessage to UTF-8 that is viewable in WoW, we are adding a CHAT_MSG_ADDON_LOGGED event.

Now that I've had more time to think, I think we really need a better way to deal with "Blizzard-printable" characters. As things stand, the protocol design necessary to handle logged addon messages with non-English languages is going to be a nightmare, since you can't just blindly quoted-printable encode all UTF-8 characters (along with ASCII control codes, which are safe to blindly encode) and still get the benefits of a message's contents being reportable.

Bare minimum, we could use a function that checks a given string and gives a return status of whether the string has any non-Blizzard-printable characters in it. Best would be a string.gsub()-esque function that can be used to replace any non-Blizzard-printable sequences of bytes with an encoded version. Middle-of-the-road would be just a list of Unicode codepoints that are considered Blizzard-printable (or non-Blizzard-printable, whichever is shorter).

It's not absolutely essential for logged addon messages to be baseline usable, but it is almost-essential for them to be easily usable (increasing the odds of existing addons and protocols switching) with non-English, and especially non-Latin-script, languages.

Join the Conversation

Return to Forum