vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
GATHERER_TOKEN_SEPARATOR = ";";
GATHERER_ADDON_MESSAGE_PREFIX = "gatherer_p2p";

function Gatherer_BroadcastGather(gather, gatherType, gatherC, gatherZ, gatherX, gatherY, iconIndex, gatherEventType)
    assert(type(iconIndex) == 'number')
    local message = Gatherer_EncodeGather(GetUnitName("player"), gather, gatherType, gatherC, gatherZ, gatherX, gatherY, iconIndex, gatherEventType);

    if Gatherer_Settings.debug then
        local prettyNodeName = gather;
        local prettyZoneName = GatherRegionData[gatherC][gatherZ].name;
        Gatherer_ChatNotify(
                        "Broadcasting new " .. prettyNodeName .. " node found in " .. prettyZoneName .. ".",
                        Gatherer_ENotificationType.sending
                );
        Gatherer_ChatNotify(
                        "gatherType: " .. gatherType .. ", gatherEventType: " .. gatherEventType .. ".",
                        Gatherer_ENotificationType.sending
                );
    end

    Gatherer_SendRawMessage(message);
end


VERSION_REG_EXP = '(%d+)\.(%d+)\.(%d+)';


local function extractVersion(str)
    -- type(Text) -> Tuple[int, int, int]
    local major, minor, fix = unpack(Gatherer_split(str, '.'))
    return {tonumber(major), tonumber(minor), tonumber(fix)}
end


local function validPrefix(prefix)
    -- type: (Text) -> bool
    -- Return true if prefix has correct format and acceptable version.
    -- Message format is considered broken *every tenth* minor version.
    -- E.g. 1.0.x and 1.9.x are compatible, 1.0.x and 1.10.x are not.
        -- Thus when breaking message format don't forget to switch to the next ten
        -- in the minor version.

    -- check overall prefix format
    local prefixPos = strfind(
        prefix, '^'..GATHERER_ADDON_MESSAGE_PREFIX..GATHERER_TOKEN_SEPARATOR..VERSION_REG_EXP..'$'
    );
    if (not prefixPos) then
        return
        end

        local versionPos = strfind(prefix, VERSION_REG_EXP)
        local prefixVersionStr = strsub(prefix, versionPos)
        -- check version components
    local prefixVersion = extractVersion(prefixVersionStr);
    local currentVersion = extractVersion(GATHERER_VERSION);
        Gatherer_ChatNotify(
                'Message version: '..table.concat(prefixVersion, ', ')..' vs '..table.concat(currentVersion, ', '),
                Gatherer_ENotificationType.debug
        )
    if (
                (prefixVersion[1] ~= currentVersion[1])
                or (floor(prefixVersion[2]/10) ~= floor(currentVersion[2]/10))
        ) then
        return
    end
        return true
end


function Gatherer_AddonMessageEvent(prefix, message, type)
        if (not Gatherer_Settings.p2p) or (not validPrefix(prefix)) then
        return
        end
        Gatherer_ReceiveBroadcast(message);
end

function Gatherer_EncodeGather(sender, gather, gatherType, gatherC, gatherZ, gatherX, gatherY, gatherIcon, gatherEventType)
    return sender .. GATHERER_TOKEN_SEPARATOR ..
           gather .. GATHERER_TOKEN_SEPARATOR ..
           gatherType .. GATHERER_TOKEN_SEPARATOR ..
           gatherC .. GATHERER_TOKEN_SEPARATOR ..
           gatherZ .. GATHERER_TOKEN_SEPARATOR ..
           gatherX .. GATHERER_TOKEN_SEPARATOR ..
           gatherY .. GATHERER_TOKEN_SEPARATOR ..
           gatherIcon .. GATHERER_TOKEN_SEPARATOR ..
           gatherEventType .. GATHERER_TOKEN_SEPARATOR;
end

function Gatherer_DecodeGather(message)
    local function eatToken(str)
        local sep = string.find(str, GATHERER_TOKEN_SEPARATOR);
        local arg = string.sub(str, 1, sep-1);
        local rest = string.sub(str, sep+1);
        return arg, rest
    end

    local sender, rest = eatToken(message);
    local gather, rest = eatToken(rest);
    local gatherType, rest = eatToken(rest);
    local gatherC, rest = eatToken(rest);
    local gatherZ, rest = eatToken(rest);
    local gatherX, rest = eatToken(rest);
    local gatherY, rest = eatToken(rest);
    local iconIndex, rest = eatToken(rest);
    local gatherEventType, rest = eatToken(rest);

    -- correct types
    gatherType = tonumber(gatherType);
    gatherC = tonumber(gatherC);
    gatherZ = tonumber(gatherZ);
    gatherX = tonumber(gatherX);
    gatherY = tonumber(gatherY);
    iconIndex = tonumber(iconIndex);
    gatherEventType = tonumber(gatherEventType);

    return sender, gather, gatherType, gatherC, gatherZ, gatherX, gatherY, iconIndex, gatherEventType;
end


function Gatherer_ReceiveBroadcast(message)
    local sender, gather, gatherType, gatherC, gatherZ, gatherX, gatherY, iconIndex, gatherEventType = Gatherer_DecodeGather(message);
    assert(type(iconIndex) == 'number')
    if sender ~= GetUnitName("player") then
        if Gatherer_Settings.debug then
            local prettyNodeName = gather;
            local prettyZoneName = GatherRegionData[gatherC][gatherZ].name;
            Gatherer_ChatNotify(
                Gatherer_coloredText(
                                        sender, {170, 115, 255}
                                ) .. " discovered a new " .. prettyNodeName .. " node in " .. prettyZoneName .. ".",
                                Gatherer_ENotificationType.receiving
                        );
                        Gatherer_ChatNotify(
                                'gatherType: '..gatherType..', iconIndex: '.. iconIndex ..', gatherEventType: '..gatherEventType,
                                Gatherer_ENotificationType.receiving
                        )
        end
        local newNodeFound = Gatherer_AddGatherToBase(gather, gatherType, gatherC, gatherZ, gatherX, gatherY, iconIndex, gatherEventType, false);
        if Gatherer_Settings.debug then
            if newNodeFound then
                                Gatherer_ChatNotify('It was a new node!', Gatherer_ENotificationType.info)
            else
                Gatherer_ChatNotify('It was a duplicate.', Gatherer_ENotificationType.warning)
            end
        end
    end
end

function Gatherer_SendRawMessage(message)
    SendAddonMessage(
        GATHERER_ADDON_MESSAGE_PREFIX..GATHERER_TOKEN_SEPARATOR..GATHERER_VERSION,
        message, "GUILD"
    );
end