diff --git a/legacy-1_17-compat/pom.xml b/legacy-1_17-compat/pom.xml
index 57ec9a9..578aa58 100644
--- a/legacy-1_17-compat/pom.xml
+++ b/legacy-1_17-compat/pom.xml
@@ -4,10 +4,10 @@
4.0.0
net.sourcewriters.spigot.rwg
legacy-1_17-compat
- 3.0.0
+ 4.0.0
- 3.0.0
+ 4.0.0
diff --git a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/Accessors.java b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/Accessors.java
new file mode 100644
index 0000000..0057187
--- /dev/null
+++ b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/Accessors.java
@@ -0,0 +1,19 @@
+package net.sourcewriters.spigot.rwg.legacy.api.impl;
+
+import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
+import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlockEntityState;
+import org.bukkit.craftbukkit.v1_17_R1.generator.CustomChunkGenerator;
+
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.Accessor;
+import net.sourcewriters.spigot.rwg.legacy.api.version.provider.VersionProvider;
+
+public final class Accessors {
+
+ private static final VersionProvider PROVIDER = VersionProvider.get();
+
+ public static final Accessor CUSTOM_CHUNK_GENERATOR = Accessor.of(CustomChunkGenerator.class).findField("generator", "generator");
+ public static final Accessor CRAFT_WORLD = Accessor.of(CraftWorld.class).findField("generator", "generator");
+ public static final Accessor CRAFT_BLOCK_ENTITY_STATE = Accessor.of(CraftBlockEntityState.class).findField("entity", "getTileEntity");
+ public static final Accessor CRAFT_META_SKULL = PROVIDER.craftBukkitAccess("inventory.CraftMetaSkull").findField("profile", "profile");
+
+}
diff --git a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
index 087b046..d2c8117 100644
--- a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
+++ b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
@@ -7,18 +7,12 @@
import com.mojang.authlib.GameProfile;
+import net.sourcewriters.spigot.rwg.legacy.api.impl.Accessors;
import net.sourcewriters.spigot.rwg.legacy.api.util.rwg.RWGMaterial;
import net.sourcewriters.spigot.rwg.legacy.api.version.IConversionAccess;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
public final class ConversionAccessImpl implements IConversionAccess {
- private final ClassLookupProvider provider;
-
- public ConversionAccessImpl(final ClassLookupProvider provider) {
- this.provider = provider;
- }
-
@Override
public Material asBukkit(final RWGMaterial material) {
switch (material) {
@@ -62,7 +56,7 @@ public boolean isGiantTree(final TreeType type) {
public ItemStack asHeadItem(final GameProfile profile) {
final ItemStack stack = new ItemStack(RWGMaterial.HEAD_ITEM.asBukkit(this));
final SkullMeta meta = (SkullMeta) stack.getItemMeta();
- provider.getLookup("cb_skull_meta").setFieldValue(meta, "profile", profile);
+ Accessors.CRAFT_META_SKULL.setValue(meta, "profile", profile);
stack.setItemMeta(meta);
return stack;
}
diff --git a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
index 47de58c..11bcd88 100644
--- a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
+++ b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
@@ -2,35 +2,25 @@
import com.syntaxphoenix.syntaxapi.logging.ILogger;
-import net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle.GlobalLookup;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsBiomeAccessImpl;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsNbtAccessImpl;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsWorldAccessImpl;
import net.sourcewriters.spigot.rwg.legacy.api.version.INmsAccess;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsBiomeAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsNbtAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsWorldAccess;
public final class NmsAccessImpl implements INmsAccess {
- private final ClassLookupProvider provider = new ClassLookupProvider(GlobalLookup::setup);
-
private final NmsNbtAccessImpl nbtAccess;
private final NmsBiomeAccessImpl biomeAccess;
private final NmsWorldAccessImpl worldAccess;
public NmsAccessImpl(final ILogger logger) {
nbtAccess = new NmsNbtAccessImpl();
- biomeAccess = new NmsBiomeAccessImpl(provider);
- worldAccess = new NmsWorldAccessImpl(provider);
+ biomeAccess = new NmsBiomeAccessImpl();
+ worldAccess = new NmsWorldAccessImpl();
}
-
- @Override
- public ClassLookupProvider getLookupProvider() {
- return provider;
- }
-
@Override
public INmsNbtAccess getNbtAccess() {
return nbtAccess;
diff --git a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
index a32c686..c7c6fb6 100644
--- a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
+++ b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
@@ -15,7 +15,7 @@ public final class VersionAccessImpl implements IVersionAccess {
public VersionAccessImpl(final ILogger logger) {
nmsAccess = new NmsAccessImpl(logger);
- conversionAccess = new ConversionAccessImpl(nmsAccess.getLookupProvider());
+ conversionAccess = new ConversionAccessImpl();
biomeAccess = new BiomeAccessImpl();
}
diff --git a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java
deleted file mode 100644
index 94bdd3b..0000000
--- a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
-
-import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
-import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlockEntityState;
-import org.bukkit.craftbukkit.v1_17_R1.generator.CustomChunkGenerator;
-import org.bukkit.generator.ChunkGenerator;
-
-import com.mojang.authlib.GameProfile;
-
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
-
-public final class GlobalLookup {
-
- private GlobalLookup() {}
-
- public static void setup(final ClassLookupProvider provider) {
-
- provider.createLookup("cb_world", CraftWorld.class).searchField("generator", "generator", ChunkGenerator.class);
- provider.createLookup("cb_generator", CustomChunkGenerator.class).searchField("generator", "generator", ChunkGenerator.class);
-
- provider.createLookup("cb_block_entity_state", CraftBlockEntityState.class).searchMethod("entity", "getTileEntity");
-
- provider.createLookup("cb_skull_meta", provider.getCBClass("inventory.CraftMetaSkull")).searchField("field", "field",
- GameProfile.class);
-
- }
-
-}
diff --git a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
index 304e760..5b514a5 100644
--- a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
+++ b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
@@ -10,13 +10,10 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsBiomeAccess;
public final class NmsBiomeAccessImpl implements INmsBiomeAccess {
- public NmsBiomeAccessImpl(final ClassLookupProvider _ignore) {}
-
@Override
public org.bukkit.block.Biome getBiomeAt(final World bukkitWorld, final int x, final int y, final int z) {
if (bukkitWorld == null) {
diff --git a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
index 97558e9..3a6b748 100644
--- a/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
+++ b/legacy-1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
@@ -11,19 +11,13 @@
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
+import net.sourcewriters.spigot.rwg.legacy.api.impl.Accessors;
import net.sourcewriters.spigot.rwg.legacy.api.util.minecraft.ProfileCache;
import net.sourcewriters.spigot.rwg.legacy.api.util.rwg.RWGEntityType;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsWorldAccess;
public final class NmsWorldAccessImpl implements INmsWorldAccess {
- private final ClassLookupProvider provider;
-
- public NmsWorldAccessImpl(final ClassLookupProvider provider) {
- this.provider = provider;
- }
-
@Override
public void setSpawner(final Block block, final EntityType type, final short spawnCount, final short spawnRange, final short delay,
final short maxDelay, final short minDelay, final short maxNearbyEntities, final short requiredPlayerRange) {
@@ -31,7 +25,7 @@ public void setSpawner(final Block block, final EntityType type, final short spa
if (!(blockState instanceof CreatureSpawner)) {
return;
}
- final SpawnerBlockEntity entity = (SpawnerBlockEntity) provider.getLookup("cb_block_entity_state").run(blockState, "entity");
+ final SpawnerBlockEntity entity = (SpawnerBlockEntity) Accessors.CRAFT_BLOCK_ENTITY_STATE.invoke(blockState, "entity");
final CompoundTag tag = entity.getUpdateTag();
tag.putShort("SpawnCount", spawnCount);
tag.putShort("SpawnRange", spawnRange);
@@ -53,7 +47,7 @@ public void setHeadTexture(final Block block, final String texture) {
return;
}
final GameProfile gameProfile = ProfileCache.asProfile(texture);
- final SkullBlockEntity entity = (SkullBlockEntity) provider.getLookup("cb_block_entity_state").run(blockState, "entity");
+ final SkullBlockEntity entity = (SkullBlockEntity) Accessors.CRAFT_BLOCK_ENTITY_STATE.invoke(blockState, "entity");
entity.setOwner(gameProfile);
}
@@ -64,7 +58,7 @@ public String getHeadTexture(final Block block) {
return null;
}
return ProfileCache
- .asTexture(((SkullBlockEntity) provider.getLookup("cb_block_entity_state").run(blockState, "entity")).getOwnerProfile());
+ .asTexture(((SkullBlockEntity) Accessors.CRAFT_BLOCK_ENTITY_STATE.invoke(blockState, "entity")).getOwnerProfile());
}
}
diff --git a/legacy-1_17-compat/src/main/resources/api.json b/legacy-1_17-compat/src/main/resources/api.json
index 2569489..a793b90 100644
--- a/legacy-1_17-compat/src/main/resources/api.json
+++ b/legacy-1_17-compat/src/main/resources/api.json
@@ -1,5 +1,5 @@
{
- "api": 3,
+ "api": 4,
"version": "${project.version}",
"minecraft": [
"1.17"
diff --git a/legacy-1_17_1-compat/pom.xml b/legacy-1_17_1-compat/pom.xml
index 65305f4..135d3a2 100644
--- a/legacy-1_17_1-compat/pom.xml
+++ b/legacy-1_17_1-compat/pom.xml
@@ -4,10 +4,10 @@
4.0.0
net.sourcewriters.spigot.rwg
legacy-1_17_1-compat
- 3.0.0
+ 4.0.0
- 3.0.0
+ 4.0.0
diff --git a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/Accessors.java b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/Accessors.java
new file mode 100644
index 0000000..c8ecb9c
--- /dev/null
+++ b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/Accessors.java
@@ -0,0 +1,19 @@
+package net.sourcewriters.spigot.rwg.legacy.api.impl;
+
+import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
+import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlockEntityState;
+import org.bukkit.craftbukkit.v1_17_R1.generator.CustomChunkGenerator;
+
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.Accessor;
+import net.sourcewriters.spigot.rwg.legacy.api.version.provider.VersionProvider;
+
+public final class Accessors {
+
+ private static final VersionProvider PROVIDER = VersionProvider.get();
+
+ public static final Accessor CUSTOM_CHUNK_GENERATOR = Accessor.of(CustomChunkGenerator.class).findField("generator", "generator");
+ public static final Accessor CRAFT_WORLD = Accessor.of(CraftWorld.class).findField("generator", "generator");
+ public static final Accessor CRAFT_BLOCK_ENTITY_STATE = Accessor.of(CraftBlockEntityState.class).findField("entity", "getTileEntity");
+ public static final Accessor CRAFT_META_SKULL = PROVIDER.craftBukkitAccess("inventory.CraftMetaSkull").findField("profile", "profile");
+
+}
\ No newline at end of file
diff --git a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
index 087b046..d2c8117 100644
--- a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
+++ b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
@@ -7,18 +7,12 @@
import com.mojang.authlib.GameProfile;
+import net.sourcewriters.spigot.rwg.legacy.api.impl.Accessors;
import net.sourcewriters.spigot.rwg.legacy.api.util.rwg.RWGMaterial;
import net.sourcewriters.spigot.rwg.legacy.api.version.IConversionAccess;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
public final class ConversionAccessImpl implements IConversionAccess {
- private final ClassLookupProvider provider;
-
- public ConversionAccessImpl(final ClassLookupProvider provider) {
- this.provider = provider;
- }
-
@Override
public Material asBukkit(final RWGMaterial material) {
switch (material) {
@@ -62,7 +56,7 @@ public boolean isGiantTree(final TreeType type) {
public ItemStack asHeadItem(final GameProfile profile) {
final ItemStack stack = new ItemStack(RWGMaterial.HEAD_ITEM.asBukkit(this));
final SkullMeta meta = (SkullMeta) stack.getItemMeta();
- provider.getLookup("cb_skull_meta").setFieldValue(meta, "profile", profile);
+ Accessors.CRAFT_META_SKULL.setValue(meta, "profile", profile);
stack.setItemMeta(meta);
return stack;
}
diff --git a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
index 47de58c..11bcd88 100644
--- a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
+++ b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
@@ -2,35 +2,25 @@
import com.syntaxphoenix.syntaxapi.logging.ILogger;
-import net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle.GlobalLookup;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsBiomeAccessImpl;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsNbtAccessImpl;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsWorldAccessImpl;
import net.sourcewriters.spigot.rwg.legacy.api.version.INmsAccess;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsBiomeAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsNbtAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsWorldAccess;
public final class NmsAccessImpl implements INmsAccess {
- private final ClassLookupProvider provider = new ClassLookupProvider(GlobalLookup::setup);
-
private final NmsNbtAccessImpl nbtAccess;
private final NmsBiomeAccessImpl biomeAccess;
private final NmsWorldAccessImpl worldAccess;
public NmsAccessImpl(final ILogger logger) {
nbtAccess = new NmsNbtAccessImpl();
- biomeAccess = new NmsBiomeAccessImpl(provider);
- worldAccess = new NmsWorldAccessImpl(provider);
+ biomeAccess = new NmsBiomeAccessImpl();
+ worldAccess = new NmsWorldAccessImpl();
}
-
- @Override
- public ClassLookupProvider getLookupProvider() {
- return provider;
- }
-
@Override
public INmsNbtAccess getNbtAccess() {
return nbtAccess;
diff --git a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
index a32c686..c7c6fb6 100644
--- a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
+++ b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
@@ -15,7 +15,7 @@ public final class VersionAccessImpl implements IVersionAccess {
public VersionAccessImpl(final ILogger logger) {
nmsAccess = new NmsAccessImpl(logger);
- conversionAccess = new ConversionAccessImpl(nmsAccess.getLookupProvider());
+ conversionAccess = new ConversionAccessImpl();
biomeAccess = new BiomeAccessImpl();
}
diff --git a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java
deleted file mode 100644
index 94bdd3b..0000000
--- a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
-
-import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
-import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlockEntityState;
-import org.bukkit.craftbukkit.v1_17_R1.generator.CustomChunkGenerator;
-import org.bukkit.generator.ChunkGenerator;
-
-import com.mojang.authlib.GameProfile;
-
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
-
-public final class GlobalLookup {
-
- private GlobalLookup() {}
-
- public static void setup(final ClassLookupProvider provider) {
-
- provider.createLookup("cb_world", CraftWorld.class).searchField("generator", "generator", ChunkGenerator.class);
- provider.createLookup("cb_generator", CustomChunkGenerator.class).searchField("generator", "generator", ChunkGenerator.class);
-
- provider.createLookup("cb_block_entity_state", CraftBlockEntityState.class).searchMethod("entity", "getTileEntity");
-
- provider.createLookup("cb_skull_meta", provider.getCBClass("inventory.CraftMetaSkull")).searchField("field", "field",
- GameProfile.class);
-
- }
-
-}
diff --git a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
index 304e760..5b514a5 100644
--- a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
+++ b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
@@ -10,13 +10,10 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsBiomeAccess;
public final class NmsBiomeAccessImpl implements INmsBiomeAccess {
- public NmsBiomeAccessImpl(final ClassLookupProvider _ignore) {}
-
@Override
public org.bukkit.block.Biome getBiomeAt(final World bukkitWorld, final int x, final int y, final int z) {
if (bukkitWorld == null) {
diff --git a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
index 97558e9..3a6b748 100644
--- a/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
+++ b/legacy-1_17_1-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
@@ -11,19 +11,13 @@
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
+import net.sourcewriters.spigot.rwg.legacy.api.impl.Accessors;
import net.sourcewriters.spigot.rwg.legacy.api.util.minecraft.ProfileCache;
import net.sourcewriters.spigot.rwg.legacy.api.util.rwg.RWGEntityType;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsWorldAccess;
public final class NmsWorldAccessImpl implements INmsWorldAccess {
- private final ClassLookupProvider provider;
-
- public NmsWorldAccessImpl(final ClassLookupProvider provider) {
- this.provider = provider;
- }
-
@Override
public void setSpawner(final Block block, final EntityType type, final short spawnCount, final short spawnRange, final short delay,
final short maxDelay, final short minDelay, final short maxNearbyEntities, final short requiredPlayerRange) {
@@ -31,7 +25,7 @@ public void setSpawner(final Block block, final EntityType type, final short spa
if (!(blockState instanceof CreatureSpawner)) {
return;
}
- final SpawnerBlockEntity entity = (SpawnerBlockEntity) provider.getLookup("cb_block_entity_state").run(blockState, "entity");
+ final SpawnerBlockEntity entity = (SpawnerBlockEntity) Accessors.CRAFT_BLOCK_ENTITY_STATE.invoke(blockState, "entity");
final CompoundTag tag = entity.getUpdateTag();
tag.putShort("SpawnCount", spawnCount);
tag.putShort("SpawnRange", spawnRange);
@@ -53,7 +47,7 @@ public void setHeadTexture(final Block block, final String texture) {
return;
}
final GameProfile gameProfile = ProfileCache.asProfile(texture);
- final SkullBlockEntity entity = (SkullBlockEntity) provider.getLookup("cb_block_entity_state").run(blockState, "entity");
+ final SkullBlockEntity entity = (SkullBlockEntity) Accessors.CRAFT_BLOCK_ENTITY_STATE.invoke(blockState, "entity");
entity.setOwner(gameProfile);
}
@@ -64,7 +58,7 @@ public String getHeadTexture(final Block block) {
return null;
}
return ProfileCache
- .asTexture(((SkullBlockEntity) provider.getLookup("cb_block_entity_state").run(blockState, "entity")).getOwnerProfile());
+ .asTexture(((SkullBlockEntity) Accessors.CRAFT_BLOCK_ENTITY_STATE.invoke(blockState, "entity")).getOwnerProfile());
}
}
diff --git a/legacy-1_17_1-compat/src/main/resources/api.json b/legacy-1_17_1-compat/src/main/resources/api.json
index 5e82a58..266fee0 100644
--- a/legacy-1_17_1-compat/src/main/resources/api.json
+++ b/legacy-1_17_1-compat/src/main/resources/api.json
@@ -1,5 +1,5 @@
{
- "api": 3,
+ "api": 4,
"version": "${project.version}",
"minecraft": [
"1.17.1"
diff --git a/legacy-api/pom.xml b/legacy-api/pom.xml
index f84f9b1..440e7cb 100644
--- a/legacy-api/pom.xml
+++ b/legacy-api/pom.xml
@@ -4,7 +4,7 @@
4.0.0
net.sourcewriters.spigot.rwg
legacy-api
- 3.0.1
+ 4.0.0
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/compatibility/AddonIncompatibleException.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/compatibility/AddonIncompatibleException.java
index 054208b..3246312 100644
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/compatibility/AddonIncompatibleException.java
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/compatibility/AddonIncompatibleException.java
@@ -1,6 +1,6 @@
package net.sourcewriters.spigot.rwg.legacy.api.compatibility;
-import net.sourcewriters.spigot.rwg.legacy.api.util.java.Tracker;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.JavaTracker;
public class AddonIncompatibleException extends RuntimeException {
@@ -34,7 +34,7 @@ public AddonIncompatibleException(final String message) {
* @param versions the compatible versions of this plugin
*/
public AddonIncompatibleException(final IPluginPackage pluginPackage, final String... versions) {
- super(pluginPackage.getName() + " is not compatible with the " + Tracker.getClassFromStack(1).map(Class::getName).orElse(null)
+ super(pluginPackage.getName() + " is not compatible with the " + JavaTracker.getClassFromStack(1).map(Class::getName).orElse(null)
+ " addon. Please use one of the following versions instead: " + String.join(", ", versions));
}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/generator/forward/ForwardHelper.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/generator/forward/ForwardHelper.java
index 19ce1a9..bc36b25 100644
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/generator/forward/ForwardHelper.java
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/generator/forward/ForwardHelper.java
@@ -2,6 +2,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import org.bukkit.World;
@@ -9,13 +10,11 @@
import org.bukkit.generator.ChunkGenerator;
import net.sourcewriters.spigot.rwg.legacy.api.generator.IRwgGenerator;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookup;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupCache;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.Accessor;
public final class ForwardHelper {
- private static final ClassLookupCache CACHE = ClassLookupProvider.DEFAULT.getCache();
+ private static final ConcurrentHashMap ACCESSORS = new ConcurrentHashMap<>();
private static final ArrayList LIST = new ArrayList<>();
private ForwardHelper() {}
@@ -27,17 +26,17 @@ public static boolean isForward(final ChunkGenerator generator) {
final Class> clazz = generator.getClass();
final String name = clazz.getName();
if (LIST.contains(name)) {
- return CACHE.get(name).isPresent();
+ return ACCESSORS.containsKey(name);
}
- final ClassLookup lookup = CACHE.create(name, clazz);
- final Object object = lookup.searchMethod("id", "getIdentifier").run(generator, "id");
+ final Accessor access = Accessor.of(clazz);
+ final Object object = access.findMethod("id", "getIdentifier").invoke(generator, "id");
final boolean valid = object != null && (long) object == 345679324062398605L;
LIST.add(name);
if (!valid) {
- CACHE.delete(name);
return false;
}
- lookup.searchMethod("set", "setGenerator", ChunkGenerator.class).searchMethod("get", "getGenerator").searchMethod("populators",
+ ACCESSORS.put(name, access);
+ access.findMethod("set", "setGenerator", ChunkGenerator.class).findMethod("get", "getGenerator").findMethod("populators",
"setPopulators", BlockPopulator[].class);
return valid;
}
@@ -50,7 +49,7 @@ public static IRwgGenerator get(final ChunkGenerator generator) {
if (!isForward(generator)) {
return null;
}
- final Object found = CACHE.get(generator.getClass().getName()).orElse(null).run(generator, "get");
+ final Object found = ACCESSORS.get(generator.getClass().getName()).invoke(generator, "get");
return found instanceof IRwgGenerator ? (IRwgGenerator) found : null;
}
@@ -63,10 +62,10 @@ public static boolean set(final World world, final Function list = generator.getDefaultPopulators(world);
- lookup.run(current, "populators",
+ access.invoke(current, "populators",
(Object) (list == null ? new BlockPopulator[0] : list.stream().filter(obj -> obj != null).toArray(BlockPopulator[]::new)));
return true;
}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/RandomAdapter.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/RandomAdapter.java
index 57c8074..c1dd891 100644
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/RandomAdapter.java
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/RandomAdapter.java
@@ -1,15 +1,16 @@
package net.sourcewriters.spigot.rwg.legacy.api.util.java;
+import java.lang.reflect.Field;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
import com.syntaxphoenix.syntaxapi.random.RandomNumberGenerator;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookup;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.JavaAccess;
public final class RandomAdapter extends RandomNumberGenerator {
- private static final ClassLookup LOOKUP = ClassLookup.of(Random.class).searchField("seed", "seed", AtomicLong.class);
+ private static final Field SEED_FIELD = JavaAccess.getField(Random.class, "seed");
private final Random random;
private final AtomicLong seedState;
@@ -18,7 +19,7 @@ public final class RandomAdapter extends RandomNumberGenerator {
public RandomAdapter(final Random random) {
this.random = random;
- this.seedState = (AtomicLong) LOOKUP.getFieldValue(random, "seed");
+ this.seedState = (AtomicLong) JavaAccess.getValue(random, SEED_FIELD);
}
@Override
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/Accessor.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/Accessor.java
new file mode 100644
index 0000000..902867d
--- /dev/null
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/Accessor.java
@@ -0,0 +1,363 @@
+package net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.syntaxphoenix.syntaxapi.reflection.ReflectionTools;
+
+public final class Accessor {
+
+ public static final Accessor INVALID = new Accessor();
+
+ static final AccessorCache CACHE = new AccessorCache();
+
+ public static Accessor of(Class> owner) {
+ return CACHE.get(owner);
+ }
+
+ public static Accessor ofNullable(Class> owner) {
+ if (owner == null) {
+ return INVALID;
+ }
+ return CACHE.get(owner);
+ }
+
+ private final Class> owner;
+
+ private final ConcurrentHashMap methods = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap fields = new ConcurrentHashMap<>();
+
+ private Accessor() {
+ this.owner = null;
+ }
+
+ Accessor(Class> owner) {
+ this.owner = Objects.requireNonNull(owner);
+ }
+
+ /*
+ * Management
+ */
+
+ public boolean valid() {
+ return owner != null;
+ }
+
+ public void delete() {
+ if (valid()) {
+ CACHE.delete(owner);
+ }
+ clear();
+ }
+
+ public Class> getOwner() {
+ return owner;
+ }
+
+ public Collection getMethods() {
+ return methods.values();
+ }
+
+ public Collection getFields() {
+ return fields.values();
+ }
+
+ public List getMethods(final String baseName) {
+ String base = baseName + '#';
+ int index = 0;
+ ArrayList methods = new ArrayList<>();
+ String name;
+ while (this.methods.containsKey(name = base + (index++))) {
+ methods.add(this.methods.get(name));
+ }
+ return methods;
+ }
+
+ public List getFields(final String baseName) {
+ String base = baseName + '#';
+ int index = 0;
+ ArrayList fields = new ArrayList<>();
+ String name;
+ while (this.fields.containsKey(name = base + (index++))) {
+ fields.add(this.fields.get(name));
+ }
+ return fields;
+ }
+
+ public Method getMethod(String name) {
+ return methods.get(name);
+ }
+
+ public Field getField(String name) {
+ return fields.get(name);
+ }
+
+ public boolean hasMethod(final String name) {
+ return methods.containsKey(name);
+ }
+
+ public boolean hasField(final String name) {
+ return fields.containsKey(name);
+ }
+
+ public void putMethod(final String name, final Method method) {
+ if (!valid() || methods.containsKey(name) || !method.getDeclaringClass().isAssignableFrom(owner)) {
+ return;
+ }
+ methods.put(name, method);
+ }
+
+ public void putField(final String name, final Field field) {
+ if (!valid() || fields.containsKey(name) || !field.getDeclaringClass().isAssignableFrom(owner)) {
+ return;
+ }
+ fields.put(name, field);
+ }
+
+ public void removeMethod(final String name) {
+ methods.remove(name);
+ }
+
+ public void removeField(final String name) {
+ fields.remove(name);
+ }
+
+ public void clear() {
+ methods.clear();
+ fields.clear();
+ }
+
+ public void clearMethods() {
+ methods.clear();
+ }
+
+ public void clearFields() {
+ fields.clear();
+ }
+
+ /*
+ * Reflections
+ */
+
+ public Class> findNestedClass(final String name) {
+ if (!valid()) {
+ return null;
+ }
+ return JavaAccess.findClass(owner, name);
+ }
+
+ public Constructor> findConstructor(final Class>... parameters) {
+ if (!valid()) {
+ return null;
+ }
+ return JavaAccess.getConstructor(owner, parameters);
+ }
+
+ public Object initialize(Object... arguments) {
+ if (!valid()) {
+ return null;
+ }
+ return InstanceBuilder.create(owner, arguments);
+ }
+
+ public Object initializeVersionExact(Object... arguments) {
+ if (!valid()) {
+ return null;
+ }
+ return InstanceBuilder.buildExact(owner).orElse(null);
+ }
+
+ public Object initializeVersionBelow(Object... arguments) {
+ if (!valid()) {
+ return null;
+ }
+ return InstanceBuilder.buildBelow(owner).orElse(null);
+ }
+
+ public Object getValue(final String name) {
+ return getValue(null, name);
+ }
+
+ public Object getValue(final Object instance, final String name) {
+ Field field = fields.get(name);
+ if (field == null) {
+ return null;
+ }
+ if (Modifier.isStatic(field.getModifiers())) {
+ return JavaAccess.getStaticValue(field);
+ }
+ if (instance == null) {
+ return null;
+ }
+ return JavaAccess.getObjectValue(instance, fields.get(name));
+ }
+
+ public void setValue(final String name, final Object value) {
+ setValue(null, name, value);
+ }
+
+ public void setValue(final Object instance, final String name, final Object value) {
+ Field field = fields.get(name);
+ if (field == null) {
+ return;
+ }
+ if (Modifier.isStatic(field.getModifiers())) {
+ JavaAccess.setStaticValue(field, value);
+ return;
+ }
+ if (instance == null) {
+ return;
+ }
+ JavaAccess.setObjectValue(instance, field, value);
+ }
+
+ public Object invoke(final String name, final Object... arguments) {
+ return invoke(null, name, arguments);
+ }
+
+ public Object invoke(final Object instance, final String name, final Object... arguments) {
+ Method method = methods.get(name);
+ if (method == null || method.getParameterCount() != arguments.length) {
+ return null;
+ }
+ if (Modifier.isStatic(method.getModifiers())) {
+ return JavaAccess.invokeStatic(method, arguments);
+ }
+ if (instance == null) {
+ return null;
+ }
+ return JavaAccess.invoke(instance, method, arguments);
+ }
+
+ /*
+ * Search
+ */
+
+ public Accessor findMethod(final String name, final String methodName, final Class>... parameters) {
+ if (!valid() || methods.containsKey(name)) {
+ return this;
+ }
+ Method method = JavaAccess.getMethod(owner, methodName, parameters);
+ if (method != null) {
+ methods.put(name, method);
+ }
+ return this;
+ }
+
+ public Accessor findMethod(final String name, final Class>... parameters) {
+ return findMethod(name, 0, parameters);
+ }
+
+ public Accessor findMethod(final String name, int index, final Class>... parameters) {
+ if (!valid() || methods.containsKey(name)) {
+ return this;
+ }
+ Method[] methods = JavaAccess.getMethods(owner);
+ if (methods.length == 0) {
+ return this;
+ }
+ int idx = 0;
+ for (final Method method : methods) {
+ Class>[] methodParameters = method.getParameterTypes();
+ if (methodParameters.length != parameters.length || !ReflectionTools.hasSameArguments(methodParameters, parameters)) {
+ continue;
+ }
+ if (idx++ != index) {
+ continue;
+ }
+ this.methods.put(name, method);
+ }
+ return this;
+ }
+
+ public Accessor findMethods(final String baseName, final Class>... parameters) {
+ if (!valid()) {
+ return this;
+ }
+ Method[] methods = JavaAccess.getMethods(owner);
+ if (methods.length == 0) {
+ return this;
+ }
+ String base = baseName + '#';
+ int index = 0;
+ for (final Method method : methods) {
+ Class>[] methodParameters = method.getParameterTypes();
+ if (methodParameters.length != parameters.length || !ReflectionTools.hasSameArguments(methodParameters, parameters)) {
+ continue;
+ }
+ String name = base + (index++);
+ if (this.methods.containsKey(name)) {
+ continue;
+ }
+ this.methods.put(name, method);
+ }
+ return this;
+ }
+
+ public Accessor findField(final String name, final String fieldName) {
+ if (!valid() || fields.containsKey(name)) {
+ return this;
+ }
+ Field field = JavaAccess.getField(owner, fieldName);
+ if (field != null) {
+ fields.put(name, field);
+ }
+ return this;
+ }
+
+ public Accessor findField(final String name, final Class> type) {
+ return findField(name, 0, type);
+ }
+
+ public Accessor findField(final String name, int index, final Class> type) {
+ if (!valid() || this.fields.containsKey(name)) {
+ return this;
+ }
+ Field[] fields = JavaAccess.getFields(owner);
+ if (fields.length == 0) {
+ return this;
+ }
+ int idx = 0;
+ for (final Field field : fields) {
+ if (!field.getType().equals(type)) {
+ continue;
+ }
+ if (idx++ != index) {
+ continue;
+ }
+ this.fields.put(name, field);
+ }
+ return this;
+ }
+
+ public Accessor findFields(final String baseName, final Class> type) {
+ if (!valid()) {
+ return this;
+ }
+ Field[] fields = JavaAccess.getFields(owner);
+ if (fields.length == 0) {
+ return this;
+ }
+ String base = baseName + '#';
+ int index = 0;
+ for (final Field field : fields) {
+ if (!field.getType().equals(type)) {
+ continue;
+ }
+ String name = base + (index++);
+ if (this.fields.containsKey(name)) {
+ continue;
+ }
+ this.fields.put(name, field);
+ }
+ return this;
+ }
+
+}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/AccessorCache.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/AccessorCache.java
new file mode 100644
index 0000000..145d871
--- /dev/null
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/AccessorCache.java
@@ -0,0 +1,55 @@
+package net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect;
+
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+
+final class AccessorCache {
+
+ private final ConcurrentHashMap, Accessor> accessors = new ConcurrentHashMap<>();
+ private final ArrayList providers = new ArrayList<>();
+
+ AccessorCache() {}
+
+ final void listen(AccessorProvider provider) {
+ if (providers.contains(provider)) {
+ providers.remove(provider);
+ return;
+ }
+ providers.add(provider);
+ }
+
+ public final Accessor get(Class> owner) {
+ return accessors.computeIfAbsent(owner, Accessor::new);
+ }
+
+ public final void delete(Class> owner) {
+ accessors.remove(owner);
+ for (AccessorProvider provider : providers) {
+ provider.remove(owner);
+ }
+ }
+
+ public final void clear(ClassLoader loader) {
+ ArrayList> classes = new ArrayList<>();
+ for (Class> clazz : accessors.keySet()) {
+ if (!clazz.getClassLoader().equals(loader)) {
+ continue;
+ }
+ classes.add(clazz);
+ }
+ for (Class> clazz : classes) {
+ accessors.remove(clazz);
+ for (AccessorProvider provider : providers) {
+ provider.remove(clazz);
+ }
+ }
+ }
+
+ public final void clear() {
+ accessors.clear();
+ for (AccessorProvider provider : providers) {
+ provider.clear();
+ }
+ }
+
+}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/AccessorProvider.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/AccessorProvider.java
new file mode 100644
index 0000000..2b794ea
--- /dev/null
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/AccessorProvider.java
@@ -0,0 +1,60 @@
+package net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect;
+
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
+public final class AccessorProvider {
+
+ private boolean deleted = false;
+
+ private final ConcurrentHashMap, String> names = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap accessors = new ConcurrentHashMap<>();
+
+ public AccessorProvider() {
+ Accessor.CACHE.listen(this);
+ }
+
+ public void delete() {
+ if (deleted) {
+ return;
+ }
+ deleted = true;
+ Accessor.CACHE.listen(this);
+ clear();
+ }
+
+ public Optional get(String name) {
+ return Optional.ofNullable(accessors.get(name));
+ }
+
+ public Accessor getOrNull(String name) {
+ return accessors.get(name);
+ }
+
+ public Accessor create(String name, Class> clazz) {
+ Accessor accessor = accessors.get(name);
+ if (accessor != null) {
+ return accessor;
+ }
+ if (clazz == null) {
+ return Accessor.INVALID;
+ }
+ accessors.put(name, accessor = Accessor.of(clazz));
+ names.put(clazz, name);
+ return accessor;
+ }
+
+ void clear() {
+ names.clear();
+ accessors.clear();
+ }
+
+ void remove(Class> owner) {
+ String name = names.remove(owner);
+ if (name == null) {
+ return;
+ }
+ accessors.remove(name);
+ }
+
+}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/InstanceBuilder.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/InstanceBuilder.java
similarity index 77%
rename from legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/InstanceBuilder.java
rename to legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/InstanceBuilder.java
index 17225ab..b72da4f 100644
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/InstanceBuilder.java
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/InstanceBuilder.java
@@ -1,11 +1,8 @@
-package net.sourcewriters.spigot.rwg.legacy.api.util.java;
+package net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect;
import java.lang.reflect.Constructor;
import java.util.Optional;
-import com.syntaxphoenix.syntaxapi.utils.java.Arrays;
-
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookup;
import net.sourcewriters.spigot.rwg.legacy.api.version.util.ServerVersion;
import net.sourcewriters.spigot.rwg.legacy.api.version.util.Versions;
@@ -13,7 +10,7 @@ public final class InstanceBuilder {
private InstanceBuilder() {}
- public static Optional buildBelow(final Class abstraction) {
+ public static Optional buildBelow(final Class abstraction, final Object... arguments) {
final ServerVersion server = Versions.getServer();
final int major = server.getMajor();
Optional> optional = Optional.empty();
@@ -27,17 +24,14 @@ public static Optional buildBelow(final Class abstraction) {
if (optional.isEmpty()) {
return Optional.empty();
}
- final ClassLookup lookup = ClassLookup.of(optional.get());
- final Object object = lookup.init();
+ final Object object = create(optional.get(), arguments);
if (object == null) {
- lookup.delete();
return Optional.empty();
}
- lookup.delete();
return Optional.of(abstraction.cast(object));
}
- public static Optional buildExact(final Class abstraction) {
+ public static Optional buildExact(final Class abstraction, final Object... arguments) {
final ServerVersion server = Versions.getServer();
final int major = server.getMajor();
final int minor = server.getMinor();
@@ -46,13 +40,10 @@ public static Optional buildExact(final Class abstraction) {
if (optional.isEmpty()) {
return Optional.empty();
}
- final ClassLookup lookup = ClassLookup.of(optional.get());
- final Object object = lookup.init();
+ final Object object = create(optional.get(), arguments);
if (object == null) {
- lookup.delete();
return Optional.empty();
}
- lookup.delete();
return Optional.of(abstraction.cast(object));
}
@@ -64,8 +55,11 @@ private static Optional> loadClass(final Class> search, final String
}
}
- public static T create(final Class clazz, final Object... arguments) throws Exception {
- final Constructor>[] constructors = Arrays.merge(Constructor[]::new, clazz.getConstructors(), clazz.getDeclaredConstructors());
+ public static T create(final Class clazz, final Object... arguments) {
+ if (arguments.length == 0) {
+ return clazz.cast(JavaAccess.instance(clazz));
+ }
+ final Constructor>[] constructors = JavaAccess.getConstructors(clazz);
final Class>[] classes = new Class>[arguments.length];
for (int index = 0; index < arguments.length; index++) {
classes[index] = arguments[index].getClass();
@@ -87,7 +81,7 @@ public static T create(final Class clazz, final Object... arguments) thro
int tmpArgs = 0;
for (int index = 0; index < count; index++) {
for (int idx = 0; idx < max; idx++) {
- if (!types[index].isAssignableFrom(classes[idx])) {
+ if (!types[index].equals(classes[idx])) {
continue;
}
tmpIdx[idx] = index;
@@ -97,25 +91,24 @@ public static T create(final Class clazz, final Object... arguments) thro
if (tmpArgs != count) {
continue;
}
- args = tmpArgs;
argIdx = tmpIdx;
+ args = tmpArgs;
builder = constructor;
}
if (builder == null) {
return null;
}
if (args == 0) {
- return clazz.cast(builder.newInstance());
+ return clazz.cast(JavaAccess.instance(builder));
}
final Object[] parameters = new Object[args];
- final Class>[] types = builder.getParameterTypes();
for (int idx = 0; idx < max; idx++) {
if (argIdx[idx] == -1) {
continue;
}
- parameters[argIdx[idx]] = types[argIdx[idx]].cast(arguments[idx]);
+ parameters[argIdx[idx]] = arguments[idx];
}
- return clazz.cast(builder.newInstance(parameters));
+ return clazz.cast(JavaAccess.instance(builder, parameters));
}
}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/JavaAccess.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/JavaAccess.java
new file mode 100644
index 0000000..65640b5
--- /dev/null
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/JavaAccess.java
@@ -0,0 +1,724 @@
+package net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect;
+
+import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.VarHandle;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+
+import sun.misc.Unsafe;
+
+public final class JavaAccess {
+
+ private static final JavaAccess INSTANCE = new JavaAccess();
+
+ private Unsafe unsafe;
+ private Lookup lookup;
+
+ private JavaAccess() {
+ final Optional> option = JavaTracker.getCallerClass();
+ if (option.isEmpty() || option.get() != JavaAccess.class) {
+ throw new UnsupportedOperationException("Utility class");
+ }
+ }
+
+ public Unsafe unsafe() {
+ if (unsafe != null) {
+ return unsafe;
+ }
+ try {
+ final Field field = Unsafe.class.getDeclaredField("theUnsafe");
+ field.setAccessible(true);
+ return unsafe = (Unsafe) field.get(null);
+ } catch (final Exception exp) {
+ return null;
+ }
+ }
+
+ public Lookup lookup() {
+ if (lookup != null) {
+ return lookup;
+ }
+ return lookup = (Lookup) getStaticValueUnsafe(getField(Lookup.class, "IMPL_LOOKUP"));
+ }
+
+ /*
+ * Method invokation
+ */
+
+ public Object execute(final Object instance, final Method method, final Object... arguments) {
+ if (method == null || method.getParameterCount() != arguments.length) {
+ return null;
+ }
+ try {
+ return executeThrows(instance, method, arguments);
+ } catch (final Throwable e) {
+ return null;
+ }
+ }
+
+ public Object executeThrows(final Object instance, final Method method, final Object... arguments) throws Throwable {
+ if (method == null || method.getParameterCount() != arguments.length) {
+ return null;
+ }
+ if (!Modifier.isStatic(method.getModifiers())) {
+ if (instance == null) {
+ return null;
+ }
+ if (arguments.length == 0) {
+ return lookup().unreflect(method).invokeWithArguments(instance);
+ }
+ final Object[] input = new Object[arguments.length + 1];
+ input[0] = instance;
+ System.arraycopy(arguments, 0, input, 1, arguments.length);
+ return lookup().unreflect(method).invokeWithArguments(input);
+ }
+ return lookup().unreflect(method).invokeWithArguments(arguments);
+ }
+
+ public Object init(final Constructor> constructor, final Object... arguments) {
+ if (constructor == null || constructor.getParameterCount() != arguments.length) {
+ return null;
+ }
+ try {
+ return lookup().unreflectConstructor(constructor).invokeWithArguments(arguments);
+ } catch (final Throwable e) {
+ return null;
+ }
+ }
+
+ /*
+ * Safe Accessors
+ */
+
+ public VarHandle handle(final Field field, final boolean force) {
+ if (field == null) {
+ return null;
+ }
+ if (force) {
+ unfinalize(field);
+ }
+ try {
+ return lookup().unreflectVarHandle(field);
+ } catch (final Throwable e) {
+ return null;
+ }
+ }
+
+ public MethodHandle handleGetter(final Field field) {
+ if (field == null) {
+ return null;
+ }
+ try {
+ return lookup().unreflectGetter(field);
+ } catch (final Throwable e) {
+ return null;
+ }
+ }
+
+ public MethodHandle handleSetter(final Field field) {
+ if (field == null) {
+ return null;
+ }
+ unfinalize(field);
+ try {
+ return lookup().unreflectSetter(field);
+ } catch (final Throwable e) {
+ return null;
+ }
+ }
+
+ public MethodHandle handle(final Method method) {
+ if (method == null) {
+ return null;
+ }
+ try {
+ return lookup().unreflect(method);
+ } catch (final Throwable e) {
+ return null;
+ }
+ }
+
+ public MethodHandle handle(final Constructor> constructor) {
+ if (constructor == null) {
+ return null;
+ }
+ try {
+ return lookup().unreflectConstructor(constructor);
+ } catch (final Throwable e) {
+ return null;
+ }
+ }
+
+ /*
+ * Safe Accessors helper
+ */
+
+ public Object executeSafe(final Object instance, final MethodHandle handle, final Object... arguments) {
+ if (handle == null || handle.type().parameterCount() != arguments.length) {
+ return null;
+ }
+ try {
+ if (instance != null) {
+ if (arguments.length == 0) {
+ return handle.invokeWithArguments(instance);
+ }
+ final Object[] input = new Object[arguments.length + 1];
+ input[0] = instance;
+ System.arraycopy(arguments, 0, input, 1, arguments.length);
+ return handle.invokeWithArguments(input);
+ }
+ return handle.invokeWithArguments(arguments);
+ } catch (final Throwable e) {
+ return null;
+ }
+ }
+
+ public Object getValueSafe(final Object instance, final VarHandle handle) {
+ if (handle == null) {
+ return null;
+ }
+ try {
+ if (instance == null) {
+ return handle.getVolatile();
+ }
+ return handle.getVolatile(instance);
+ } catch (final Throwable e) {
+ throw new AccessUnsuccessful();
+ }
+ }
+
+ public void setValueSafe(final Object instance, final VarHandle handle, final Object value) {
+ if (handle == null || value != null && !handle.varType().isAssignableFrom(value.getClass())) {
+ return;
+ }
+ try {
+ if (instance != null) {
+ handle.setVolatile(value);
+ return;
+ }
+ handle.setVolatile(instance, value);
+ } catch (final Throwable e) {
+ throw new AccessUnsuccessful();
+ }
+ }
+
+ /*
+ * Safe Field Modifier
+ */
+
+ public Object getObjectValueSafe(final Object instance, final Field field) {
+ if (instance == null || field == null) {
+ return null;
+ }
+ try {
+ return lookup().unreflectVarHandle(field).get(instance);
+ } catch (final Throwable e) {
+ throw new AccessUnsuccessful();
+ }
+ }
+
+ public Object getStaticValueSafe(final Field field) {
+ if (field == null) {
+ return null;
+ }
+ try {
+ return lookup().unreflectVarHandle(field).get();
+ } catch (final Throwable e) {
+ throw new AccessUnsuccessful();
+ }
+ }
+
+ public void setObjectValueSafe(final Object instance, final Field field, final Object value) {
+ if (instance == null || field == null) {
+ return;
+ }
+ unfinalize(field);
+ try {
+ lookup().unreflectVarHandle(field).set(instance, value);
+ } catch (final Throwable e) {
+ throw new AccessUnsuccessful();
+ }
+ }
+
+ public void setStaticValueSafe(final Field field, final Object value) {
+ if (field == null) {
+ return;
+ }
+ unfinalize(field);
+ try {
+ lookup().unreflectVarHandle(field).set(value);
+ } catch (final Throwable e) {
+ throw new AccessUnsuccessful();
+ }
+ }
+
+ /*
+ * Unsafe Field Modifier
+ */
+
+ public Object getObjectValueUnsafe(final Object instance, final Field field) {
+ if (instance == null || field == null) {
+ return null;
+ }
+ final Unsafe unsafe = unsafe();
+ return unsafe.getObjectVolatile(instance, unsafe.objectFieldOffset(field));
+ }
+
+ public Object getStaticValueUnsafe(final Field field) {
+ if (field == null) {
+ return null;
+ }
+ final Unsafe unsafe = unsafe();
+ return unsafe.getObjectVolatile(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
+ }
+
+ public void setObjectValueUnsafe(final Object instance, final Field field, final Object value) {
+ if (instance == null || field == null) {
+ return;
+ }
+ unfinalize(field);
+ final Unsafe unsafe = unsafe();
+ if (value == null) {
+ unsafe.putObject(instance, unsafe.objectFieldOffset(field), null);
+ return;
+ }
+ unsafe.putObject(instance, unsafe.objectFieldOffset(field), field.getType().cast(value));
+ }
+
+ public void setStaticValueUnsafe(final Field field, final Object value) {
+ if (field == null) {
+ return;
+ }
+ unfinalize(field);
+ final Unsafe unsafe = unsafe();
+ if (value == null) {
+ unsafe.putObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field), null);
+ return;
+ }
+ unsafe.putObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field), field.getType().cast(value));
+ }
+
+ /*
+ * Internal Utilities
+ */
+
+ private void unfinalize(final Field field) {
+ if (!Modifier.isFinal(field.getModifiers())) {
+ return;
+ }
+ try {
+ lookup().findSetter(Field.class, "modifiers", int.class).invokeExact(field, field.getModifiers() & ~Modifier.FINAL);
+ } catch (final Throwable e) {
+ // Ignore
+ }
+ }
+
+ /*
+ * Static Accessors Helper
+ */
+
+ public static Object getStaticValue(final VarHandle handle) {
+ return INSTANCE.getValueSafe(null, handle);
+ }
+
+ public static Object getValue(final Object instance, final VarHandle handle) {
+ return INSTANCE.getValueSafe(instance, handle);
+ }
+
+ public static void setStaticValue(final VarHandle handle, final Object value) {
+ INSTANCE.setValueSafe(null, handle, value);
+ }
+
+ public static void setValue(final Object instance, final VarHandle handle, final Object value) {
+ INSTANCE.setValueSafe(instance, handle, value);
+ }
+
+ public static Object invokeStatic(final MethodHandle handle, final Object... arguments) {
+ return INSTANCE.executeSafe(null, handle, arguments);
+ }
+
+ public static Object invoke(final Object instance, final MethodHandle handle, final Object... arguments) {
+ return INSTANCE.executeSafe(instance, handle, arguments);
+ }
+
+ /*
+ * Static Implementation
+ */
+
+ // Invokation
+
+ public static Object instance(final Class> clazz) {
+ return INSTANCE.init(getConstructor(clazz));
+ }
+
+ public static Object instance(final Constructor> constructor, final Object... arguments) {
+ return INSTANCE.init(constructor, arguments);
+ }
+
+ public static Object invokeStatic(final Method method, final Object... arguments) {
+ return INSTANCE.execute(null, method, arguments);
+ }
+
+ public static Object invoke(final Object instance, final Method method, final Object... arguments) {
+ return INSTANCE.execute(instance, method, arguments);
+ }
+
+ public static Object invokeThrows(final Object instance, final Method method, final Object... arguments) throws Throwable {
+ return INSTANCE.executeThrows(instance, method, arguments);
+ }
+
+ // Setter
+
+ public static void setValue(final Object instance, final Class> clazz, final String fieldName, final Object value) {
+ setValue(instance, getField(clazz, fieldName), value);
+ }
+
+ public static void setObjectValue(final Object instance, final Class> clazz, final String fieldName, final Object value) {
+ setObjectValue(instance, getField(clazz, fieldName), value);
+ }
+
+ public static void setStaticValue(final Class> clazz, final String fieldName, final Object value) {
+ setStaticValue(getField(clazz, fieldName), value);
+ }
+
+ public static void setValue(final Object instance, final Field field, final Object value) {
+ if (field == null) {
+ return;
+ }
+ if (Modifier.isStatic(field.getModifiers())) {
+ setStaticValue(field, value);
+ return;
+ }
+ setObjectValue(instance, field, value);
+ }
+
+ public static void setObjectValue(final Object instance, final Field field, final Object value) {
+ if (instance == null || field == null) {
+ return;
+ }
+ try {
+ INSTANCE.setObjectValueSafe(instance, field, value);
+ } catch (final AccessUnsuccessful unsafe) {
+ INSTANCE.setObjectValueUnsafe(instance, field, value);
+ }
+ }
+
+ public static void setStaticValue(final Field field, final Object value) {
+ if (field == null) {
+ return;
+ }
+ try {
+ INSTANCE.setStaticValueSafe(field, value);
+ } catch (final AccessUnsuccessful unsafe) {
+ INSTANCE.setStaticValueUnsafe(field, value);
+ }
+ }
+
+ // Getter
+
+ public static Object getValue(final Object instance, final Class> clazz, final String fieldName) {
+ return getValue(instance, getField(clazz, fieldName));
+ }
+
+ public static Object getObjectValue(final Object instance, final Class> clazz, final String fieldName) {
+ return getObjectValue(instance, getField(clazz, fieldName));
+ }
+
+ public static Object getStaticValue(final Class> clazz, final String fieldName) {
+ return getStaticValue(getField(clazz, fieldName));
+ }
+
+ public static Object getValue(final Object instance, final Field field) {
+ if (field == null) {
+ return null;
+ }
+ if (Modifier.isStatic(field.getModifiers())) {
+ return getStaticValue(field);
+ }
+ return getObjectValue(instance, field);
+ }
+
+ public static Object getObjectValue(final Object instance, final Field field) {
+ if (instance == null || field == null) {
+ return null;
+ }
+ try {
+ return INSTANCE.getObjectValueSafe(instance, field);
+ } catch (final AccessUnsuccessful unsafe) {
+ return INSTANCE.getObjectValueUnsafe(instance, field);
+ }
+ }
+
+ public static Object getStaticValue(final Field field) {
+ if (field == null) {
+ return null;
+ }
+ try {
+ return INSTANCE.getStaticValueSafe(field);
+ } catch (final AccessUnsuccessful unsafe) {
+ return INSTANCE.getStaticValueUnsafe(field);
+ }
+ }
+
+ /*
+ * Static Accessors
+ */
+
+ public static VarHandle accessField(final Field field) {
+ return INSTANCE.handle(field, false);
+ }
+
+ public static VarHandle accessField(final Field field, final boolean forceModification) {
+ return INSTANCE.handle(field, forceModification);
+ }
+
+ public static MethodHandle accessFieldGetter(final Field field) {
+ return INSTANCE.handleGetter(field);
+ }
+
+ public static MethodHandle accessFieldSetter(final Field field) {
+ return INSTANCE.handleSetter(field);
+ }
+
+ public static MethodHandle accessMethod(final Method method) {
+ return INSTANCE.handle(method);
+ }
+
+ public static MethodHandle accessConstructor(final Constructor> constructor) {
+ return INSTANCE.handle(constructor);
+ }
+
+ /*
+ * Static Utilities
+ */
+
+ public static String getClassName(final Class> clazz) {
+ final String name = clazz.getSimpleName();
+ if (name.contains(".")) {
+ return name.split("\\.")[0];
+ }
+ return name;
+ }
+
+ public static Field getField(final Class> clazz, final String field) {
+ if (clazz == null || field == null) {
+ return null;
+ }
+ try {
+ return clazz.getDeclaredField(field);
+ } catch (NoSuchFieldException | SecurityException ignore) {
+ try {
+ return clazz.getField(field);
+ } catch (NoSuchFieldException | SecurityException ignore0) {
+ return null;
+ }
+ }
+ }
+
+ public static Field[] getFields(final Class> clazz) {
+ final Field[] field0 = clazz.getFields();
+ final Field[] field1 = clazz.getDeclaredFields();
+ final HashSet fields = new HashSet<>();
+ Collections.addAll(fields, field0);
+ Collections.addAll(fields, field1);
+ return fields.toArray(new Field[fields.size()]);
+ }
+
+ public static Field getStaticField(final Class> clazz, final Class> returnType) {
+ return getField(clazz, true, returnType);
+ }
+
+ public static Field getDeclaredField(final Class> clazz, final Class> returnType) {
+ return getField(clazz, false, returnType);
+ }
+
+ public static Field getField(final Class> clazz, final boolean isStatic, final Class> returnType) {
+ if (clazz == null) {
+ return null;
+ }
+ final Field[] fields = getFields(clazz);
+ for (final Field field : fields) {
+ if (Modifier.isStatic(field.getModifiers()) != isStatic || !field.getType().equals(returnType)) {
+ continue;
+ }
+ return field;
+ }
+ return null;
+ }
+
+ public static Method getMethod(final Class> clazz, final String method, final Class>... arguments) {
+ if (clazz == null || method == null) {
+ return null;
+ }
+ try {
+ return clazz.getDeclaredMethod(method, arguments);
+ } catch (NoSuchMethodException | SecurityException ignore) {
+ try {
+ return clazz.getMethod(method, arguments);
+ } catch (NoSuchMethodException | SecurityException ignore0) {
+ return null;
+ }
+ }
+ }
+
+ public static Method[] getMethods(final Class> clazz) {
+ final Method[] method0 = clazz.getMethods();
+ final Method[] method1 = clazz.getDeclaredMethods();
+ final HashSet methods = new HashSet<>();
+ Collections.addAll(methods, method0);
+ Collections.addAll(methods, method1);
+ return methods.toArray(new Method[methods.size()]);
+ }
+
+ public static Method getDeclaredMethod(final Class> clazz, final Class> returnType, final Class>... arguments) {
+ return getMethod(clazz, false, returnType, Collections.emptyList(), arguments);
+ }
+
+ public static Method getDeclaredMethod(final Class> clazz, final Class> returnType, final List blacklisted,
+ final Class>... arguments) {
+ return getMethod(clazz, false, returnType, blacklisted, arguments);
+ }
+
+ public static Method getStaticMethod(final Class> clazz, final Class> returnType, final Class>... arguments) {
+ return getMethod(clazz, true, returnType, Collections.emptyList(), arguments);
+ }
+
+ public static Method getStaticMethod(final Class> clazz, final Class> returnType, final List blacklisted,
+ final Class>... arguments) {
+ return getMethod(clazz, true, returnType, blacklisted, arguments);
+ }
+
+ public static Method getMethod(final Class> clazz, final boolean isStatic, final Class> returnType, final List blacklisted,
+ final Class>... arguments) {
+ if (clazz == null) {
+ return null;
+ }
+ final Method[] methods = getMethods(clazz);
+ mainLoop:
+ for (final Method method : methods) {
+ if (Modifier.isStatic(method.getModifiers()) != isStatic || !method.getReturnType().equals(returnType)
+ || blacklisted.contains(method.getName())) {
+ continue;
+ }
+ final Class>[] parameters = method.getParameterTypes();
+ if (parameters.length != arguments.length) {
+ continue;
+ }
+ for (int index = 0; index < parameters.length; index++) {
+ if (!parameters[index].isAssignableFrom(arguments[index])) {
+ continue mainLoop;
+ }
+ }
+ return method;
+ }
+ return null;
+ }
+
+ public static Constructor> getConstructor(final Class> clazz, final Class>... arguments) {
+ if (clazz == null) {
+ return null;
+ }
+ try {
+ return clazz.getDeclaredConstructor(arguments);
+ } catch (NoSuchMethodException | SecurityException ignore) {
+ try {
+ return clazz.getConstructor(arguments);
+ } catch (NoSuchMethodException | SecurityException ignore0) {
+ return null;
+ }
+ }
+ }
+
+ public static Constructor>[] getConstructors(final Class> clazz) {
+ final Constructor>[] constructor0 = clazz.getConstructors();
+ final Constructor>[] constructor1 = clazz.getDeclaredConstructors();
+ final HashSet> constructors = new HashSet<>();
+ Collections.addAll(constructors, constructor0);
+ Collections.addAll(constructors, constructor1);
+ return constructors.toArray(new Constructor[constructors.size()]);
+
+ }
+
+ public static Class> findClass(final String name) {
+ try {
+ return Class.forName(name);
+ } catch (final ClassNotFoundException | LinkageError e) {
+ return null;
+ }
+ }
+
+ public static Class> findClass(final Class> clazz, final String name) {
+ if (clazz == null || name == null) {
+ return null;
+ }
+ final int size = clazz.getClasses().length + clazz.getDeclaredClasses().length;
+ if (size == 0) {
+ return null;
+ }
+ final Class>[] classes = new Class>[size];
+ final Class>[] tmp = clazz.getClasses();
+ System.arraycopy(tmp, 0, classes, 0, tmp.length);
+ System.arraycopy(clazz.getDeclaredClasses(), tmp.length, classes, tmp.length, size - tmp.length);
+ for (int i = 0; i < size; i++) {
+ String target = classes[i].getSimpleName();
+ if (target.contains(".")) {
+ target = target.split(".", 2)[0];
+ }
+ if (target.equals(name)) {
+ return classes[i];
+ }
+ }
+ return null;
+ }
+
+ public static boolean hasAnnotation(final AnnotatedElement element, final Class extends Annotation> annotationType) {
+ return element.isAnnotationPresent(annotationType);
+ }
+
+ public static A getAnnotation(final AnnotatedElement element, final Class annotationType) {
+ final A annotation = element.getAnnotation(annotationType);
+ if (annotation != null) {
+ return annotation;
+ }
+ return element.getDeclaredAnnotation(annotationType);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static A[] getAnnotations(final AnnotatedElement element, final Class annotationType) {
+ final A[] annotation0 = element.getAnnotationsByType(annotationType);
+ final A[] annotation1 = element.getDeclaredAnnotationsByType(annotationType);
+ if (annotation0.length != 0 && annotation1.length != 0) {
+ final HashSet annotations = new HashSet<>();
+ Collections.addAll(annotations, annotation0);
+ Collections.addAll(annotations, annotation1);
+ return annotations.toArray((A[]) Array.newInstance(annotationType, annotations.size()));
+ }
+ if (annotation0.length == 0) {
+ return annotation1;
+ }
+ return annotation0;
+ }
+
+ public static Optional getOptionalAnnotation(final AnnotatedElement element, final Class annotationType) {
+ return Optional.ofNullable(getAnnotation(element, annotationType));
+ }
+
+ /*
+ * Internal Exceptions
+ */
+
+ private static final class AccessUnsuccessful extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ }
+
+}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/Tracker.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/JavaTracker.java
similarity index 51%
rename from legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/Tracker.java
rename to legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/JavaTracker.java
index 76eab12..37910bc 100644
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/Tracker.java
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/util/java/reflect/JavaTracker.java
@@ -1,24 +1,27 @@
-package net.sourcewriters.spigot.rwg.legacy.api.util.java;
+package net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect;
import java.util.Optional;
-import com.syntaxphoenix.syntaxapi.reflection.ClassCache;
+public final class JavaTracker {
-public final class Tracker {
+ private JavaTracker() {
+ throw new UnsupportedOperationException("Utility class");
+ }
- private Tracker() {}
+ private static StackTraceElement[] getStack() {
+ return new Throwable().getStackTrace();
+ }
public static Optional> getClassFromStack(final int offset) {
final StackTraceElement element = getStack()[3 + offset];
- return element == null ? Optional.empty() : ClassCache.getOptionalClass(element.getClassName());
+ if (element == null) {
+ return Optional.empty();
+ }
+ return Optional.ofNullable(JavaAccess.findClass(element.getClassName()));
}
public static Optional> getCallerClass() {
return getClassFromStack(1);
}
- private static StackTraceElement[] getStack() {
- return new Throwable().getStackTrace();
- }
-
}
\ No newline at end of file
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/INmsAccess.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/INmsAccess.java
index 7dc2431..d136cb0 100644
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/INmsAccess.java
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/INmsAccess.java
@@ -1,16 +1,12 @@
package net.sourcewriters.spigot.rwg.legacy.api.version;
import net.sourcewriters.spigot.rwg.legacy.api.util.annotation.source.NonNull;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsBiomeAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsNbtAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsWorldAccess;
public interface INmsAccess {
- @NonNull
- ClassLookupProvider getLookupProvider();
-
@NonNull
INmsNbtAccess getNbtAccess();
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/AbstractClassLookupCache.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/AbstractClassLookupCache.java
deleted file mode 100644
index 600b7f4..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/AbstractClassLookupCache.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle;
-
-import java.util.HashMap;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Optional;
-
-import net.sourcewriters.spigot.rwg.legacy.api.util.annotation.source.NonNull;
-
-public abstract class AbstractClassLookupCache {
-
- protected final HashMap cache = new HashMap<>();
-
- public void clear() {
- cache.values().forEach(ClassLookup::uncache);
- }
-
- @NonNull
- public Optional get(final String name) {
- return Optional.ofNullable(cache.get(name));
- }
-
- public boolean has(final String name) {
- return cache.containsKey(name);
- }
-
- @NonNull
- public R create(@NonNull final String name, @NonNull final String path) {
- Objects.requireNonNull(name, "String name can't be null!");
- Objects.requireNonNull(name, "String path can't be null!");
- if (has(name)) {
- return cache.get(name);
- }
- final R reflect = create(path);
- cache.put(name, reflect);
- return reflect;
- }
-
- @NonNull
- public R create(@NonNull final String name, @NonNull final Class> clazz) {
- Objects.requireNonNull(name, "String name can't be null!");
- Objects.requireNonNull(clazz, "Class can't be null!");
- if (has(name)) {
- return cache.get(name);
- }
- final R reflect = create(clazz);
- cache.put(name, reflect);
- return reflect;
- }
-
- public void delete(final String name) {
- final ClassLookup lookup = cache.remove(name);
- if (lookup != null) {
- lookup.delete();
- }
- }
-
- @NonNull
- @SuppressWarnings("unchecked")
- public Entry[] entries() {
- return cache.entrySet().toArray(Entry[]::new);
- }
-
- protected abstract R create(Class> clazz);
-
- protected abstract R create(String path);
-
-}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookup.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookup.java
deleted file mode 100644
index 75ec9b0..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookup.java
+++ /dev/null
@@ -1,505 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.invoke.VarHandle;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.function.Predicate;
-
-import com.syntaxphoenix.syntaxapi.reflection.ClassCache;
-import com.syntaxphoenix.syntaxapi.reflection.ReflectionTools;
-import com.syntaxphoenix.syntaxapi.utils.java.Arrays;
-
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.field.IFieldHandle;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.field.SafeFieldHandle;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.field.UnsafeDeclaredFieldHandle;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.field.UnsafeStaticFieldHandle;
-
-public class ClassLookup {
-
- public static final Lookup LOOKUP = MethodHandles.lookup();
-
- private Class> owner;
- private Lookup privateLookup;
-
- private final HashMap constructors = new HashMap<>();
- private final HashMap methods = new HashMap<>();
- private final HashMap> fields = new HashMap<>();
-
- protected ClassLookup(final String classPath) throws IllegalAccessException {
- this(ClassCache.getClass(classPath));
- }
-
- protected ClassLookup(final Class> owner) throws IllegalAccessException {
- this.owner = owner;
- this.privateLookup = owner != null ? MethodHandles.privateLookupIn(owner, LOOKUP) : null;
- }
-
- /*
- *
- */
-
- public Class> getOwner() {
- return owner;
- }
-
- public Lookup getPrivateLockup() {
- return privateLookup;
- }
-
- /*
- *
- */
-
- public void delete() {
- constructors.clear();
- methods.clear();
- fields.clear();
- owner = null;
- privateLookup = null;
- }
-
- public boolean isValid() {
- return owner != null;
- }
-
- /*
- *
- */
-
- public Collection getConstructors() {
- return constructors.values();
- }
-
- public Collection getMethods() {
- return methods.values();
- }
-
- public Collection> getFields() {
- return fields.values();
- }
-
- /*
- *
- */
-
- public MethodHandle getConstructor(final String name) {
- return isValid() ? constructors.get(name) : null;
- }
-
- public MethodHandle getMethod(final String name) {
- return isValid() ? methods.get(name) : null;
- }
-
- public IFieldHandle> getField(final String name) {
- return isValid() ? fields.get(name) : null;
- }
-
- /*
- *
- */
-
- public boolean hasConstructor(final String name) {
- return isValid() && constructors.containsKey(name);
- }
-
- public boolean hasMethod(final String name) {
- return isValid() && methods.containsKey(name);
- }
-
- public boolean hasField(final String name) {
- return isValid() && fields.containsKey(name);
- }
-
- /*
- *
- */
-
- public Object init() {
- if (!isValid()) {
- return null;
- }
- final MethodHandle handle = constructors.computeIfAbsent("$base#empty", ignore -> {
- try {
- return LOOKUP.unreflectConstructor(owner.getConstructor());
- } catch (IllegalAccessException | NoSuchMethodException | SecurityException e0) {
- try {
- return LOOKUP.unreflectConstructor(owner.getDeclaredConstructor());
- } catch (IllegalAccessException | NoSuchMethodException | SecurityException e1) {
- return null;
- }
- }
- });
- if (handle == null) {
- constructors.remove("$base#empty");
- return null;
- }
- try {
- return handle.invoke();
- } catch (final Throwable e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public Object init(final String name, final Object... args) {
- if (!isValid() || !constructors.containsKey(name)) {
- return null;
- }
- try {
- return constructors.get(name).invokeWithArguments(args);
- } catch (final Throwable e) {
- e.printStackTrace();
- }
- return null;
- }
-
- /*
- *
- */
-
- public ClassLookup execute(final String name, final Object... args) {
- run(name, args);
- return this;
- }
-
- public ClassLookup execute(final Object source, final String name, final Object... args) {
- run(source, name, args);
- return this;
- }
-
- public Object run(final String name, final Object... args) {
- if (!isValid() || !methods.containsKey(name)) {
- return null;
- }
- try {
- return methods.get(name).invokeWithArguments(args);
- } catch (final Throwable e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public Object run(final Object source, final String name, final Object... args) {
- if (!isValid() || !methods.containsKey(name)) {
- return null;
- }
- try {
- return methods.get(name).invokeWithArguments(mergeBack(args, source));
- } catch (final Throwable e) {
- e.printStackTrace();
- }
- return null;
- }
-
- /*
- *
- */
-
- public Object getFieldValue(final String name) {
- return isValid() && fields.containsKey(name) ? fields.get(name).getValue() : null;
- }
-
- public Object getFieldValue(final Object source, final String name) {
- return isValid() && fields.containsKey(name) ? fields.get(name).getValue(source) : null;
- }
-
- public void setFieldValue(final String name, final Object value) {
- if (!isValid() || !fields.containsKey(name)) {
- return;
- }
- fields.get(name).setValue(value);
- }
-
- public void setFieldValue(final Object source, final String name, final Object value) {
- if (!isValid() || !fields.containsKey(name)) {
- return;
- }
- fields.get(name).setValue(source, value);
- }
-
- /*
- *
- */
-
- public ClassLookup searchConstructor(final Predicate predicate, final String name, final Class>... args) {
- return predicate.test(this) ? searchConstructor(name, args) : this;
- }
-
- public ClassLookup searchConstructor(final String name, final Class>... arguments) {
- if (hasConstructor(name)) {
- return this;
- }
- Constructor> constructor = null;
- try {
- constructor = owner.getDeclaredConstructor(arguments);
- } catch (NoSuchMethodException | SecurityException e) {
- }
- if (constructor == null) {
- try {
- constructor = owner.getConstructor(arguments);
- } catch (NoSuchMethodException | SecurityException e) {
- }
- }
- if (constructor != null) {
- try {
- constructors.put(name, unreflect(constructor));
- } catch (final IllegalAccessException e) {
- }
- }
- return this;
- }
-
- public ClassLookup searchConstructorsByArguments(String base, final Class>... arguments) {
- final Constructor>[] constructors = Arrays.merge(Constructor>[]::new, owner.getDeclaredConstructors(), owner.getConstructors());
- if (constructors.length == 0) {
- return this;
- }
- base += '-';
- int current = 0;
- for (final Constructor> constructor : constructors) {
- final Class>[] args = constructor.getParameterTypes();
- if (args.length != arguments.length) {
- continue;
- }
- try {
- if (ReflectionTools.hasSameArguments(arguments, args)) {
- this.constructors.put(base + current, unreflect(constructor));
- current++;
- }
- } catch (final IllegalAccessException e) {
- }
- }
- return this;
- }
-
- /*
- *
- */
-
- public ClassLookup searchMethod(final Predicate predicate, final String name, final String methodName,
- final Class>... arguments) {
- return predicate.test(this) ? searchMethod(name, methodName, arguments) : this;
- }
-
- public ClassLookup searchMethod(final String name, final String methodName, final Class>... arguments) {
- if (hasMethod(name)) {
- return this;
- }
- Method method = null;
- try {
- method = owner.getDeclaredMethod(methodName, arguments);
- } catch (NoSuchMethodException | SecurityException e) {
- }
- if (method == null) {
- try {
- method = owner.getMethod(methodName, arguments);
- } catch (NoSuchMethodException | SecurityException e) {
- }
- }
- if (method != null) {
- try {
- methods.put(name, unreflect(method));
- } catch (IllegalAccessException | SecurityException e) {
- }
- }
- return this;
- }
-
- public ClassLookup searchMethodsByArguments(String base, final Class>... arguments) {
- final Method[] methods = Arrays.merge(Method[]::new, owner.getDeclaredMethods(), owner.getMethods());
- if (methods.length == 0) {
- return this;
- }
- base += '-';
- int current = 0;
- for (final Method method : methods) {
- final Class>[] args = method.getParameterTypes();
- if (args.length != arguments.length) {
- continue;
- }
- try {
- if (ReflectionTools.hasSameArguments(arguments, args)) {
- this.methods.put(base + current, unreflect(method));
- current++;
- }
- } catch (IllegalAccessException | SecurityException e) {
- }
- }
- return this;
- }
-
- /*
- *
- */
-
- public ClassLookup searchField(final Predicate predicate, final String name, final String fieldName, final Class> type) {
- return predicate.test(this) ? searchField(name, fieldName, type) : this;
- }
-
- public ClassLookup searchField(final String name, final String fieldName) {
- if (hasMethod(name)) {
- return this;
- }
- Field field = null;
- try {
- field = owner.getDeclaredField(fieldName);
- } catch (NoSuchFieldException | SecurityException e) {
- }
- if (field == null) {
- try {
- field = owner.getField(fieldName);
- } catch (NoSuchFieldException | SecurityException e) {
- }
- }
- if (field != null) {
- storeField(name, field);
- }
- return this;
- }
-
- public ClassLookup searchField(final String name, final String fieldName, final Class> type) {
- if (hasField(name)) {
- return this;
- }
- VarHandle handle = null;
- try {
- handle = privateLookup.findVarHandle(owner, fieldName, type);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- }
- if (handle == null) {
- try {
- handle = privateLookup.findStaticVarHandle(owner, fieldName, type);
- } catch (SecurityException | NoSuchFieldException | IllegalAccessException e) {
- }
- }
- if (handle != null) {
- fields.put(name, new SafeFieldHandle(handle));
- }
- return this;
- }
-
- /*
- *
- */
-
- private void storeField(final String name, final Field field) {
- if (!Modifier.isFinal(field.getModifiers())) {
- try {
- fields.put(name, new SafeFieldHandle(unreflect(field)));
- return;
- } catch (IllegalAccessException | SecurityException e) {
- }
- }
- if (!Modifier.isStatic(field.getModifiers())) {
- fields.put(name, new UnsafeDeclaredFieldHandle(field));
- return;
- }
- fields.put(name, new UnsafeStaticFieldHandle(field));
- }
-
- private VarHandle unreflect(final Field field) throws IllegalAccessException, SecurityException {
- if (Modifier.isStatic(field.getModifiers())) {
- final boolean access = field.canAccess(null);
- if (!access) {
- field.setAccessible(true);
- }
- final VarHandle out = LOOKUP.unreflectVarHandle(field);
- if (!access) {
- field.setAccessible(false);
- }
- return out;
- }
- if (field.trySetAccessible()) {
- final VarHandle out = LOOKUP.unreflectVarHandle(field);
- field.setAccessible(false);
- return out;
- }
- return LOOKUP.unreflectVarHandle(field);
- }
-
- private MethodHandle unreflect(final Method method) throws IllegalAccessException, SecurityException {
- if (Modifier.isStatic(method.getModifiers())) {
- final boolean access = method.canAccess(null);
- if (!access) {
- method.setAccessible(true);
- }
- final MethodHandle out = LOOKUP.unreflect(method);
- if (!access) {
- method.setAccessible(false);
- }
- return out;
- }
- if (method.trySetAccessible()) {
- final MethodHandle out = LOOKUP.unreflect(method);
- method.setAccessible(false);
- return out;
- }
- return LOOKUP.unreflect(method);
- }
-
- private MethodHandle unreflect(final Constructor> constructor) throws IllegalAccessException {
- final boolean access = constructor.canAccess(null);
- if (!access) {
- constructor.setAccessible(true);
- }
- final MethodHandle out = LOOKUP.unreflectConstructor(constructor);
- if (!access) {
- constructor.setAccessible(false);
- }
- return out;
- }
-
- /*
- *
- */
-
- public static void uncache(final ClassLookup lookup) {
- final Class> search = lookup.getOwner();
- lookup.delete();
- if (ClassCache.CLASSES.isEmpty()) {
- return;
- }
- final Optional>> option = ClassCache.CLASSES.entrySet().stream()
- .filter(entry -> entry.getValue().equals(search)).findFirst();
- if (option.isPresent()) {
- ClassCache.CLASSES.remove(option.get().getKey());
- }
- }
-
- public static Object[] mergeBack(final Object[] array1, final Object... array2) {
- final Object[] output = new Object[array1.length + array2.length];
- System.arraycopy(array2, 0, output, 0, array2.length);
- System.arraycopy(array1, 0, output, array2.length, array1.length);
- return output;
- }
-
- /*
- *
- */
-
- public static final ClassLookup of(final Class> clazz) {
- try {
- return new ClassLookup(clazz);
- } catch (final IllegalAccessException e) {
- return null;
- }
- }
-
- public static final ClassLookup of(final String path) {
- try {
- return new ClassLookup(path);
- } catch (final IllegalAccessException e) {
- return null;
- }
- }
-
-}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookupCache.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookupCache.java
deleted file mode 100644
index 1ef9bbd..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookupCache.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle;
-
-public class ClassLookupCache extends AbstractClassLookupCache {
-
- @Override
- protected ClassLookup create(final Class> clazz) {
- return ClassLookup.of(clazz);
- }
-
- @Override
- protected ClassLookup create(final String path) {
- return ClassLookup.of(path);
- }
-
-}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookupProvider.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookupProvider.java
deleted file mode 100644
index b715fd0..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/ClassLookupProvider.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle;
-
-import static net.sourcewriters.spigot.rwg.legacy.api.version.handle.FakeLookup.FAKE;
-
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.function.Consumer;
-
-import com.syntaxphoenix.syntaxapi.reflection.ClassCache;
-
-import net.sourcewriters.spigot.rwg.legacy.api.util.annotation.source.NonNull;
-import net.sourcewriters.spigot.rwg.legacy.api.version.util.ServerVersion;
-import net.sourcewriters.spigot.rwg.legacy.api.version.util.Versions;
-
-public class ClassLookupProvider {
-
- public static final String CB_PATH_FORMAT = "org.bukkit.craftbukkit.%s.%s";
- public static final String NMS_PATH_FORMAT = "net.minecraft.server.%s.%s";
-
- public static final ClassLookupProvider DEFAULT = new ClassLookupProvider();
-
- protected final ClassLookupCache cache;
-
- protected final String cbPath;
- protected final String nmsPath;
-
- protected final ServerVersion version;
-
- private boolean skip = false;
-
- public ClassLookupProvider() {
- this((Consumer) null);
- }
-
- public ClassLookupProvider(final Consumer setup) {
- this(new ClassLookupCache(), setup);
- }
-
- public ClassLookupProvider(final ClassLookupCache cache) {
- this(cache, null);
- }
-
- public ClassLookupProvider(final ClassLookupCache cache, final Consumer setup) {
- this.cache = cache;
- this.version = Versions.getServer();
- this.cbPath = String.format(CB_PATH_FORMAT, Versions.getServerAsString(), "%s");
- this.nmsPath = String.format(NMS_PATH_FORMAT, Versions.getServerAsString(), "%s");
- if (setup != null) {
- setup.accept(this);
- }
- }
-
- @NonNull
- public ServerVersion getVersion() {
- return version;
- }
-
- /*
- * Delete
- */
-
- public void deleteByName(final String name) {
- cache.delete(name);
- }
-
- public void deleteByPackage(final String path) {
- final Entry[] array = cache.entries();
- for (final Entry entry : array) {
- if (!entry.getValue().getOwner().getPackageName().equals(path)) {
- continue;
- }
- cache.delete(entry.getKey());
- }
- }
-
- /*
- * Skip
- */
-
- public ClassLookupProvider require(final boolean skip) {
- this.skip = !skip;
- return this;
- }
-
- public ClassLookupProvider skip(final boolean skip) {
- this.skip = skip;
- return this;
- }
-
- public boolean skip() {
- return skip;
- }
-
- /*
- * Reflection
- */
-
- @NonNull
- public ClassLookupCache getCache() {
- return cache;
- }
-
- @NonNull
- public String getNmsPath() {
- return nmsPath;
- }
-
- @NonNull
- public String getCbPath() {
- return cbPath;
- }
-
- @NonNull
- public ClassLookup createNMSLookup(final String name, final String path) {
- return skip ? FAKE : cache.create(name, getNMSClass(path));
- }
-
- @NonNull
- public ClassLookup createCBLookup(final String name, final String path) {
- return skip ? FAKE : cache.create(name, getCBClass(path));
- }
-
- @NonNull
- public ClassLookup createLookup(final String name, final String path) {
- return skip ? FAKE : cache.create(name, getClass(path));
- }
-
- @NonNull
- public ClassLookup createLookup(final String name, final Class> clazz) {
- return skip ? FAKE : cache.create(name, clazz);
- }
-
- @NonNull
- public Optional getOptionalLookup(final String name) {
- return cache.get(name);
- }
-
- public ClassLookup getLookup(final String name) {
- return cache.get(name).orElse(null);
- }
-
- public Class> getNMSClass(final String path) {
- return getClass(String.format(nmsPath, path));
- }
-
- public Class> getCBClass(final String path) {
- return getClass(String.format(cbPath, path));
- }
-
- public Class> getClass(final String path) {
- return ClassCache.getClass(path);
- }
-
-}
\ No newline at end of file
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/FakeLookup.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/FakeLookup.java
deleted file mode 100644
index 1c3a311..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/FakeLookup.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle;
-
-public class FakeLookup extends ClassLookup {
-
- public static final FakeLookup FAKE = build();
-
- private FakeLookup() throws IllegalAccessException {
- super((Class>) null);
- }
-
- private static final FakeLookup build() {
- try {
- return new FakeLookup();
- } catch (final IllegalAccessException e) {
- return null;
- }
- }
-
-}
\ No newline at end of file
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/IFieldHandle.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/IFieldHandle.java
deleted file mode 100644
index 1bfd5c9..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/IFieldHandle.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle.field;
-
-public interface IFieldHandle {
-
- Object getValue();
-
- Object getValue(Object source);
-
- IFieldHandle setValue(Object value);
-
- IFieldHandle setValue(Object source, Object value);
-
- O getHandle();
-
- boolean isUnsafe();
-
-}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/SafeFieldHandle.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/SafeFieldHandle.java
deleted file mode 100644
index 5afcc76..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/SafeFieldHandle.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle.field;
-
-import java.lang.invoke.VarHandle;
-
-public class SafeFieldHandle implements IFieldHandle {
-
- private final VarHandle handle;
-
- public SafeFieldHandle(final VarHandle handle) {
- this.handle = handle;
- }
-
- @Override
- public Object getValue() {
- return handle.get();
- }
-
- @Override
- public Object getValue(final Object source) {
- return handle.get(source);
- }
-
- @Override
- public IFieldHandle setValue(final Object value) {
- handle.set(value);
- return this;
- }
-
- @Override
- public IFieldHandle setValue(final Object source, final Object value) {
- handle.set(source, value);
- return this;
- }
-
- @Override
- public VarHandle getHandle() {
- return handle;
- }
-
- @Override
- public boolean isUnsafe() {
- return false;
- }
-
-}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeDeclaredFieldHandle.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeDeclaredFieldHandle.java
deleted file mode 100644
index 7382b18..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeDeclaredFieldHandle.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle.field;
-
-import java.lang.reflect.Field;
-
-public final class UnsafeDeclaredFieldHandle extends UnsafeFieldHandle {
-
- private final Field handle;
- private final long offset;
-
- public UnsafeDeclaredFieldHandle(final Field handle) {
- this.handle = handle;
- this.offset = UNSAFE.objectFieldOffset(handle);
- }
-
- @Override
- public Object getValue() {
- return null; // Stay null because its not static
- }
-
- @Override
- public Object getValue(final Object source) {
- return getMemoryValue(source, offset);
- }
-
- @Override
- public IFieldHandle setValue(final Object value) {
- return this; // Do nothing because its not static
- }
-
- @Override
- public IFieldHandle setValue(final Object source, final Object value) {
- return setMemoryValue(source, offset, value);
- }
-
- @Override
- public Field getHandle() {
- return handle;
- }
-
-}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeFieldHandle.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeFieldHandle.java
deleted file mode 100644
index 24c145a..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeFieldHandle.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle.field;
-
-import java.lang.reflect.Field;
-
-import sun.misc.Unsafe;
-
-public abstract class UnsafeFieldHandle implements IFieldHandle {
-
- protected static final Unsafe UNSAFE = getUnsafe();
-
- protected final IFieldHandle setMemoryValue(final Object base, final long offset, final Object value) {
- UNSAFE.putObject(base, offset, value);
- return this;
- }
-
- protected final Object getMemoryValue(final Object base, final long offset) {
- return UNSAFE.getObject(base, offset);
- }
-
- @Override
- public final boolean isUnsafe() {
- return true;
- }
-
- private static Unsafe getUnsafe() {
- try {
- final Field field = Unsafe.class.getDeclaredField("theUnsafe");
- field.setAccessible(true);
- return (Unsafe) field.get(null);
- } catch (final Exception ignore) {
- return null;
- }
- }
-
-}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeStaticFieldHandle.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeStaticFieldHandle.java
deleted file mode 100644
index 9001efc..0000000
--- a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/handle/field/UnsafeStaticFieldHandle.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.version.handle.field;
-
-import java.lang.reflect.Field;
-
-public final class UnsafeStaticFieldHandle extends UnsafeFieldHandle {
-
- private final Field handle;
- private final Object base;
- private final long offset;
-
- public UnsafeStaticFieldHandle(final Field handle) {
- this.handle = handle;
- this.base = UNSAFE.staticFieldBase(handle);
- this.offset = UNSAFE.staticFieldOffset(handle);
- }
-
- @Override
- public Object getValue() {
- return getMemoryValue(base, offset);
- }
-
- @Override
- public Object getValue(final Object source) {
- return null; // Stay null because its static
- }
-
- @Override
- public IFieldHandle setValue(final Object value) {
- return setMemoryValue(base, offset, value);
- }
-
- @Override
- public IFieldHandle setValue(final Object source, final Object value) {
- return this; // Do nothing because its static
- }
-
- @Override
- public Field getHandle() {
- return handle;
- }
-
-}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/LegacyVersionProvider.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/LegacyVersionProvider.java
new file mode 100644
index 0000000..136c3a9
--- /dev/null
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/LegacyVersionProvider.java
@@ -0,0 +1,11 @@
+package net.sourcewriters.spigot.rwg.legacy.api.version.provider;
+
+import net.sourcewriters.spigot.rwg.legacy.api.version.util.ServerVersion;
+
+public final class LegacyVersionProvider extends VersionProvider {
+
+ public LegacyVersionProvider(ServerVersion version) {
+ super(version);
+ }
+
+}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/MappedVersionProvider.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/MappedVersionProvider.java
new file mode 100644
index 0000000..ad440af
--- /dev/null
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/MappedVersionProvider.java
@@ -0,0 +1,16 @@
+package net.sourcewriters.spigot.rwg.legacy.api.version.provider;
+
+import net.sourcewriters.spigot.rwg.legacy.api.version.util.ServerVersion;
+
+public final class MappedVersionProvider extends VersionProvider {
+
+ public MappedVersionProvider(ServerVersion version) {
+ super(version);
+ }
+
+ @Override
+ protected String buildMinecraftPath(ServerVersion version) {
+ return "net.minecraft.%s";
+ }
+
+}
diff --git a/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/VersionProvider.java b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/VersionProvider.java
new file mode 100644
index 0000000..7ea686c
--- /dev/null
+++ b/legacy-api/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/version/provider/VersionProvider.java
@@ -0,0 +1,87 @@
+package net.sourcewriters.spigot.rwg.legacy.api.version.provider;
+
+import com.syntaxphoenix.syntaxapi.utils.java.tools.Container;
+
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.Accessor;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.JavaAccess;
+import net.sourcewriters.spigot.rwg.legacy.api.version.util.ServerVersion;
+import net.sourcewriters.spigot.rwg.legacy.api.version.util.Versions;
+
+public abstract class VersionProvider {
+
+ private static final Container PROVIDER = Container.of();
+
+ public static VersionProvider get() {
+ if (PROVIDER.isPresent()) {
+ return PROVIDER.get();
+ }
+ return PROVIDER.replace(build()).lock().get();
+ }
+
+ private static VersionProvider build() {
+ ServerVersion version = Versions.getServer();
+ if (Versions.isServerCompat(1, 17)) {
+ return new MappedVersionProvider(version);
+ }
+ return new LegacyVersionProvider(version);
+ }
+
+ private final String minecraftPath;
+ private final String craftBukkitPath;
+ private final String bukkitPath;
+
+ public VersionProvider(ServerVersion version) {
+ this.minecraftPath = buildMinecraftPath(version);
+ this.craftBukkitPath = buildCraftBukkitPath(version);
+ this.bukkitPath = buildBukkitPath(version);
+ }
+
+ protected String buildMinecraftPath(ServerVersion version) {
+ return String.format("net.minecraft.server.%s.%s", version.toString(), "%s");
+ }
+
+ protected String buildCraftBukkitPath(ServerVersion version) {
+ return String.format("org.bukkit.craftbukkit.%s.%s", version.toString(), "%s");
+ }
+
+ protected String buildBukkitPath(ServerVersion version) {
+ return "org.bukkit.%s";
+ }
+
+ public final String minecraft(String path) {
+ return String.format(minecraftPath, path);
+ }
+
+ public final String craftBukkit(String path) {
+ return String.format(craftBukkitPath, path);
+ }
+
+ public final String bukkit(String path) {
+ return String.format(bukkitPath, path);
+ }
+
+ public final Class> minecraftClass(String path) {
+ return JavaAccess.findClass(minecraft(path));
+ }
+
+ public final Class> craftBukkitClass(String path) {
+ return JavaAccess.findClass(craftBukkit(path));
+ }
+
+ public final Class> bukkitClass(String path) {
+ return JavaAccess.findClass(bukkit(path));
+ }
+
+ public final Accessor minecraftAccess(String path) {
+ return Accessor.ofNullable(minecraftClass(path));
+ }
+
+ public final Accessor craftBukkitAccess(String path) {
+ return Accessor.ofNullable(craftBukkitClass(path));
+ }
+
+ public final Accessor bukkitAccess(String path) {
+ return Accessor.ofNullable(bukkitClass(path));
+ }
+
+}
diff --git a/legacy-pre1_17-compat/pom.xml b/legacy-pre1_17-compat/pom.xml
index b975acc..7db0ecf 100644
--- a/legacy-pre1_17-compat/pom.xml
+++ b/legacy-pre1_17-compat/pom.xml
@@ -4,10 +4,10 @@
4.0.0
net.sourcewriters.spigot.rwg
legacy-pre1_17-compat
- 3.0.0
+ 4.0.0
- 3.0.0
+ 4.0.0
@@ -53,8 +53,8 @@
org.spigotmc
- spigot-api
- 1.17-R0.1-SNAPSHOT
+ spigot
+ 1.16.5-R0.1-SNAPSHOT
provided
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/BiomeAccessImpl.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/BiomeAccessImpl.java
index c83022a..643580e 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/BiomeAccessImpl.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/BiomeAccessImpl.java
@@ -5,7 +5,7 @@
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.biome.BiomeProvider;
-import net.sourcewriters.spigot.rwg.legacy.api.util.java.InstanceBuilder;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.InstanceBuilder;
import net.sourcewriters.spigot.rwg.legacy.api.version.IBiomeAccess;
public final class BiomeAccessImpl implements IBiomeAccess {
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
index 332223a..e963c8c 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/ConversionAccessImpl.java
@@ -7,15 +7,15 @@
import com.mojang.authlib.GameProfile;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
import net.sourcewriters.spigot.rwg.legacy.api.util.rwg.RWGMaterial;
import net.sourcewriters.spigot.rwg.legacy.api.version.IConversionAccess;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
public final class ConversionAccessImpl implements IConversionAccess {
- private final ClassLookupProvider provider;
+ private final AccessorProvider provider;
- public ConversionAccessImpl(final ClassLookupProvider provider) {
+ public ConversionAccessImpl(final AccessorProvider provider) {
this.provider = provider;
}
@@ -62,7 +62,7 @@ public boolean isGiantTree(final TreeType type) {
public ItemStack asHeadItem(final GameProfile profile) {
final ItemStack stack = new ItemStack(RWGMaterial.HEAD_ITEM.asBukkit(this));
final SkullMeta meta = (SkullMeta) stack.getItemMeta();
- provider.getLookup("bkt_skull_meta").setFieldValue(meta, "profile", profile);
+ provider.getOrNull("cb_skull_meta").setValue(meta, "profile", profile);
stack.setItemMeta(meta);
return stack;
}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
index 50a5486..7278b33 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/NmsAccessImpl.java
@@ -6,29 +6,29 @@
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsBiomeAccessImpl;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsNbtAccessImpl;
import net.sourcewriters.spigot.rwg.legacy.api.impl.version.nms.NmsWorldAccessImpl;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.INmsAccess;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsBiomeAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsNbtAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsWorldAccess;
+import net.sourcewriters.spigot.rwg.legacy.api.version.provider.VersionProvider;
public final class NmsAccessImpl implements INmsAccess {
- private final ClassLookupProvider provider = ClassLookupProvider.DEFAULT;
+ private final AccessorProvider provider = new AccessorProvider();
private final NmsNbtAccessImpl nbtAccess;
private final NmsBiomeAccessImpl biomeAccess;
private final NmsWorldAccessImpl worldAccess;
public NmsAccessImpl(final ILogger logger) {
- GlobalLookup.setup(provider);
+ GlobalLookup.setup(provider, VersionProvider.get());
nbtAccess = new NmsNbtAccessImpl(provider, logger);
biomeAccess = new NmsBiomeAccessImpl(provider);
worldAccess = new NmsWorldAccessImpl(provider, nbtAccess);
}
- @Override
- public ClassLookupProvider getLookupProvider() {
+ public AccessorProvider getProvider() {
return provider;
}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
index a32c686..15619da 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/VersionAccessImpl.java
@@ -15,7 +15,7 @@ public final class VersionAccessImpl implements IVersionAccess {
public VersionAccessImpl(final ILogger logger) {
nmsAccess = new NmsAccessImpl(logger);
- conversionAccess = new ConversionAccessImpl(nmsAccess.getLookupProvider());
+ conversionAccess = new ConversionAccessImpl(nmsAccess.getProvider());
biomeAccess = new BiomeAccessImpl();
}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java
index e830e67..69cb1ab 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/GlobalLookup.java
@@ -3,78 +3,75 @@
import java.io.DataInput;
import java.io.DataOutput;
-import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.SkullMeta;
import com.mojang.authlib.GameProfile;
-import net.sourcewriters.spigot.rwg.legacy.api.util.java.InstanceBuilder;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.InstanceBuilder;
+import net.sourcewriters.spigot.rwg.legacy.api.version.provider.VersionProvider;
public final class GlobalLookup {
private GlobalLookup() {}
- public static void setup(final ClassLookupProvider provider) {
+ public static void setup(final AccessorProvider provider, final VersionProvider version) {
/*
* Setup everything else
*/
- final Class> nbtTagCompoundClass = provider.createLookup("nms_nbt_compound", provider.getNMSClass("NBTTagCompound")).getOwner();
- final Class> nmsItemStackClass = provider.createLookup("nms_itemstack", provider.getNMSClass("ItemStack"))
- .searchMethod("save", "save", nbtTagCompoundClass).searchMethod("load", "a", nbtTagCompoundClass).getOwner();
+ final Class> nbtTagCompoundClass = provider.create("nms_nbt_compound", version.minecraftClass("NBTTagCompound")).getOwner();
+ final Class> nmsItemStackClass = provider.create("nms_itemstack", version.minecraftClass("ItemStack"))
+ .findMethod("save", "save", nbtTagCompoundClass).findMethod("load", "a", nbtTagCompoundClass).getOwner();
- final Class> nbtBaseClass = provider.getNMSClass("NBTBase");
- final Class> nbtReadLimiterClass = provider.getNMSClass("NBTReadLimiter");
+ final Class> nbtBaseClass = version.minecraftClass("NBTBase");
+ final Class> nbtReadLimiterClass = version.minecraftClass("NBTReadLimiter");
- provider.createLookup("nms_nbt_read_limiter", nbtReadLimiterClass).searchField("limiter", "a", nbtReadLimiterClass);
+ provider.create("nms_nbt_read_limiter", nbtReadLimiterClass).findField("limiter", "a");
- provider.createLookup("nms_minecraft_key", provider.getNMSClass("MinecraftKey")).searchMethod("key", "getKey");
- provider.createLookup("nms_area_transformer_8", provider.getNMSClass("AreaTransformer8")).searchMethod("apply", "apply", int.class,
+ provider.create("nms_minecraft_key", version.minecraftClass("MinecraftKey")).findMethod("key", "getKey");
+ provider.create("nms_area_transformer_8", version.minecraftClass("AreaTransformer8")).findMethod("apply", "apply", int.class,
int.class);
- provider.createLookup("nms_chunk_generator", provider.getNMSClass("ChunkGenerator")).searchMethod("worldChunkManager",
+ provider.create("nms_chunk_generator", version.minecraftClass("ChunkGenerator")).findMethod("worldChunkManager",
"getWorldChunkManager");
- provider.createLookup("nms_world_server", provider.getNMSClass("WorldServer")).searchMethod("chunkProvider", "getChunkProvider");
- provider.createLookup("nms_chunk_provider_server", provider.getNMSClass("ChunkProviderServer")).searchMethod("generator",
+ provider.create("nms_world_server", version.minecraftClass("WorldServer")).findMethod("chunkProvider", "getChunkProvider");
+ provider.create("nms_chunk_provider_server", version.minecraftClass("ChunkProviderServer")).findMethod("generator",
"getChunkGenerator");
- provider.createLookup("nms_entity_skull", provider.getNMSClass("TileEntitySkull")).searchMethod("profile", "setGameProfile",
+ provider.create("nms_entity_skull", version.minecraftClass("TileEntitySkull")).findMethod("profile", "setGameProfile",
GameProfile.class);
- provider.createLookup("nms_entity_spawner", provider.getNMSClass("TileEntityMobSpawner"))
- .searchMethod("save", "save", nbtTagCompoundClass).searchMethod("load", "load", nbtTagCompoundClass);
-
- provider.createLookup("nms_stream_tools", provider.getNMSClass("NBTCompressedStreamTools"))
- .searchMethod("read", "a", DataInput.class, int.class, nbtReadLimiterClass)
- .searchMethod("write", "a", nbtBaseClass, DataOutput.class);
-
- provider.createLookup("cb_world", provider.getCBClass("CraftWorld")).searchMethod("handle", "getHandle").searchField("generator",
- "generator", ChunkGenerator.class);
- provider.createLookup("cb_generator", provider.getCBClass("generator.CustomChunkGenerator")).searchField("generator", "generator",
- ChunkGenerator.class);
- provider.createLookup("cb_block_entityState", provider.getCBClass("block.CraftBlockEntityState")).searchMethod("entity",
+ provider.create("nms_entity_spawner", version.minecraftClass("TileEntityMobSpawner"))
+ .findMethod("save", "save", nbtTagCompoundClass).findMethod("load", "load", nbtTagCompoundClass);
+
+ provider.create("nms_stream_tools", version.minecraftClass("NBTCompressedStreamTools"))
+ .findMethod("read", "a", DataInput.class, int.class, nbtReadLimiterClass)
+ .findMethod("write", "a", nbtBaseClass, DataOutput.class);
+
+ provider.create("cb_world", version.craftBukkitClass("CraftWorld")).findMethod("handle", "getHandle").findField("generator",
+ "generator");
+ provider.create("cb_generator", version.craftBukkitClass("generator.CustomChunkGenerator")).findField("generator", "generator");
+ provider.create("cb_block_entityState", version.craftBukkitClass("block.CraftBlockEntityState")).findMethod("entity",
"getTileEntity");
- provider.createLookup("cb_block_skull", provider.getCBClass("block.CraftSkull")).searchField("profile", "profile",
- GameProfile.class);
- provider.createLookup("cb_itemstack", provider.getCBClass("inventory.CraftItemStack"))
- .searchMethod("nms", "asNMSCopy", ItemStack.class).searchMethod("bukkit", "asBukkitCopy", nmsItemStackClass);
+ provider.create("cb_block_skull", version.craftBukkitClass("block.CraftSkull")).findField("profile", "profile");
+ provider.create("cb_itemstack", version.craftBukkitClass("inventory.CraftItemStack"))
+ .findMethod("nms", "asNMSCopy", ItemStack.class).findMethod("bukkit", "asBukkitCopy", nmsItemStackClass);
- provider.createLookup("bkt_skull_meta", SkullMeta.class).searchField("field", "field", GameProfile.class);
+ provider.create("cb_skull_meta", version.craftBukkitClass("inventory.CraftMetaSkull")).findField("profile", "profile");
/*
* Setup version related stuff
*/
- versionSetup(provider);
+ versionSetup(provider, version);
}
- private static void versionSetup(final ClassLookupProvider provider) {
+ private static void versionSetup(final AccessorProvider provider, final VersionProvider version) {
final VersionLookup lookup = InstanceBuilder.buildExact(VersionLookup.class).orElse(null);
if (lookup == null) {
return;
}
- lookup.setup(provider);
+ lookup.setup(provider, version);
}
}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_14.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_14.java
deleted file mode 100644
index 7fce3fe..0000000
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_14.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
-
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
-
-public final class Lookup1_14 extends VersionLookup {
-
- Lookup1_14() {}
-
- @Override
- public void setup(final ClassLookupProvider provider) {
-
- final Class> iRegistryClass = provider.getNMSClass("IRegistry");
- final Class> genLayerClass = provider.getNMSClass("GenLayer");
- final Class> areaLazyClass = provider.getNMSClass("AreaLazy");
- final Class> areaTransformer8Class = provider.getNMSClass("AreaTransformer8");
-
- provider.createLookup("nms_world_chunk_manager_overworld", provider.getNMSClass("WorldChunkManagerOverworld"))
- .searchField("genLayer", "d", genLayerClass);
- provider.createLookup("nms_gen_layer", genLayerClass).searchField("areaLazy", "b", areaLazyClass);
- provider.createLookup("nms_area_lazy", areaLazyClass).searchField("transformer", "a", areaTransformer8Class);
-
- provider.createLookup("nms_registry", iRegistryClass).searchField("biomeRegistry", "BIOME", iRegistryClass);
- provider.createLookup("nms_registry_materials", provider.getNMSClass("RegistryMaterials")).searchMethod("id", "fromId", int.class)
- .searchMethod("key", "getKey", Object.class);
-
- }
-
-}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_15.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_15.java
deleted file mode 100644
index 0368eed..0000000
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_15.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
-
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
-
-public final class Lookup1_15 extends VersionLookup {
-
- Lookup1_15() {}
-
- @Override
- public void setup(final ClassLookupProvider provider) {
-
- final Class> iRegistryClass = provider.getNMSClass("IRegistry");
- final Class> genLayerClass = provider.getNMSClass("GenLayer");
- final Class> areaLazyClass = provider.getNMSClass("AreaLazy");
- final Class> areaTransformer8Class = provider.getNMSClass("AreaTransformer8");
-
- provider.createLookup("nms_world_chunk_manager_overworld", provider.getNMSClass("WorldChunkManagerOverworld"))
- .searchField("genLayer", "d", genLayerClass);
- provider.createLookup("nms_gen_layer", genLayerClass).searchField("areaLazy", "b", areaLazyClass);
- provider.createLookup("nms_area_lazy", areaLazyClass).searchField("transformer", "a", areaTransformer8Class);
-
- provider.createLookup("nms_registry", iRegistryClass).searchField("biomeRegistry", "BIOME", iRegistryClass);
- provider.createLookup("nms_registry_materials", provider.getNMSClass("RegistryMaterials")).searchMethod("id", "fromId", int.class)
- .searchMethod("key", "getKey", Object.class);
-
- }
-
-}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_16.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_16.java
deleted file mode 100644
index 4a8bc78..0000000
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/Lookup1_16.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
-
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
-import net.sourcewriters.spigot.rwg.legacy.api.version.util.Versions;
-
-public final class Lookup1_16 extends VersionLookup {
-
- Lookup1_16() {}
-
- @Override
- public void setup(final ClassLookupProvider provider) {
-
- final Class> nbtTagCompoundClass = provider.getLookup("nms_nbt_compound").getOwner();
- final Class> iBlockDataClass = provider.createLookup("nms_blockdata", provider.getNMSClass("IBlockData")).getOwner();
-
- final Class> iRegistryClass = provider.getNMSClass("IRegistry");
- final Class> genLayerClass = provider.getNMSClass("GenLayer");
- final Class> areaLazyClass = provider.getNMSClass("AreaLazy");
- final Class> areaTransformer8Class = provider.getNMSClass("AreaTransformer8");
-
- provider.createLookup("nms_world_chunk_manager_overworld", provider.getNMSClass("WorldChunkManagerOverworld"))
- .searchField("genLayer", "f", genLayerClass);
- provider.createLookup("nms_gen_layer", genLayerClass).searchField("areaLazy", "b", areaLazyClass);
- provider.createLookup("nms_area_lazy", areaLazyClass).searchField("transformer", "a", areaTransformer8Class);
-
- if (Versions.isServerCompat(1, 16, 2)) {
- provider.createLookup("nms_biome_registry", provider.getNMSClass("BiomeRegistry")).searchMethod("id", "a", int.class);
- provider.createLookup("nms_resource_key", provider.getNMSClass("ResourceKey")).searchMethod("key", "a");
- } else {
- provider.createLookup("nms_registry", iRegistryClass).searchField("biomeRegistry", "BIOME", iRegistryClass);
- provider.createLookup("nms_registry_materials", provider.getNMSClass("RegistryMaterials"))
- .searchMethod("id", "fromId", int.class).searchMethod("key", "getKey", Object.class);
- }
-
- provider.getLookup("nms_entity_spawner").searchMethod("load", "load", iBlockDataClass, nbtTagCompoundClass);
-
- }
-
-}
\ No newline at end of file
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup.java
index 72ea66a..3a4a257 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup.java
@@ -1,9 +1,10 @@
package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.version.provider.VersionProvider;
public abstract class VersionLookup {
- public abstract void setup(ClassLookupProvider provider);
+ public abstract void setup(final AccessorProvider provider, final VersionProvider version);
}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_14.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_14.java
new file mode 100644
index 0000000..3602892
--- /dev/null
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_14.java
@@ -0,0 +1,28 @@
+package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
+
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.version.provider.VersionProvider;
+
+public final class VersionLookup1_14 extends VersionLookup {
+
+ public VersionLookup1_14() {}
+
+ @Override
+ public void setup(final AccessorProvider provider, final VersionProvider version) {
+
+ final Class> iRegistryClass = version.minecraftClass("IRegistry");
+ final Class> genLayerClass = version.minecraftClass("GenLayer");
+ final Class> areaLazyClass = version.minecraftClass("AreaLazy");
+
+ provider.create("nms_world_chunk_manager_overworld", version.minecraftClass("WorldChunkManagerOverworld")).findField("genLayer",
+ "d");
+ provider.create("nms_gen_layer", genLayerClass).findField("areaLazy", "b");
+ provider.create("nms_area_lazy", areaLazyClass).findField("transformer", "a");
+
+ provider.create("nms_registry", iRegistryClass).findField("biomeRegistry", "BIOME");
+ provider.create("nms_registry_materials", version.minecraftClass("RegistryMaterials")).findMethod("id", "fromId", int.class)
+ .findMethod("key", "getKey", Object.class);
+
+ }
+
+}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_15.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_15.java
new file mode 100644
index 0000000..bd2ace5
--- /dev/null
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_15.java
@@ -0,0 +1,28 @@
+package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
+
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.version.provider.VersionProvider;
+
+public final class VersionLookup1_15 extends VersionLookup {
+
+ public VersionLookup1_15() {}
+
+ @Override
+ public void setup(final AccessorProvider provider, final VersionProvider version) {
+
+ final Class> iRegistryClass = version.minecraftClass("IRegistry");
+ final Class> genLayerClass = version.minecraftClass("GenLayer");
+ final Class> areaLazyClass = version.minecraftClass("AreaLazy");
+
+ provider.create("nms_world_chunk_manager_overworld", version.minecraftClass("WorldChunkManagerOverworld")).findField("genLayer",
+ "d");
+ provider.create("nms_gen_layer", genLayerClass).findField("areaLazy", "b");
+ provider.create("nms_area_lazy", areaLazyClass).findField("transformer", "a");
+
+ provider.create("nms_registry", iRegistryClass).findField("biomeRegistry", "BIOME");
+ provider.create("nms_registry_materials", version.minecraftClass("RegistryMaterials")).findMethod("id", "fromId", int.class)
+ .findMethod("key", "getKey", Object.class);
+
+ }
+
+}
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_16.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_16.java
new file mode 100644
index 0000000..1e462e0
--- /dev/null
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/handle/VersionLookup1_16.java
@@ -0,0 +1,38 @@
+package net.sourcewriters.spigot.rwg.legacy.api.impl.version.handle;
+
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.version.provider.VersionProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.version.util.Versions;
+
+public final class VersionLookup1_16 extends VersionLookup {
+
+ public VersionLookup1_16() {}
+
+ @Override
+ public void setup(final AccessorProvider provider, final VersionProvider version) {
+
+ final Class> nbtTagCompoundClass = provider.getOrNull("nms_nbt_compound").getOwner();
+ final Class> iBlockDataClass = provider.create("nms_blockdata", version.minecraftClass("IBlockData")).getOwner();
+
+ final Class> iRegistryClass = version.minecraftClass("IRegistry");
+ final Class> genLayerClass = version.minecraftClass("GenLayer");
+ final Class> areaLazyClass = version.minecraftClass("AreaLazy");
+ provider.create("nms_world_chunk_manager_overworld", version.minecraftClass("WorldChunkManagerOverworld")).findField("genLayer",
+ "f");
+ provider.create("nms_gen_layer", genLayerClass).findField("areaLazy", "b");
+ provider.create("nms_area_lazy", areaLazyClass).findField("transformer", "a");
+
+ if (Versions.isServerCompat(1, 16, 2)) {
+ provider.create("nms_biome_registry", version.minecraftClass("BiomeRegistry")).findMethod("id", "a", int.class);
+ provider.create("nms_resource_key", version.minecraftClass("ResourceKey")).findMethod("key", "a");
+ } else {
+ provider.create("nms_registry", iRegistryClass).findField("biomeRegistry", "BIOME");
+ provider.create("nms_registry_materials", version.minecraftClass("RegistryMaterials")).findMethod("id", "fromId", int.class)
+ .findMethod("key", "getKey", Object.class);
+ }
+
+ provider.getOrNull("nms_entity_spawner").findMethod("load", "load", iBlockDataClass, nbtTagCompoundClass);
+
+ }
+
+}
\ No newline at end of file
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
index 553811c..24dda98 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsBiomeAccessImpl.java
@@ -8,36 +8,35 @@
import com.google.common.hash.Hashing;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookup;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupCache;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.Accessor;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsBiomeAccess;
public final class NmsBiomeAccessImpl implements INmsBiomeAccess {
private final ConcurrentHashMap hashCache = new ConcurrentHashMap<>();
- private final ClassLookupCache cache;
+ private final AccessorProvider provider;
- public NmsBiomeAccessImpl(final ClassLookupProvider provider) {
- this.cache = provider.getCache();
+ public NmsBiomeAccessImpl(final AccessorProvider provider) {
+ this.provider = provider;
}
@Override
public Biome getBiomeAt(final World bukkitWorld, final int x, final int y, final int z) {
- Optional option;
- final ClassLookup refCbWorld = get("cb_world");
- final ClassLookup refWorldServer = get("nms_world_server");
- final ClassLookup refChunkProviderServer = get("nms_chunk_provider_server");
- final ClassLookup refChunkGenerator = get("nms_chunk_generator");
- final ClassLookup refWorldChunkManagerOverworld = get("nms_world_chunk_manager_overworld");
- final ClassLookup refGenLayer = get("nms_gen_layer");
- final ClassLookup refAreaLazy = get("nms_area_lazy");
- final ClassLookup refTransformer = get("nms_area_transformer_8");
- option = cache.get("nms_biome_registry");
- ClassLookup refRegistryExt = null;
- ClassLookup refRegistry;
- ClassLookup refMinecraftKeyExt = null;
+ Optional option;
+ final Accessor refCbWorld = get("cb_world");
+ final Accessor refWorldServer = get("nms_world_server");
+ final Accessor refChunkProviderServer = get("nms_chunk_provider_server");
+ final Accessor refChunkGenerator = get("nms_chunk_generator");
+ final Accessor refWorldChunkManagerOverworld = get("nms_world_chunk_manager_overworld");
+ final Accessor refGenLayer = get("nms_gen_layer");
+ final Accessor refAreaLazy = get("nms_area_lazy");
+ final Accessor refTransformer = get("nms_area_transformer_8");
+ option = provider.get("nms_biome_registry");
+ Accessor refRegistryExt = null;
+ Accessor refRegistry;
+ Accessor refMinecraftKeyExt = null;
if (option.isPresent()) {
refRegistry = option.get();
refMinecraftKeyExt = get("nms_resource_key");
@@ -45,31 +44,31 @@ public Biome getBiomeAt(final World bukkitWorld, final int x, final int y, final
refRegistryExt = get("nms_i_registry");
refRegistry = get("nms_registry_materials");
}
- final ClassLookup refMinecraftKey = get("nms_minecraft_key");
+ final Accessor refMinecraftKey = get("nms_minecraft_key");
- final Object worldServer = refCbWorld.run(bukkitWorld, "handle");
- final Object chunkProviderServer = refWorldServer.run(worldServer, "chunkProvider");
- final Object generator = refChunkProviderServer.run(chunkProviderServer, "generator");
- final Object chunkManager = refChunkGenerator.run(generator, "worldChunkManager");
- final Object genLayer = refWorldChunkManagerOverworld.getFieldValue(chunkManager, "genLayer");
- final Object areaLazy = refGenLayer.getFieldValue(genLayer, "areaLazy");
- final Object transformer = refAreaLazy.getFieldValue(areaLazy, "transformer");
+ final Object worldServer = refCbWorld.invoke(bukkitWorld, "handle");
+ final Object chunkProviderServer = refWorldServer.invoke(worldServer, "chunkProvider");
+ final Object generator = refChunkProviderServer.invoke(chunkProviderServer, "generator");
+ final Object chunkManager = refChunkGenerator.invoke(generator, "worldChunkManager");
+ final Object genLayer = refWorldChunkManagerOverworld.getValue(chunkManager, "genLayer");
+ final Object areaLazy = refGenLayer.getValue(genLayer, "areaLazy");
+ final Object transformer = refAreaLazy.getValue(areaLazy, "transformer");
final int[] coords = zoomInto(bukkitWorld.getSeed(), x, y, z);
- final int biomeId = (int) refTransformer.run(transformer, "apply", coords[0], coords[2]);
+ final int biomeId = (int) refTransformer.invoke(transformer, "apply", coords[0], coords[2]);
Object minecraftKey;
if (refRegistryExt == null) {
- final Object resourceKey = refRegistry.run("id", biomeId);
- minecraftKey = refMinecraftKeyExt.run(resourceKey, "key");
+ final Object resourceKey = refRegistry.invoke("id", biomeId);
+ minecraftKey = refMinecraftKeyExt.invoke(resourceKey, "key");
} else {
- final Object registry = refRegistryExt.getFieldValue("biomeRegistry");
- final Object object = refRegistry.run(registry, "id", biomeId);
- minecraftKey = refRegistry.run(registry, "key", object);
+ final Object registry = refRegistryExt.getValue("biomeRegistry");
+ final Object object = refRegistry.invoke(registry, "id", biomeId);
+ minecraftKey = refRegistry.invoke(registry, "key", object);
}
- final String biomeName = (String) refMinecraftKey.run(minecraftKey, "key");
+ final String biomeName = (String) refMinecraftKey.invoke(minecraftKey, "key");
return Biome.valueOf(biomeName.toUpperCase());
}
@@ -78,8 +77,8 @@ public long getSeedHash(final long seed) {
return hashCache.computeIfAbsent(seed, ignore -> Hashing.sha256().hashLong(seed).asLong());
}
- private ClassLookup get(final String name) {
- return cache.get(name).orElseThrow(() -> new NullPointerException("Some reflections are not available!"));
+ private Accessor get(final String name) {
+ return provider.get(name).orElseThrow(() -> new NullPointerException("Some reflections are not available!"));
}
/*
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsNbtAccessImpl.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsNbtAccessImpl.java
index c447b06..d69f6dc 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsNbtAccessImpl.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsNbtAccessImpl.java
@@ -17,16 +17,16 @@
import com.syntaxphoenix.syntaxapi.nbt.tools.NbtDeserializer;
import com.syntaxphoenix.syntaxapi.nbt.tools.NbtSerializer;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookup;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.Accessor;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsNbtAccess;
public final class NmsNbtAccessImpl implements INmsNbtAccess {
- private final ClassLookupProvider provider;
+ private final AccessorProvider provider;
private final ILogger logger;
- public NmsNbtAccessImpl(final ClassLookupProvider provider, final ILogger logger) {
+ public NmsNbtAccessImpl(final AccessorProvider provider, final ILogger logger) {
this.provider = provider;
this.logger = logger;
}
@@ -34,21 +34,21 @@ public NmsNbtAccessImpl(final ClassLookupProvider provider, final ILogger logger
@Override
public NbtCompound itemToCompound(final ItemStack itemStack) {
- final Optional option0 = provider.getOptionalLookup("cb_itemstack");
- final Optional option1 = provider.getOptionalLookup("nms_itemstack");
- final Optional option2 = provider.getOptionalLookup("nms_nbt_compound");
+ final Optional option0 = provider.get("cb_itemstack");
+ final Optional option1 = provider.get("nms_itemstack");
+ final Optional option2 = provider.get("nms_nbt_compound");
if (!option0.isPresent() || !option1.isPresent() || !option2.isPresent()) {
return null;
}
- final ClassLookup cbStack = option0.get();
- final ClassLookup nmsStack = option1.get();
- final ClassLookup nbt = option2.get();
+ final Accessor cbStack = option0.get();
+ final Accessor nmsStack = option1.get();
+ final Accessor nbt = option2.get();
- Object nbtCompound = nbt.init();
+ Object nbtCompound = nbt.initialize();
- final Object item = cbStack.run("nms", itemStack);
- nbtCompound = nmsStack.run(item, "save", nbtCompound);
+ final Object item = cbStack.invoke("nms", itemStack);
+ nbtCompound = nmsStack.invoke(item, "save", nbtCompound);
return (NbtCompound) fromMinecraftTag(nbtCompound);
@@ -57,17 +57,17 @@ public NbtCompound itemToCompound(final ItemStack itemStack) {
@Override
public ItemStack itemFromCompound(final NbtCompound compound) {
- final Optional option0 = provider.getOptionalLookup("cb_itemstack");
- final Optional option1 = provider.getOptionalLookup("nms_itemstack");
+ final Optional option0 = provider.get("cb_itemstack");
+ final Optional option1 = provider.get("nms_itemstack");
if (!option0.isPresent() || !option1.isPresent()) {
return null;
}
- final ClassLookup cbStack = option0.get();
- final ClassLookup nmsStack = option1.get();
+ final Accessor cbStack = option0.get();
+ final Accessor nmsStack = option1.get();
- final Object nmsItem = nmsStack.run("load", toMinecraftTag(compound));
- final Object bktItem = cbStack.run("bukkit", nmsItem);
+ final Object nmsItem = nmsStack.invoke("load", toMinecraftTag(compound));
+ final Object bktItem = cbStack.invoke("bukkit", nmsItem);
return (ItemStack) bktItem;
@@ -79,7 +79,7 @@ public NbtTag fromMinecraftTag(final Object nmsTag) {
final PipedOutputStream output = new PipedOutputStream();
final PipedInputStream stream = new PipedInputStream(output);
- provider.getLookup("nms_stream_tools").execute("write", nmsTag, new DataOutputStream(output));
+ provider.getOrNull("nms_stream_tools").invoke("write", nmsTag, new DataOutputStream(output));
final NbtTag tag = NbtDeserializer.UNCOMPRESSED.fromStream(stream).getTag();
output.close();
@@ -101,8 +101,8 @@ public Object toMinecraftTag(final NbtTag tag) {
NbtSerializer.UNCOMPRESSED.toStream(new NbtNamedTag("root", tag), stream);
- final Object nbt = provider.getLookup("nms_stream_tools").run("read", new DataInputStream(input), 0,
- provider.getLookup("nms_nbt_read_limiter").getFieldValue("limiter"));
+ final Object nbt = provider.getOrNull("nms_stream_tools").invoke("read", new DataInputStream(input), 0,
+ provider.getOrNull("nms_nbt_read_limiter").getValue("limiter"));
input.close();
stream.close();
diff --git a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
index 0f2927f..90e6626 100644
--- a/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
+++ b/legacy-pre1_17-compat/src/main/java/net/sourcewriters/spigot/rwg/legacy/api/impl/version/nms/NmsWorldAccessImpl.java
@@ -11,11 +11,10 @@
import com.mojang.authlib.GameProfile;
import com.syntaxphoenix.syntaxapi.nbt.NbtCompound;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.Accessor;
+import net.sourcewriters.spigot.rwg.legacy.api.util.java.reflect.AccessorProvider;
import net.sourcewriters.spigot.rwg.legacy.api.util.minecraft.ProfileCache;
import net.sourcewriters.spigot.rwg.legacy.api.util.rwg.RWGEntityType;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookup;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupCache;
-import net.sourcewriters.spigot.rwg.legacy.api.version.handle.ClassLookupProvider;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsNbtAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.nms.INmsWorldAccess;
import net.sourcewriters.spigot.rwg.legacy.api.version.util.ServerVersion;
@@ -23,11 +22,11 @@
public final class NmsWorldAccessImpl implements INmsWorldAccess {
- private final ClassLookupCache cache;
+ private final AccessorProvider provider;
private final INmsNbtAccess access;
- public NmsWorldAccessImpl(final ClassLookupProvider provider, final INmsNbtAccess access) {
- this.cache = provider.getCache();
+ public NmsWorldAccessImpl(final AccessorProvider provider, final INmsNbtAccess access) {
+ this.provider = provider;
this.access = access;
}
@@ -37,28 +36,28 @@ public void setSpawner(final Block block, final EntityType type, final short spa
final ServerVersion version = Versions.getServer();
- final Optional option0 = cache.get("cb_block_entityState");
- final Optional option1 = cache.get("nms_entity_spawner");
- final Optional option2 = cache.get("nms_nbt_compound");
- final Optional option3 = cache.get("nms_blockdata");
+ final Optional option0 = provider.get("cb_block_entityState");
+ final Optional option1 = provider.get("nms_entity_spawner");
+ final Optional option2 = provider.get("nms_nbt_compound");
+ final Optional option3 = provider.get("nms_blockdata");
if (!option0.isPresent() || !option1.isPresent() || !option2.isPresent() || version.getMinor() >= 16 && !option3.isPresent()) {
return;
}
- final ClassLookup state = option0.get();
- final ClassLookup spawner = option1.get();
- final ClassLookup nbt = option2.get();
- final ClassLookup blockData = option3.orElse(null);
+ final Accessor state = option0.get();
+ final Accessor spawner = option1.get();
+ final Accessor nbt = option2.get();
+ final Accessor blockData = option3.orElse(null);
final BlockState blockState = block.getState();
if (!(blockState instanceof CreatureSpawner)) {
return;
}
- final Object spawnerObject = state.run(blockState, "entity");
+ final Object spawnerObject = state.invoke(blockState, "entity");
- Object nbtCompound = nbt.init();
- nbtCompound = spawner.run(spawnerObject, "save", nbtCompound);
+ Object nbtCompound = nbt.initialize();
+ nbtCompound = spawner.invoke(spawnerObject, "save", nbtCompound);
final NbtCompound compound = (NbtCompound) access.fromMinecraftTag(nbtCompound);
@@ -80,9 +79,9 @@ public void setSpawner(final Block block, final EntityType type, final short spa
final Object spawnerCompound = access.toMinecraftTag(compound);
if (version.getMinor() >= 16) {
- spawner.execute(spawnerObject, "load", blockData.getOwner().cast(null), spawnerCompound);
+ spawner.invoke(spawnerObject, "load", blockData.getOwner().cast(null), spawnerCompound);
} else {
- spawner.execute(spawnerObject, "load", spawnerCompound);
+ spawner.invoke(spawnerObject, "load", spawnerCompound);
}
}
@@ -94,14 +93,14 @@ public void setHeadTexture(final Block block, final String texture) {
return;
}
- final Optional option0 = cache.get("nms_entity_skull");
- final Optional option1 = cache.get("cb_block_entityState");
+ final Optional option0 = provider.get("nms_entity_skull");
+ final Optional option1 = provider.get("cb_block_entityState");
if (!option0.isPresent() || !option1.isPresent()) {
return;
}
- final ClassLookup nmsSkull = option0.get();
- final ClassLookup cbEntityState = option1.get();
+ final Accessor nmsSkull = option0.get();
+ final Accessor cbEntityState = option1.get();
final BlockState state = block.getState();
if (!(state instanceof Skull)) {
@@ -110,27 +109,27 @@ public void setHeadTexture(final Block block, final String texture) {
final GameProfile gameProfile = ProfileCache.asProfile(texture);
- final Object tileEntity = cbEntityState.run(state, "entity");
- nmsSkull.execute(tileEntity, "profile", gameProfile);
+ final Object tileEntity = cbEntityState.invoke(state, "entity");
+ nmsSkull.invoke(tileEntity, "profile", gameProfile);
}
@Override
public String getHeadTexture(final Block block) {
- final Optional option0 = cache.get("cb_block_skull");
+ final Optional option0 = provider.get("cb_block_skull");
if (!option0.isPresent()) {
return null;
}
- final ClassLookup skull = option0.get();
+ final Accessor skull = option0.get();
final BlockState state = block.getState();
if (!(state instanceof Skull)) {
return null;
}
- return ProfileCache.asTexture((GameProfile) skull.getFieldValue(state, "profile"));
+ return ProfileCache.asTexture((GameProfile) skull.getValue(state, "profile"));
}
}
diff --git a/legacy-pre1_17-compat/src/main/resources/api.json b/legacy-pre1_17-compat/src/main/resources/api.json
index 3c08842..96a7c47 100644
--- a/legacy-pre1_17-compat/src/main/resources/api.json
+++ b/legacy-pre1_17-compat/src/main/resources/api.json
@@ -1,5 +1,5 @@
{
- "api": 3,
+ "api": 4,
"version": "${project.version}",
"minecraft": [
"1.13",