View Single Post
02-09-23, 06:50 PM   #1
Recreo
A Kobold Labourer
Join Date: Feb 2023
Posts: 1
Wow Addon traslate macros

Hello, I'm trying to revive a addonn that translates the content of macros to the client's language for the WotLK Classic version.
I'm autodidactic. and I'm having trouble getting it to work. I can fix some parts of the code so that it doesn't throw LUA errors in the game. But it doesn't change the macros. I tried various debugging, and the problem is that it doesn't record the spells.
Perhaps the problem is that the API changed, and I don't know what would be the equivalent in WotLK Classic.
Any help is appreciated..

This is my code:

Lua Code:
  1. local ADDON, myAddon = ...
  2. MacroTranslatorDB = {}
  3. Macro = Addon -- #DEBUG
  4.  
  5. local queue = {}
  6.  
  7. local commands = {
  8.     "^#show",
  9.     "^#showtooltip",
  10.     "^"..SLASH_CAST1,
  11.     "^"..SLASH_CAST2,
  12.     "^"..SLASH_CAST3,
  13.     "^"..SLASH_CAST4,
  14.     "^"..SLASH_CASTRANDOM1,
  15.     "^"..SLASH_CASTRANDOM2,
  16.     "^"..SLASH_CASTSEQUENCE1,
  17.     "^"..SLASH_CASTSEQUENCE2,
  18.     "^"..SLASH_EQUIP1,
  19.     "^"..SLASH_EQUIP2,
  20.     "^"..SLASH_EQUIP3,
  21.     "^"..SLASH_EQUIP4,
  22.     "^"..SLASH_EQUIP_SET1,
  23.     "^"..SLASH_EQUIP_SET2,
  24.     "^"..SLASH_EQUIP_TO_SLOT1,
  25.     "^"..SLASH_EQUIP_TO_SLOT2,
  26.     "^"..SLASH_USE1,
  27.     "^"..SLASH_USE2,
  28.     "^"..SLASH_USERANDOM1,
  29.     "^"..SLASH_USERANDOM2,
  30. }
  31.  
  32. ------------------------------------------------------------------------
  33. --  General
  34.  
  35. function myAddon:CleanMacro(body)
  36.     if type(body) ~= "string" then return "" end
  37.     local length = strlen(body)
  38.     if strsub(body, length, length) == "\n" then
  39.         body = strsub(body, 1, length - 1)
  40.     end
  41.     body = gsub(body, "; ", ";")
  42.     body = gsub(body, "%] ", "]")
  43.     body = gsub(body, "%[(^%]+), ", "[%1,")
  44.     return body
  45. end
  46. --------------------------------------------------------------------------------------------
  47. --------------------------------------------------------------------------------------------
  48. local spellbook = {}
  49.  
  50. function myAddon:ScanSpellbook()
  51.     print(">> |cffffc000ScanSpellbook|r")
  52.     local p1, p2, p3, p4, p5, p6 = GetProfessions()
  53.     local numTabs = math.max(p1 or 0, p2 or 0, p3 or 0, p4 or 0, p5 or 0, p6 or 0)
  54.     if numTabs == 0 then
  55.         numTabs = GetNumSpellTabs()
  56.     end
  57.  
  58.     local _, _, offset, numSpells = GetSpellTabInfo(numTabs)
  59.     for i = 1, offset + numSpells do
  60.         local skillType, id = GetSpellBookItemInfo(i, "spell")
  61.         if skillType == "FLYOUT" then
  62.             local _, _, numFlyoutSpells = GetFlyoutInfo(id)
  63.             for j = 1, numFlyoutSpells do
  64.                 local id, _, _, name = GetFlyoutSlotInfo(id, j)
  65.                 spellbook[string.lower(name)] = GetSpellLink(id)
  66.             end
  67.         else
  68.             local name = GetSpellBookItemName(i, "spell")
  69.             spellbook[string.lower(name)] = GetSpellLink(id)
  70.         end
  71.     end
  72.  
  73.     local talentGroup = GetActiveSpecGroup(false)
  74.     GameTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
  75.     for i = 1, 21 do
  76.         GameTooltip:SetTalent(i)
  77.         local name, _, id = GameTooltip:GetSpell()
  78.         if name and id then
  79.             spellbook[string.lower(name)] = GetSpellLink(id)
  80.         end
  81.     end
  82.     GameTooltip:Hide()
  83. end
  84.  
  85. --  Asigna nombres de hechizos a ID para la configuración regional actual al cerrar la sesión
  86.  
  87. function myAddon:FindSpell(name)
  88.     print(">> FindSpell:", name)
  89.     name = strlower(name)
  90.     if not next(spellbook) then
  91.         self:ScanSpellbook()
  92.     end
  93.    
  94.     local link = spellbook[name]
  95.     if link then
  96.         --print(">> FindSpell:", "found:", link)
  97.         return link
  98.     else
  99.         --print(">> FindSpell:", "no match")
  100.         return nil
  101.     end
  102. end
  103. --------------------------------------------------------------------------------------------
  104. --------------------------------------------------------------------------------------------
  105.  
  106. function myAddon:SaveNameToID(name)
  107.     --print(">> SaveNameTo|r:", format("%q", name))
  108.     local link = GetSpellLink(name) or select(2, GetItemInfo(name)) or self:FindSpell(name)
  109.     if link then
  110.         local id = strmatch(link, "|H(.-:%d+)")
  111.         --print(">> SaveNameTo|r:", "found", id, link)
  112.         MacroTranslatorDB[string.lower(name)] = id
  113.         return id
  114.     end
  115.     --print(">> SaveNameTo|r:", "no match")
  116. end
  117.  
  118. function myAddon:SaveMacroText(body)
  119.     --print("   ")
  120.     --print(">> SaveMacroText:", body)
  121.     --body = self:CleanMacro(body)
  122.     for line in gmatch(body, "[^\n]+") do
  123.         --print(">> SaveMacroText:", "processing line:", line)
  124.         local ok
  125.         for i = 1, #commands do
  126.             if strmatch(line, commands[i]) then
  127.                 ok = true
  128.                 break
  129.             end
  130.         end
  131.         if ok then
  132.             local div = (strmatch(line, SLASH_CASTSEQUENCE1) or strmatch(line, SLASH_CASTSEQUENCE2)) and "[^,;]+" or "[^;]+"
  133.             for name in gmatch(line, div) do
  134.                 --print(">> SaveMacroText:", "processing part:", format("%q", name))
  135.                 --name = strlower(name)
  136.                 name = gsub(name, ".+%]", "")
  137.                 name = gsub(name, "[#/]%S+", "")
  138.                 name = gsub(name, "reset=%S+ ?", "")
  139.                 name = strtrim(name)
  140.                 if strlen(name) > 0 and not strmatch(name, "^[%d%s]+$") then
  141.                     self:SaveNameToID(name)
  142.                 else
  143.                     -- ignore /use <invslot> and /use <bag> <slot>
  144.                     --print(">> SaveMacroText:", "skipping zero length or numeric part")
  145.                 end
  146.             end
  147.         else
  148.             --print(">> SaveMacroText:", "skipping unsupported command")
  149.         end
  150.     end
  151. end
  152.  
  153. function myAddon:SaveMacro(i) -- /run MacroTranslator:SaveMacro(50) /run MacroTranslator:PLAYER_LOGOUT()
  154.     if type(i) ~= "number" or i < 1 or i > (MAX_CHARACTER_MACROS + MAX_ACCOUNT_MACROS) then return end
  155.     local macro, _, body = GetMacroInfo(i)
  156.     if not macro then return end
  157.     --print("   ")
  158.     --print(">> SaveMacro:", i, macro)
  159.     self:SaveMacroText(body)
  160. end
  161.  
  162. ------------------------------------------------------------------------
  163.  
  164.  
  165.  
  166. function myAddon:TranslateName(name)
  167.     name = string.lower(name)
  168.     --print(">> TranslateName:", name)
  169.     local data = MacroTranslatorDB[name]
  170.     if data then
  171.         --print(">> TranslateName:", "found data", data)
  172.         local what, id, name = strsplit(":", data)
  173.         id = tonumber(id)
  174.         if what == "spell" then
  175.             name = GetSpellInfo(id)
  176.         elseif what == "item" then
  177.             name = GetItemInfo(id)
  178.         end
  179.         if name then
  180.             MacroTranslatorDB[string.lower(name)] = data
  181.             --print(">> TranslateName:", "saved data", name)
  182.             return name, id
  183.         end
  184.     end
  185.     --print(">> TranslateName:", "no match")
  186. end
  187.  
  188. function myAddon:RestoreMacroText(body)
  189.     -- body = self:CleanMacro(body)
  190.     local newbody = body
  191.     local changes, missing = 0, 0
  192.     --print("   ")
  193.     --print(">> RestoreMacroText:", i, macro)
  194.     for line in gmatch(newbody, "[^\n]+") do
  195.         --print(">> RestoreMacroText:", "processing line:", line)
  196.         local ok
  197.         for i = 1, #commands do
  198.             if strmatch(line, commands[i]) then
  199.                 ok = true
  200.                 break
  201.             end
  202.         end
  203.         if ok then
  204.             local div = (strmatch(line, SLASH_CASTSEQUENCE1) or strmatch(line, SLASH_CASTSEQUENCE2)) and "[^,;]+" or "[^;]+"
  205.             for name in gmatch(line, div) do
  206.                 --print(">> RestoreMacroText:", "processing part:", format("%q", name))
  207.                 name = gsub(name, ".+%]", "")
  208.                 name = gsub(name, "[#/]%S+", "")
  209.                 name = gsub(name, "[Rr][Ee][Ss][Ee][Tt]=%S+ ?", "")
  210.                 name = strtrim(name)
  211.                 if strlen(name) > 0 then
  212.                     local newname = self:TranslateName(name)
  213.                     if newname then
  214.                         if newname == name then
  215.                             --print(">> RestoreMacroText:", "no change for", name)
  216.                         else
  217.                             newbody = gsub(newbody, name, newname)
  218.                             changes = changes + 1
  219.                             --print(">> RestoreMacroText:", name, "=>", newname)
  220.                         end
  221.                     else
  222.                         --print(">> RestoreMacroText:", "no match for", name)
  223.                         missing = missing + 1
  224.                     end
  225.                 end
  226.             end
  227.         --else
  228.             --print(">> SaveMacroText:", "skipping unsupported command")
  229.         end
  230.     end
  231.     --print(">> RestoreMacroText:", changes, "changes")
  232.     if changes > 0 then
  233.         return newbody, missing
  234.     else
  235.         return nil, missing
  236.     end
  237. end
  238.  
  239. function myAddon:RestoreMacro(i) -- /run MacroTranslator:RestoreMacro(46)
  240.     if type(i) ~= "number" or i < 1 or i > (MAX_CHARACTER_MACROS + MAX_ACCOUNT_MACROS) then return end
  241.     local name, icon, body = GetMacroInfo(i)
  242.     if not name then return end
  243.     --print("   ")
  244.     --print(">> RestoreMacro:", i, name)
  245.     local newbody, missing = self:RestoreMacroText(body)
  246.     if missing == 0 and not newbody then return end
  247.  
  248.     if InCombatLockdown() then
  249.         --print(">> RestoreMacro:", "Queued for end of combat")
  250.         return self:Queue(i)
  251.     end
  252.  
  253.     if missing > 0 then
  254.         --print(">> RestoreMacro:", "Item name(s) missing, queued for retry")
  255.         self:Queue(i)
  256.     end
  257.  
  258.     self.editing = true
  259.     EditMacro(i, nil, nil, newbody)
  260.     self.editing = nil
  261. end
  262.  
  263. ------------------------------------------------------------------------
  264.  
  265. local f = CreateFrame("Frame", ADDON)
  266. f:SetScript("OnEvent", function(self, event, ...) return self[event](self, ...) end)
  267. f:RegisterEvent("PLAYER_LOGIN")
  268. f:RegisterEvent("PLAYER_LOGOUT")
  269. myAddon.EventFrame = f
  270.  
  271. f:Hide()
  272. f:SetScript("OnUpdate", function(self, elapsed)
  273.     self.delay = self.delay - elapsed
  274.     if self.delay < 0 then
  275.         self:Hide()
  276.         if InCombatLockdown() then
  277.             return self:RegisterEvent("PLAYER_REGEN_ENABLED")
  278.         end
  279.         for i in pairs(queue) do
  280.             --print(">> QUEUED:", i)
  281.             myAddon:RestoreMacro(i)
  282.             queue[i] = nil -- if it failed again a second time, just let it go, probably an NPC spell or something
  283.         end
  284.     end
  285. end)
  286.  
  287. function f:PLAYER_REGEN_ENABLED()
  288.     --print(">> PLAYER_REGEN_ENABLED")
  289.     self:UnregisterEvent("PLAYER_REGEN_ENABLED")
  290.     self.delay = 1
  291.     self:Show()
  292. end
  293.  
  294. function myAddon:Queue(i)
  295.     --print(">> Queue:", i)
  296.     queue[i] = true
  297.     if InCombatLockdown() then
  298.         f:RegisterEvent("PLAYER_REGEN_ENABLED")
  299.     else
  300.         f.delay = 3
  301.         f:Show()
  302.     end
  303. end
  304.  
  305. function myAddon:RestoreAllMacros()
  306.     local global, char = GetNumMacros()
  307.     --print(">> RestoreAllMacros:", global, "+", char, "macros found")
  308.     for i = 1, global do
  309.         self:RestoreMacro(i)
  310.     end
  311.     for i = 1, char do
  312.         self:RestoreMacro(i + MAX_ACCOUNT_MACROS)
  313.     end
  314. end
  315.  
  316. ------------------------------------------------------------------------
  317.  
  318. local addons = {
  319.     Clique = function()
  320.         local AddBinding = Clique.AddBinding
  321.         function Clique:AddBinding(entry)
  322.             --print(">> Clique/AddBinding")
  323.             if entry.spell then
  324.                 myAddon:SaveNameToID(entry.spell)
  325.             elseif entry.macrotext then
  326.                 myAddon:SaveMacroText(entry.macrotext)
  327.             end
  328.             AddBinding(self, entry)
  329.         end
  330.  
  331.         local loading
  332.  
  333.         local BINDINGS_CHANGED = Clique.BINDINGS_CHANGED
  334.         function Clique:BINDINGS_CHANGED()
  335.             --print(">> Clique/BINDINGS_CHANGED:", loading)
  336.             local bindings = Clique.bindings
  337.             for i = 1, #bindings do
  338.                 local entry = bindings[i]
  339.                 if entry.spell then
  340.                     local name = myAddon:TranslateName(entry.spell)
  341.                     --print("s">> Clique/BINDINGS_CHANGED:", pell", entry.spell, "->", name)
  342.                     entry.spell = name or entry.spell
  343.                 elseif entry.macrotext then
  344.                     myAddon:SaveMacroText(entry.macrotext)
  345.                     local text = myAddon:RestoreMacroText(entry.macrotext)
  346.                     --print(">> Clique/BINDINGS_CHANGED:", "macro", entry.macrotext)
  347.                     --print(">> Clique/BINDINGS_CHANGED:", "   ->", text)
  348.                     entry.macrotext = text or entry.macrotext
  349.                 end
  350.             end
  351.             if not loading then
  352.                 BINDINGS_CHANGED(self)
  353.             end
  354.         end
  355.  
  356.         if Clique.bindings then
  357.             --loading = true
  358.             Clique:BINDINGS_CHANGED()
  359.             loading = nil
  360.         end
  361.     end
  362. }
  363.  
  364. function f:ADDON_LOADED(addon)
  365.     local func = addons[addon]
  366.     if func then
  367.         addons[addon] = nil
  368.         func()
  369.     end
  370.     if not next(addons) then
  371.         self:UnregisterEvent("ADDON_LOADED")
  372.     end
  373. end
  374.  
  375. function f:PLAYER_LOGIN()
  376.     --print(">> PLAYER_LOGIN")
  377.     myAddon:RestoreAllMacros()
  378.  
  379.     for addon, func in pairs(addons) do
  380.         if IsAddOnLoaded(addon) then
  381.             addons[addon] = nil
  382.             func()
  383.         end
  384.     end
  385.     if next(addons) then
  386.         self:RegisterEvent("ADDON_LOADED")
  387.     end
  388. end
  389.  
  390.  
  391. function f:PLAYER_LOGOUT()
  392.     local global, char = GetNumMacros()
  393.     for i = 1, global do
  394.         myAddon:SaveMacro(i)
  395.     end
  396.     for i = 1, char do
  397.         myAddon:SaveMacro(i + MAX_ACCOUNT_MACROS)
  398.     end
  399. end
  400.  
  401. hooksecurefunc("EditMacro", function(i)
  402.     if f.editing then return end
  403.     --print(">> EditMacro:", i)
  404.     if type(i) == "string" then
  405.         --print(">> EditMacro:", "found index", i)
  406.         i = GetMacroIndexByName(i)
  407.     end
  408.     if i > 0 then
  409.         myAddon:SaveMacro(i)
  410.     end
  411. end)
  412.  
  413. ------------------------------------------------------------------------
  414.  
  415. local MESSAGE_SAVED = "Spell and item names for the current language have been saved."
  416. local MESSAGE_RESTORED = "Your macros have been updated."
  417. if GetLocale() == "deDE" then
  418.     MESSAGE_SAVED = "Die Zauber- und Gegenstandsnamen der aktuellen Sprache wurden gespiechert."
  419.     MESSAGE_RESTORED = "Eure Makros wurden aktualisiert."
  420. elseif GetLocale():match("^es") then
  421.     MESSAGE_SAVED = "Los nombres de hechizos y objetos en el idioma actual han sido guardados."
  422.     MESSAGE_RESTORED = "Tus macros han sido actualizados."
  423. end
  424.  
  425. SLASH_MACROTRANSLATOR1 = "/macrotrans"
  426. SlashCmdList.MACROTRANSLATOR = function(cmd)
  427.     local type, id, name = strmatch(strlower(cmd), "^%s*(%S+)%s*(%d+)%s*(.+)%s*$")
  428.     if id and name and (type == "spell" or type == "item") then
  429.         MacroTranslatorDB[name] = type..":"..id
  430.     end
  431.     local type, id, name = strmatch(strlower(cmd), "^%s*(|h(.-):(%d+):.+|h%s*(%S+)%s*$")
  432.     if id and name and (type == "spell" or type == "item") then
  433.         MacroTranslatorDB[name] = type..":"..id
  434.     end
  435.     f:PLAYER_LOGOUT()
  436.     print("|cffffb000"..ADDON..":|r", MESSAGE_SAVED)
  437.     f:PLAYER_LOGIN()
  438.     print("|cffffb000"..ADDON..":|r", MESSAGE_RESTORED)
  439. end

Thank you in advance for your help.

Last edited by Recreo : 02-09-23 at 11:41 PM.
  Reply With Quote