Skip to content

Instantly share code, notes, and snippets.

@dumptruckman
Created July 11, 2019 19:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dumptruckman/b637506f33936ee117168b3dee3df3b7 to your computer and use it in GitHub Desktop.
Save dumptruckman/b637506f33936ee117168b3dee3df3b7 to your computer and use it in GitHub Desktop.
A simple immutable block Location replacement for Bukkit that lacks references to Bukkit objects.
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
/**
* An immutable and "safe" location object for representing a block location.
* <p/>
* This is considered safe as it contains no references to any Bukkit objects so there is no risk of any ghost
* references. This makes it an ideal candidate for a hashable key.
*/
public class ImmutableBlockLocation implements ConfigurationSerializable {
private final UUID worldId;
private final int x, y, z;
/**
* Creates an origin location object in no world.
*/
private ImmutableBlockLocation() {
this(null, 0, 0, 0);
}
/**
* Creates a location object based on the location of the given block.
*
* @param block The block to copy the location of.
*/
public ImmutableBlockLocation(Block block) {
this(block.getWorld().getUID(), block.getX(), block.getY(), block.getZ());
}
/**
* Creates a location in the world with the given world id and x, y, z coordinates.
*
* @param worldId The uuid of the world for this location.
* @param x The x position.
* @param y The y position.
* @param z The z position.
*/
public ImmutableBlockLocation(UUID worldId, int x, int y, int z) {
this.worldId = worldId;
this.x = x;
this.y = y;
this.z = z;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ImmutableBlockLocation)) return false;
final ImmutableBlockLocation that = (ImmutableBlockLocation) o;
return x == that.x &&
y == that.y &&
z == that.z &&
Objects.equals(worldId, that.worldId);
}
@Override
public int hashCode() {
return Objects.hash(worldId, x, y, z);
}
@NotNull
public UUID getWorldId() {
return worldId;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
/**
* Creates a Bukkit {@link Location} object that matches the position of this location object.
*
* @return a Bukkit {@link Location} object that matches the position of this location object.
*/
@NotNull
public Location toBukkitLocation() {
return new Location(Bukkit.getWorld(worldId), x, y, z);
}
/**
* Returns the Block found at the location this object represents.
*
* @return the Block found at the location this object represents or null if this location does not have an
* associated world.
*/
@Nullable
public Block getBlock() {
World world = Bukkit.getWorld(worldId);
if (world == null) {
return null;
}
return world.getBlockAt(x, y, z);
}
@Override
public String toString() {
World world = Bukkit.getWorld(worldId);
return (world != null ? world.getName() : worldId) +
", " + x +
", " + y +
", " + z;
}
@NotNull
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("worldId", worldId.toString());
map.put("x", x);
map.put("y", y);
map.put("z", z);
return map;
}
/**
* Deserialize an ImmutableBlockLocation from the given map of serialized data.
*
* @param map The serialized data representing an ImmutableBlockLocation.
* @return A new ImmutableBlockLocation representing the serialized data.
*/
public static ImmutableBlockLocation deserialize(Map<String, Object> map) {
UUID worldId = UUID.fromString(map.get("worldId").toString());
int x = (int) map.get("x");
int y = (int) map.get("y");
int z = (int) map.get("z");
return new ImmutableBlockLocation(worldId, x, y, z);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment