vanilla-wow-addons – Rev 1
?pathlinks?
--[[
Guild Event Manager by Kiki of European Cho'gall (Alliance)
Commands module (handle)
]]
--------------- Shared variables ---------------
--------------- Local variables ---------------
local _GEM_CMD_CloseEventSends = {};
local _GEM_CMD_AutoAckCorrespondance = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSCRIBE] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSCRIBE][GEM_CMD_CMD_SUBSCRIBE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSCRIBE][GEM_CMD_CMD_UNSUBSCRIBE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_UNSUBSCRIBE] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_UNSUBSCRIBE][GEM_CMD_CMD_SUBSCRIBE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_UNSUBSCRIBE][GEM_CMD_CMD_UNSUBSCRIBE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_TITULAR] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_TITULAR][GEM_CMD_CMD_TITULAR] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_TITULAR][GEM_CMD_CMD_SUBSTITUTE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_TITULAR][GEM_CMD_CMD_REPLACEMENT] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_TITULAR][GEM_CMD_CMD_KICK] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_TITULAR][GEM_CMD_CMD_BAN] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSTITUTE] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSTITUTE][GEM_CMD_CMD_TITULAR] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSTITUTE][GEM_CMD_CMD_SUBSTITUTE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSTITUTE][GEM_CMD_CMD_REPLACEMENT] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSTITUTE][GEM_CMD_CMD_KICK] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_SUBSTITUTE][GEM_CMD_CMD_BAN] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_REPLACEMENT] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_REPLACEMENT][GEM_CMD_CMD_TITULAR] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_REPLACEMENT][GEM_CMD_CMD_SUBSTITUTE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_REPLACEMENT][GEM_CMD_CMD_REPLACEMENT] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_REPLACEMENT][GEM_CMD_CMD_KICK] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_REPLACEMENT][GEM_CMD_CMD_BAN] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_KICK] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_KICK][GEM_CMD_CMD_TITULAR] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_KICK][GEM_CMD_CMD_SUBSTITUTE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_KICK][GEM_CMD_CMD_REPLACEMENT] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_KICK][GEM_CMD_CMD_KICK] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_KICK][GEM_CMD_CMD_BAN] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_BAN] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_BAN][GEM_CMD_CMD_TITULAR] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_BAN][GEM_CMD_CMD_SUBSTITUTE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_BAN][GEM_CMD_CMD_REPLACEMENT] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_BAN][GEM_CMD_CMD_KICK] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_BAN][GEM_CMD_CMD_BAN] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_UNBAN] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_UNBAN][GEM_CMD_CMD_KICK] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_UNBAN][GEM_CMD_CMD_UNBAN] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_ASSISTANT] = {};
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_ASSISTANT][GEM_CMD_CMD_UNSUBSCRIBE] = 1;
_GEM_CMD_AutoAckCorrespondance[GEM_CMD_CMD_ASSISTANT][GEM_CMD_CMD_ASSISTANT] = 1;
--------------- Internal functions ---------------
--[[
function _GEM_CMD_CheckExpiredCommand
Checks if the Event has expired yet (well 10h after)
ev_id : String -- EventID
ev_date : Integer -- Event's date
--
Returns True if the event has expired. False otherwise
]]
local function _GEM_CMD_CheckExpiredCommand(ev_id,ev_date)
if(ev_id == nil or ev_date == nil)
then
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"_GEM_CMD_CheckExpiredCommand : ev_id or ev_date is nil. Set as expired !");
return true;
end
local tim = time();
if((ev_date + GEM_ExpirationTime) < (tim-GEM_GetOffsetTime(ev_id)))
then
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"_GEM_CMD_CheckExpiredCommand : Command expired for Event "..ev_id.." ! ("..date("%c",ev_date).."--"..date("%c",tim)..")");
GEM_EVT_ClearEvent(ev_id,"Expired command",true);
return true;
end
return false;
end
local function _GEM_CMD_AckCommand(ev_id,cmd_id)
GEM_Events.realms[GEM_Realm].commands[ev_id].cmds[cmd_id].acked = 1;
end
--[[
_GEM_CMD_CheckCommandForward :
Params[1] = leader (STRING) -- Leader of the event
Params[2] = ev_date (INT) -- Date of the event
Params[3] = ack (STRING) -- 1 or 0, if the packet is an ack to the command or not
Params[4] = pl_dest (STRING) -- Name of player the command is destinated to
Params[5] = pl_src (STRING) -- Name of player the command is originating from
Returns true if command must be processed, false if it has been forwarded to the new leader
]]
local function _GEM_CMD_CheckCommandForward(channel,cmd,from,stamp,ev_id,params)
local forwarder = GEM_Events.realms[GEM_Realm].forward[ev_id];
-- Check if we have a forwarder set
if(forwarder ~= nil)
then
if(cmd == GEM_CMD_CMD_SUBSCRIBE or cmd == GEM_CMD_CMD_UNSUBSCRIBE) -- For leader commands, we must forward
then
-- Build new params
local new_params = {};
for i=1,table.getn(params) do table.insert(new_params,params[i]); end;
new_params[1] = forwarder;
new_params[4] = forwarder;
if(new_params[3] == "1") -- A ACK
then
GEM_ChatWarning("_GEM_CMD_CheckCommandForward : Params[3] is acked. Must creat new_params entierely");
new_params[3] = "0";
end
-- Store new command
local cmd_id = forwarder.."-"..params[5].."-"..stamp.."-"..cmd;
GEM_CMD_CreateCommandId(ev_id,cmd_id,cmd,stamp,new_params);
-- Send the forwarded message
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"_GEM_CMD_CheckCommandForward : Forwarding "..from.."'s cmd "..cmd.." from "..params[1].." to "..forwarder);
GEM_COM_SendForwardCommand(channel,cmd,ev_id,stamp,new_params);
return false;
end
end
return true;
end
function _GEM_CMD_PurgeMultipleCommands_Sorting(a,b)
if(a.stamp < b.stamp)
then
return true;
else
return false;
end
end
local function _GEM_CMD_PurgeMultipleCommands(ev_id,cmd_id,from)
local thiscmd = GEM_Events.realms[GEM_Realm].commands[ev_id].cmds[cmd_id].cmd;
local thisautoack = _GEM_CMD_AutoAckCorrespondance[thiscmd];
-- First, sort cmds by stamp
local cmds = {};
for cmdid,cmdtab in GEM_Events.realms[GEM_Realm].commands[ev_id].cmds
do
if(from == cmdtab.params[5]) -- This cmd is from 'from' too, add it to the list
then
table.insert(cmds,{ id=cmdid, cmd=cmdtab.cmd, stamp=cmdtab.stamp, acked=cmdtab.acked });
end
end
table.sort(cmds,_GEM_CMD_PurgeMultipleCommands_Sorting);
-- Now check for auto acked cmds
for i,cmd in cmds
do
if(cmd.id == cmd_id) -- Found our cmd, stop parsing
then
break;
end
if(thisautoack[cmd.cmd]) -- This older command must be auto-acked
then
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"_GEM_CMD_PurgeMultipleCommands : Auto acking CmdId "..cmd.id.." because of "..cmd_id);
_GEM_CMD_AckCommand(ev_id,cmd.id);
end
end
end
local function _GEM_CMD_IsTooSoonCmd(ev_id,cmd_id)
if(ev_id == nil or cmd_id == nil)
then
GEM_ChatWarning("_GEM_CMD_IsTooSoonCmd : ev_id or cmd_id is nil : "..tostring(ev_id).." : "..tostring(cmd_id));
return true;
end
if(GEM_Events.realms[GEM_Realm].commands[ev_id].cmds[cmd_id].LastSend and GEM_Events.realms[GEM_Realm].commands[ev_id].cmds[cmd_id].LastSend > GEM_COM_LastJoinerTime) -- Sending too soon ?
then
return true;
end
return false;
end
--------------- Exported functions ---------------
function GEM_CMD_IsCommandAcked(ev_id,cmd_id)
return GEM_Events.realms[GEM_Realm].commands[ev_id].cmds[cmd_id].acked == 1;
end
function GEM_CMD_CreateCommands(channel,ev_id,leader,ev_date)
local s_cmd = {}
s_cmd.cmds = {};
s_cmd.channel = channel;
s_cmd.leader = leader;
s_cmd.ev_date = ev_date;
GEM_Events.realms[GEM_Realm].commands[ev_id] = s_cmd;
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"GEM_CMD_CreateCommands : Creating cmds for eventID "..ev_id);
end
function GEM_CMD_CreateCommandId(ev_id,cmd_id,cmd,stamp,params)
local s_cmd = {};
s_cmd.cmd = cmd;
s_cmd.stamp = stamp;
s_cmd.acked = 0;
s_cmd.params = params;
GEM_Events.realms[GEM_Realm].commands[ev_id].cmds[cmd_id] = s_cmd;
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"GEM_CMD_CreateCommandId : Creating a new cmdID "..cmd_id.." for eventID "..ev_id);
_GEM_CMD_PurgeMultipleCommands(ev_id,cmd_id,params[5]);
end
function GEM_CMD_GetCommands(ev_id)
return GEM_Events.realms[GEM_Realm].commands[ev_id];
end
--[[
GEM_CMD_ReceivedCommand :
Params[1] = leader (STRING) -- Leader of the event
Params[2] = ev_date (INT) -- Date of the event
Params[3] = ack (STRING) -- 1 or 0, if the packet is an ack to the command or not
Params[4] = pl_dest (STRING) -- Name of player the command is destinated to
Params[5] = pl_src (STRING) -- Name of player the command is originating from
]]
function GEM_CMD_ReceivedCommand(channel,cmd,from,stamp,ev_id,params)
local cmd_id = params[4].."-"..params[5].."-"..stamp.."-"..cmd;
local ev_date = tonumber(params[2]);
local must_process = false;
-- First check if command is not expired
if(_GEM_CMD_CheckExpiredCommand(ev_id,ev_date))
then
return must_process;
end
-- Check for unknown event if I'm leader
if(GEM_IsMyReroll(params[1]) and GEM_Events.realms[GEM_Realm].events[ev_id] == nil) -- Unknown event
then
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"GEM_CMD_ReceivedCommand : I'm leader of EventID "..ev_id..", but I don't know it.");
end
-- Create the CMD struct for this ev_id, if it does not exist
if(GEM_Events.realms[GEM_Realm].commands[ev_id] == nil)
then
GEM_CMD_CreateCommands(channel,ev_id,params[1],ev_date);
end
-- Then check if commandID exists
if(GEM_Events.realms[GEM_Realm].commands[ev_id].cmds[cmd_id] == nil)
then
GEM_CMD_CreateCommandId(ev_id,cmd_id,cmd,stamp,params);
end
GEM_QUE_RemoveCommandFromQueue(ev_id,cmd_id); -- Remove from queue. It will be resent if needed
if(params[3] == "1") -- A ACK
then
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"GEM_CMD_ReceivedCommand : Received an ACK from "..from.." for cmdID : "..cmd_id);
_GEM_CMD_AckCommand(ev_id,cmd_id);
else -- A command (not a ACK)
-- Check if I already have a ACK for this
if(GEM_CMD_IsCommandAcked(ev_id,cmd_id)) -- I have a ACK
then
if(not _GEM_CMD_IsTooSoonCmd(ev_id,cmd_id))
then
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"GEM_CMD_ReceivedCommand : I already have a ACK for cmdID "..cmd_id..". Broadcasting my ACK");
GEM_COM_SendAckCommand(ev_id,cmd_id); -- Broadcast the ACK
end
elseif(GEM_IsMyReroll(params[4])) -- This command is for me, ACK it
then
GEM_ChatDebug(GEM_DEBUG_COMMANDS,"GEM_CMD_ReceivedCommand : Got cmdID "..cmd_id.." for me. Broadcasting ACK");
_GEM_CMD_AckCommand(ev_id,cmd_id);
GEM_COM_SendAckCommand(ev_id,cmd_id); -- Broadcast the ACK
must_process = _GEM_CMD_CheckCommandForward(channel,cmd,from,stamp,ev_id,params);
end
end
return must_process;
end
--[[
function GEM_CMD_CheckExpiredCommands
Checks all commands, for expired ones
]]
function GEM_CMD_CheckExpiredCommands()
for ev_id,cmdtab in GEM_Events.realms[GEM_Realm].commands
do
_GEM_CMD_CheckExpiredCommand(ev_id,cmdtab.ev_date);
end
end