Mercurial > wow > mailopener
diff Core.lua @ 0:823e33465b6e
Initial commit
| author | Zerotorescue |
|---|---|
| date | Fri, 03 Sep 2010 12:43:36 +0200 |
| parents | |
| children | 6f17035de058 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core.lua Fri Sep 03 12:43:36 2010 +0200 @@ -0,0 +1,728 @@ +MailOpener = LibStub("AceAddon-3.0"):NewAddon("MailOpener", "AceEvent-3.0", "AceTimer-3.0"); + +local enabled = true; +local MailOpenerConfig, lastAmount, lastQuickAuctionsStatus, opening, freshList, mailboxEmptySoundPlayed; + +function MailOpener:OnInitialize() + local defaults = { + global = { + uses = 0; + }, + profile = { + general = { + defaultStatus = "_enabled", + defaultQAStatus = "__remember", + continueOpeningStackableItems = false, + autoDisableQAAutoMail = true, + autoReenableQAAutoMail = false, + autoSetBackQAAutoMail = true, + continueOpening = false, + waitTime = 5, + initialDelay = 0.5, + }, + modules = { + Collected = true, + }, + notifications = { + welcome = true, + bye = true, + finishedCurrentBatch = true, + mailboxIsEmpty = true, + + skipped = { + all = true, + inventoryFull = true, + keepFreeSpaceLimit = true, + GMMail = true, + COD = true, + normalGoldMail = true, + normalItemsMail = true, + AHexpired = true, + AHsuccess = true, + AHwon = true, + AHcanceled = true, + AHoutbid = true, + other = true, + }, + processed = { + all = true, + normalGoldMail = true, + normalItemsMail = true, + AHexpired = true, + AHsuccess = true, + AHwon = true, + AHcanceled = true, + AHoutbid = true, + other = true, + }, + + bagsFullSound = false, + bagsFullSoundFile = "Sound\\Spells\\SimonGame_Visual_BadPress.wav", + bagsFullSoundFileName = "Simon Error", + bagsFullSoundOnlyOnce = true, + mailboxEmptySound = false, + mailboxEmptySoundFile = "Sound\\Spells\\SimonGame_Visual_GameStart.wav", + mailboxEmptySoundFileName = "Simon Start", + mailboxEmptySoundOnlyOnce = true, + }, + }, + }; + + -- Register our saved variables database + self.db = LibStub("AceDB-3.0"):New("MailOpenerDB", defaults, true); + + -- Set these as object variables so we can use them in our modules + if select(6, GetAddOnInfo("Postal")) == nil then + self.PostalEnabled = true; + + -- Ensure this addon is loaded if AddonLoader is installed + if AddonLoader and AddonLoader.LoadAddOn and not Postal then + AddonLoader:LoadAddOn("Postal"); + end + end + + if select(6, GetAddOnInfo("QuickAuctions")) == nil then + self.QuickAuctionsEnabled = true; + + -- Ensure this addon is loaded if AddonLoader is installed + if AddonLoader and AddonLoader.LoadAddOn then + AddonLoader:LoadAddOn("QuickAuctions"); + end + end + + -- Don't enable the config module until we need it + for name, module in self:IterateModules() do + if name == "Config" then + module:SetEnabledState(false); + elseif self.db.profile.modules[name] ~= nil then + if self.db.profile.modules[name] then + self:Debug("|cff00ff00Enabling|r module: " .. name); + else + self:Debug("|cffff0000Disabling|r module: " .. name); + end + + module:SetEnabledState(self.db.profile.modules[name]); + end + end + + -- Make the open all checkbox + local check = CreateFrame("CheckButton", "cbMailOpenerEnable", MailFrame, "ChatConfigCheckButtonTemplate"); + check:SetHeight(26); + check:SetWidth(26); + check:SetChecked(enabled); + check:SetHitRectInsets(0, -80, 0, 0); + check:SetScript("OnClick", function(self) + if self:GetChecked() then + MailOpener:Enable(); + else + MailOpener:Disable(); + end + end); + check.tooltip = "Toggle Mail Opener on or off."; + check:SetPoint("TOPLEFT", MailFrame, "TOPLEFT", 68, -13) + + if self.QuickAuctionsEnabled then + -- QA is enabled so move the checkbox further to the right + + check:SetPoint("TOPLEFT", MailFrame, "TOPLEFT", 155, -13); + end + + -- Get reference to the text field + local checkboxText = _G[check:GetName() .. "Text"]; + checkboxText:SetText("Mail Opener"); + -- We like this color more + checkboxText:SetTextColor(1, 0.8, 0, 1); + + self.cbOpenAll = check; + + -- Make the config button + local button = CreateFrame("Button", "btnMailOpenerConfig", MailFrame, "UIPanelButtonTemplate") + button:SetText("Config") + button:SetHeight(23) + button:SetWidth(55) + if self.PostalEnabled then + button:SetPoint("TOPRIGHT", MailFrame, "TOPRIGHT", -75, -13); + else + button:SetPoint("TOPRIGHT", MailFrame, "TOPRIGHT", -55, -13); + end + button:SetScript("OnClick", function() + MailOpener:EnableConfigModule(); + + MailOpenerConfig:Show(); + + if MailOpener.db.global.uses >= 15 then + MailOpener:ShowBetaPopup(); + end + end); + + self.btnConfig = button; + + -- Disable the AddonLoader slash commands + SLASH_MO1 = nil; + SLASH_MAILOPEN1 = nil; + SLASH_MAILOPENER1 = nil; + + -- Register our own slash commands + SLASH_MAILOPENER1 = "/mo"; + SLASH_MAILOPENER2 = "/mailopen"; + SLASH_MAILOPENER3 = "/mailopener"; + SlashCmdList["MAILOPENER"] = function(msg) + MailOpener:EnableConfigModule(); + + MailOpenerConfig:CommandHandler(msg); + end + + -- Attempt to remove the interface options added by AddonLoader (if enabled) + if AddonLoader and AddonLoader.RemoveInterfaceOptions then + AddonLoader:RemoveInterfaceOptions("Mail Opener"); + end + + -- Now create our own options frame + local frame = CreateFrame("Frame", nil, UIParent); + frame:Hide(); + frame.name = "Mail Opener"; + frame:HookScript("OnShow", function(self) + -- Enable the config module + MailOpener:EnableConfigModule(); + + -- Load the options and add it to the blizzard interface list + MailOpenerConfig:Load(); + + -- Refresh the frame to instantly show the right options + InterfaceOptionsFrame_OpenToCategory(self.name) + end); + -- And add it to the interface options + InterfaceOptions_AddCategory(frame); + + -- If the above becomes impossible this is another way to load the config module when required due to Interface/AddOns options + --InterfaceOptionsFrameTab2:HookScript("OnClick", function() + -- -- Load the config module + -- MailOpener:EnableConfigModule(); + + -- -- Load the options and add it to the blizzard interface list + -- MailOpenerConfig:Load(); + --end); +end + +function MailOpener:OnEnable() + self:RegisterEvent("MAIL_SHOW"); + self:RegisterEvent("PLAYER_ENTERING_WORLD"); + + self.btnConfig:Show(); + + -- Reset variables + lastAmount = 0; + self.debugChannel = nil; + + self.db.global.uses = ( self.db.global.uses + 1 ); + + if self.db.global.uses == 15 then + self:ShowBetaPopup(); + end + + -- If we were toggling this addon on while the mailbox is opened we must register all events again + if MailFrame:IsVisible() then + self:MAIL_SHOW(); + end +end + +function MailOpener:OnDisable() + self:UnregisterEvent("MAIL_SHOW"); + + self.btnConfig:Hide(); + + enabled = false; + MailOpener:Stop(); +end + +-- We must disable Quick Auction's auto mail (if set up that way in the settings) before opening the mailbox or it will instantly start sending stuff +function MailOpener:PLAYER_ENTERING_WORLD() + self:UnregisterEvent("PLAYER_ENTERING_WORLD"); + + self:ToggleQAStatus(); +end + +-- Fired when the mailbox is opened +function MailOpener:MAIL_SHOW() + -- To stop the timer when the mailbox is closed + self:RegisterEvent("MAIL_CLOSED", "Stop"); + self:RegisterEvent("PLAYER_LEAVING_WORLD", "Stop"); + + -- To set the timer for when to refresh again + self:RegisterEvent("MAIL_INBOX_UPDATE"); + + -- We need to know when opening has completed + self:RegisterMessage("MO_OPEN_COMPLETE"); + + self:Debug("defaultStatus:" .. self.db.profile.general.defaultStatus); + -- Change the mail opening status according to our settings + if self.db.profile.general.defaultStatus == "_enabled" then + enabled = true; + else + enabled = false; + end + self.cbOpenAll:SetChecked(enabled); + + self:ToggleQAStatus(); + + -- Hide the InboxTooMuchMail warning to allow room for our mail remaining info line + InboxTooMuchMail:Hide() + InboxTooMuchMail.Show = function() end + + if self.QuickAuctionsEnabled then + -- Go through all children of the mail frame to find the post button + local kids = { InboxFrame:GetChildren() }; + + for _, child in ipairs(kids) do + if child then + local width = floor( child:GetWidth() + .5 ); + local height = floor( child:GetHeight() + .5 ); + + -- The open all button has a static width and height + if width == 130 and height == 24 then + child:Hide(); + break; + end + end + end + end + + if self.db.profile.notifications.welcome then + -- Welcome notification + local _, c = UnitClass("player"); + c = RAID_CLASS_COLORS[c]; + c = string.format("|cff%02x%02x%02x", c.r * 255 + 0.5, c.g * 255 + 0.5, c.b * 255 + 0.5); + + print("|cff15ff00Mail Opener|r: Welcome back "..c..UnitName("player").."|r. Requesting new mail from the local Postal Service, your mail will automatically be opened when it becomes available."); + end + + mailboxEmptySoundPlayed = nil; + + self:Recheck(); + + if self.db.profile.general.continueOpening then + self:ScheduleOpen(true); + end +end + +-- Fired after a successful server sync +-- Fired when mail is deleted (which happens after taking all attachments from a mail sent by the game) +function MailOpener:MAIL_INBOX_UPDATE() + local current, total = GetInboxNumItems(); + + local tempLastAmount = lastAmount; + lastAmount = current; + + if current ~= tempLastAmount then + self:Debug("MAIL_INBOX_UPDATE - lastAmount:" .. tempLastAmount .. " - current:" .. current); + end + + if current > tempLastAmount then + -- New messages arrived in our mailbox, so this was a refresh, so set a timer + + -- Yell that we successfully synced with the server + self:SendMessage("MO_SERVER_SYNCED"); + + -- This list is fresh + freshList = true; + mailboxEmptySoundPlayed = nil; + + -- Stop previous timer + self:CancelTimer(self.tmrRecheck, true); + -- More will arrive in 60 seconds + self.tmrRecheck = self:ScheduleTimer(function() + self:Debug("tmrRecheck 61 finished"); + + -- We can get a fresh list now, so query the server + freshList = false; + + -- Look for mail + self:Recheck(); + end, 61); + self:Debug("tmrRecheck 61"); + + if not IsShiftKeyDown() then + -- Allow overriding of mailopening with the shift key + + -- Open the current mail + self:ScheduleOpen(false); + end + elseif (current == 50 and tempLastAmount == 50) then + if not IsShiftKeyDown() then + -- Allow overriding of mailopening with the shift key + + -- Open the current mail + self:ScheduleOpen(false); + end + end + + tempLastAmount = current; +end + +function MailOpener:ScheduleOpen(continued) + if lastAmount > 0 then + local waitTime; + if continued then + waitTime = self.db.profile.general.waitTime; + else + -- Even though this is not a continuation and should be instant, we set a .5 second timer to prevent multiple calls of the OpenNow function + waitTime = self.db.profile.general.initialDelay; + end + + -- Stop previous timer + self:CancelTimer(self.tmrOpenNow, true); + -- Schedule the next open + self.tmrOpenNow = self:ScheduleTimer("OpenNow", waitTime); + end +end + +function MailOpener:OpenNow() + self:Debug("OpenNow (" .. ((opening and "1") or "0") .. ")"); + if not opening and MailFrame:IsVisible() then + self:Debug("OpenNow"); + + -- BeanCounter is the only addon hiding the mail close button while busy, so we can look for that + local BeanCounterActive = not InboxCloseButton:IsVisible(); + + if not BeanCounterActive then + -- BeanCounter is INACTIVE + + self:CancelTimer(self.tmrTryAgain, true); -- Insurance + + if QuickAuctionsAutoMail then + -- Remember the last known quick auctions status + lastQuickAuctionsStatus = QuickAuctionsAutoMail:GetChecked(); + end + if self.db.profile.general.autoDisableQAAutoMail and self.QuickAuctionsEnabled and QuickAuctionsAutoMail and QuickAuctionsAutoMail:GetChecked() then + -- If auto disable "QA Auto mail" is enabled and QA's auto mail is currently toggled on, turn it off + -- We need to do this with a :click to trigger the right events + + self:Debug("Turning automail |cffff0000off|r."); + + QuickAuctionsAutoMail:Click(); + end + + opening = true; + + self:Debug("MO_OPEN_MAIL"); + + -- Summon the mail opening gods + self:SendMessage("MO_OPEN_MAIL"); + else + -- BeanCounter is ACTIVE + self:Debug("BeanCounter active, waiting .5 seconds..."); + + self:CancelTimer(self.tmrTryAgain, true); -- Insurance + -- Wait with summoning until BeanCounter is done, try again every 0.5 seconds + self.tmrTryAgain = self:ScheduleTimer("OpenNow", 0.5); + end + end +end + +function MailOpener:MO_OPEN_COMPLETE() + opening = false; + + local current, total = GetInboxNumItems(); + + if (total - current) == 0 then + -- Play the sound + if self.db.profile.notifications.mailboxEmptySound and (not MailOpener.db.profile.notifications.mailboxEmptySoundOnlyOnce or not mailboxEmptySoundPlayed) then + PlaySoundFile(self.db.profile.notifications.mailboxEmptySoundFile); + mailboxEmptySoundPlayed = true; + end + end + + if self.db.profile.general.autoReenableQAAutoMail and self.QuickAuctionsEnabled and QuickAuctionsAutoMail and not QuickAuctionsAutoMail:GetChecked() then + -- If auto re-enable "QA Auto mail" is enabled and QA's auto mail is currently toggled OFF, turn it on + -- We need to do this with a :click to trigger the right events + + self:Debug("Turning automail |cff00ff00on|r."); + + QuickAuctionsAutoMail:Click(); + elseif self.db.profile.general.autoSetBackQAAutoMail and self.QuickAuctionsEnabled and QuickAuctionsAutoMail and lastQuickAuctionsStatus ~= QuickAuctionsAutoMail:GetChecked() then + -- If auto set back "QA Auto mail" is enabled and QA's auto mail is currently not the same as it was before starting, toggle it + -- We need to do this with a :click to trigger the right events + + if lastQuickAuctionsStatus then + self:Debug("Turning automail |cff00ff00on|r."); + else + self:Debug("Turning automail |cffff0000off|r."); + end + + QuickAuctionsAutoMail:Click(); + end + + if self.db.profile.general.continueOpening then + self:ScheduleOpen(true); + end +end + +-- Run another CheckInbox +function MailOpener:Recheck() + self:Debug("|cffffff00Recheck|r"); + + -- Freshlist prevents this from being run too often + -- It is set to true after a server sync + -- and set to false 61 seconds afterwards with a recheck called instantly after it + if not freshList and MailFrame:IsVisible() then + self:Debug("|cff00ff00Recheck|r"); + + -- If this isn't a fresh list (so messages weren't received within the last 60 seconds) and the mailbox wasn't closed + + -- BeanCounter is the only addon hiding the mail close button while busy, so we can look for that + local BeanCounterActive = not InboxCloseButton:IsVisible(); + + if not BeanCounterActive then + -- Query the server + CheckInbox(); + end + + -- Stop previous timer + self:CancelTimer(self.tmrRecheck, true); + -- Keep trying until it works + self.tmrRecheck = self:ScheduleTimer("Recheck", 2); + + self:Debug("tmrRecheck 2"); + end +end + +-- Stop checking for new mail and unregister the events we needed +function MailOpener:Stop() + if self.db.profile.notifications.bye then + print("|cff15ff00Mail Opener|r: Have a nice day. :)"); + end + + opening = false; + + -- We won't need this anymore + self:UnregisterEvent("MAIL_CLOSED"); + self:UnregisterEvent("PLAYER_LEAVING_WORLD"); + self:UnregisterEvent("MAIL_INBOX_UPDATE"); + + -- Messages + self:UnregisterMessage("MO_OPEN_COMPLETE"); + + -- Timers + self:CancelTimer(self.tmrTryAgain, true); + self:CancelTimer(self.tmrOpenNow, true); + + -- If we wait with disabling QA automail until MAIL_SHOW, QA will beat us to it and already start sending stuff + self:ToggleQAStatus(); +end + +function MailOpener:Debug(t) + if not self.debugChannel and self.debugChannel ~= false then + -- We want to check just once, so if you add a debug channel later just do a /reload (registering an event for this is wasted resources) + self.debugChannel = false; + + for i = 1, NUM_CHAT_WINDOWS do + local name = GetChatWindowInfo(i); + + if name:upper() == "DEBUG" then + self.debugChannel = _G["ChatFrame" .. i]; + end + end + end + + if self.debugChannel then + self.debugChannel:AddMessage(t); + end +end + +-- Enable our config module if it's disabled and make a reference to it +function MailOpener:EnableConfigModule() + if not MailOpenerConfig then + MailOpenerConfig = self:GetModule("Config"); + MailOpenerConfig:Enable(); + end +end + +-- Toggle Postal's opening modules on or off +function MailOpener:TogglePostalModule(name, status) + if MailOpener.PostalEnabled and Postal then + -- Postal must be enabled + + -- Remember the setting in Postal + Postal.db.profile.ModuleEnabledState[name] = status; + + -- Toggle module + if status then + Postal:GetModule(name):Enable(); + else + Postal:GetModule(name):Disable(); + end + end +end + +-- Change Quick Auction's auto mail status based on our prefered settings +function MailOpener:ToggleQAStatus() + self:Debug("defaultQAStatus:" .. self.db.profile.general.defaultQAStatus); + + if self.QuickAuctionsEnabled and self.db.profile.general.defaultQAStatus ~= "__remember" and QuickAuctionsAutoMail then + if self.db.profile.general.defaultQAStatus == "_enabled" and not QuickAuctionsAutoMail:GetChecked() then + self:Debug("Turning automail |cff00ff00on|r."); + + QuickAuctionsAutoMail:Click(); + elseif self.db.profile.general.defaultQAStatus == "disabled" and QuickAuctionsAutoMail:GetChecked() then + self:Debug("Turning automail |cffff0000off|r."); + + QuickAuctionsAutoMail:Click(); + end + end +end + +function MailOpener:FormatMoney(copper) + local gold = floor( copper / 10000 ); + local silver = floor( ( copper - ( gold * 10000 ) ) / 100 ); + local copper = mod(copper, 100); + + if gold > 0 then + return format(GOLD_AMOUNT_TEXTURE .. " " .. SILVER_AMOUNT_TEXTURE .. " " .. COPPER_AMOUNT_TEXTURE, gold, 0, 0, silver, 0, 0, copper, 0, 0); + elseif silver > 0 then + return format(SILVER_AMOUNT_TEXTURE .. " " .. COPPER_AMOUNT_TEXTURE, silver, 0, 0, copper, 0, 0); + else + return format(COPPER_AMOUNT_TEXTURE, copper, 0, 0); + end +end + +StaticPopupDialogs["MailOpenerCopyWindow"] = { + text = "Please CTRL-C to copy.", + button2 = CLOSE, + hasEditBox = 1, + hasWideEditBox = 1, + OnShow = function() + local editBox = _G[this:GetName().."WideEditBox"]; + if editBox and MailOpener.currentPopupContents then + editBox:SetText(MailOpener.currentPopupContents); + editBox:SetFocus(); + editBox:HighlightText(0); + end + + -- Position the close button in the middle + local button = _G[this:GetName().."Button2"]; + if button then + -- Remove previous know position + button:ClearAllPoints(); + button:SetWidth(200); + -- Reposition in the center + button:SetPoint("CENTER", editBox, "CENTER", 0, -30); + end + end, + EditBoxOnEscapePressed = function() + this:GetParent():Hide(); + end, + timeout = 0, + whileDead = 1, + hideOnEscape = 1, + maxLetters = 1024, +} + +function MailOpener:ShowBetaPopup() + function TableDump(key, val, jumps) + local cache = ""; + + if not jumps then + jumps = 0; + end + + local spacer = ""; + if jumps > 0 then + for i = 1, jumps do + spacer = spacer .. " "; + end + end + + if type(val) == "table" then + cache = cache .. spacer .. key .. " = {\n"; + foreach(val, function(k, v) + cache = cache .. TableDump(k, v, (jumps + 1)); + end); + cache = cache .. spacer .. "},\n"; + else + cache = cache .. spacer .. key .. " = " .. tostring(val) .. ",\n"; + end + + return cache; + end + + local cache = ""; + foreach(MailOpener.db.profile, function(k, v) + cache = cache .. TableDump(k, v, 0); + end); + + local AceGUI = LibStub("AceGUI-3.0"); + local frame = AceGUI:Create("Frame"); + frame:SetTitle("Mail Opener ALPHA"); + frame:SetWidth(575); + frame:SetHeight(375); + + -- Add a normal description label + local desc = AceGUI:Create("Label"); + desc:SetText("|cff00ff00After you have been using Mail Opener for a while and configured it just as you want it to be, please report your favorite settings by copying the text below at either of the below links. Thanks in advance!|r\n\n"); + desc:SetFont(GameFontHighlightSmall:GetFont(), 13); + desc:SetFullWidth(true); + frame:AddChild(desc); + + -- Add a MultiLineEditBox + local settingsMLEEB = AceGUI:Create("MultiLineEditBox"); + settingsMLEEB:SetText(cache); + settingsMLEEB:SetLabel("Hit CTRL-A to select all and CTRL-C to copy the text. You can then use CTRL-V to paste."); + settingsMLEEB:SetFullWidth(true); + settingsMLEEB:SetNumLines(8); + settingsMLEEB:DisableButton(true); + settingsMLEEB:SetCallback("OnTextChanged", function() + settingsMLEEB:SetText(cache); + end); + frame:AddChild(settingsMLEEB); + + -- Empty line between the two links + local label = AceGUI:Create("Label"); + label:SetText("Please post the above text at either of these two links:"); + label:SetFullWidth(true); + frame:AddChild(label); + + local desc1 = AceGUI:Create("InteractiveLabel"); + desc1:SetText("|cff00bbbb[http://wow.curseforge.com/addons/mailopener/create-ticket/]|r"); + desc1:SetFont(GameFontHighlightSmall:GetFont(), 13); + desc1:SetFullWidth(true); + desc1:SetCallback("OnClick", function() + MailOpener.currentPopupContents = "http://wow.curseforge.com/addons/mailopener/create-ticket/"; + + StaticPopup_Show("MailOpenerCopyWindow"); + end); + desc1:SetCallback("OnEnter", function() + frame:SetStatusText("Click to copy this URL."); + end); + desc1:SetCallback("OnLeave", function() + frame:SetStatusText(""); + end); + frame:AddChild(desc1); + + -- Empty line between the two links + local spacer = AceGUI:Create("Label"); + spacer:SetText(" "); + frame:AddChild(spacer); + + local desc2 = AceGUI:Create("InteractiveLabel"); + desc2:SetText("|cff00bbbb[http://20kleveling.com/JMTCforum/posting.php?mode=reply&f=9&t=1403]|r"); + desc2:SetFont(GameFontHighlightSmall:GetFont(), 13); + desc2:SetFullWidth(true); + desc2:SetCallback("OnClick", function() + MailOpener.currentPopupContents = "http://20kleveling.com/JMTCforum/posting.php?mode=reply&f=9&t=1403"; + + StaticPopup_Show("MailOpenerCopyWindow"); + end); + desc2:SetCallback("OnEnter", function() + frame:SetStatusText("Click to copy this URL."); + end); + desc2:SetCallback("OnLeave", function() + frame:SetStatusText(""); + end); + frame:AddChild(desc2); + + -- Empty line between the two links + local label = AceGUI:Create("Label"); + label:SetText("\n\nps. You can always view this window again at a later time by clicking the \"Config\" button in the mail frame.\nps2. The information above is completely Mail Opener related. It will be used to determine the best default settings."); + label:SetFullWidth(true); + frame:AddChild(label); +end \ No newline at end of file
