vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
SIMPLECOMM_DEBUG = false;                               -- output debug information

SIMPLECOMM_CHARACTERSPERTICK_MAX = 512; -- char per tick
SIMPLECOMM_TICK_DELAY = 1;                              -- delay in second between tick

local PIPE_ENTITIE = "\127p";

SimpleComm_Channel = nil;
SimpleComm_Password = nil;
SimpleComm_ChatFrame = nil;

SimpleComm_JoinHandler = nil;
SimpleComm_LeaveHandler = nil;

local SimpleComm_Handler = nil;
local SimpleComm_Serialize = nil;
local SimpleComm_Unserialize = nil;
local SimpleComm_FilterText = nil;

local SimpleComm_oldChatFrame_OnEvent = nil;

SimpleComm_oldSendChatMessage = nil;
local SimpleComm_chanSlashCmd = nil;
local SimpleComm_chanSlashCmdUpper = nil;

local SimpleComm_FlagListener = nil;

local SimpleComm_messageQueueHeader = {};
local SimpleComm_messageQueueLast = SimpleComm_messageQueueHeader;
        -- .delay
        -- .to
        -- .serialized
        -- .next
        
local SimpleComm_sentBytes = 0;
local SimpleComm_channelName = nil;

SimpleComm_Disconnected = {};

SimpleComm_DisconnectedMessage = string.format(ERR_CHAT_PLAYER_NOT_FOUND_S, "(.*)");
SimpleComm_AFK_MESSAGE = string.format(MARKED_AFK_MESSAGE, "(.*)");
SimpleComm_DND_MESSAGE = string.format(MARKED_DND, "(.*)");
SimpleComm_Flags = {};
SimpleComm_FlagTestMessage = "-= SimpleComm test message =-";
SimpleComm_WaitingForFlagTest = false;

---------------------------------------------------------------------------------
--
-- Debug
-- 
---------------------------------------------------------------------------------
local function DEBUG_MSG(msg, high)
        if (SIMPLECOMM_DEBUG)
        then
                if high then
                        ChatFrame1:AddMessage(msg, 1.0, 0.0, 0.25);
                else
                        ChatFrame1:AddMessage(msg, 1.0, 1.0, 0.75);
                end
        end
end

---------------------------------------------------------------------------------
--
-- On load
-- 
---------------------------------------------------------------------------------
function SimpleComm_OnLoad()
        this:RegisterEvent("CHAT_MSG_WHISPER");
        this:RegisterEvent("CHAT_MSG_CHANNEL");
        this:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE");
end

---------------------------------------------------------------------------------
--
-- Init
-- 
---------------------------------------------------------------------------------
local function SimpleComm_joinChannel()
        DEBUG_MSG("[SimpleComm_joinChannel] begin");
        if ( GetChannelName(SimpleComm_Channel) == 0) then
                local zoneChannel, channelName = JoinChannelByName(SimpleComm_Channel, SimpleComm_Password, SimpleComm_ChatFrame:GetID());
                
                if (zoneChannel ~= 0) then
                        local name = SimpleComm_Channel;
                        if ( channelName ) then
                                name = channelName;
                        end
                        
                        local i = 1;
                        while ( SimpleComm_ChatFrame.channelList[i] ) do
                                i = i + 1;
                        end
                        SimpleComm_ChatFrame.channelList[i] = name;
                        SimpleComm_ChatFrame.zoneChannelList[i] = zoneChannel;
                end
                DEBUG_MSG("[SimpleComm_joinChannel] end - false");
                return false;
        else
                DEBUG_MSG("[SimpleComm_joinChannel] end - true");
                return true;
        end
end

local function SimpleComm_leaveChannel()
        if ( GetChannelName(SimpleComm_Channel) ~= 0) then
                LeaveChannelByName(SimpleComm_Channel);
                SimpleComm_Channel = nil;
                SimpleComm_Password = nil;
        end
end

local function SimpleComm_initChannel()
        DEBUG_MSG("[SimpleComm_initChannel] begin");
        SimpleComm_messageQueue = { };
        SimpleComm.update = SIMPLECOMM_TICK_DELAY;
        DEBUG_MSG("[SimpleComm_initChannel] end");
        return SimpleComm_joinChannel();
end

local function SimpleComm_doneChannel()
        SimpleComm.update = nil;
        SimpleComm_leaveChannel();
end

---------------------------------------------------------------------------------
--
-- Alias
-- 
---------------------------------------------------------------------------------
local function SimpleComm_SetAliasChannel()
        id = GetChannelName( SimpleComm_Channel );
        if (id~=0 and SimpleComm_aliasMustBeSet) then
                local id = GetChannelName( SimpleComm_Channel );
                
                ChatTypeInfo[SimpleComm_chanSlashCmdUpper] = ChatTypeInfo["CHANNEL"..id];
                ChatTypeInfo[SimpleComm_chanSlashCmdUpper].sticky = 1;
                
                setglobal("CHAT_MSG_"..SimpleComm_chanSlashCmdUpper, SimpleComm_chanAlias);
                setglobal("CHAT_"..SimpleComm_chanSlashCmdUpper.."_GET", "["..SimpleComm_chanAlias.."] %s:\32");
                setglobal("CHAT_"..SimpleComm_chanSlashCmdUpper.."_SEND", SimpleComm_chanAlias..":\32");
                
                SlashCmdList[SimpleComm_chanSlashCmdUpper] = SimpleComm_test;
                setglobal("SLASH_"..SimpleComm_chanSlashCmdUpper.."1", "/"..SimpleComm_chanSlashCmd);
                
                -- hook only one time
                if (not SimpleComm_oldSendChatMessage) then
                        SimpleComm_oldSendChatMessage = SendChatMessage;
                        SendChatMessage = SimpleComm_newSendChatMessage;
                end

                SimpleComm_aliasMustBeSet = false;
        end
end

local function SimpleComm_UnsetAliasChannel()
        if (SimpleComm_chanSlashCmdUpper) then
                
                if ( DEFAULT_CHAT_FRAME.editBox.stickyType == string.upper(SimpleComm_chanSlashCmdUpper) ) then
                        DEFAULT_CHAT_FRAME.editBox.chatType = "SAY"
                        DEFAULT_CHAT_FRAME.editBox.stickyType = "SAY"
                end
                
                setglobal("CHAT_MSG_"..SimpleComm_chanSlashCmdUpper, nil);
                setglobal("CHAT_"..SimpleComm_chanSlashCmdUpper.."_GET", nil);
                setglobal("CHAT_"..SimpleComm_chanSlashCmdUpper.."_SEND", nil);
                
                SlashCmdList[SimpleComm_chanSlashCmdUpper] = nil;
                setglobal("SLASH_"..SimpleComm_chanSlashCmdUpper.."1", nil);
                
                SimpleComm_aliasMustBeSet = true;
        end
end

function SimpleComm_newSendChatMessage(msg, sys, lang, name)
        -- DEBUG_MSG("SimpleComm_newSendChatMessage("..msg..","..sys..","..NoNil(lang)..","..NoNil(name)..")");
        if (sys == SimpleComm_chanSlashCmdUpper) then
                return SimpleComm_oldSendChatMessage(string.gsub(msg, "|", PIPE_ENTITIE), "CHANNEL", lang, GetChannelName( SimpleComm_Channel ));
        else
                return SimpleComm_oldSendChatMessage(msg, sys, lang, name);
        end
end;

function SimpleComm_test()
        DEBUG_MSG("ok");
end

---------------------------------------------------------------------------------
--
-- AFK/DND status
-- 
---------------------------------------------------------------------------------
function SimpleComm_SetFlag(player, flag, message)
        if player==nil then
                player = UnitName("player");
                if SimpleComm_FlagListener then
                        SimpleComm_FlagListener(flag, message);
                end
        end
        if flag then
                SimpleComm_Flags[player] = { flag=flag; message=message; count = 0 };
        else
                SimpleComm_Flags[player] = nil;
        end

end

