Способ реализации:
Версия Warcraft:

[WarCraft III] Jass identifier renamer

автор статьи: host_pi
автор программы: PT153
[WarCraft III] Jass identifier renamer - автопереименование функций и переменных в j коде
скрипт позволяет вернуть обфусцированному j коду читабельный вид, пакетно меняя имена функций и переменных
(например если у вас есть незащищённый код от другой версии карты или вы произвели реверс-инжиниринг кода и можете самостоятельно дать смысловые имена)

как юзнуть:

  1. регистрируетесь в реплите
  2. клонируете себе этот репл
  3. в war3map.j кидаете свой код, в main.py описываете имена, что хотите заменить и на что.
  4. запускаете main.py, в output.j результат.
кнопка клонирования справа сверху:
код main.py под спойлером:
Открыть
import re
from collections import Counter
from collections.abc import Iterable


WORDS_TO_REPLACE = {
    'fu': 'Test1',
    'ti': 'Test2',
    'jass': 'Test3',
    'hpea': 'Test4',
    'd': 'Test5',
}

words = '|'.join(re.escape(w) for w in WORDS_TO_REPLACE)
REGEX_WORDS = re.compile(rf'\b({words})\b')

REPLACEMENTS_N = Counter()
FOUND_IN_QUOTES = Counter()


def replacement(m: re.Match, /) -> str:
    word = m[0]
    start, end = m.span()
    assert start < end
    for s, e in SPANS:
        if s >= end: break

        if s <= start and end <= e:
            FOUND_IN_QUOTES[word] += 1
            return word

    REPLACEMENTS_N[word] += 1
    return WORDS_TO_REPLACE[word]


def find_quotes(content: str, /) -> Iterable[tuple[int, int]]:
    is_double = is_single = False
    start = end = -1
    for i, c in enumerate(content):
        if is_double:
            if c == '"':
                if content[i - 1] == '\\':
                    continue

                end = i + 1
                is_double = False

                assert start < end
                assert start > -1 and end > -1
                yield start, end
                start = end = -1
        elif is_single:
            if c == "'":
                if content[i - 1] == '\\':
                    continue

                end = i + 1
                is_single = False

                assert start < end
                assert start > -1 and end > -1
                yield start, end
                start = end = -1
        else:
            if c == '"':
                is_double = True
                start = i
            elif c == "'":
                is_single = True
                start = i


with open('war3map-actual.j') as f, open('output.j', 'w') as out:
    content = f.read()
    SPANS = tuple(find_quotes(content))
    out.write(REGEX_WORDS.sub(replacement, content))

col1_len = max(map(len, map(repr, REPLACEMENTS_N.keys() | FOUND_IN_QUOTES.keys())))
print('Replaced count:')
for w, n in sorted(REPLACEMENTS_N.items()):
    print(f'    {w!r:{col1_len}} -- {n}')
    
print('Found inside quotes:')
for w, n in sorted(FOUND_IN_QUOTES.items()):
    print(f'    {w!r:{col1_len}} -- {n}')
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
38
Поле "источник" создано не для этой цели. У тебя авторский контент, а по этому полю в дальнейшем может определяться дизайн страницы (авторское или нет)
28
Автор скрипта я, так что если вас корёжит с его кода, все претензии писать мне)
18
Интересно почему Iterable импортируется из collections, а не из typing
28
Vlod, потому что импорт абстрактных коллекций из typing является устаревшим с 3.9.

host_pi, закинь код в саму статью по спойлер.
18
Vlod, потому что импорт абстрактных коллекций из typing является устаревшим с 3.9.
Интересно почему типы не должны быть в typing) Если импорт из typing признан устаревшим можно линк
28
Vlod, прочитав комментарий, я аж посмеялся)
typing это не types. Это другой модуль. И кстати, абстрактных коллекций в types нет и никогда не было. Они всегда были в collections.abc, где им и самое место.
Если импорт из typing признан устаревшим можно линк
Я напомню, что 3.9 вышел октябре 2020 в и его полноценная поддержка прекратилась в 2022 (осталась поддержка только для security issues до 2025). Вот статья What's new, раздел You should check for DeprecationWarning in your code:
Aliases to Abstract Base Classes in the collections module, like collections.Mapping alias to collections.abc.Mapping, are kept for one last release for backward compatibility. They will be removed from Python 3.10.
Впрочем, они передумали и алиасы оставили, о чём сказано в последней документации модуля typing, раздел Deprecated aliases:
This module defines several deprecated aliases to pre-existing standard library classes. These were originally included in the typing module in order to support parameterizing these generic classes using []. However, the aliases became redundant in Python 3.9 when the corresponding pre-existing classes were enhanced to support [] (see PEP 585).
The redundant types are deprecated as of Python 3.9. However, while the aliases may be removed at some point, removal of these aliases is not currently planned. As such, no deprecation warnings are currently issued by the interpreter for these aliases.
Чуть ниже расписан таймлайн устаревания и удаления из модуля:
Загруженные файлы
12
Немного не понял сути программы. Допустим решил поменять что-то в карте с обфусцированный j файлом, всё равно, по итогу, нужно будет читать каждую строку и исходя из контекста давать название, что в целом можно сделать [ctrl + h].
Удобно, если б можно было бы менять строки не по имени, а по содержанию по типу local unit ${?} = GetTriggerUnit() => "local unit caster = GetTriggerUnit()"
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.