package com.comphenix.protocol.wrappers; import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.ConstructorAccessor; import com.comphenix.protocol.reflect.accessors.FieldAccessor; import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract; import com.comphenix.protocol.utility.MinecraftReflection; import com.google.common.base.Objects; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.List; /** * Represents a ChunkCoordIntPair. * @author Kristian */ public class ChunkCoordIntPair { private static Class COORD_PAIR_CLASS = MinecraftReflection.getChunkCoordIntPair(); private static ConstructorAccessor COORD_CONSTRUCTOR; private static FieldAccessor COORD_X; private static FieldAccessor COORD_Z; // Use protected members, like Bukkit protected final int chunkX; protected final int chunkZ; /** * Construct a new chunk coord int pair. * @param x - the x index of the chunk. * @param z - the z index of the chunk. */ public ChunkCoordIntPair(int x, int z) { this.chunkX = x; this.chunkZ = z; } /** * Retrieve the chunk index in the x-dimension. *

* This is the number of adjacent chunks to (0, 0), not a block coordinate. * @return The x chunk index. */ public int getChunkX() { return chunkX; } /** * Retrieve the chunk index in the z-dimension. *

* This is the number of adjacent chunks to (0, 0), not a block coordinate. * @return The z chunk index. */ public int getChunkZ() { return chunkZ; } /** * Used to convert between NMS ChunkPosition and the wrapper instance. * @return A new converter. */ public static EquivalentConverter getConverter() { return new EquivalentConverter() { @Override public Object getGeneric(ChunkCoordIntPair specific) { if (COORD_CONSTRUCTOR == null) { COORD_CONSTRUCTOR = Accessors.getConstructorAccessor(COORD_PAIR_CLASS, int.class, int.class); } return COORD_CONSTRUCTOR.invoke(specific.chunkX, specific.chunkZ); } @Override public ChunkCoordIntPair getSpecific(Object generic) { if (MinecraftReflection.isChunkCoordIntPair(generic)) { if (COORD_X == null || COORD_Z == null) { FuzzyReflection fuzzy = FuzzyReflection.fromClass(COORD_PAIR_CLASS, true); List fields = fuzzy.getFieldList(FuzzyFieldContract .newBuilder() .banModifier(Modifier.STATIC) .typeExact(int.class) .build()); COORD_X = Accessors.getFieldAccessor(fields.get(0)); COORD_Z = Accessors.getFieldAccessor(fields.get(1)); } return new ChunkCoordIntPair((Integer) COORD_X.get(generic), (Integer) COORD_Z.get(generic)); } // Otherwise, return NULL return null; } @Override public Class getSpecificType() { return ChunkCoordIntPair.class; } }; } @Override public boolean equals(Object obj) { if (this == obj) return true; // Only compare objects of similar type if (obj instanceof ChunkCoordIntPair) { ChunkCoordIntPair other = (ChunkCoordIntPair) obj; return chunkX == other.chunkX && chunkZ == other.chunkZ; } return false; } @Override public int hashCode() { return Objects.hashCode(chunkX, chunkZ); } @Override public String toString() { return "ChunkCoordIntPair [x=" + chunkX + ", z=" + chunkZ + "]"; } }