Access Transformer
Access Transformer(줄여서 AT)는 클래스, 메서드, 필드의 가시성 및 불변 여부를 변경하는 시스템 입니다. 모드가 접근 불가능한 멤버를 사용 및 수정할 수 있도록 해 줍니다.
무엇의 가시성을 변경할지 지정하는 AT 설정 파일 규격은 이곳에 나와있습니다.
AT 추가하기
AT를 활성화 하려면 아래와 같이 build.gradle
에 설정 파일을 추가하세요. 이 파일이 컴파일 출력 폴더의 resources
로 복사되기만 한다면 어디에 저장하셔도 상관 없습니다.
// build.gradle
// 여기서 매핑 채널과 버전도 지정할 수 있습니다.
minecraft {
accessTransformers {
file('src/main/resources/META-INF/accesstransformer.cfg')
}
}
네오 포지는 기본적으로 AT 설정 파일을 META-INF/accesstransformer.cfg
에서 찾습니다. 만약 다른 곳에 설정 파일을 저장하셨다면 아래와 같이 neoforge.mods.toml
에서 위치를 지정해 주세요:
# neoforge.mods.toml에서:
[[accessTransformers]]
## 아래 주소는 컴파일 출력 폴더의 resources, 또는 배포 jar의 루트 폴더에서 출발합니다
## 프로젝트의 'resources' 폴더는 컴파일 출력 폴더의 resources의 최상위 폴더가 됩니다
file="META-INF/accesstransformer.cfg"
AT 설정 파일을 여러개 지정하면 순서대로 적용됩니다. 모드가 거대해 여러 패키지로 나눌 때 용이합니다.
// build.gradle에서:
minecraft {
accessTransformers {
file('src/main/resources/accesstransformer_main.cfg')
file('src/additions/resources/accesstransformer_additions.cfg')
}
}
# neoforge.mods.toml에서:
[[accessTransformers]]
file="accesstransformer_main.cfg"
[[accessTransformers]]
file="accesstransformer_additions.cfg"
AT 설정 파일을 수정하거나 추가한 이후, Gradle 프로젝트를 다시 불러와야만 적용됩니다.
AT 설정 파일 문법
주석
#
로 시작하는 줄은 주석으로 처리되며 무시됩니다.
접근 수정자
접근 수정자(Access Modifier)는 멤버의 새로운 가시성을 지정하는 키워드를 뜻합니다. Java와 똑같이 아래 네 개의 키워드를 지원합니다:
public
- 패키지 안, 또는 밖에 있는 모든 클래스에서 접근할 수 있음protected
- 패키지 안에 있는 클래스, 또는 자식 클래스에서만 접근할 수 있음default
- 패키지 내부에 있는 클래스에서만 접근할 수 있음private
- 클래스 내부에서만 접근할 수 있음
위 키워드에 +f
또는 -f
를 추가하여 가시성 뿐 아니라 final
키워드도 추가 및 제거할 수 있습니다. 기존에는 불가능하던 자식 클래스 생성이나, 메서드 재정의, 또는 필드 값 변경 등을 가능하게 해 줍니다.
메서드의 가시성을 변경할 때, 지정된 메서드만 변경됩니다; 만약 자식 클래스에서 해당 메서드를 재정의한다면 똑같은 가시성 수정이 이루어지지 않아, 자식 메서드가 부모 메서드보다 더 낮은 가시성을 가져 JVM 오류가 발생할 수 있으니, 가시성을 변경하고자 하는 메서드가 다른 곳에서 재정의되면 안 됩니다!
private
메서드나 final
메서드(또는 final
클래스에 정의된 메서드), 그리고 static
(정적) 메서드들은 재정의가 불가능하기에 안전하게 가시성을 변경할 수 있습니다.
변환 타깃
클래스
클래스의 가시성을 바꾼다면:
<접근 수정자> <완전한 클래스 이름>
내부 클래스들은, 외부 클래스의 전체 이름과 내부 클래스의 이름을 $
로 분리하여 표시합니다.
필드
필드의 가시성을 바꾼다면:
<접근 수정자> <완전한 클래스 이름> <필드 이름>
메서드
메서드는 아래와 같이 가시성 뿐 아니라 인자들과 반환값의 타입까지 표시합니다:
<접근 수정자> <완전한 클래스 이름> <메서드 이름>(<인자의 타입들>)<반환 타입>
메서드 타입
메서드의 인자 및 반환값의 타입은 "descriptor"라고 불리기도 합니다. 자세한 사항은 Oracle 기술 문서에서 확인하세요(Java Virtual Machine Specification, SE 21, sections 4.3.2 and 4.3.3)
B
-byte
, 부호가 있는 바이트C
-char
, UTF-16 유니코드 문자 번호D
-double
, 배정밀도 부동 소수점F
-float
, 단정밀도 부동 소수점I
-integer
, 32비트 정수J
-long
, 64비트 정수S
-short
, 부호가 있는 16비트 정수Z
-boolean
,true
또는false
인 값[
- 배열의 차원 1개를 표시함- 예:
[[S
는short[][]
- 예:
L<class name>;
- 참조 타입, 모든 클래스가 해당됨- 예:
Ljava/lang/String;
는 참조 타입java.lang.String
를 가리킴 (빗금 대신 마침표로 패키지 구분)
- 예:
(
- 메서드 디스크립터, 메서드의 인자들은 괄호 안에 적음, 반환 타입은 괄호 뒤에 적음- 예:
<method>(I)Z
는int
를 받고boolean
을 반환하는 메서드
- 예:
V
- 메서드 반환 타입이void
일 때 사용- 예:
<method>()V
는 인자 및 반환 값이 없는 메서드
- 예:
예시
# Crypt 클래스의 ByteArrayToKeyFunction의 가시성을 public으로 변경합니다.
public net.minecraft.util.Crypt$ByteArrayToKeyFunction
# MinecraftServer의 'random' 필드를 protected로 만들고 final 키워드를 제거합니다
protected-f net.minecraft.server.MinecraftServer random
# String을 인자로 받고 ExecutorService를 반환하는 'Util#makeExecutor' 메서드를 public으로 만듭니다
public net.minecraft.Util makeExecutor(Ljava/lang/String;)Ljava/util/concurrent/ExecutorService;
# 2개의 long을 인자로 받고 int[]를 반환하는 'UUIDUtil#leastMostToIntArray' 메서드를 public으로 만듭니다
public net.minecraft.core.UUIDUtil leastMostToIntArray(JJ)[I