|
|
|
|
--imports
|
|
|
|
|
local WIM = WIM;
|
|
|
|
|
local _G = _G;
|
|
|
|
|
local table = table;
|
|
|
|
|
local string = string;
|
|
|
|
|
local pairs = pairs;
|
|
|
|
|
local tonumber = tonumber;
|
|
|
|
|
local type = type;
|
|
|
|
|
local math = math;
|
|
|
|
|
local tostring = tostring;
|
|
|
|
|
|
|
|
|
|
--set namespace
|
|
|
|
|
setfenv(1, WIM);
|
|
|
|
|
|
|
|
|
|
db_defaults.disableAddonMessages = isPrivateServer;
|
|
|
|
|
|
|
|
|
|
local SocketPool = {};
|
|
|
|
|
local recycled = {};
|
|
|
|
|
|
|
|
|
|
local socketCount = 0;
|
|
|
|
|
local socketFrame = _G.CreateFrame("Frame");
|
|
|
|
|
socketFrame:RegisterEvent("CHAT_MSG_ADDON");
|
|
|
|
|
|
|
|
|
|
local CommandHandlers = {};
|
|
|
|
|
|
|
|
|
|
WIM.stats.Socket = {
|
|
|
|
|
i = 0,
|
|
|
|
|
o = 0,
|
|
|
|
|
};
|
|
|
|
|
local Stats = WIM.stats.Socket;
|
|
|
|
|
|
|
|
|
|
local function getNewTable()
|
|
|
|
|
if(#recycled > 0) then
|
|
|
|
|
local tbl = recycled[1];
|
|
|
|
|
table.remove(recycled, 1);
|
|
|
|
|
return tbl;
|
|
|
|
|
else
|
|
|
|
|
return {};
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function recycleTable(tbl)
|
|
|
|
|
for k, _ in pairs(tbl) do
|
|
|
|
|
tbl[k] = nil;
|
|
|
|
|
end
|
|
|
|
|
table.insert(recycled, tbl);
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- inbound Traffic:
|
|
|
|
|
local function getSocket(user, socketIndex)
|
|
|
|
|
-- returns nil if socket doesn't exist
|
|
|
|
|
return SocketPool[user] and SocketPool[user][socketIndex] or nil;
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function createNewSocket(user, socketIndex, dataLength)
|
|
|
|
|
SocketPool[user] = SocketPool[user] or getNewTable();
|
|
|
|
|
SocketPool[user][socketIndex] = getNewTable();
|
|
|
|
|
SocketPool[user][socketIndex].data = "";
|
|
|
|
|
SocketPool[user][socketIndex].len = tonumber(dataLength);
|
|
|
|
|
return SocketPool[user][socketIndex];
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function ProcessData(channel, from, data)
|
|
|
|
|
local cmd, dat = string.match(data, "^(%w+):(.*)$")
|
|
|
|
|
dat = Decompress(dat);
|
|
|
|
|
dPrint(channel..":"..from.."->"..cmd..":"..dat);
|
|
|
|
|
if(CommandHandlers[cmd]) then
|
|
|
|
|
for i = 1, #CommandHandlers[cmd] do
|
|
|
|
|
if(CommandHandlers[cmd][i].callBack) then
|
|
|
|
|
CommandHandlers[cmd][i].callBack(from, dat);
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function OnEvent(self, event, ...)
|
|
|
|
|
local addon, data, channel, from = ...;
|
|
|
|
|
-- we are only processing WIM addon messages
|
|
|
|
|
if(addon == "WIM") then
|
|
|
|
|
Stats.i = Stats.i + string.len(data);
|
|
|
|
|
local cmd, args, pcmd = string.match(data, "^#HEADER:(%d+):(%d+):(%w+)");
|
|
|
|
|
if(cmd and args) then
|
|
|
|
|
local socket = createNewSocket(from, tonumber(cmd), tonumber(args));
|
|
|
|
|
socket.cmd = pcmd;
|
|
|
|
|
return;
|
|
|
|
|
end
|
|
|
|
|
local sIndex, packet = string.match(data, "^#(%d+):(.*)");
|
|
|
|
|
if(sIndex and packet) then
|
|
|
|
|
local socket = getSocket(from, tonumber(sIndex));
|
|
|
|
|
socket.data = socket.data..packet;
|
|
|
|
|
cmd = string.match(socket.data, "^(%w+):(.*)");
|
|
|
|
|
--dPrint(string.len(socket.data)/socket.len*100 .. "%")
|
|
|
|
|
if(CommandHandlers[cmd]) then
|
|
|
|
|
for i = 1, #CommandHandlers[cmd] do
|
|
|
|
|
if(CommandHandlers[cmd][i].progress) then
|
|
|
|
|
CommandHandlers[cmd][i].progress(from, string.len(socket.data)/socket.len);
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if(string.len(socket.data) == socket.len) then
|
|
|
|
|
ProcessData(channel, from, socket.data);
|
|
|
|
|
SocketPool[from][tonumber(sIndex)] = nil;
|
|
|
|
|
recycleTable(socket);
|
|
|
|
|
end
|
|
|
|
|
return;
|
|
|
|
|
end
|
|
|
|
|
cmd, args = string.match(data, "^!(.*)");
|
|
|
|
|
if(cmd) then
|
|
|
|
|
ProcessData(channel, from, cmd);
|
|
|
|
|
return;
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
socketFrame:SetScript("OnEvent", OnEvent);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function RegisterAddonMessageHandler(command, callBack, progressCallBack)
|
|
|
|
|
command = string.upper(command);
|
|
|
|
|
CommandHandlers[command] = CommandHandlers[command] or {};
|
|
|
|
|
table.insert(CommandHandlers[command], {
|
|
|
|
|
callBack = callBack,
|
|
|
|
|
progress = progressCallBack
|
|
|
|
|
});
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function debugSentData(msg, ttype, target)
|
|
|
|
|
if(WIM.beta) then
|
|
|
|
|
WIM.debugSentData = WIM.debugSentData or {};
|
|
|
|
|
table.insert(WIM.debugSentData, "["..msg.."],["..(ttype or "NIL").."],["..(target or "NIL").."]");
|
|
|
|
|
if(#WIM.debugSentData > 100) then
|
|
|
|
|
table.remove(WIM.debugSentData, #WIM.debugSentData);
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function isBattleNet(user)
|
|
|
|
|
return _G.BNet_GetBNetIDAccount(user);
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- outbound Traffic:
|
|
|
|
|
function SendData(ttype, target, cmd, data)
|
|
|
|
|
if(db.disableAddonMessages or (ttype == "WHISPER" and isBattleNet(target))) then
|
|
|
|
|
return; -- we don't want to send addon messages if on a private server.
|
|
|
|
|
end
|
|
|
|
|
data = data and tostring(data) or ""; --tostring(data);
|
|
|
|
|
ttype = string.upper(ttype);
|
|
|
|
|
if(ttype == "WHISPER" and IsGM(target)) then
|
|
|
|
|
-- we do not want to send any messages to GM's
|
|
|
|
|
return;
|
|
|
|
|
end
|
|
|
|
|
debugSentData(string.upper(cmd)..":"..data, ttype, target); -- for debugging
|
|
|
|
|
if((string.len(cmd) + string.len(data) + 1) <= 200) then
|
|
|
|
|
msg = string.upper(cmd)..":"..data;
|
|
|
|
|
else
|
|
|
|
|
msg = string.upper(cmd)..":"..Compress(data);
|
|
|
|
|
end
|
|
|
|
|
--local msg = string.upper(cmd)..":"..data
|
|
|
|
|
local msgCount = math.ceil(string.len(msg)/200);
|
|
|
|
|
if(msgCount == 1) then
|
|
|
|
|
Stats.o = Stats.o + string.len(msg) + 1;
|
|
|
|
|
_G.ChatThrottleLib:SendAddonMessage("NORMAL", "WIM", "!"..msg, ttype, target);
|
|
|
|
|
else
|
|
|
|
|
socketCount = socketCount + 1;
|
|
|
|
|
local header = "#HEADER:"..socketCount..":"..string.len(msg)..":"..string.upper(cmd);
|
|
|
|
|
local prefix = "#"..socketCount..":";
|
|
|
|
|
Stats.o = Stats.o + string.len(header);
|
|
|
|
|
_G.ChatThrottleLib:SendAddonMessage("NORMAL", "WIM", header, ttype, target);
|
|
|
|
|
for i=1, msgCount do
|
|
|
|
|
local chunk = string.sub(msg, ((i-1)*200+1), (((i-1)*200)+200));
|
|
|
|
|
Stats.o = Stats.o + string.len(prefix) + string.len(chunk);
|
|
|
|
|
_G.ChatThrottleLib:SendAddonMessage("BULK", "WIM", prefix..chunk, ttype, target);
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Private Server Checks
|
|
|
|
|
local function addonMessages()
|
|
|
|
|
if(db.disableAddonMessages) then
|
|
|
|
|
db.disableAddonMessages = false;
|
|
|
|
|
_G.DEFAULT_CHAT_FRAME:AddMessage("WIM: Addon Messages "..L["Enabled"]);
|
|
|
|
|
else
|
|
|
|
|
db.disableAddonMessages = true;
|
|
|
|
|
_G.DEFAULT_CHAT_FRAME:AddMessage("WIM: Addon Messages "..L["Disabled"]);
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
RegisterSlashCommand("addon_messages", addonMessages, L["Enable/Disable addon messages."]); -- ReloadUI()
|
|
|
|
|
|
|
|
|
|
|