From 185ec64011ddfb2b82504bcabe4a84693dd517d4 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 14 Mar 2024 01:27:09 +0100 Subject: [PATCH] Added mail safety --- MoveEmAll.toc | 2 +- changelog.md | 8 +++++++ main.lua | 59 +++++++++++++++++++++++++++++++-------------------- readme.md | 18 +++++++++++++--- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/MoveEmAll.toc b/MoveEmAll.toc index db3f6ca..782245a 100755 --- a/MoveEmAll.toc +++ b/MoveEmAll.toc @@ -1,6 +1,6 @@ ## Interface: 100205 ## Title: Move 'em All -## Version: 2.1.3 +## Version: 2.1.4 ## IconTexture: Interface/Buttons/JumpUpArrow ## Notes: One-click mass move all items with the same ID to the bank or other locations. ## Author: Mot diff --git a/changelog.md b/changelog.md index d36e2c6..e2618b3 100755 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,11 @@ +#### 2.1.4 (2024-03-13) + +- Safer transfers to mailbox: Added a check to make sure we are in the Send Mail frame (not Inbox) when executing. Unfortunately, with this safeguard MEA no longer works with TSM Mail or any other mail addon where the Blizzard Send Mail button is not visible. (Though you can disable it, see below.) + - Background: If you right-click an item in your bags while the mailbox is open and you're still in the inbox, the item will be _used_ (i.e. consumed or equipped). This is standard Blizz behavior and not a bug in this addon. When you hold down your MEA modifier key, this default behavior is applied to all items with the same ID. So this safety should protect you from accidentally _using_ all items instead of sending them. + - I added this because the "accident" actually happened to me: I crafted 8 'Draconium Fisherfriend' and wanted to 1-click-move them to the mailbox to send them to my AH toon. Unfortunately, the inbox frame was active and I didn't pay attention, so the result of my click was that I equipped all 8 Fisherfriend, which turned them into garbage, as they are now soulbound... + - The same problem exists with the TSM mailbox, but I haven't found a reliable way to detect if we are in 'send mode', so this safeguard will effectively disable MEA for TSM mailing. + - If you are aware of the potential pitfall, you can disable (and re-enable) the safety with `/mea togglemailsafety`, which also restores functionality with TSM. Though I recommend to leave it enabled, and for mass-moving just switch to the Blizz Mail UI. + #### 2.1.3 (2024-01-16) - Just a toc bump for 10.2.5. Compatibility update will follow if needed. diff --git a/main.lua b/main.lua index dd895cf..97ef2ef 100755 --- a/main.lua +++ b/main.lua @@ -30,7 +30,7 @@ local MSG_PREFIX = C_MEA .. "Move 'em All\124r:" local DELAY_GB_DEFAULT = 0.6 local is_mac = IsMacClient() -local pimf, count, wait, delay, to_reabank +local pimf, aborting_msg_sent, count, wait, delay, to_reabank local modifiers = { ['command'] = IsMetaKeyDown, @@ -45,6 +45,11 @@ local buttons = { ['right'] = 'RightButton', } +local function debugprint(...) + if debug then print(MSG_PREFIX, 'Debug:', ...) end +end + + local function mea_modifier_down() return modifiers[a.db.modifier]() end @@ -70,15 +75,26 @@ local PIMF_VOID = Enum.PlayerInteractionType.VoidStorageBanker -- 26 local valid_targets = { [PIMF_BANK] = true, -- Bank - [PIMF_MAIL] = true, -- Mail +-- [PIMF_MAIL] = true, -- Mail; better to have an extra check, see `safe_to_run` func [PIMF_GUILDBANK] = true, -- Guild bank [PIMF_MERCHANT] = true, -- Merchant [PIMF_TRADE] = true, -- Trade [PIMF_VOID] = true, -- Void Storage } -local function debugprint(...) - if debug then print(MSG_PREFIX, 'Debug:', ...) end +local function safe_to_run() +-- debugprint('PIMF:', pimf) + if valid_targets[pimf] then return true end + if pimf == PIMF_MAIL then + if a.db.disable_mail_safety or SendMailMailButton:IsVisible() then + return true + end + end + if not aborting_msg_sent then + print(MSG_PREFIX, 'No valid destination to move items to, aborting transfer!') + aborting_msg_sent = true + end + return false end @@ -100,6 +116,7 @@ ef:SetScript('OnEvent', function(self, event, ...) a.db.modifier = a.db.modifier or (is_mac and 'command' or 'shift') a.db.modifier_rea = a.db.modifier_rea or (is_mac and 'option' or 'alt') a.db.delay_normal = a.db.delay_normal or nil + a.db.disable_mail_safety = a.db.disable_mail_safety or nil -- Will also reset to default if the user had set it to none. This is good, because as of now guild bank -- transfers will not work without any delay. a.db.delay_guildbank = a.db.delay_guildbank or DELAY_GB_DEFAULT @@ -109,6 +126,7 @@ ef:SetScript('OnEvent', function(self, event, ...) else pimf = nil end + debugprint('PIMF:', pimf) end) @@ -117,25 +135,17 @@ end) ---------------------------------------------------------------------------]]-- local function use_items(bag, item) - local aborting_msg_sent = nil for slot = 1, C_ContainerGetContainerNumSlots(bag) do - if not valid_targets[pimf] then - print(MSG_PREFIX, 'Target frame closed, aborting transfer.') - return - end + if not safe_to_run() then return end local bag_item = C_ContainerGetContainerItemID(bag, slot) if bag_item == item then -- debugprint('Count:', count, 'Bag:', bag, 'Slot:', slot) if delay then wait = delay * count C_TimerAfter(wait, function() - -- We *have* to check here again, as target frame can be closed while there are still timers in the queue. - if valid_targets[pimf] then - C_ContainerUseContainerItem(bag, slot, nil, to_reabank) - elseif not aborting_msg_sent then - print(MSG_PREFIX, 'Target frame closed, aborting transfer.') - aborting_msg_sent = true - end + -- We *have* to check here again, since target frame can be closed while there are still timers in the queue. + if not safe_to_run() then return end + C_ContainerUseContainerItem(bag, slot, nil, to_reabank) end) else C_ContainerUseContainerItem(bag, slot, nil, to_reabank) @@ -148,9 +158,10 @@ end hooksecurefunc('HandleModifiedItemClick', function(link, itemLocation) -- if mea_button_pressed() and (mea_modifier_down() or pimf == 8 and mea_modifier_rea_down()) then if mea_button_pressed() and mea_modifier_down() then -- Probably better, to avoid conflicts - debugprint 'Button and modifier conditionals passed.' - if itemLocation and itemLocation:IsBagAndSlot() and valid_targets[pimf] then - debugprint 'itemLocation and target frame validation passed.' +-- debugprint 'Button and modifier conditionals passed.' + aborting_msg_sent = nil + if itemLocation and itemLocation:IsBagAndSlot() and safe_to_run() then +-- debugprint '`itemLocation` and `safe_to_run` passed.' -- debugprint(tf6.tprint(itemLocation)) local bag_id = itemLocation.bagID local slot_id = itemLocation.slotIndex @@ -158,7 +169,7 @@ hooksecurefunc('HandleModifiedItemClick', function(link, itemLocation) if clicked_item then count, wait = 0, 0 delay = pimf == PIMF_GUILDBANK and max(a.db.delay_guildbank or 0, a.db.delay_normal or 0) or a.db.delay_normal - debugprint('At work now. Active delay:', delay) +-- debugprint('At work now. Active delay:', delay) if bag_id >= BAG_FIRST and bag_id <= BAG_LAST then -- From bags to_reabank = (pimf == PIMF_BANK and (mea_modifier_rea_down() or ReagentBankFrame:IsShown())) for bag = BAG_FIRST, BAG_LAST do @@ -223,12 +234,14 @@ SlashCmdList['MOVEEMALL'] = function(msg) local d = tonumber(mt[2]) a.db.delay_guildbank = (d > 0 and d <= 1) and d or nil print(MSG_PREFIX, 'Delay for guild bank set to ' .. (a.db.delay_guildbank or 'none (no timer used)') .. '.') + elseif mt[1] == 'togglemailsafety' then + a.db.disable_mail_safety = not a.db.disable_mail_safety + print(MSG_PREFIX, 'Mail safety '.. (a.db.disable_mail_safety and 'disabled' or 'enabled') .. '.') elseif mt[1] == 'debug' then debug = not debug print(MSG_PREFIX, 'Debug mode '.. (debug and 'enabled' or 'disabled') .. '.') elseif #mt == 0 then - print(MSG_PREFIX, 'Current settings: Mouse button: '.. C_KW .. cap(a.db.button) .. ' \124r| Modifier key: ' .. C_KW .. cap(a.db.modifier).. ' \124r| Reagent bank modifier key: ' .. C_KW .. cap(a.db.modifier_rea) .. ' \124r| Delay: ' .. C_EMPH .. (a.db.delay_normal and a.db.delay_normal .. 's' or 'none') .. ' \124r| Delay for guild bank: ' .. C_EMPH .. (a.db.delay_guildbank and a.db.delay_guildbank .. 's' or 'none') - .. '\n\124rYou can freely customize mouse button and modifier keys. Type ' .. C_KW .. '/mea help\124r to learn how.' + print(MSG_PREFIX, 'Current settings: Mouse button: '.. C_KW .. cap(a.db.button) .. ' \124r| Modifier key: ' .. C_KW .. cap(a.db.modifier).. ' \124r| Reagent bank modifier key: ' .. C_KW .. cap(a.db.modifier_rea) .. ' \124r| Delay: ' .. C_EMPH .. (a.db.delay_normal and a.db.delay_normal .. 's' or 'none') .. ' \124r| Delay for guild bank: ' .. C_EMPH .. (a.db.delay_guildbank and a.db.delay_guildbank .. 's' or 'none') .. ' \124r| Mail safety: ' .. C_EMPH .. (a.db.disable_mail_safety and 'off' or 'on') .. '\n\124rYou can freely customize mouse button and modifier keys. Type ' .. C_KW .. '/mea help\124r to learn how.' ) elseif wants_help(mt[1]) and #mt == 1 then print(MSG_PREFIX, @@ -261,7 +274,7 @@ end --[[ License =================================================================== - Copyright © 2023 Thomas Floeren + Copyright © 2024 Thomas Floeren This file is part of Move'em All. diff --git a/readme.md b/readme.md index 3b876f7..b176df6 100755 --- a/readme.md +++ b/readme.md @@ -15,8 +15,8 @@ Currently the mass moving works from Bag to… - Mail - Merchant - Trade -- Guild Bank (new since v2.0) -- Void Storage (new since v2.0) +- Guild Bank +- Void Storage …and from Bank to Bag. @@ -43,6 +43,7 @@ The addon is lightweight, super fast - and dumb. (And I actually plan to keep it ‘Dumb’ means: +- MEA simply applies the default right-click action to all items with the same ID. Of course, it only does this if it detects a valid destination to move the items to (e.g. open bank, merchant, mailbox, …). - It does not check if the clicked items actually have all arrived (e.g. when the bank is full). So, when it prints “Probably moved 12x [Shrouded Cloth]” to the chat, this is actually an optimistic estimation. Hence the “probably” word ;) - It doesn’t know or care if a bag slot holds a single item or a stack of 1000, it always reports back the number of slots it has “moved”, which can be stacks or single items. @@ -68,7 +69,18 @@ The sweet spot seems to be somewhere around 0.5/0.6s. The longer the delay, the MEA works flawlessly with _Blizzard’s bags, LiteBag, AdiBags,_ very likely also with many other bag addons. I briefly tested it with _ArkInventory, Baud Bag, Bagnon,_ and haven’t noticed any issues. (By the way, LiteBag uses the standard Blizz Reagent Bank frame, which is an advantage here.) -It works great with _TSM Mail, Easy Mail, Postal_ too, probably also with other mailbox mods. +It _can_ work (see below) with _TSM Mail, Easy Mail, Postal_ too, probably also with other mailbox mods. + +For safety reasons, as of version 2.1.4 (2024-03-13), MEA no longer works – out of the box – with TSM Mail or any mail addon that hides the Blizzard Send Mail button. See the 2.1.4 (2024-03-13) change notes to understand why. + +You can disable (and re-enable) the safety with `/mea togglemailsafety`, which will also restore functionality with TSM. + +If you do this, please make sure that the Send Mail UI (not the Inbox!) of Blizz Mail (or whatever Mail addon) is actually active before clicking on an item with MEA. If the Inbox is active (and the safety disabled), the item(s) will be _used_ (consumed or equipped) instead of being sent! (With some item types you may get an “Action Blocked” popup (taint), which is a good thing in this particular case.) + +I recommend to leave the safety enabled, and for mass-moving just switch to the Blizz Mail UI. + +Please note that the described behavior is not a bug in MEA, this is the standard Blizz behavior when you right-click an item against the Mail inbox. The thing is, with MEA, the consequences of such a misclick can be more dire, since it potentially affects multiple items. Hence the protection. (Actually, with the protection, MEA is safer than Blizz’s default behavior, since a MEA click does absolutely nothing when the inbox frame is active.) + ## Notes