
com.github.sanctum.labyrinth.data.Region Maven / Gradle / Ivy
package com.github.sanctum.labyrinth.data;
import com.github.sanctum.labyrinth.LabyrinthProvider;
import com.github.sanctum.labyrinth.formatting.UniformedComponents;
import com.github.sanctum.labyrinth.library.Cuboid;
import com.github.sanctum.labyrinth.library.HUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@SuppressWarnings("UnusedReturnValue")
public abstract class Region implements Cuboid, Cloneable {
public static final FileManager DATA = FileList.search(LabyrinthProvider.getInstance().getPluginInstance()).get("Regions", "Persistent");
private static final List RECORD = new LinkedList<>();
private static final List LOADING = new LinkedList<>();
private static final List SPAWNING = new LinkedList<>();
private final int xMin;
private final int xMax;
private final int yMin;
private final int yMax;
private final int zMin;
private final int zMax;
private final World world;
private final HUID id;
private UUID owner;
private String name;
private boolean passthrough;
private Plugin plugin;
protected final List FLAGS;
private final List MEMBERS;
protected Region(Region cuboid) { // TODO: add explanation why passthrough field isn't copied
this(cuboid.xMin, cuboid.xMax, cuboid.yMin, cuboid.yMax, cuboid.zMin, cuboid.zMax, cuboid.world, cuboid.id);
setPlugin(cuboid.plugin);
setOwner(cuboid.owner);
setName(cuboid.getName());
addFlag(cuboid.FLAGS.toArray(new Flag[0]));
addMember(cuboid.MEMBERS.stream().map(Bukkit::getOfflinePlayer).toArray(OfflinePlayer[]::new));
}
protected Region(final Location point1, final Location point2) {
this(point1, point2, HUID.randomID());
}
protected Region(final Location point1, final Location point2, HUID id) {
this(Math.min(point1.getBlockX(), point2.getBlockX()), Math.max(point1.getBlockX(), point2.getBlockX()), Math.min(point1.getBlockY(), point2.getBlockY()), Math.max(point1.getBlockY(), point2.getBlockY()), Math.min(point1.getBlockZ(), point2.getBlockZ()), Math.max(point1.getBlockZ(), point2.getBlockZ()), point1.getWorld(), id);
}
protected Region(int xMin, int xMax, int yMin, int yMax, int zMin, int zMax, World world, HUID id) {
this.xMin = xMin;
this.xMax = xMax;
this.yMin = yMin;
this.yMax = yMax;
this.zMin = zMin;
this.zMax = zMax;
this.world = world;
this.id = id;
this.FLAGS = new LinkedList<>();
this.MEMBERS = new LinkedList<>();
this.plugin = JavaPlugin.getProvidingPlugin(getClass());
}
protected void setPlugin(Plugin plugin) {
this.plugin = plugin;
}
public Plugin getPlugin() {
return this.plugin;
}
public HUID getId() {
return this.id;
}
public Iterator getBlocksWithin() {
final List list = new ArrayList<>(this.getTotalBlockSize());
for (int x = this.xMin; x <= this.xMax; ++x) {
for (int y = this.yMin; y <= this.yMax; ++y) {
for (int z = this.zMin; z <= this.zMax; ++z) {
final Block b = this.world.getBlockAt(x, y, z);
list.add(b);
}
}
}
return list.iterator();
}
public List getLacedRegions() {
List list = new LinkedList<>();
for (Region c : cache().list()) {
for (Iterator it = getBlocksWithin(); it.hasNext(); ) {
Block b = it.next();
if (c.contains(b.getLocation()) && !c.getId().equals(getId())) {
list.add(c);
break;
}
}
}
return list;
}
public Location getHighest() {
return getStartingPoint().getBlockY() > getEndingPoint().getBlockY() ? getStartingPoint() : getEndingPoint();
}
public Location getLowest() {
return getEndingPoint().getBlockY() < getStartingPoint().getBlockY() ? getEndingPoint() : getStartingPoint();
}
public Location getCenter() {
return new Location(this.world, (double) (this.xMax - this.xMin) / 2 + this.xMin, (double) (this.yMax - this.yMin) / 2 + this.yMin, (double) (this.zMax - this.zMin) / 2 + this.zMin);
}
public double getDistanceBetween() {
return this.getStartingPoint().distance(this.getEndingPoint());
}
public Location getStartingPoint() {
return new Location(this.world, this.xMin, this.yMin, this.zMin);
}
public Location getEndingPoint() {
return new Location(this.world, this.xMax, this.yMax, this.zMax);
}
public Location getRandomWithin() {
Random r = new Random();
int x = r.nextInt(Math.abs(this.xMax - this.xMin) + 1) + this.xMin;
int y = r.nextInt(Math.abs(this.yMax - this.yMin) + 1) + this.yMin;
int z = r.nextInt(Math.abs(this.zMax - this.zMin) + 1) + this.zMin;
return new Location(this.world, x, y, z);
}
public void setName(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name != null ? name : id.toString();
}
@Override
public Boundary getBoundary() {
return new Boundary(xMax + 0.5, xMin + 0.5, yMax + 0.5, yMin + 0.5, zMax + 0.5, zMin + 0.5);
}
@Override
public World getWorld() {
return this.world;
}
@Override
public int getHeight() {
return this.yMax - this.yMin + 1;
}
@Override
public int getTotalBlockSize() {
return this.getHeight() * this.getXWidth() * this.getZWidth();
}
@Override
public int getXWidth() {
return this.xMax - this.xMin + 1;
}
@Override
public int getZWidth() {
return this.zMax - this.zMin + 1;
}
@Override
public int xMax() {
return xMax;
}
@Override
public int xMin() {
return xMin;
}
@Override
public int yMax() {
return yMax;
}
@Override
public int yMin() {
return yMin;
}
@Override
public int zMax() {
return zMax;
}
@Override
public int zMin() {
return zMin;
}
public OfflinePlayer getOwner() {
return owner != null ? Bukkit.getOfflinePlayer(owner) : null;
}
public void setOwner(UUID owner) {
this.owner = owner;
}
public List getMembers() {
return UniformedComponents.accept(MEMBERS).map(Bukkit::getOfflinePlayer).collect(Collectors.toList());
}
public List getFlags() {
return UniformedComponents.accept(FLAGS).sort();
}
public Optional getFlag(String id) {
return this.FLAGS.stream().filter(f -> f.getId().equals(id)).findFirst();
}
public boolean isMember(OfflinePlayer p) {
return UniformedComponents.accept(getMembers()).filter(o -> o.getUniqueId().equals(p.getUniqueId())).findAny().isPresent();
}
public boolean hasFlag(String id) {
return getFlag(id).isPresent();
}
public boolean hasFlag(Flag flag) {
return this.FLAGS.stream().anyMatch(f -> f.getId().equals(flag.getId()));
}
public boolean addFlag(Flag flag) {
if (!hasFlag(flag) && RegionServicesManager.getInstance().isRegistered(flag)) {
return this.FLAGS.add(flag.clone());
}
if (!hasFlag(flag) && !RegionServicesManager.getInstance().isRegistered(flag) && RegionServicesManager.getInstance().getFlagManager().getDefault().stream().anyMatch(f -> f.getId().equals(flag.getId()))) {
return this.FLAGS.add(flag.clone());
}
return false;
}
public boolean isPassthrough() {
return passthrough;
}
public void setPassthrough(boolean passthrough) {
this.passthrough = passthrough;
}
public boolean addFlag(Flag... flag) {
for (Flag f : flag) {
if (!addFlag(f)) {
return false;
}
}
return true;
}
public boolean addMember(OfflinePlayer p) {
if (isMember(p)) {
return false;
}
return MEMBERS.add(p.getUniqueId());
}
public boolean addMember(OfflinePlayer... p) {
for (OfflinePlayer op : p) {
if (!addMember(op)) {
return false;
}
}
return true;
}
public boolean removeMember(OfflinePlayer p) {
if (!isMember(p)) {
return false;
}
return MEMBERS.remove(p.getUniqueId());
}
public boolean removeFlag(Flag flag) {
return this.FLAGS.removeIf(f -> f.getId().equals(flag.getId()));
}
public boolean removeFlag(Flag... flag) {
for (Flag f : flag) {
if (!removeFlag(f)) {
return false;
}
}
return true;
}
public boolean removeMember(OfflinePlayer... p) {
for (OfflinePlayer op : p) {
if (!removeMember(op)) {
return false;
}
}
return true;
}
public boolean contains(final Location loc) {
return loc.getWorld() == this.world && loc.getBlockX() >= this.xMin && loc.getBlockX() <= this.xMax && loc.getBlockY() >= this.yMin && loc.getBlockY() <= this.yMax && loc
.getBlockZ() >= this.zMin && loc.getBlockZ() <= this.zMax;
}
public boolean contains(final Player player) {
return this.contains(player.getLocation());
}
public boolean contains(final Location loc, double precision) {
return loc.getWorld() == this.world && loc.getX() >= (xMin() + 0.5) - precision && loc.getX() <= (xMax() + 0.5) + precision && loc.getY() >= (yMin() + 0.5) - precision && loc
.getY() <= (yMax() + 0.5) + precision && loc.getZ() >= (zMin() + 0.5) - precision && loc.getZ() <= (zMax() + 0.5) + precision;
}
public boolean remove() {
return RECORD.remove(this);
}
public boolean load() {
return RECORD.add(this);
}
public void save() throws IOException {
if (this.getStartingPoint() != null && this.getEndingPoint() != null) {
if (!this.getName().equals(getId().toString())) {
DATA.getConfig().set("Markers.region." + getId().toString() + ".name", this.getName());
}
DATA.getConfig().set("Markers.region." + getId().toString() + ".plugin", this.getPlugin().getName());
DATA.getConfig().set("Markers.region." + getId().toString() + ".pos1", this.getStartingPoint());
DATA.getConfig().set("Markers.region." + getId().toString() + ".pos2", this.getEndingPoint());
DATA.getConfig().set("Markers.region." + getId().toString() + ".pass", this.isPassthrough());
DATA.getConfig().set("Markers.region." + getId().toString() + ".owner", this.getOwner().getUniqueId().toString());
DATA.getConfig().set("Markers.region." + getId().toString() + ".members", MEMBERS.stream().map(UUID::toString).collect(Collectors.toList()));
for (Flag f : getFlags()) {
DATA.getConfig().set("Markers.region." + getId().toString() + ".flags." + f.getId() + ".allowed", f.isAllowed());
DATA.getConfig().set("Markers.region." + getId().toString() + ".flags." + f.getId() + ".plugin", f.isValid() ? f.getHost().getName() : "NA");
DATA.getConfig().set("Markers.region." + getId().toString() + ".flags." + f.getId() + ".message", f.getMessage());
}
DATA.saveConfig();
} else
throw new IOException("One or more locations were found null during the saving process.");
}
@SuppressWarnings("MethodDoesntCallSuperMethod")
@Override
public Region clone() {
return new Standard(this);
}
public static UniformedComponents cache() {
return UniformedComponents.accept(RECORD);
}
public static UniformedComponents loading() {
return UniformedComponents.accept(LOADING);
}
public static UniformedComponents spawning() {
return UniformedComponents.accept(SPAWNING);
}
public static Optional spawn() {
for (Region c : cache().list()) {
if (c instanceof Spawn) {
if (((Spawn) c).location() != null)
return Optional.of((Spawn) c);
}
}
return Optional.empty();
}
public static Optional match(Location location) {
for (Region c : cache().list()) {
if (c.contains(location)) {
return Optional.of(c);
}
}
return Optional.empty();
}
public static List list(Location location) {
List list = new LinkedList<>();
for (Region c : cache().list()) {
if (c.contains(location)) {
list.add(c);
}
}
return list;
}
public static class Resident {
public static final List LIST = new LinkedList<>();
private final OfflinePlayer p;
private boolean spawnTagged;
private boolean pastSpawn;
protected Resident(OfflinePlayer player) {
this.p = player;
LIST.add(this);
}
public static Resident get(OfflinePlayer player) {
for (Resident resident : LIST) {
if (resident.getPlayer().equals(player)) {
return resident;
}
}
Resident r = new Resident(player);
LIST.add(r);
return r;
}
public OfflinePlayer getPlayer() {
return p;
}
public Player getOnline() {
return getPlayer().getPlayer();
}
public Optional getRegion() {
if (getPlayer().isOnline()) {
return CompletableFuture.supplyAsync(() -> Optional.ofNullable(getPlayer())
.map(OfflinePlayer::getPlayer)
.map(Player::getLocation)
.flatMap(Region::match)
).join();
}
return Optional.empty();
}
public boolean isSpawnTagged() {
return spawnTagged;
}
public boolean isPastSpawn() {
return pastSpawn;
}
public void setPastSpawn(boolean pastSpawn) {
this.pastSpawn = pastSpawn;
}
public void setSpawnTagged(boolean spawnTagged) {
this.spawnTagged = spawnTagged;
}
}
public static class Spawning extends Region {
private Location loc;
protected Spawning(Region cuboid) {
super(cuboid);
}
public Spawning(Location point1, Location point2) {
super(point1, point2);
}
public Spawning(Location point1, Location point2, HUID id) {
super(point1, point2, id);
}
public void setPlugin(Plugin plugin) {
super.setPlugin(plugin);
}
@Override
public boolean remove() {
return SPAWNING.remove(this);
}
@Override
public boolean load() {
return SPAWNING.add(this);
}
public Location location() {
return loc;
}
public void setLocation(Location loc) {
this.loc = loc;
}
public List getArea() {
List list = new LinkedList<>();
for (Spawning c : SPAWNING) {
for (Iterator it = getBlocksWithin(); it.hasNext(); ) {
Block b = it.next();
if (c.contains(b.getLocation())) {
list.add(c);
break;
}
}
}
return list;
}
@Override
public void save() throws IOException {
if (this.getStartingPoint() != null && this.getEndingPoint() != null && this.location() != null) {
if (!this.getName().equals(getId().toString())) {
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".name", this.getName());
}
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".plugin", this.getPlugin().getName());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".pos1", this.getStartingPoint());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".pos2", this.getEndingPoint());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".start", location());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".pass", this.isPassthrough());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".owner", this.getOwner().getUniqueId().toString());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".members", getMembers().stream().map(OfflinePlayer::getUniqueId).map(UUID::toString).collect(Collectors.toList()));
for (Flag f : getFlags()) {
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".flags." + f.getId() + ".allowed", f.isAllowed());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".flags." + f.getId() + ".plugin", f.isValid() ? f.getHost().getName() : "NA");
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".flags." + f.getId() + ".message", f.getMessage());
}
DATA.saveConfig();
} else
throw new IOException("One or more locations were found null during the saving process.");
}
}
public static class Loading extends Region {
protected Loading(Region cuboid) {
super(cuboid);
}
public Loading(Location point1, Location point2) {
super(point1, point2);
}
public Loading(Location point1, Location point2, HUID id) {
super(point1, point2, id);
}
public void setPlugin(Plugin plugin) {
super.setPlugin(plugin);
}
@Override
public boolean remove() {
return LOADING.remove(this);
}
@Override
public boolean load() {
return LOADING.add(this);
}
}
public static class Standard extends Region {
public Standard(Region cuboid) {
super(cuboid);
if (cuboid.getFlags().isEmpty()) {
FLAGS.addAll(RegionServicesManager.getInstance().getFlagManager().getDefault());
}
}
public Standard(Location point1, Location point2) {
super(point1, point2);
if (getFlags().isEmpty()) {
FLAGS.addAll(RegionServicesManager.getInstance().getFlagManager().getDefault());
}
}
public Standard(Location point1, Location point2, HUID id) {
super(point1, point2, id);
if (getFlags().isEmpty()) {
FLAGS.addAll(RegionServicesManager.getInstance().getFlagManager().getDefault());
}
}
public Standard forPlugin(Plugin plugin) {
super.setPlugin(plugin);
return this;
}
}
public static class Spawn extends Region {
private Location loc;
public Spawn(Spawning cuboid) {
super(cuboid);
if (cuboid.getFlags().isEmpty()) {
FLAGS.addAll(RegionServicesManager.getInstance().getFlagManager().getDefault());
}
}
public Spawn(Location point1, Location point2) {
super(point1, point2);
if (getFlags().isEmpty()) {
FLAGS.addAll(RegionServicesManager.getInstance().getFlagManager().getDefault());
}
}
public Spawn(Location point1, Location point2, HUID id) {
super(point1, point2, id);
if (getFlags().isEmpty()) {
FLAGS.addAll(RegionServicesManager.getInstance().getFlagManager().getDefault());
}
}
public Location location() {
return loc;
}
public void setLocation(Location loc) {
this.loc = loc;
}
public List getArea() {
List list = new LinkedList<>();
for (Region c : RECORD) {
if (c instanceof Spawn) {
for (Iterator it = getBlocksWithin(); it.hasNext(); ) {
Block b = it.next();
if (c.contains(b.getLocation())) {
list.add((Spawn) c);
break;
}
}
}
}
return list;
}
public Spawn forPlugin(Plugin plugin) {
super.setPlugin(plugin);
return this;
}
@Override
public void save() throws IOException {
if (this.getStartingPoint() != null && this.getEndingPoint() != null && this.location() != null) {
if (!this.getName().equals(getId().toString())) {
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".name", this.getName());
}
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".plugin", this.getPlugin().getName());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".pos1", this.getStartingPoint());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".pos2", this.getEndingPoint());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".start", location());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".pass", this.isPassthrough());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".owner", this.getOwner().getUniqueId().toString());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".members", getMembers().stream().map(OfflinePlayer::getUniqueId).map(UUID::toString).collect(Collectors.toList()));
for (Flag f : getFlags()) {
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".flags." + f.getId() + ".allowed", f.isAllowed());
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".flags." + f.getId() + ".plugin", f.isValid() ? f.getHost().getName() : "NA");
DATA.getConfig().set("Markers.spawn." + getId().toString() + ".flags." + f.getId() + ".message", f.getMessage());
}
DATA.saveConfig();
} else
throw new IOException("One or more locations were found null during the saving process.");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy