--[[ This WIM Plugin was created to educate those interested in creating plugins for WIM. I have tried to comment as much as possible where I felt someone might be confused. for more information, visit http://www.wimaddon.com. ]] --initiate some tables that we will use for processing when receiving messages. local MessageQueue = {}; local UserOkCache = {}; local BlockedMessages = {}; local NoSpamBlockersLoaded = true; --some default settings wpSpamBlocker_Data_DEFAULT = { enabled = true, blockLevel = 1, saveWhiteList = true, notify = true, confirmation = true }; --simple localization definition. wbSpamBlocker_LOCALIZED_OPTIONS_DESC = [[WIM - Spam Blocker is a plugin which takes a simple approach at blocking gold spammers. By blocking whispers based off of the sender's level, almost all chances of receiving spam are eliminated. Allowing "Positive confirmation" allows you to screen non-spammers by sending them an authorization code. The user will then be required to respond with that code in order to be added to your white list. This helps to prevent a non-spammer from being blocked by WIM - SpamBlocker. if you wish to be alerted in the general chat frame when spam has been blocked, enable the option "Notify me when spam is blocked.". if you wish to use a clean white list everytime you log on, disable the option title "Save white list between sessions.". More information on WIM and WIM - SpamBlocker can be found at: |rhttp://www.wimaddon.com ]]; wpSpamBlocker_LOCALIZED_RESPONSE = UnitName("player").." requests that you confirm your identity by responding with the following code: "; wpSpamBlocker_LOCALIZED_THANKYOU = "Thank you! You have now been added to "..UnitName("player").."'s white list."; wpSpamBlocker_LOCALIZED_OTHERLOADED = [[ WIM - SpamBlocker has detected that one of the following spam blocking addons are loaded: - SpamSentry - SpamMeNot - STFU This plugin may not be used in conjunction with one of these addons and is therefore disabled until these addons are no longer being loaded. If you no longer wish to use this plugin, from your character screen, disable WIM_SpamBlocker from your addon list. ]]; --by default, include youself in cache since you don't need to filter yourself. UserOkCache[UnitName("player")] = 1; --Call when this plugin is loaded by its associated xml file. function wpSpamBlocker_OnLoad() -- create plugin info table & register with WIM. local pluginInfo = { version = "1.0.11", description = wbSpamBlocker_LOCALIZED_OPTIONS_DESC, optionsFrame = wbSpamBlocker_Options, interceptInboundFunction = "wpSpamBlocker_InterceptInbound", interceptOutboundFunction = "wpSpamBlocker_InterceptOutbound" }; WIM_RegisterPlugin("WIM - Spam Blocker", pluginInfo, "2.1.0"); -- Using WIM's available API, create a cron job (scheduled task) to run every 5 seconds. WIM_API_AddCronJob("wbSpamBlocker_WhoCheck", wpSpamBlocker_CronWho, 5); WIM_API_AddCronJob("wpSpamBlocker_CleanBlockedMessages", wpSpamBlocker_CleanBlockedMessages, 60); -- hook for who test wpSpamBlocker_FriendsFrame_OnEvent_orig = FriendsFrame_OnEvent; FriendsFrame_OnEvent = wpSpamBlocker_FriendsFrame_OnEvent; wpSpamBlocker_SetItemRef_orig = SetItemRef; SetItemRef = wpSpamBlocker_SetItemRef; wbSpamBlocker_Options_OtherLoadedText:SetText(wpSpamBlocker_LOCALIZED_OTHERLOADED); end -- As definied in the registered plugin info tabe, this function will be called whenever a whisper is received. function wpSpamBlocker_InterceptInbound(theUser, theMSG, msgID) if(wpSpamBlocker_Data.enabled and NoSpamBlockersLoaded) then -- first check if user is responding with confirmation code. if(BlockedMessages[theUser]) then if(wpSpamBlocker_Data.confirmation and BlockedMessages[theUser].code == theMSG) then wpSpamBlocker_ReleaseUser(theUser, true); SendChatMessage(": "..wpSpamBlocker_LOCALIZED_THANKYOU, "WHISPER", nil, theUser); return true; -- stop here, no need to block user and no need to capture code. end end -- screen user if(not wpSpamBlocker_isUserFriendly(theUser) and not UserOkCache[theUser]) then table.insert(MessageQueue, {user = theUser, msg = theMSG, msg_id = msgID}); return true; end end end -- As definied in the registered plugin info tabe, this function will be called whenever a whisper is sent. function wpSpamBlocker_InterceptOutbound(theUser, theMSG) -- This intercept is only used to add the user to the UserOkCache. -- Since you are initiating the whisper, user is considered friendly. if(strfind(theMSG, "^:") ~= nil) then return true; end UserOkCache[theUser] = 1; end -- This function is called automaticaly through WIM's cron job as declared previously. function wpSpamBlocker_CronWho() --if messages are waiting to be approved, get to work. if(table.getn(MessageQueue) > 0) then SetWhoToUI(1); SendWho("\""..MessageQueue[1].user.."\""); end end -- Hooked function used to retrieve who information. (uses some of WIM's built in tables and public functions.) function wpSpamBlocker_FriendsFrame_OnEvent() local foundUser = false; if(event == "WHO_LIST_UPDATE") then local numWhos, totalCount = GetNumWhoResults(); if(numWhos > 0) then for i=1, numWhos do local name, tGuild, tLevel, tRace, tClass, tZone = GetWhoInfo(i); for j = 1, table.getn(MessageQueue) do if(name == MessageQueue[j].user) then foundUser = true; MessageQueue[j].done = true; if(wpSpamBlocker_CheckMessage(MessageQueue[j].user, MessageQueue[j].msg, tLevel, MessageQueue[j].msg_id)) then -- third parameter can be passed to specify whether or not to skip who check. No need if we already have the user's information. WIM_PassIncomingMessage(MessageQueue[j].user, MessageQueue[j].msg, true, MessageQueue[j].msg_id); WIM_Windows[MessageQueue[j].user].waiting_who = false; WIM_Windows[MessageQueue[j].user].class = tClass; WIM_Windows[MessageQueue[j].user].level = tLevel; WIM_Windows[MessageQueue[j].user].race = tRace; WIM_Windows[MessageQueue[j].user].guild = tGuild; WIM_Windows[MessageQueue[j].user].location = tZone; WIM_SetWhoInfo(MessageQueue[j].user); UserOkCache[MessageQueue[j].user] = 1; ChatEdit_SetLastTellTarget(MessageQueue[j].user); else if(wpSpamBlocker_Blocked[MessageQueue[j].user]) then wpSpamBlocker_Blocked[MessageQueue[j].user] = wpSpamBlocker_Blocked[MessageQueue[j].user] + 1; else wpSpamBlocker_Blocked[MessageQueue[j].user] = 1; end if(BlockedMessages[MessageQueue[j].user]) then table.insert(BlockedMessages[MessageQueue[j].user].messages, MessageQueue[j].msg); BlockedMessages[MessageQueue[j].user].stamp = time(); BlockedMessages[MessageQueue[j].user].msg_id = MessageQueue[j].msg_id; else BlockedMessages[MessageQueue[j].user] = { code = ""..random(1000, 9999), who = { class = tClass, level = tLevel, race = tRace, guild = tGuild, location = tZone }, msg_id = MessageQueue[j].msg_id, stamp = time(), messages = {} }; table.insert(BlockedMessages[MessageQueue[j].user].messages, MessageQueue[j].msg); if(wpSpamBlocker_Data.confirmation) then SendChatMessage(": "..wpSpamBlocker_LOCALIZED_RESPONSE..BlockedMessages[MessageQueue[j].user].code, "WHISPER", nil, MessageQueue[j].user); end end end end end end if(foundUser) then -- clean queue for i = table.getn(MessageQueue), 1, -1 do if(MessageQueue[i].done) then table.remove(MessageQueue, i); end end return; end else SetWhoToUI(0); wpSpamBlocker_FriendsFrame_OnEvent_orig(event); end end wpSpamBlocker_FriendsFrame_OnEvent_orig(event); end --check whether or not a user is friendly. In regards to this plugin, friendly means either: --on your friend list, in your guild, in your party or in your raid. If user is decided to be friendly, --messages will be whitelisted. function wpSpamBlocker_isUserFriendly(theUser) if(WIM_FriendList[theUser] or WIM_GuildList[theUser] or wpSpamBlocker_WhiteList[theUser]) then UserOkCache[theUser] = 1; return true; else for i=1,4 do if(UnitName("party"..i) == theUser) then UserOkCache[theUser] = 1; return true; end end for i=1,40 do if(UnitName("raid"..i) == theUser) then UserOkCache[theUser] = 1; return true; end end end return false; end function wpSpamBlocker_CheckMessage(theUser, theMSG, theLevel, msgId) if(theLevel <= wpSpamBlocker_Data.blockLevel) then if(wpSpamBlocker_Data.notify and not BlockedMessages[theUser]) then DEFAULT_CHAT_FRAME:AddMessage("|cff"..WIM_RGBtoHex(1,.8,0)..": "..theUser.."'s whisper has been blocked."); DEFAULT_CHAT_FRAME:AddMessage("|cff"..WIM_RGBtoHex(1,.8,0)..": |Hspam:"..theUser.."|h|cffffffff[Click here]|h|r|cff"..WIM_RGBtoHex(1,.8,0).." to view this user's message.|r"); DEFAULT_CHAT_FRAME:AddMessage("|cff"..WIM_RGBtoHex(1,.8,0)..": |cff"..WIM_RGBtoHex(1,.8,0).."You can report this user by |Hreportspam:"..theUser..":"..msgId.."|h|cffffffff[Clicking here]|h|r.|r"); PlaySound("TellMessage"); end return false; end return true; end function wpSpamBlocker_ReleaseUser(theUser, addWhiteList) if(not BlockedMessages[theUser] or table.getn(BlockedMessages[theUser].messages) == 0) then return; end for i = 1, table.getn(BlockedMessages[theUser].messages) do -- third parameter can be passed to specify whether or not to skip who check. No need if we already have the user's information. WIM_PassIncomingMessage(theUser, BlockedMessages[theUser].messages[i], true); end WIM_Windows[theUser].waiting_who = false; WIM_Windows[theUser].class = BlockedMessages[theUser].who.class; WIM_Windows[theUser].level = BlockedMessages[theUser].who.level; WIM_Windows[theUser].race = BlockedMessages[theUser].who.race; WIM_Windows[theUser].guild = BlockedMessages[theUser].who.guild; WIM_Windows[theUser].location = BlockedMessages[theUser].who.location; WIM_SetWhoInfo(theUser); if(addWhiteList) then UserOkCache[theUser] = 1; wpSpamBlocker_Blocked[theUser] = nil; wpSpamBlocker_WhiteList[theUser] = 1; BlockedMessages[theUser] = nil; else if(not wpSpamBlocker_isUserFriendly(theUser)) then if(table.getn(BlockedMessages[theUser].messages) > 0) then WIM_PostMessage(theUser, "This conversation is being previewed. The user has not been added to your white list.", 3); BlockedMessages[theUser].messages = {}; end end end end function wpSpamBlocker_SetItemRef (link, text, button) if (strsub(link, 1, 4) == "spam") then link = string.gsub(link, "spam:", ""); wpSpamBlocker_ReleaseUser(link); return; end if (strsub(link, 1, 10) == "reportspam") then local namelink = string.gsub(link, "reportspam:", ""); local name, lineid = strsplit(":", namelink); if ( name and (strlen(name) > 0) ) then name = gsub(name, "([^%s]*)%s+([^%s]*)%s+([^%s]*)", "%3"); name = gsub(name, "([^%s]*)%s+([^%s]*)", "%2"); local dialog = StaticPopup_Show("CONFIRM_REPORT_SPAM_CHAT", name); if ( dialog ) then dialog.data = lineid; end end return; end wpSpamBlocker_SetItemRef_orig(link, text, button); end function wpSpamBlocker_CleanBlockedMessages() for key, _ in pairs(BlockedMessages) do -- if 5 min old, delete. if(time() - BlockedMessages[key].stamp > 300) then BlockedMessages[key] = nil; end end end function wpSpamBlocker_CheckAddonLoaded() -- This function will check to see if another spam blocker is loaded, if so, disable WIM - SpamBlocker & Notify. if(NoSpamBlockersLoaded == false) then return; end -- already found one, stop checking. if(IsAddOnLoaded("SpamSentry") or IsAddOnLoaded("STFU") or IsAddOnLoaded("SpamMeNot")) then WIM_Plugins["WIM - Spam Blocker"].optionsFrame = wbSpamBlocker_Options_OtherLoaded; NoSpamBlockersLoaded = false; end end