function SimpleComm_GetFlag(player)
        if SimpleComm_Flags[player] then
                return SimpleComm_Flags[player].flag, SimpleComm_Flags[player].message;
        else
                return nil;
        end
end

function SimpleComm_AddWhisper(player)
        if SimpleComm_Flags[player] then
                SimpleComm_Flags[player].count = SimpleComm_Flags[player].count +1;
        end
end

function SimpleComm_DelWhisper(player)
        if SimpleComm_Flags[player] then
                if SimpleComm_Flags[player].count>0 then
                        SimpleComm_Flags[player].count = SimpleComm_Flags[player].count -1;
                        return true;
                end
        end
        return false;
end

function SimpleComm_SendFlagTest()
        SimpleComm_WaitingForFlagTest = time();
        SendChatMessage(SimpleComm_FlagTestMessage, "WHISPER", nil, UnitName("player"));
end

---------------------------------------------------------------------------------
--
-- Envois
-- 
---------------------------------------------------------------------------------
local function SimpleComm_SendQueue(elapsed)
        -- DEBUG_MSG("[SimpleComm_SendQueue] begin");
        
        local clearAFK = GetCVar("autoClearAFK");
        SetCVar("autoClearAFK", 0);
        -- GetLanguageByIndex(1), GetDefaultLanguage()
        
        SimpleComm_sentBytes = 0;
        SimpleComm_channelName = GetChannelName(SimpleComm_Channel);
        
        local previousMessage = SimpleComm_messageQueueHeader;
        local message = SimpleComm_messageQueueHeader.next;
        
        while message do
                
                -- update delay
                if message.delay then
                        message.delay = message.delay-elapsed;
                        if message.delay<=0 then
                                message.delay = nil;
                        end
                end
                
                if message.delay then
                        -- skip the current message
                        previousMessage = message;
                        message = message.next;
                else
                        -- check chat traffic
                        SimpleComm_sentBytes = SimpleComm_sentBytes + string.len(message.serialized);
                        if SimpleComm_sentBytes > SIMPLECOMM_CHARACTERSPERTICK_MAX then
                                SimpleComm_sentBytes = SimpleComm_sentBytes - string.len(message.serialized);
                                previousMessage = SimpleComm_messageQueueLast;
                                break;
                        end
                        
                        -- send message
                        if message.to then
                                if not SimpleComm_Disconnected[message.to] then
                                        -- DEBUG_MSG("Envois a("..message.to..") de("..message.serialized..")");
                                        SendChatMessage(message.serialized, "WHISPER", nil, message.to);
                                        SimpleComm_AddWhisper(message.to);
                                else
                                        -- Ignore the message since the player is offline.
                                        SimpleComm_sentBytes = SimpleComm_sentBytes - string.len(message.serialized);
                                end
                        else
                                -- DEBUG_MSG("Envois a tous de("..message.serialized..")");
                                SendChatMessage(message.serialized, "CHANNEL", nil, SimpleComm_channelName);
                        end
                        
                        -- delete current message in queue
                        previousMessage.next = message.next;
                        
                        -- go to next message (previousMessage keeps the same value)
                        message = message.next
                end
                
        end
        
        SimpleComm_messageQueueLast = previousMessage;
        
        SetCVar("autoClearAFK", clearAFK);
        if (SimpleComm_sentBytes > 0) then
                DEBUG_MSG("Octets envoyes:"..SimpleComm_sentBytes, true);
        end
        
        -- DEBUG_MSG("[SimpleComm_SendQueue] end");
end

---------------------------------------------------------------------------------
--
-- Reception
-- 
---------------------------------------------------------------------------------
local function SimpleComm_ParseMessage(author, text)
        local message = SimpleComm_Unserialize(text);
        if ((message) and (SimpleComm_Handler)) then
                SimpleComm_Handler(author, message);
        end
end

