Skip to content

Instantly share code, notes, and snippets.

@strayge
Created June 26, 2021 14:50
Show Gist options
  • Save strayge/755cad67a68a00a98fc7b99a1a90de54 to your computer and use it in GitHub Desktop.
Save strayge/755cad67a68a00a98fc7b99a1a90de54 to your computer and use it in GitHub Desktop.
wow addon patches
# addon
# [comment]
#
# changes
# file
#
# replace => text
# or
# after_line, [before_line] => text
# or
# before_line => text
patches = [{'comment': 'fix inbox text',
'addon': 'TradeSkillMaster',
'changes': [{'file': 'Core\\UI\\MailingUI\\Inbox.lua',
'replace': 'RegisterTopLevelPage(INBOX,',
'text': 'RegisterTopLevelPage(L["Inbox"],',
},
{'file': 'Locale\\Locale.lua',
'after_line': 'locale == "enGB" then',
'text': 'TSM.L["Inbox"] = "Inbox"',
},
{'file': 'Locale\\Locale.lua',
'after_line': 'locale == "ruRU" then',
'before_line': 'TSM.L["',
'text': 'TSM.L["Inbox"] = "Входящие"',
},
],
},
{'comment': 'disable popup after login',
'addon': 'TradeSkillMaster',
'changes': [{'file': 'TradeSkillMaster.lua',
'replace': 'private.appInfo.lastSync > 60 * 60 then',
'text': 'private.appInfo.lastSync > 3 * 24 * 60 * 60 then',
},
],
},
{'comment': 'fix long texts',
'addon': 'TradeSkillMaster',
'changes': [{'file': 'Locale\\Locale.lua',
'replace': '"Обновление данных:"',
'text': '"База:"',
},
],
},
{'comment': 'total count in craft',
'addon': 'TradeSkillMaster',
'changes': [{'file': 'Core\\Service\\Crafting\\Core.lua',
'replace': '"bagQuantity", "number", Inventory.GetBagQuantity, "itemString"',
'text': '"bagQuantity", "number", Inventory.GetTotalQuantity, "itemString"',
},
],
},
{'comment': 'pull in english',
'addon': 'ExRT',
'changes': [{'file': 'localization\\localization.ru.lua',
'replace': 'L.timerattack = "Атака"',
'text': 'L.timerattack = "Pull"',
},
{'file': 'localization\\localization.ru.lua',
'replace': 'L.timerattackcancel = "Атака отменена"',
'text': 'L.timerattackcancel = "CANCELED"',
},
{'file': 'localization\\localization.ru.lua',
'replace': 'L.timerattackt = "Атака через"',
'text': 'L.timerattackt = "Pull in"',
},
{'file': 'localization\\localization.ru.lua',
'replace': 'L.timerafk = "Перерыв"',
'text': 'L.timerafk = "Break"',
},
{'file': 'localization\\localization.ru.lua',
'replace': 'L.timerafkcancel = "Перерыв отменен"',
'text': 'L.timerafkcancel = "Break canceled"',
},
{'file': 'localization\\localization.ru.lua',
'replace': 'L.timermin = "мин."',
'text': 'L.timermin = "min."',
},
{'file': 'localization\\localization.ru.lua',
'replace': 'L.timersec = "сек."',
'text': 'L.timersec = "sec."',
},
],
},
]
import os
import sys
def patch(p):
addon = p['addon']
comment = p.get('comment', '')
print('\n{}: {}'.format(addon, comment))
for change in p['changes']:
file = change['file'].replace('\\', os.sep).replace('/', os.sep)
filename = os.path.join(base_path, addon, file)
original = read_file(filename)
print('\n File: {}'.format(file))
if 'replace' in change:
# replace line part
replace = change['replace']
text = change['text']
if text in original:
print('\tLooks like already patched')
continue
if replace not in original:
print('\tERROR: part not founded!')
continue
patched = original.replace(replace, text, 1)
print('\t"{}" => "{}"'.format(replace, text))
elif 'after_line' in change and 'before_line' in change:
after_line = change['after_line']
before_line = change['before_line']
text = change['text']
if text in original:
print('\tLooks like already patched')
continue
pos = find_pos(original, after_line)
if pos < 0:
print('\tERROR: after_line not founded')
continue
pos = find_pos(original, before_line, pos)
if pos < 0:
print('\tERROR: before_line not founded')
continue
pos = line_start(original, pos)
patched = insert(original, pos, text, add_newline=True)
print("\t+ {}".format(text))
elif 'after_line' in change:
# add line after line with provided text
after_line = change['after_line']
text = change['text']
if text in original:
print('\tLooks like already patched')
continue
pos = find_pos(original, after_line)
if pos < 0:
print('\tERROR: after_line not founded')
continue
pos = line_end(original, pos)
patched = insert(original, pos, text, add_newline=True)
print("\t+ {}".format(text))
elif 'before_line' in change:
# insert line before line with provided text
before_line = change['before_line']
text = change['text']
if text in original:
print('\tLooks like already patched')
continue
pos = find_pos(original, before_line)
if pos < 0:
print('\tERROR: before_line not founded')
continue
pos = line_start(original, pos)
patched = insert(original, pos, text, add_newline=True)
print("\t+ {}".format(text))
else:
print('\tERROR: actions not founded, change skipped!')
write_file(filename, patched)
def read_file(filename):
if not os.path.isfile(filename):
print('\tERROR: {} not found!'.format(filename))
return
return open(filename, 'rt', encoding='utf-8').read()
def write_file(filename, text):
f = open(filename, 'wt', encoding='utf-8')
f.write(text)
f.close()
def find_pos(text, word, start=0):
return text.find(word, start)
def line_start(text, pos):
# return pos after previous \n
end_pos = text.rfind('\n', 0, pos)
if end_pos == -1:
return len(end_pos)
return end_pos + 1
def line_end(text, pos):
# return pos after next \n
end_pos = text.find('\n', pos)
if end_pos == -1:
return len(end_pos)
return end_pos + 1
def insert(text, pos, newpart, add_newline=False):
def detect_line_ending(text):
if text.find('\r\n') != -1:
return '\r\n'
else:
return '\n'
if add_newline:
newpart = newpart + detect_line_ending(text)
return text[:pos] + newpart + text[pos:]
if __name__ == '__main__':
base_path = os.path.dirname(sys.argv[0])
if os.path.isdir('AddOns'):
base_path = os.path.join(base_path, 'AddOns')
elif os.path.isdir(os.path.join('Interface', 'AddOns')):
base_path = os.path.join(base_path, 'Interface', 'AddOns')
for p in patches:
patch(p)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment