Skip to content
This repository has been archived by the owner on May 9, 2022. It is now read-only.

Commit

Permalink
Супер-гайд от Dahaka
Browse files Browse the repository at this point in the history
  • Loading branch information
CMTV committed Dec 25, 2017
1 parent 38f86fd commit be5e85d
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 1 deletion.
54 changes: 54 additions & 0 deletions book/1.12+/forge/other/access_transformers/article.md
@@ -0,0 +1,54 @@
# Access Transformers
Автор статьи — [Dahaka](https://forum.mcmodding.ru/members/dahaka.4288/).

Файлы, использующиесяв этой статье можно скачать [здесь](images/root.zip).

Во время написания мода иногда возникают ситуации, когда хочется использовать приватные методы и поля данных, но, к сожалению, IDE нам не позволяет это сделать. Первое, что приходит в голову, это использовать возможности рефлексии (преимущественно `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
```
Магическая строка `func_179217_a(ILjava/lang/String;Lnet/minecraft/item/Item;)V` это srg имя с дескриптором. Узнать их можно, например, при помощи программки [MCP Mapping Viewer](http://bspk.rs/MC/MCPMappingViewer/index.html). В ней интуитивно понятный интерфейс, так что проблем возникнуть не должно. Выбираем маппинги под нужную версию и через поиск ищем метод или поле.

После того, как создали и заполнили файл `example_at.cfg`, необходимо добавить в файл `build.gradle` следующие строки:
```
jar {
manifest {
attributes 'FMLAT': 'example_at.cfg'
}
}
```
Теперь остается лишь все пересобрать: `gradlew clean setupDecompWorkspace --refresh-dependencies`. В результате вы увидите, что указанные поля и методы имеют `public` модификатор.

Заметки.
1. Указывать можно не только `public` модификатор, но и `protected`. Правда я не знаю, для чего это может пригодится. И работать это будет только в сторону снятия инкапсуляции, но не наоборот.
2. Печально, но иногда трансформер может не примениться, т.е. поле/метод так и останется инкапсулировано. Но это редкость. Зачастую это вставки forge.
3. Указанные в примере трансформеры относятся к версии 1.12.
4. В прикрепленном архиве лежит исходный `build.gradle` файл, в который добавлены указанные выше строки, а также файл `example_at.cfg` в нужной папке. Достаточно лишь скопировать к себе в проект, пересобрать, и все должно работать.
10 changes: 10 additions & 0 deletions book/1.12+/forge/other/access_transformers/config.yml
@@ -0,0 +1,10 @@
title: Access Transformers

description: >
Удобный способ для получения доступа к приватным полям и методам без рефлексии
contributors:
-
name: CMTV
role: Перенес с форума
github: https://github.com/CMTV
Binary file not shown.
3 changes: 2 additions & 1 deletion book/1.12+/forge/other/config.yml
Expand Up @@ -4,4 +4,5 @@ category-title: Дополнительно
# Articles order
articles-order:
- sources
- jei_integration
- jei_integration
- access_transformers

0 comments on commit be5e85d

Please sign in to comment.