Skip to content

Commit

Permalink
Added mail safety
Browse files Browse the repository at this point in the history
  • Loading branch information
tflo committed Mar 14, 2024
1 parent c886087 commit 185ec64
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 27 deletions.
2 changes: 1 addition & 1 deletion MoveEmAll.toc
Original file line number Diff line number Diff line change
@@ -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
Expand Down
8 changes: 8 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
59 changes: 36 additions & 23 deletions main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand All @@ -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


Expand All @@ -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
Expand All @@ -109,6 +126,7 @@ ef:SetScript('OnEvent', function(self, event, ...)
else
pimf = nil
end
debugprint('PIMF:', pimf)
end)


Expand All @@ -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)
Expand All @@ -148,17 +158,18 @@ 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
local clicked_item = C_ContainerGetContainerItemID(bag_id, slot_id)
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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -261,7 +274,7 @@ end

--[[ License ===================================================================
Copyright © 2023 Thomas Floeren
Copyright © 2024 Thomas Floeren
This file is part of Move'em All.
Expand Down
18 changes: 15 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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.

Expand All @@ -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

Expand Down

0 comments on commit 185ec64

Please sign in to comment.