This repository has been archived by the owner on May 9, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
66 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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` в нужной папке. Достаточно лишь скопировать к себе в проект, пересобрать, и все должно работать. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
title: Access Transformers | ||
|
||
description: > | ||
Удобный способ для получения доступа к приватным полям и методам без рефлексии | ||
contributors: | ||
- | ||
name: CMTV | ||
role: Перенес с форума | ||
github: https://github.com/CMTV |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters