- Версия(и) Minecraft
- 1.7.10-1.12
Во время написания мода иногда возникают ситуации, когда хочется использовать приватные методы и поля данных, но, к сожалению, IDE нам не позволяет это сделать. Первое, что приходит в голову, это использовать возможности рефлексии (преимущественно
Но решение есть - трансформеры доступа (Access Transformers - AT). Смысл в том, что они позволяют изменить модификаторы доступа к полям и методам в исходниках майнкрафта сразу при сборке рабочего пространства (проекта), т.е. при выполнении
Перейдем к практике.
Необходимо создать файл
Магическая строка
После того, как создали и заполнили файл
Теперь остается лишь все пересобрать:
Заметки.
1. Указывать можно не только public модификатор, но и protected. Правда я не знаю, для чего это может пригодиться. И работать это будет только в сторону снятия инкапсуляции, но не наоборот.
2. Печально, но иногда трансформер может не примениться, т.е. поле/метод так и останется инкапсулировано. Но это редкость. Зачастую это вставки forge.
3. Указанные в примере трансформеры относятся к версии 1.12.
4. В прикрепленном архиве лежит исходный
5. Если вдруг ваша версия Minecraft более ранняя, то об использовании AT можно почитать здесь.
ReflectionHelper
). И, естественно, это плохое решение проблемы, начиная с того, что падает производительность, заканчивая уродованием кода.Но решение есть - трансформеры доступа (Access Transformers - AT). Смысл в том, что они позволяют изменить модификаторы доступа к полям и методам в исходниках майнкрафта сразу при сборке рабочего пространства (проекта), т.е. при выполнении
setupDecompWorkspace
. И это будет работать в отдельном клиенте из-за того, что forge в runtime (во время выполнения) меняет модификаторы доступа на public.Перейдем к практике.
Необходимо создать файл
example_at.cfg
в каталоге /src/main/resources/META-INF/
. Если META-INF
нет, нужно создать вручную. Имя example
значения не имеет, можно выбрать любое. Например, <modid>
. Но важно, чтобы файл заканчивался на _at.cfg
. Сам файл описывает, какие методы и поля должны быть преобразованы.
Код:
# Это комментарий.
# Все поля в классе Item станут публичными.
public net.minecraft.item.Item *
# Суффикс -f позволяет снять модификатор final.
# Все поля в классе ItemStack станут публичными, изменяемыми.
public-f net.minecraft.item.ItemStack *
# Все методы в классе ItemStack станут публичными.
# Так делать нельзя, если класс кем-то наследуется. Возможно может не собраться рабочая среда.
# Это происходит из-за того, что в целевом классе модификаторы доступа методов изменятся, а в производных - нет.
# Т.е. будет ошибка компиляции.
public net.minecraft.item.ItemStack *()
# Для обращения к внутренним классам используется '$'.
# Все поля в классе ToolMaterial станут публичными.
public net.minecraft.item.Item$ToolMaterial *
# Поле unlocalizedName в классе Item станет публичным.
public net.minecraft.item.Item field_77774_bZ
# Метод Item#registerItem(int, String, Item) станет публичным.
public net.minecraft.item.Item func_179217_a(ILjava/lang/String;Lnet/minecraft/item/Item;)V
# Конструктор класса называется <init>.
Магическая строка
func_179217_a(ILjava/lang/String;Lnet/minecraft/item/Item;)V
это srg имя с дескриптором. Узнать их можно, например, при помощи программки MCP Mapping Viewer. В ней интуитивно понятный интерфейс, так что проблем возникнуть не должно. Выбираем маппинги под нужную версию и через поиск ищем метод или поле.После того, как создали и заполнили файл
example_at.cfg
, необходимо добавить в файл build.gradle
следующие строки:
Код:
jar {
manifest {
attributes 'FMLAT': 'example_at.cfg'
}
}
Теперь остается лишь все пересобрать:
gradlew clean setupDecompWorkspace eclipse (или idea) --refresh-dependencies
. В результате вы увидите, что указанные поля и методы имеют public
модификатор.Заметки.
1. Указывать можно не только public модификатор, но и protected. Правда я не знаю, для чего это может пригодиться. И работать это будет только в сторону снятия инкапсуляции, но не наоборот.
2. Печально, но иногда трансформер может не примениться, т.е. поле/метод так и останется инкапсулировано. Но это редкость. Зачастую это вставки forge.
3. Указанные в примере трансформеры относятся к версии 1.12.
4. В прикрепленном архиве лежит исходный
build.gradle
файл, в который добавлены указанные выше строки, а также файл example_at.cfg
в нужной папке. Достаточно лишь скопировать к себе в проект, пересобрать, и все должно работать.5. Если вдруг ваша версия Minecraft более ранняя, то об использовании AT можно почитать здесь.