function SimpleComm_ParseEvent(event)
        if (SimpleComm_Channel) then
                
                -- event=CHAT_MSG_CHANNEL; arg1=chat message; arg2=author; arg3=language; arg4=channel name with number; arg8=channel number; arg9=channel name without number
                if ((event == "CHAT_MSG_CHANNEL") and (arg9 == SimpleComm_Channel)) then
                        -- DEBUG_MSG("Reception depuis le channel:"..arg1);
                        SimpleComm_Disconnected[arg2] = nil;
                        SimpleComm_ParseMessage(arg2, arg1);
                
                elseif (event == "CHAT_MSG_WHISPER") then
                        -- DEBUG_MSG("Reception de "..arg2..":"..arg1);
                        SimpleComm_Disconnected[arg2] = nil;
                        SimpleComm_ParseMessage(arg2, arg1);
                
                elseif ((event == "CHAT_MSG_CHANNEL_NOTICE") and (arg9 == SimpleComm_Channel)) then
                        if (arg1 == "YOU_JOINED") then
                                if (SimpleComm_Password) then
                                        SetChannelPassword(SimpleComm_Channel, SimpleComm_Password);
                                end
                                if (SimpleComm_chanSlashCmd) then
                                        SimpleComm_SetAliasChannel();
                                end
                                if (SimpleComm_JoinHandler) then
                                        SimpleComm_JoinHandler();
                                end
                        elseif (arg1 == "YOU_LEFT") then
                                if (SimpleComm_chanSlashCmd) then
                                        SimpleComm_UnsetAliasChannel();
                                end
                                if (SimpleComm_LeaveHandler) then
                                        SimpleComm_LeaveHandler();
                                end
                        end
                end
                
        end
end

function SimpleComm_newChatFrame_OnEvent(event)
        if (SimpleComm_Channel) then
                
                if ((event == "CHAT_MSG_CHANNEL") and (arg9 == SimpleComm_Channel)) then

                        -- Hide if this is an internal message
                        if SimpleComm_FilterText(arg1) then
                                return;
                        end
                        
                        -- the message is shown in this ChatFrame ?
                        local info;
                        local found = 0;
                        local channelLength = strlen(arg4);
                        for index, value in this.channelList do
                                if ( channelLength > strlen(value) ) then
                                        -- arg9 is the channel name without the number in front...
                                        if ( ((arg7 > 0) and (this.zoneChannelList[index] == arg7)) or (strupper(value) == strupper(arg9)) ) then
                                                found = 1;
                                                info = ChatTypeInfo["CHANNEL"..arg8];
                                                break;
                                        end
                                end
                        end
                        if ( (found == 0) or not info ) then
                                return;
                        end
                        
                        -- unpack PIPE_ENTITIE
                        arg1 = string.gsub(arg1, PIPE_ENTITIE, "|")
                        
                        if (SimpleComm_chanSlashCmdUpper) then
                                event = "CHAT_MSG_"..SimpleComm_chanSlashCmdUpper;
                                arg4 = "";   --  channel name with number
                        end
                end
                
                if (event == "CHAT_MSG_SYSTEM") then
                        local iStart, iEnd, playerName = string.find(arg1, SimpleComm_DisconnectedMessage);
                        if iStart then
                                if SimpleComm_Disconnected[playerName] then
                                        if time()-SimpleComm_Disconnected[playerName] < 2 then 
                                                return;
                                        end
                                else
                                        SimpleComm_Disconnected[playerName] = time();
                                end
                        end
                        
                        local iStart, iEnd, message = string.find(arg1, SimpleComm_AFK_MESSAGE);
                        if iStart or arg1==MARKED_AFK then 
                                SimpleComm_SetFlag(nil, "AFK", message);
                        end
                        
                        local iStart, iEnd, message = string.find(arg1, SimpleComm_DND_MESSAGE);
                        if iStart then
                                SimpleComm_SetFlag(nil, "DND", message);
                        end
                        
                        if arg1==CLEARED_AFK or arg1==CLEARED_DND then
                                SimpleComm_SetFlag(nil, nil, nil);
                        end
                end
                
                if (event == "CHAT_MSG_WHISPER") then
                        if SimpleComm_FilterText(arg1) or arg1==SimpleComm_FlagTestMessage then
                                return;
                        end
                end
                
                if (event == "CHAT_MSG_WHISPER_INFORM") then
                        if SimpleComm_FilterText(arg1) or arg1==SimpleComm_FlagTestMessage then
                                return;
                        end
                end
                
                if (event == "CHAT_MSG_CHANNEL_JOIN") and (arg9 == SimpleComm_Channel) then
                        SimpleComm_Disconnected[arg2] = nil;
                        return;
                end
                
                if (event == "CHAT_MSG_CHANNEL_LEAVE") and (arg9 == SimpleComm_Channel) then
                        -- to avoid bug #1315237 : guess that player is offline if he isn't on the channel
                        SimpleComm_Disconnected[arg2] = time();
                        return;
                end
                
                if event == "CHAT_MSG_AFK" or event == "CHAT_MSG_DND" then
                        if SimpleComm_DelWhisper(arg2) then
                                return;
                        elseif SimpleComm_WaitingForFlagTest and arg2==UnitName("player") then
                                -- whisper to myself, and SimpleComm is waiting for the AFK/DND status
                                if (SimpleComm_WaitingForFlagTest-time())<10 then
                                        -- event before 10 seconds -> the player is AFK/DND
                                        if event=="CHAT_MSG_AFK" then
                                                SimpleComm_SetFlag(nil, "AFK", arg1);
                                        elseif event=="CHAT_MSG_DND" then
                                                SimpleComm_SetFlag(nil, "DND", arg1);
                                        end
                                        SimpleComm_WaitingForFlagTest = false;
                                        return
                                else
                                        -- event 10 seconds after the init -> the player wrote and sent a whisper to himself while he is AFK/DND.
                                        SimpleComm_WaitingForFlagTest = false;
                                end
                        end
                end
        else
                if event=="CHAT_MSG_CHANNEL" or event=="CHAT_MSG_WHISPER" or event=="CHAT_MSG_WHISPER_INFORM" then
                        if SimpleComm_FilterText and SimpleComm_FilterText(arg1) then
                                return;
                        end
                end
        end
        
        SimpleComm_oldChatFrame_OnEvent(event);
