Addon Comm Sobriety Filter

Note: This filter is not a requirement, but highly recommended. If addons do not do this drunken players could cause problems. As of 1.12 this is not a problem for messages sent through SendAddonMessage, but there's still channels where we can't use that API; whispers and worldwide communication being two good examples.

When you are drunk, your text is slurred in two possible ways: "s" is changed to "sh" and " ...hic!" (localized) is added to the end of your message.

The internal Blizzard function can be represented as such: function Drunkify(text) -- turns regular text into drunken, slurred text. return string.gsub(text, "([Ss])", "%1h") .. " ...hic!" end assert(Drunkify("I drank seven beers") == "I drank sheven beersh ...hic!")

Human Readable
Note: Due to the fact this method increases the size of a message it should only be used for messages which need to remain human readable.

In order to prevent this, special care must be taken to make sure that "sh"s are turned back into "s"s, but without overkill. Also, the " ...hic!" must be stripped from the end, paying careful attention to localization.

Here are two functions to handle this on send and receive:

Note: the hidden character can be absolutely any character except "S" or "s"

-- Package a message for transmission function Encode(text) text = string.gsub(text, "([h°])", "°%1") -- encode a hidden character in front of all the "h"s and the same hidden character return text.."°" -- add the hidden character to the very end. end

-- Clean a received message function Decode(text) text = string.gsub(text, "([Ss])h", "%1")      -- find "h"s added to any "s", remove. text = string.gsub(text, "°([h°])", "%1")      -- remove the hidden character. text = string.gsub(text, "^(.*)°.-$", "%1") -- make sure there hasn't been further tampering with the msg. return text end

By definition, Decode(Encode(text)) == text, but also Decode(Drunkify(Encode(text))) == text, where Drunkify is Blizzard's internal function.

-- some tests: assert(Decode(Encode("It's 58° out!")) == "It's 58° out!") assert(Decode(Encode("She sells sea shells by the sea shore")) == "She sells sea shells by the sea shore") assert(Decode(Drunkify(Encode("She sells sea shells by the sea shore"))) == "She sells sea shells by the sea shore")

Consistent Message Length
Note: May be preferable to the human readable method because it does not increase the message length.

An alternate method is to simply remove the "S" and "s" characters and replace them with another to prevent the slurring from even happening.

-- Package a message for transmission function Encode(text) text = string.gsub(msg, "s", "$"); text = string.gsub(msg, "S", "§"); return text; end

-- Clean a received message local DrunkSuffix = string.gsub(SLURRED_SPEECH, "%%s(.+)", "%1$"); -- remove "%s" from the localized " ...hic!" text; function Decode(text) text = string.gsub(text, "%$", "s"); text = string.gsub(text, "§", "S"); text = string.gsub(text, DrunkSuffix, ""); -- likely only needed if decoding an entire message return text; end

This can be faster than the human readable method for two reasons. First the message size is not increased at all unless the player is already drunk and the " ...hic!" gets added. Second, the switching of characters from "s" to another character can be done before hand by the mod author, the encoding and decoding of the string can be done only to specific pieces of the message on a "need" basis (ie: sending player or mob names).