You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
639 lines
24 KiB
639 lines
24 KiB
-- imports
|
|
local WIM = WIM;
|
|
local _G = _G;
|
|
local CreateFrame = CreateFrame;
|
|
local select = select;
|
|
local type = type;
|
|
local table = table;
|
|
local pairs = pairs;
|
|
local string = string;
|
|
local next = next;
|
|
local Ambiguate = Ambiguate;
|
|
|
|
-- set name space
|
|
setfenv(1, WIM);
|
|
|
|
-- Core information
|
|
addonTocName = "WIM";
|
|
version = "3.10.12";
|
|
beta = false; -- flags current version as beta.
|
|
debug = false; -- turn debugging on and off.
|
|
useProtocol2 = true; -- test switch for new W2W Protocol. (Dev use only)
|
|
local buildNumber = select(4, _G.GetBuildInfo());
|
|
isShadowlands = buildNumber >= 90001;
|
|
isModernApi = buildNumber >= 30401
|
|
isDragonflight = buildNumber >= 100000;
|
|
|
|
-- is Private Server?
|
|
--[[isPrivateServer = not (string.match(_G.GetCVar("realmList"), "worldofwarcraft.com$")
|
|
or string.match(_G.GetCVar("realmList"), "battle.net$")
|
|
or string.match(_G.GetCVar("realmListbn"), "battle.net$")) and true or false;--]]
|
|
|
|
constants = {}; -- constants such as class colors will be stored here. (includes female class names).
|
|
modules = {}; -- module table. consists of all registerd WIM modules/plugins/skins. (treated the same).
|
|
windows = {active = {whisper = {}, chat = {}, w2w = {}}}; -- table of WIM windows.
|
|
libs = {}; -- table of loaded library references.
|
|
stats = {};
|
|
|
|
-- default options. live data is found in WIM.db
|
|
-- modules may insert fields into this table to
|
|
-- respect their option contributions.
|
|
db_defaults = {
|
|
enabled = true,
|
|
showToolTips = true,
|
|
modules = {},
|
|
alertedPrivateServer = false,
|
|
};
|
|
|
|
-- WIM.env is an evironmental reference for the current instance of WIM.
|
|
-- Information is stored here such as .realm and .character.
|
|
-- View table dump for more available information.
|
|
env = {};
|
|
|
|
-- default lists - This will store lists such as friends, guildies, raid members etc.
|
|
lists = {};
|
|
|
|
-- list of all the events registered from attached modules.
|
|
local Events = {};
|
|
|
|
-- create a frame to moderate events and frame updates.
|
|
local workerFrame = CreateFrame("Frame", "WIM_workerFrame");
|
|
workerFrame:SetScript("OnEvent", function(self, event, ...) WIM:CoreEventHandler(event, ...); end);
|
|
|
|
-- some events we always want to listen to so data is ready upon WIM being enabled.
|
|
workerFrame:RegisterEvent("VARIABLES_LOADED");
|
|
workerFrame:RegisterEvent("ADDON_LOADED");
|
|
|
|
-- import libraries.
|
|
libs.SML = _G.LibStub:GetLibrary("LibSharedMedia-3.0");
|
|
libs.ChatHandler = _G.LibStub:GetLibrary("LibChatHandler-1.0");
|
|
libs.DropDownMenu = _G.LibStub:GetLibrary("LibDropDownMenu");
|
|
|
|
-- called when WIM is first loaded into memory but after variables are loaded.
|
|
local function initialize()
|
|
--load cached information from the WIM_Cache saved variable.
|
|
env.cache[env.realm] = env.cache[env.realm] or {};
|
|
env.cache[env.realm][env.character] = env.cache[env.realm][env.character] or {};
|
|
lists.friends = env.cache[env.realm][env.character].friendList;
|
|
lists.guild = env.cache[env.realm][env.character].guildList;
|
|
|
|
if(type(lists.friends) ~= "table") then lists.friends = {}; end
|
|
if(type(lists.guild) ~= "table") then lists.guild = {}; end
|
|
|
|
workerFrame:RegisterEvent("GUILD_ROSTER_UPDATE");
|
|
workerFrame:RegisterEvent("FRIENDLIST_UPDATE");
|
|
workerFrame:RegisterEvent("BN_FRIEND_LIST_SIZE_CHANGED");
|
|
workerFrame:RegisterEvent("BN_FRIEND_INFO_CHANGED");
|
|
|
|
--querie guild roster
|
|
if( _G.IsInGuild() ) then
|
|
-- H.Sch. - ReglohPri - this is deprecated -> GuildRoster() - changed to C_GuildInfo.GuildRoster()
|
|
if not isShadowlands then
|
|
--for classic
|
|
_G.GuildRoster();
|
|
else
|
|
_G.C_GuildInfo.GuildRoster();
|
|
end
|
|
end
|
|
|
|
isInitialized = true;
|
|
|
|
RegisterPrematureSkins();
|
|
|
|
--enableModules
|
|
for moduleName, tData in pairs(modules) do
|
|
modules[moduleName].db = db;
|
|
if(modules[moduleName].canDisable ~= false) then
|
|
local modDB = db.modules[moduleName];
|
|
if(modDB) then
|
|
if(modDB.enabled == nil) then
|
|
modDB.enabled = modules[moduleName].enableByDefault;
|
|
end
|
|
EnableModule(moduleName, modDB.enabled);
|
|
else
|
|
if(modules[moduleName].enableByDefault) then
|
|
EnableModule(moduleName, true);
|
|
end
|
|
end
|
|
else
|
|
EnableModule(moduleName, true);
|
|
end
|
|
end
|
|
|
|
for mName, module in pairs(modules) do
|
|
if(db.enabled) then
|
|
if(type(module.OnEnableWIM) == "function") then
|
|
module:OnEnableWIM();
|
|
end
|
|
else
|
|
if(type(module.OnDisableWIM) == "function") then
|
|
module:OnDisableWIM();
|
|
end
|
|
end
|
|
end
|
|
|
|
-- notify all modules of current state.
|
|
CallModuleFunction("OnStateChange", WIM.curState);
|
|
RegisterSlashCommand("enable", function() SetEnabled(not db.enabled) end, L["Toggle WIM 'On' and 'Off'."]);
|
|
RegisterSlashCommand("debug", function() debug = not debug; end, L["Toggle Debugging Mode 'On' and 'Off'."]);
|
|
FRIENDLIST_UPDATE(); -- pretend event has been fired in order to get cache loaded.
|
|
CallModuleFunction("OnInitialized");
|
|
WindowParent:Show();
|
|
dPrint("WIM initialized...");
|
|
end
|
|
|
|
--Begin Compat wrappers for retail and classic to access same functions and expect same returns
|
|
--These should work in all files that use them since they are written to WIMs global namespace
|
|
--Retail kind of has these for now, but won't forever, and classic is not expected to make same API restructuring, so this ugly mess is probably required forever
|
|
function GetBNGetFriendInfo(friendIndex)
|
|
if not isShadowlands then--Classic
|
|
return _G.BNGetFriendInfo(friendIndex)
|
|
else
|
|
local accountInfo = _G.C_BattleNet.GetFriendAccountInfo(friendIndex);
|
|
if accountInfo then
|
|
local wowProjectID = accountInfo.gameAccountInfo.wowProjectID or 0;
|
|
local clientProgram = accountInfo.gameAccountInfo.clientProgram ~= "" and accountInfo.gameAccountInfo.clientProgram or nil;
|
|
|
|
return accountInfo.bnetAccountID, accountInfo.accountName, accountInfo.battleTag, accountInfo.isBattleTagFriend,
|
|
accountInfo.gameAccountInfo.characterName, accountInfo.gameAccountInfo.gameAccountID, clientProgram,
|
|
accountInfo.gameAccountInfo.isOnline, accountInfo.lastOnlineTime, accountInfo.isAFK, accountInfo.isDND, accountInfo.customMessage, accountInfo.note, accountInfo.isFriend,
|
|
accountInfo.customMessageTime, wowProjectID, accountInfo.rafLinkType == _G.Enum.RafLinkType.Recruit, accountInfo.gameAccountInfo.canSummon, accountInfo.isFavorite, accountInfo.gameAccountInfo.isWowMobile;
|
|
end
|
|
end
|
|
end
|
|
|
|
function GetBNGetFriendInfoByID(id)
|
|
if not isShadowlands then--Classic/TBC
|
|
return _G.BNGetFriendInfoByID(id)
|
|
else--Retail
|
|
local accountInfo = _G.C_BattleNet.GetAccountInfoByID(id) or {};
|
|
if accountInfo and accountInfo.gameAccountInfo then
|
|
local wowProjectID = accountInfo.gameAccountInfo.wowProjectID or 0;
|
|
local clientProgram = accountInfo.gameAccountInfo.clientProgram ~= "" and accountInfo.gameAccountInfo.clientProgram or nil;
|
|
|
|
return accountInfo.bnetAccountID, accountInfo.accountName, accountInfo.battleTag, accountInfo.isBattleTagFriend,
|
|
accountInfo.gameAccountInfo.characterName, accountInfo.gameAccountInfo.gameAccountID, clientProgram,
|
|
accountInfo.gameAccountInfo.isOnline, accountInfo.lastOnlineTime, accountInfo.isAFK, accountInfo.isDND, accountInfo.customMessage, accountInfo.note, accountInfo.isFriend,
|
|
accountInfo.customMessageTime, wowProjectID, accountInfo.rafLinkType == _G.Enum.RafLinkType.Recruit, accountInfo.gameAccountInfo.canSummon, accountInfo.isFavorite, accountInfo.gameAccountInfo.isWowMobile;
|
|
end
|
|
end
|
|
end
|
|
|
|
function GetBNGetGameAccountInfo(toonId)
|
|
if not isShadowlands then--Classic/TBC
|
|
return _G.BNGetGameAccountInfo(toonId)
|
|
else--Retail
|
|
local gameAccountInfo = _G.C_BattleNet.GetGameAccountInfoByID(toonId)
|
|
if gameAccountInfo then
|
|
local wowProjectID = gameAccountInfo.wowProjectID or 0;
|
|
local characterName = gameAccountInfo.characterName or "";
|
|
local realmName = gameAccountInfo.realmName or "";
|
|
local realmID = gameAccountInfo.realmID or 0;
|
|
local factionName = gameAccountInfo.factionName or "";
|
|
local raceName = gameAccountInfo.raceName or "";
|
|
local className = gameAccountInfo.className or "";
|
|
local areaName = gameAccountInfo.areaName or "";
|
|
local characterLevel = gameAccountInfo.characterLevel or "";
|
|
local richPresence = gameAccountInfo.richPresence or "";
|
|
local gameAccountID = gameAccountInfo.gameAccountID or 0;
|
|
local playerGuid = gameAccountInfo.playerGuid or 0;
|
|
return gameAccountInfo.hasFocus, characterName, gameAccountInfo.clientProgram,
|
|
realmName, realmID, factionName, raceName, className, "", areaName, characterLevel,
|
|
richPresence, nil, nil,
|
|
gameAccountInfo.isOnline, gameAccountID, nil, gameAccountInfo.isGameAFK, gameAccountInfo.isGameBusy,
|
|
playerGuid, wowProjectID, gameAccountInfo.isWowMobile
|
|
end
|
|
end
|
|
end
|
|
--End Compat wrappers for retail and classic to access same functions and expect same returns
|
|
|
|
-- called when WIM is enabled.
|
|
-- WIM will not be enabled until WIM is initialized event is fired.
|
|
local function onEnable()
|
|
db.enabled = true;
|
|
|
|
for tEvent, _ in pairs(Events) do
|
|
workerFrame:RegisterEvent(tEvent);
|
|
end
|
|
|
|
if(isInitialized) then
|
|
for mName, module in pairs(modules) do
|
|
if(type(module.OnEnableWIM) == "function") then
|
|
module:OnEnableWIM();
|
|
end
|
|
if(db.modules[mName] and db.modules[mName].enabled and type(module.OnEnable) == "function") then
|
|
module:OnEnable();
|
|
end
|
|
end
|
|
end
|
|
-- DisplayTutorial(L["WIM (WoW Instant Messenger)"], L["WIM is currently running. To access WIM's wide array of options type:"].." |cff69ccf0/wim|r");
|
|
dPrint("WIM is now enabled.");
|
|
|
|
--[[ --Private Server Check
|
|
if(isPrivateServer and not db.alertedPrivateServer) then
|
|
_G.StaticPopupDialogs["WIM_PRIVATE_SERVER"] = {
|
|
preferredIndex = STATICPOPUP_NUMDIALOGS,
|
|
text = L["WIM has detected that you are playing on a private server. Some servers can not process ChatAddonMessages. Would you like to enable them anyway?"],
|
|
button1 = _G.TEXT(_G.YES),
|
|
button2 = _G.TEXT(_G.NO),
|
|
OnShow = function(self) end,
|
|
OnHide = function() end,
|
|
OnAccept = function() db.disableAddonMessages = false; db.alertedPrivateServer = true; end,
|
|
OnCancel = function() db.disableAddonMessages = true; db.alertedPrivateServer = true; end,
|
|
timeout = 0,
|
|
whileDead = 1,
|
|
hideOnEscape = 1
|
|
};
|
|
_G.StaticPopup_Show ("WIM_PRIVATE_SERVER", theLink);
|
|
end--]]
|
|
end
|
|
|
|
-- called when WIM is disabled.
|
|
local function onDisable()
|
|
db.enabled = false;
|
|
|
|
for tEvent, _ in pairs(Events) do
|
|
workerFrame:UnregisterEvent(tEvent);
|
|
end
|
|
|
|
if(isInitialized) then
|
|
for _, module in pairs(modules) do
|
|
if(type(module.OnDisableWIM) == "function") then
|
|
module:OnDisableWIM();
|
|
end
|
|
if(type(module.OnDisable) == "function") then
|
|
module:OnDisable();
|
|
end
|
|
end
|
|
end
|
|
|
|
dPrint("WIM is now disabled.");
|
|
end
|
|
|
|
|
|
function SetEnabled(enabled)
|
|
if( enabled ) then
|
|
onEnable();
|
|
else
|
|
onDisable();
|
|
end
|
|
end
|
|
|
|
-- events are passed to modules. Events do not need to be
|
|
-- unregistered. A disabled module will not receive events.
|
|
local function RegisterEvent(event)
|
|
Events[event] = true;
|
|
if( db and db.enabled ) then
|
|
workerFrame:RegisterEvent(event);
|
|
end
|
|
end
|
|
|
|
-- create a new WIM module. Will return module object.
|
|
function CreateModule(moduleName, enableByDefault)
|
|
if(type(moduleName) == "string") then
|
|
modules[moduleName] = {
|
|
title = moduleName,
|
|
enabled = false,
|
|
enableByDefault = enableByDefault or false,
|
|
canDisable = true,
|
|
resources = {
|
|
lists = lists,
|
|
windows = windows,
|
|
env = env,
|
|
constants = constants,
|
|
libs = libs,
|
|
},
|
|
db = db,
|
|
db_defaults = db_defaults,
|
|
RegisterEvent = function(self, event) RegisterEvent(event); end,
|
|
Enable = function() EnableModule(moduleName, true) end,
|
|
Disable = function() EnableModule(moduleName, false) end,
|
|
dPrint = function(self, t) dPrint(t); end,
|
|
hasWidget = false,
|
|
RegisterWidget = function(widgetName, createFunction) RegisterWidget(widgetName, createFunction, moduleName); end
|
|
}
|
|
return modules[moduleName];
|
|
else
|
|
return nil;
|
|
end
|
|
end
|
|
|
|
function EnableModule(moduleName, enabled)
|
|
if(enabled == nil) then enabled = false; end
|
|
local module = modules[moduleName];
|
|
if(module) then
|
|
if(module.canDisable == false and enabled == false) then
|
|
dPrint("Module '"..moduleName.."' can not be disabled!");
|
|
return;
|
|
end
|
|
if(db) then
|
|
db.modules[moduleName] = WIM.db.modules[moduleName] or {};
|
|
db.modules[moduleName].enabled = enabled;
|
|
end
|
|
if(enabled) then
|
|
module.enabled = enabled;
|
|
if(enabled and type(module.OnEnable) == "function") then
|
|
module:OnEnable();
|
|
elseif(not enabled and type(module.OnDisable) == "function") then
|
|
module:OnDisable();
|
|
end
|
|
dPrint("Module '"..moduleName.."' Enabled");
|
|
else
|
|
if(module.hasWidget) then
|
|
dPrint("Module '"..moduleName.."' will be disabled after restart.");
|
|
else
|
|
module.enabled = enabled;
|
|
if(enabled and type(module.OnEnable) == "function") then
|
|
module:OnEnable();
|
|
elseif(not enabled and type(module.OnDisable) == "function") then
|
|
module:OnDisable();
|
|
end
|
|
dPrint("Module '"..moduleName.."' Disabled");
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function CallModuleFunction(funName, ...)
|
|
-- notify all enabled modules.
|
|
dPrint("Calling Module Function: "..funName);
|
|
for module, tData in pairs(WIM.modules) do
|
|
local fun = tData[funName];
|
|
if(type(fun) == "function" and tData.enabled) then
|
|
dPrint(" +--"..module);
|
|
fun(tData, ...);
|
|
end
|
|
end
|
|
end
|
|
--------------------------------------
|
|
-- Event Handlers --
|
|
--------------------------------------
|
|
|
|
function WIM.honorChatFrameEventFilter(event, ...)
|
|
local arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15 = ...;
|
|
local chatFilters = _G.ChatFrame_GetMessageEventFilters(event);
|
|
local filter = false;
|
|
if chatFilters then
|
|
local narg1, narg2, narg3, narg4, narg5, narg6, narg7, narg8, narg9, narg10, narg11, narg12, narg13, narg14, narg15;
|
|
for _, filterFunc in next, chatFilters do
|
|
filter, narg1, narg2, narg3, narg4, narg5, narg6, narg7, narg8, narg9, narg10, narg11, narg12, narg13, narg14, narg15 = filterFunc(workerFrame, event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
|
|
if filter then
|
|
return true, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15;
|
|
elseif(narg1) then
|
|
arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15 = narg1, narg2, narg3, narg4, narg5, narg6, narg7, narg8, narg9, narg10, narg11, narg12, narg13, narg14, narg15;
|
|
end
|
|
end
|
|
end
|
|
return filter, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15;
|
|
end
|
|
|
|
|
|
function WIM:EventHandler(event,...)
|
|
-- depricated - here for compatibility only
|
|
end
|
|
|
|
-- This is WIM's core event controler.
|
|
function WIM:CoreEventHandler(event, ...)
|
|
|
|
-- Core WIM Event Handlers.
|
|
dPrint("Event '"..event.."' received.");
|
|
|
|
local fun = WIM[event];
|
|
if(type(fun) == "function") then
|
|
dPrint(" +-- WIM:"..event);
|
|
fun(WIM, ...);
|
|
end
|
|
|
|
-- Module Event Handlers
|
|
if(db and db.enabled) then
|
|
for module, tData in pairs(modules) do
|
|
fun = tData[event];
|
|
if(type(fun) == "function" and tData.enabled) then
|
|
dPrint(" +-- "..module..":"..event);
|
|
fun(modules[module], ...);
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function WIM:VARIABLES_LOADED()
|
|
_G.WIM3_Data = _G.WIM3_Data or {};
|
|
db = _G.WIM3_Data;
|
|
_G.WIM3_Cache = _G.WIM3_Cache or {};
|
|
env.cache = _G.WIM3_Cache;
|
|
_G.WIM3_Filters = _G.WIM3_Filters or GetDefaultFilters();
|
|
_G.WIM3_ChatFilters = _G.WIM3_ChatFilters or {};
|
|
if(#_G.WIM3_Filters == 0) then
|
|
_G.WIM3_Filters = GetDefaultFilters();
|
|
end
|
|
filters = _G.WIM3_Filters;
|
|
chatFilters = _G.WIM3_ChatFilters;
|
|
|
|
_G.WIM3_History = _G.WIM3_History or {};
|
|
history = _G.WIM3_History;
|
|
|
|
-- load some environment data.
|
|
env.realm = _G.GetRealmName();
|
|
env.character = _G.UnitName("player");
|
|
|
|
-- inherrit any new default options which wheren't shown in previous releases.
|
|
inherritTable(db_defaults, db);
|
|
lists.gm = {};
|
|
|
|
-- load previous state into memory
|
|
curState = db.lastState;
|
|
|
|
SetEnabled(db.enabled);
|
|
initialize();
|
|
--_G.print("WIM Notice: Since 7.0 there is a new bug where first whisper is not visible until you get a 2nd whisper, or you scroll up and then back down. That's work around. Scroll up, then scroll down.")
|
|
end
|
|
|
|
function WIM:FRIENDLIST_UPDATE()
|
|
env.cache[env.realm][env.character].friendList = env.cache[env.realm][env.character].friendList or {};
|
|
for key, d in pairs(env.cache[env.realm][env.character].friendList) do
|
|
if(d == 1) then
|
|
env.cache[env.realm][env.character].friendList[key] = nil;
|
|
end
|
|
end
|
|
if _G.C_FriendList then
|
|
for i=1, _G.C_FriendList.GetNumFriends() do
|
|
local name = _G.C_FriendList.GetFriendInfoByIndex(i).name;
|
|
if(name) then
|
|
env.cache[env.realm][env.character].friendList[name] = 1; --[set place holder for quick lookup
|
|
end
|
|
end
|
|
else
|
|
for i=1, _G.GetNumFriends() do
|
|
local name = _G.GetFriendInfo(i);
|
|
if(name) then
|
|
env.cache[env.realm][env.character].friendList[name] = 1; --[set place holder for quick lookup
|
|
end
|
|
end
|
|
end
|
|
lists.friends = env.cache[env.realm][env.character].friendList;
|
|
dPrint("Friends list updated...");
|
|
end
|
|
|
|
function WIM:BN_FRIEND_LIST_SIZE_CHANGED()
|
|
env.cache[env.realm][env.character].friendList = env.cache[env.realm][env.character].friendList or {};
|
|
for key, d in pairs(env.cache[env.realm][env.character].friendList) do
|
|
if(d == 2) then
|
|
env.cache[env.realm][env.character].friendList[key] = nil;
|
|
end
|
|
end
|
|
for i=1, _G.BNGetNumFriends() do
|
|
local id, name = GetBNGetFriendInfo(i);
|
|
if(name) then
|
|
env.cache[env.realm][env.character].friendList[name] = 2; --[set place holder for quick lookup
|
|
if(windows.active.whisper[name]) then
|
|
windows.active.whisper[name]:SendWho();
|
|
end
|
|
end
|
|
end
|
|
lists.friends = env.cache[env.realm][env.character].friendList;
|
|
dPrint("RealID list updated...");
|
|
end
|
|
WIM.BN_FRIEND_INFO_CHANGED = WIM.BN_FRIEND_LIST_SIZE_CHANGED;
|
|
|
|
|
|
function WIM:GUILD_ROSTER_UPDATE()
|
|
env.cache[env.realm][env.character].guildList = env.cache[env.realm][env.character].guildList or {};
|
|
for key, _ in pairs(env.cache[env.realm][env.character].guildList) do
|
|
env.cache[env.realm][env.character].guildList[key] = nil;
|
|
end
|
|
if(_G.IsInGuild()) then
|
|
for i=1, _G.GetNumGuildMembers(true) do
|
|
local name = _G.GetGuildRosterInfo(i);
|
|
if(name) then
|
|
name = Ambiguate(name, "none")
|
|
env.cache[env.realm][env.character].guildList[name] = i; --[set place holder for quick lookup
|
|
end
|
|
end
|
|
end
|
|
lists.guild = env.cache[env.realm][env.character].guildList;
|
|
dPrint("Guild list updated...");
|
|
end
|
|
|
|
function IsGM(name)
|
|
if(name == nil or name == "") then
|
|
return false;
|
|
end
|
|
|
|
-- Blizz gave us a new tool. Lets use it.
|
|
if(_G.GMChatFrame_IsGM and _G.GMChatFrame_IsGM(name)) then
|
|
lists.gm[name] = 1;
|
|
return true;
|
|
end
|
|
|
|
if(lists.gm[name]) then
|
|
return true;
|
|
else
|
|
return false;
|
|
end
|
|
end
|
|
|
|
function IsInParty(user)
|
|
for i=1, 4 do
|
|
if(_G.GetUnitName("party"..i, true) == user) then
|
|
return true;
|
|
end
|
|
end
|
|
return false;
|
|
end
|
|
|
|
function IsInRaid(user)
|
|
for i=1, _G.GetNumGroupMembers() do
|
|
if(_G.GetUnitName("raid"..i, true) == user) then
|
|
return true;
|
|
end
|
|
end
|
|
return false;
|
|
end
|
|
|
|
function CompareVersion(v, withV)
|
|
withV = withV or version;
|
|
local M, m, r = string.match(v, "(%d+).(%d+).(%d+)");
|
|
local cM, cm, cr = string.match(withV, "(%d+).(%d+).(%d+)");
|
|
M, m = M*100000, m*1000;
|
|
cM, cm = cM*100000, cm*1000;
|
|
local this, that = cM+cm+cr, M+m+r;
|
|
return that - this;
|
|
end
|
|
|
|
local talentOrder = {};
|
|
function TalentsToString(talents, class)
|
|
--passed talents in format of "#/#/#";
|
|
-- first check that all required information is passed.
|
|
local t1, t2, t3 = string.match(talents or "", "(%d+)/(%d+)/(%d+)");
|
|
if(not t1 or not t2 or not t3 or not class) then
|
|
return talents;
|
|
end
|
|
|
|
-- next check if we even have information to show.
|
|
if(talents == "0/0/0") then return L["None"]; end
|
|
|
|
local classTbl = constants.classes[class];
|
|
if(not classTbl) then
|
|
return talents;
|
|
end
|
|
|
|
-- clear talentOrder
|
|
for k, _ in pairs(talentOrder) do
|
|
talentOrder[k] = nil;
|
|
end
|
|
|
|
--calculate which order the tabs should be in; in relation to spec.
|
|
table.insert(talentOrder, t1.."1");
|
|
table.insert(talentOrder, t2.."2");
|
|
table.insert(talentOrder, t3.."3");
|
|
table.sort(talentOrder);
|
|
|
|
local fVal, f = string.match(_G.tostring(talentOrder[3]), "^(%d+)(%d)$");
|
|
local sVal, s = string.match(_G.tostring(talentOrder[2]), "^(%d+)(%d)$");
|
|
local tVal, t = string.match(_G.tostring(talentOrder[1]), "^(%d+)(%d)$");
|
|
|
|
if(_G.tonumber(fVal)*.75 <= _G.tonumber(sVal)) then
|
|
if(_G.tonumber(fVal)*.75 <= _G.tonumber(tVal)) then
|
|
return L["Hybrid"]..": "..talents;
|
|
else
|
|
return classTbl.talent[_G.tonumber(f)].."/"..classTbl.talent[_G.tonumber(s)]..": "..talents;
|
|
end
|
|
else
|
|
return classTbl.talent[_G.tonumber(f)]..": "..talents;
|
|
end
|
|
end
|
|
|
|
function GetTalentSpec()
|
|
local talents, tabs = "", _G.GetNumTalentTabs();
|
|
for i=1, tabs do
|
|
local name, _, _, _, pointsSpent = _G.GetTalentTabInfo(i);
|
|
talents = i==tabs and talents..pointsSpent or talents..pointsSpent.."/";
|
|
end
|
|
return talents ~= "" and talents or "0/0/0";
|
|
end
|
|
|
|
|
|
|
|
|
|
-- list of PreSendFilterText(text)
|
|
local preSendFilterTextFunctions = {};
|
|
function PreSendFilterText(text)
|
|
for i=1, #preSendFilterTextFunctions do
|
|
text = preSendFilterTextFunctions[i](text);
|
|
end
|
|
return text;
|
|
end
|
|
|
|
function RegisterPreSendFilterText(func)
|
|
if(type(func) == "function") then
|
|
table.insert(preSendFilterTextFunctions, func);
|
|
end
|
|
end
|
|
|
|
--[[ Example usage
|
|
RegisterPreSendFilterText(
|
|
function(text)
|
|
return "john";
|
|
end
|
|
);
|
|
]]
|
|
|