end
SimpleComm_oldChatFrame_OnEvent = ChatFrame_OnEvent;
ChatFrame_OnEvent = SimpleComm_newChatFrame_OnEvent;

---------------------------------------------------------------------------------
--
-- Timer
-- 
---------------------------------------------------------------------------------
function SimpleComm_OnUpdate(elapsed)
        if (this.update) then
                this.update = this.update - elapsed;
                if (this.update <=0) then
                        SimpleComm_SendQueue(SIMPLECOMM_TICK_DELAY - this.update);
                        this.update = SIMPLECOMM_TICK_DELAY;
                end
        elseif (this.initChannel) then
                this.initChannel = this.initChannel - elapsed;
                if (this.initChannel <= 0) then
                        SimpleComm_initChannel();
                        this.initChannel = nil;
                end
        end
end

---------------------------------------------------------------------------------
--
-- Hook into Ephemeral
-- 
---------------------------------------------------------------------------------
local function initEphemeralHook()
        if ep and ep.VERSION_NUMERIC then
                ep.UnregisterForEvent( "CHAT_MSG_WHISPER", ep.RespondToWhisper )
                ep.UnregisterForEvent( "CHAT_MSG_WHISPER_INFORM", ep.RespondToWhisperNotice )
                ep.RegisterForEvent( "CHAT_MSG_WHISPER", SimpleComm_EphemeralRespondToWhisper )
                ep.RegisterForEvent( "CHAT_MSG_WHISPER_INFORM", SimpleComm_EphemeralRespondToWhisperNotice )
        end
end

if ep and not ep.UnregisterForEvent then
        function ep.UnregisterForEvent(event, callback)
                if ep.RegisteredEvents[ event ] then
                        for index, currentCB in ep.RegisteredEvents[ event ] do
                                if currentCB == callback then
                                        table.remove( ep.RegisteredEvents[ event ], index);
                                end
                        end
                end
        end
end

