Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jpenilla/reflection-remapper
Java reflection library with support for obfuscation mappings
https://github.com/jpenilla/reflection-remapper
java mappings papermc reflection remapping
Last synced: 1 day ago
JSON representation
Java reflection library with support for obfuscation mappings
- Host: GitHub
- URL: https://github.com/jpenilla/reflection-remapper
- Owner: jpenilla
- License: apache-2.0
- Created: 2021-10-29T04:06:23.000Z (almost 3 years ago)
- Default Branch: master
- Last Pushed: 2024-03-15T03:31:34.000Z (6 months ago)
- Last Synced: 2024-09-19T04:55:52.713Z (7 days ago)
- Topics: java, mappings, papermc, reflection, remapping
- Language: Java
- Homepage:
- Size: 329 KB
- Stars: 92
- Watchers: 2
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# reflection-remapper
reflection-remapper is a library to simplify making reflective calls, with specific support for remapped environments.## Getting reflection-remapper
Releases are published to [Maven Central](https://central.sonatype.com/artifact/xyz.jpenilla/reflection-remapper).>
> Using snapshot builds
>
> Snapshot builds are available on the Sonatype snapshots Maven repository: `https://s01.oss.sonatype.org/content/repositories/snapshots/`
>
> Consult your build tool's documentation for details on adding Maven repositories to your project.
>### Gradle Kotlin DSL
>
> Click to show build.gradle.kts
>
> ```kotlin
> repositories {
> mavenCentral()
> }
>
> dependencies {
> implementation("xyz.jpenilla:reflection-remapper:0.1.1")
> }
> ```
>### Gradle Groovy DSL
>
> Click to show build.gradle
>
> ```groovy
> repositories {
> mavenCentral()
> }
>
> dependencies {
> implementation 'xyz.jpenilla:reflection-remapper:0.1.1'
> }
> ```
>## Using reflection-remapper
*Note: The following is a basic introduction; For further details, consult the reflection-remapper Javadocs.*
### `ReflectionRemapper`
`ReflectionRemapper` is the interface provided by reflection-remapper for remapping class, method, and field names for reflection lookups.>
> Click to see Java code snippet
>
> ```java
> final Path mappingsFile = /* get path to mappings ... */;
> // ReflectionRemapper provides various static factory methods, in this example we use the one from a Path
> // Note that the standard ReflectionRemapper implementations store their mappings in memory, which can be multiple megabytes large in some cases.
> // This means it's best to use the remapper when your program starts and then dispose of any reference to it, so it can be garbage collected.
> final ReflectionRemapper reflectionRemapper = ReflectionRemapper.forMappings(mappingsFile, "fromNamespace", "toNamespace");
>
> final String runtimeName = reflectionRemapper.remapClassName("net.minecraft.server.level.ServerPlayer");
> final Class> serverPlayerClass = Class.forName(runtimeName); // Exception handling omitted for brevity
> final String runtimeFieldName = reflectionRemapper.remapFieldName(serverPlayerClass, "seenCredits");
> // ...
> ```
>### Reflection Proxies
A reflection proxy is a runtime generated implementation of a "reflection proxy interface", which uses cached `MethodHandle`s to invoke the targets specified by
the interface definition. Reflection proxies can also make use of a `ReflectionRemapper` on creation in order to allow them to work in a remapped (or not) environment.
The `ReflectionRemapper` on its own, while powerful, tends to make already verbose reflection code even more verbose. When combined with reflection proxies, we
can have relatively clean reflection code while still properly remapping.>
> Click to see Java code snippet
>
> #### Example target class
> ```java
> public final class ServerLevel {
> private SleepStatus sleepStatus;
>
> private BlockPos findLightningTargetAround(BlockPos pos) {
> // implementation
> }
> }
> ```
>
> #### Example reflection proxy interface
> ```java
> @Proxies(ServerLevel.class) // Can use Class or fully qualified class name (for inaccessible classes)
> private interface ServerLevelProxy {
> BlockPos findLightningTargetAround(ServerLevel instance, BlockPos pos);
>
> @FieldSetter("sleepStatus")
> void setSleepStatus(ServerLevel instance, SleepStatus value);
> }
> ```
>
> #### Creating and using reflection proxy instance
> ```java
> final ReflectionRemapper reflectionRemapper = /* get ReflectionRemapper ... */;
> final ClassLoader classLoader = /* get ClassLoader for loading proxy implementations, generally it needs to be able to see any reflection proxy interfaces you want to implement */;
> final ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper, classLoader); // ReflectionProxyFactory holds a ref to it's ReflectionRemapper
>
> // Generated proxy instances do not hold a ref to the ReflectionRemapper, and are fine to keep around.
> final ServerLevelProxy proxyInstance = reflectionProxyFactory.reflectionProxy(ServerLevelProxy.class);
>
> // ...
>
> final ServerLevel level = /* ... */;
> final BlockPos blockPos = /* ... */;
> final BlockPos target = proxyInstance.findLightningTargetAround(level, blockPos);
> proxyInstance.setSleepStatus(level, new SleepStatus());
> ```
>