package com.supaham.commons.bukkit.utils; import static com.google.common.base.Preconditions.checkArgument; import static com.supaham.commons.utils.StringUtils.checkNotNullOrEmpty; import com.supaham.commons.bukkit.utils.ImmutableBlockVector.ImmutableBlockVectorSerializer; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.util.BlockVector; import org.bukkit.util.Vector; import java.util.regex.Pattern; import javax.annotation.Nonnull; import javax.annotation.Nullable; import pluginbase.config.annotation.SerializeWith; import pluginbase.config.serializers.Serializer; import pluginbase.config.serializers.SerializerSet; /** * Represents an immutable version of Bukkit's {@link BlockVector} class; providing stability in * long-term use. This class does not actually extend {@link BlockVector}, to get an instance of * {@link BlockVector}, call {@link #toBlockVector()}. The same applies with {@link Location}, * {@link #toLocation(World)}. * <br/> * {@link ImmutableBlockVector}s may be cloned using {@link #ImmutableBlockVector(ImmutableVector)} * <br/> * This class functions exactly like Bukkit's {@link BlockVector}, so things like {@link * #equals(Object)} utilizes an {@link #EPSILON} value of 0.000001 to ensure stability. * <p/> * <b>Note: This class supports PluginBase serialization, using {@link * ImmutableBlockVectorSerializer}</b> * * @see #ImmutableBlockVector(ImmutableVector) * @see #ImmutableBlockVector(Vector) * @see #ImmutableBlockVector(int, int, int) * @since 0.3.5 */ @SerializeWith(ImmutableBlockVectorSerializer.class) public class ImmutableBlockVector extends ImmutableVector { public static final ImmutableBlockVector ZERO = new ImmutableBlockVector(0, 0, 0); public static final ImmutableBlockVector ONE = new ImmutableBlockVector(1, 1, 1); public ImmutableBlockVector(@Nonnull ImmutableVector vector) { this(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); } public ImmutableBlockVector(@Nonnull Vector vector) { this(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); } public ImmutableBlockVector(int x, int y, int z) { super(x, y, z); } public int hashCode() { return (Integer.valueOf((int) x).hashCode() >> 13) ^ (Integer.valueOf((int) y).hashCode() >> 7) ^ Integer.valueOf((int) z).hashCode(); } @Override public String toString() { return "ImmutableBlockVector{" + "x=" + getBlockX() + ", y=" + getBlockY() + ", z=" + getBlockZ() + '}'; } public static final class ImmutableBlockVectorSerializer implements Serializer<ImmutableBlockVector> { private static final Pattern PATTERN = Pattern.compile("\\s*,\\s*"); @Nullable @Override public Object serialize(@Nullable ImmutableBlockVector object, @Nonnull SerializerSet serializerSet) throws IllegalArgumentException { if (object == null) { return null; } return object.getBlockX() + "," + object.getBlockY() + "," + object.getBlockZ(); } @Nullable @Override public ImmutableBlockVector deserialize(@Nullable Object serialized, @Nonnull Class wantedType, @Nonnull SerializerSet serializerSet) throws IllegalArgumentException { if (serialized == null) { return null; } checkNotNullOrEmpty(serialized.toString(), "serialized string"); String[] split = PATTERN.split(serialized.toString(), 3); checkArgument(split.length == 3, "string is in an invalid format."); return new ImmutableBlockVector(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])); } } }