function SimpleComm_EphemeralRespondToWhisper( event, parameters )
        if not SimpleComm_FilterText(parameters[1]) then
                ep.RespondToWhisper(event, parameters);
        end
end

function SimpleComm_EphemeralRespondToWhisperNotice( event, parameters )
        if not SimpleComm_FilterText(parameters[1]) then
                ep.RespondToWhisperNotice(event, parameters);
        end
end


---------------------------------------------------------------------------------
--
-- Fonctions publiques
-- 
---------------------------------------------------------------------------------
function SimpleComm_SendMessage(who, msg, delay)
        if not(who and SimpleComm_Disconnected[who]) then
                SimpleComm_messageQueueLast.next = {to=who; serialized=SimpleComm_Serialize(msg); delay=delay };
                SimpleComm_messageQueueLast = SimpleComm_messageQueueLast.next;
        end
end

function SimpleComm_SendRawMessage(who, message, delay)
        if not(who and SimpleComm_Disconnected[who]) then
                SimpleComm_messageQueueLast.next = {to=who; serialized=message; delay=delay };
                SimpleComm_messageQueueLast = SimpleComm_messageQueueLast.next;
        end
end

function SimpleComm_PreInit(FilterText)
        SimpleComm_FilterText = FilterText;
end

function SimpleComm_Init(Channel, Password, ChatFrame, OnJoin, OnLeave, OnMessage, Serialize, Unserialize, FilterText)
        DEBUG_MSG("[SimpleComm_Init] begin");
        -- Pour la reception
        SimpleComm_Handler = OnMessage;
        SimpleComm_JoinHandler = OnJoin;
        SimpleComm_LeaveHandler = OnLeave;
        SimpleComm_Serialize =  Serialize;
        SimpleComm_Unserialize =  Unserialize;
        SimpleComm_FilterText = FilterText;
        SimpleComm_ChatFrame = ChatFrame;
        
        -- Init Channel
        SimpleComm_Channel = Channel;
        SimpleComm_Password = Password;
        local onChannelNow = SimpleComm_initChannel();
        
        -- Init hook into Ephemeral
        initEphemeralHook();
        
        -- AFK/DND test for myself
        SimpleComm_SendFlagTest();
        
        -- 
        if (onChannelNow) then
                SimpleComm_JoinHandler();
        end
        
        -- Set timer
        SimpleComm:Show();
        
        DEBUG_MSG("[SimpleComm_Init] end");
end

function SimpleComm_InitAlias(chanSlashCmd, chanAlias)
        DEBUG_MSG("[SimpleComm_InitAlias] begin");
        -- unset previous alias
        if (SimpleComm_chanSlashCmd) then
                SimpleComm_UnsetAliasChannel();
        end
        
        -- set alias
        SimpleComm_chanSlashCmd = chanSlashCmd;
        SimpleComm_chanSlashCmdUpper = string.upper(chanSlashCmd);
        SimpleComm_chanAlias = chanAlias;
        
        SimpleComm_aliasMustBeSet = true;
        SimpleComm_SetAliasChannel();
        DEBUG_MSG("[SimpleComm_InitAlias] end");
end

function SimpleComm_SetChannel(Channel, Password)
        if (Channel ~= SimpleComm_Channel) then
                -- done
                if (SimpleComm_chanSlashCmd) then
                        SimpleComm_UnsetAliasChannel();
                end
                SimpleComm_doneChannel();
                -- set channel
                SimpleComm_Channel = Channel;
                SimpleComm_Password = Password;
                -- init alias / joinHandler
                local onChannelNow = (GetChannelName(SimpleComm_Channel) ~= 0);
                if (onChannelNow) then
                        SimpleComm_JoinHandler();
                        if (SimpleComm_chanSlashCmd) then
                                SimpleComm_SetAliasChannel();
                        end
                end
                -- call SimpleComm_initChannel in 2 seconds
                SimpleComm.initChannel = 2;
        end
end

function SimpleComm_SetFlagListener(flagListener)       
        SimpleComm_FlagListener = flagListener;
end

Generated by GNU Enscript 1.6.5.90.