Restructures the code and add classes/interfaces to the API module
I tried creating a usable API module containing everything important without introducing too many changes that cost time and might confuse people when migration to the new module. We have limited time right now and need to push the 1.20 update... So no additional thoughts on the API design (so I can regret it in the somewhat near future \o/)
This commit is contained in:
parent
da2e999ef9
commit
bbfd62c1d3
|
@ -0,0 +1,29 @@
|
|||
package com.songoda.epicanchors;
|
||||
|
||||
import com.songoda.epicanchors.api.AnchorManager;
|
||||
|
||||
public final class EpicAnchorsApi {
|
||||
private static EpicAnchorsApi instance;
|
||||
|
||||
private final AnchorManager anchorManager;
|
||||
|
||||
private EpicAnchorsApi(AnchorManager anchorManager) {
|
||||
this.anchorManager = anchorManager;
|
||||
}
|
||||
|
||||
public AnchorManager getAnchorManager() {
|
||||
return this.anchorManager;
|
||||
}
|
||||
|
||||
public static EpicAnchorsApi getApi() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void initApi(AnchorManager anchorManager) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException("EpicAnchorsApi already initialized");
|
||||
}
|
||||
|
||||
instance = new EpicAnchorsApi(anchorManager);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.songoda.epicanchors.api;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Anchor {
|
||||
int getDbId();
|
||||
|
||||
UUID getOwner();
|
||||
|
||||
boolean isLegacy();
|
||||
|
||||
@NotNull Location getLocation();
|
||||
|
||||
@NotNull World getWorld();
|
||||
|
||||
@NotNull Chunk getChunk();
|
||||
|
||||
int getTicksLeft();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
void setTicksLeft(int ticksLeft);
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
int addTicksLeft(int ticks);
|
||||
|
||||
int removeTicksLeft(int ticks);
|
||||
|
||||
boolean isInfinite();
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package com.songoda.epicanchors.api;
|
||||
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
|
@ -0,0 +1,88 @@
|
|||
package com.songoda.epicanchors.api;
|
||||
|
||||
import com.craftaro.core.third_party.com.cryptomorin.xseries.XMaterial;
|
||||
import com.songoda.epicanchors.utils.Callback;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface AnchorManager {
|
||||
String NBT_TICKS_KEY = "EpicAnchors_Ticks".toLowerCase();
|
||||
|
||||
boolean isReady(World world);
|
||||
|
||||
Anchor[] getAnchors(@NotNull World world);
|
||||
|
||||
@Nullable Anchor getAnchor(@NotNull Block block);
|
||||
|
||||
boolean isAnchor(@NotNull Block block);
|
||||
|
||||
boolean hasAnchor(@NotNull Chunk chunk);
|
||||
|
||||
List<Anchor> searchAnchors(Location center, double searchRadius);
|
||||
|
||||
List<Anchor> searchAnchors(Location center, double searchRadius, boolean ignoreHeight);
|
||||
|
||||
/**
|
||||
* Creates a new anchor at a given location
|
||||
*
|
||||
* @param loc The block location for the anchor
|
||||
* @param ticks The amount of ticks the anchor lives or -1 for infinite
|
||||
*/
|
||||
void createAnchor(@NotNull Location loc, @NotNull UUID owner, int ticks, @Nullable Callback<Anchor> callback);
|
||||
|
||||
void destroyAnchor(@NotNull Anchor anchor);
|
||||
|
||||
void destroyAnchor(@NotNull Anchor anchor, boolean forceSkipItemDrop);
|
||||
|
||||
void registerAccessCheck(AnchorAccessCheck accessCheck);
|
||||
|
||||
/**
|
||||
* @param accessCheck The {@link AnchorAccessCheck} to remove
|
||||
* @return true if the {@link AnchorAccessCheck} has been found and removed, false otherwise
|
||||
*/
|
||||
boolean unregisterAccessCheck(AnchorAccessCheck accessCheck);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #hasAccess(Anchor, UUID)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
boolean hasAccess(@NotNull Anchor anchor, @NotNull OfflinePlayer p);
|
||||
|
||||
/**
|
||||
* Checks if a player has access to an Anchor. By default, only the owner has access to an Anchor.
|
||||
* <br>
|
||||
* Other plugins can grant access to other players (e.g. friends).
|
||||
* <br>
|
||||
* Legacy anchors without an owner automatically grant access to all players.
|
||||
*
|
||||
* @return true if the player may access the Anchor, false otherwise
|
||||
* @see #registerAccessCheck(AnchorAccessCheck)
|
||||
*/
|
||||
boolean hasAccess(@NotNull Anchor anchor, @NotNull UUID uuid);
|
||||
|
||||
|
||||
ItemStack createAnchorItem(int ticks);
|
||||
|
||||
ItemStack createAnchorItem(int ticks, Material material);
|
||||
|
||||
ItemStack createAnchorItem(int ticks, XMaterial material);
|
||||
|
||||
boolean toggleChunkVisualized(Player p);
|
||||
|
||||
void setChunksVisualized(Player p, boolean visualize);
|
||||
|
||||
boolean hasChunksVisualized(Player p);
|
||||
|
||||
void updateHolograms(List<Anchor> anchors);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.songoda.epicanchors;
|
||||
|
||||
import com.songoda.epicanchors.api.Anchor;
|
||||
import com.songoda.epicanchors.utils.WorldUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
|
@ -12,7 +13,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Anchor {
|
||||
public class AnchorImpl implements Anchor {
|
||||
private final int dbId;
|
||||
|
||||
private final UUID owner;
|
||||
|
@ -20,7 +21,7 @@ public class Anchor {
|
|||
private final Location location;
|
||||
private int ticksLeft;
|
||||
|
||||
public Anchor(int dbId, @Nullable UUID owner, @NotNull Location location, int ticksLeft) {
|
||||
public AnchorImpl(int dbId, @Nullable UUID owner, @NotNull Location location, int ticksLeft) {
|
||||
if (dbId <= 0) throw new IllegalArgumentException("Invalid value for dbId");
|
||||
if (ticksLeft <= 0 && ticksLeft != -1) throw new IllegalArgumentException("Invalid value for ticksLeft");
|
||||
|
||||
|
@ -66,34 +67,42 @@ public class Anchor {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDbId() {
|
||||
return this.dbId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getOwner() {
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLegacy() {
|
||||
return this.owner == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Location getLocation() {
|
||||
return this.location.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull World getWorld() {
|
||||
return this.location.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Chunk getChunk() {
|
||||
return this.location.getChunk();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTicksLeft() {
|
||||
return this.ticksLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unused")
|
||||
public void setTicksLeft(int ticksLeft) {
|
||||
if (ticksLeft < 0) throw new IllegalArgumentException("Invalid value for ticksLeft");
|
||||
|
@ -101,6 +110,7 @@ public class Anchor {
|
|||
this.ticksLeft = ticksLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public int addTicksLeft(int ticks) {
|
||||
if (!isInfinite()) {
|
||||
|
@ -110,6 +120,7 @@ public class Anchor {
|
|||
return this.ticksLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeTicksLeft(int ticks) {
|
||||
if (!isInfinite()) {
|
||||
this.ticksLeft -= ticks;
|
||||
|
@ -122,6 +133,7 @@ public class Anchor {
|
|||
return this.ticksLeft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInfinite() {
|
||||
return this.ticksLeft == -1;
|
||||
}
|
|
@ -5,10 +5,13 @@ import com.craftaro.core.compatibility.CompatibleMaterial;
|
|||
import com.craftaro.core.compatibility.CompatibleParticleHandler;
|
||||
import com.craftaro.core.compatibility.CompatibleSound;
|
||||
import com.craftaro.core.hooks.HologramManager;
|
||||
import com.craftaro.core.third_party.com.cryptomorin.xseries.XMaterial;
|
||||
import com.craftaro.core.third_party.de.tr7zw.nbtapi.NBTItem;
|
||||
import com.craftaro.core.utils.TextUtils;
|
||||
import com.craftaro.core.utils.TimeUtils;
|
||||
import com.songoda.epicanchors.api.Anchor;
|
||||
import com.songoda.epicanchors.api.AnchorAccessCheck;
|
||||
import com.songoda.epicanchors.api.AnchorManager;
|
||||
import com.songoda.epicanchors.files.DataManager;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.songoda.epicanchors.utils.Callback;
|
||||
|
@ -39,9 +42,8 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AnchorManager {
|
||||
public class AnchorManagerImpl implements AnchorManager {
|
||||
private static final String ERR_WORLD_NOT_READY = "EpicAnchors has not finished initializing that world yet";
|
||||
private static final String NBT_TICKS_KEY = "EpicAnchors_Ticks".toLowerCase();
|
||||
|
||||
private final SongodaPlugin plugin;
|
||||
private final DataManager dataManager;
|
||||
|
@ -52,7 +54,7 @@ public class AnchorManager {
|
|||
|
||||
private boolean ready;
|
||||
|
||||
public AnchorManager(SongodaPlugin plugin, DataManager dataManager) {
|
||||
public AnchorManagerImpl(SongodaPlugin plugin, DataManager dataManager) {
|
||||
this.plugin = Objects.requireNonNull(plugin);
|
||||
this.dataManager = Objects.requireNonNull(dataManager);
|
||||
}
|
||||
|
@ -82,12 +84,12 @@ public class AnchorManager {
|
|||
|
||||
this.dataManager.getAnchors(world, (ex, result) -> {
|
||||
if (ex == null) {
|
||||
this.anchors.computeIfAbsent(world, k -> new HashSet<>());
|
||||
this.anchors.computeIfAbsent(world, key -> new HashSet<>());
|
||||
|
||||
for (Anchor anchor : result) {
|
||||
anchor.init(this.plugin);
|
||||
((AnchorImpl) anchor).init(this.plugin);
|
||||
|
||||
this.anchors.computeIfAbsent(anchor.getWorld(), k -> new HashSet<>())
|
||||
this.anchors.computeIfAbsent(anchor.getWorld(), key -> new HashSet<>())
|
||||
.add(anchor);
|
||||
}
|
||||
|
||||
|
@ -115,7 +117,7 @@ public class AnchorManager {
|
|||
this.dataManager.updateAnchors(tmpAnchors, null);
|
||||
|
||||
for (Anchor anchor : tmpAnchors) {
|
||||
anchor.deInit(this.plugin);
|
||||
((AnchorImpl) anchor).deInit(this.plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,13 +128,14 @@ public class AnchorManager {
|
|||
Bukkit.getScheduler().runTaskTimer(this.plugin, this::saveAll, 20L * 60 * 5, 20L * 60 * 5);
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
@Override
|
||||
public boolean isReady(World world) {
|
||||
return this.ready && this.anchors.containsKey(world);
|
||||
}
|
||||
|
||||
/* Getter */
|
||||
|
||||
@Override
|
||||
public Anchor[] getAnchors(@NotNull World world) {
|
||||
Set<Anchor> set = this.anchors.get(world);
|
||||
|
||||
|
@ -143,13 +146,14 @@ public class AnchorManager {
|
|||
return new Anchor[0];
|
||||
}
|
||||
|
||||
public @Nullable Anchor getAnchor(@NotNull Block b) {
|
||||
if (!isReady(b.getWorld())) {
|
||||
@Override
|
||||
public @Nullable Anchor getAnchor(@NotNull Block block) {
|
||||
if (!isReady(block.getWorld())) {
|
||||
throw new IllegalStateException(ERR_WORLD_NOT_READY);
|
||||
}
|
||||
|
||||
Location bLoc = b.getLocation();
|
||||
Set<Anchor> set = this.anchors.get(b.getWorld());
|
||||
Location bLoc = block.getLocation();
|
||||
Set<Anchor> set = this.anchors.get(block.getWorld());
|
||||
|
||||
if (set != null) {
|
||||
for (Anchor anchor : set) {
|
||||
|
@ -162,10 +166,12 @@ public class AnchorManager {
|
|||
return null;
|
||||
}
|
||||
|
||||
public boolean isAnchor(@NotNull Block b) {
|
||||
return getAnchor(b) != null;
|
||||
@Override
|
||||
public boolean isAnchor(@NotNull Block block) {
|
||||
return getAnchor(block) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnchor(@NotNull Chunk chunk) {
|
||||
if (!isReady(chunk.getWorld())) {
|
||||
throw new IllegalStateException(ERR_WORLD_NOT_READY);
|
||||
|
@ -184,11 +190,13 @@ public class AnchorManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unused")
|
||||
public List<Anchor> searchAnchors(Location center, double searchRadius) {
|
||||
return searchAnchors(center, searchRadius, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Anchor> searchAnchors(Location center, double searchRadius, boolean ignoreHeight) {
|
||||
List<Anchor> result = new ArrayList<>();
|
||||
|
||||
|
@ -214,12 +222,7 @@ public class AnchorManager {
|
|||
|
||||
/* Create 'n Destroy */
|
||||
|
||||
/**
|
||||
* Creates a new anchor at a given location
|
||||
*
|
||||
* @param loc The block location for the anchor
|
||||
* @param ticks The amount of ticks the anchor lives or -1 for infinite
|
||||
*/
|
||||
@Override
|
||||
public void createAnchor(@NotNull Location loc, @NotNull UUID owner, int ticks, @Nullable Callback<Anchor> callback) {
|
||||
if (!isReady(loc.getWorld())) {
|
||||
throw new IllegalStateException(ERR_WORLD_NOT_READY);
|
||||
|
@ -234,10 +237,10 @@ public class AnchorManager {
|
|||
}
|
||||
} else {
|
||||
Bukkit.getScheduler().runTask(this.plugin, () -> {
|
||||
Block b = loc.getBlock();
|
||||
b.setType(Settings.MATERIAL.getMaterial().getMaterial());
|
||||
Block block = loc.getBlock();
|
||||
block.setType(Settings.MATERIAL.getMaterial().parseMaterial());
|
||||
|
||||
this.anchors.computeIfAbsent(anchor.getWorld(), k -> new HashSet<>())
|
||||
this.anchors.computeIfAbsent(anchor.getWorld(), key -> new HashSet<>())
|
||||
.add(anchor);
|
||||
|
||||
updateHologram(anchor);
|
||||
|
@ -250,10 +253,12 @@ public class AnchorManager {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyAnchor(@NotNull Anchor anchor) {
|
||||
destroyAnchor(anchor, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyAnchor(@NotNull Anchor anchor, boolean forceSkipItemDrop) {
|
||||
if (!isReady(anchor.getWorld())) {
|
||||
throw new IllegalStateException(ERR_WORLD_NOT_READY);
|
||||
|
@ -269,7 +274,7 @@ public class AnchorManager {
|
|||
Block anchorBlock = anchorLoc.getBlock();
|
||||
Material anchorMaterial = anchorBlock.getType();
|
||||
|
||||
if (anchorBlock.getType() == Settings.MATERIAL.getMaterial().getMaterial()) {
|
||||
if (anchorBlock.getType() == Settings.MATERIAL.getMaterial().parseMaterial()) {
|
||||
anchorBlock.setType(Material.AIR);
|
||||
}
|
||||
|
||||
|
@ -285,13 +290,13 @@ public class AnchorManager {
|
|||
CompatibleParticleHandler.spawnParticles(CompatibleParticleHandler.ParticleType.getParticle(Settings.PARTICLE_DESTROY.getString()),
|
||||
anchor.getLocation().add(.5, .5, .5), 100, .5, .5, .5);
|
||||
|
||||
anchor.deInit(this.plugin);
|
||||
((AnchorImpl) anchor).deInit(this.plugin);
|
||||
this.dataManager.deleteAnchorAsync(anchor);
|
||||
}
|
||||
|
||||
/* Anchor access */
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public void registerAccessCheck(AnchorAccessCheck accessCheck) {
|
||||
if (!this.accessChecks.contains(accessCheck)) {
|
||||
// Adding at the start of the list makes sure the default check is
|
||||
|
@ -299,31 +304,17 @@ public class AnchorManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param accessCheck The {@link AnchorAccessCheck} to remove
|
||||
*
|
||||
* @return true if the {@link AnchorAccessCheck} has been found and removed, false otherwise
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public boolean unregisterAccessCheck(AnchorAccessCheck accessCheck) {
|
||||
return this.accessChecks.remove(accessCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAccess(@NotNull Anchor anchor, @NotNull OfflinePlayer p) {
|
||||
return hasAccess(anchor, p.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has access to an Anchor. By default, only the owner has access to an Anchor.
|
||||
* <br>
|
||||
* Other plugins can grant access to other players (e.g. friends).
|
||||
* <br>
|
||||
* Legacy anchors without an owner automatically grant access to all players.
|
||||
*
|
||||
* @return true if the player may access the Anchor, false otherwise
|
||||
*
|
||||
* @see #registerAccessCheck(AnchorAccessCheck)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasAccess(@NotNull Anchor anchor, @NotNull UUID uuid) {
|
||||
if (anchor.isLegacy() || anchor.getOwner().equals(uuid)) return true;
|
||||
|
||||
|
@ -338,18 +329,21 @@ public class AnchorManager {
|
|||
|
||||
/* Anchor item */
|
||||
|
||||
@Override
|
||||
public ItemStack createAnchorItem(int ticks) {
|
||||
return createAnchorItem(ticks, Settings.MATERIAL.getMaterial());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createAnchorItem(int ticks, Material material) {
|
||||
return createAnchorItem(ticks, CompatibleMaterial.getMaterial(material));
|
||||
return createAnchorItem(ticks, CompatibleMaterial.getMaterial(material).get());
|
||||
}
|
||||
|
||||
public ItemStack createAnchorItem(int ticks, CompatibleMaterial material) {
|
||||
@Override
|
||||
public ItemStack createAnchorItem(int ticks, XMaterial material) {
|
||||
if (ticks <= 0 && ticks != -1) throw new IllegalArgumentException();
|
||||
|
||||
ItemStack item = material.getItem();
|
||||
ItemStack item = material.parseItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
assert meta != null;
|
||||
|
@ -363,43 +357,9 @@ public class AnchorManager {
|
|||
return nbtItem.getItem();
|
||||
}
|
||||
|
||||
public static int getTicksFromItem(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NBTItem nbtItem = new NBTItem(item);
|
||||
|
||||
if (nbtItem.hasTag(NBT_TICKS_KEY)) {
|
||||
return nbtItem.getInteger(NBT_TICKS_KEY);
|
||||
}
|
||||
|
||||
// Legacy code (pre v2) to stay cross-version compatible
|
||||
if (Settings.MATERIAL.getMaterial().getMaterial() == item.getType()) {
|
||||
if (nbtItem.hasTag("ticks")) {
|
||||
int result = nbtItem.getInteger("ticks");
|
||||
|
||||
return result == -99 ? -1 : result;
|
||||
}
|
||||
|
||||
// Tries to get the ticks remaining from hidden text
|
||||
if (item.hasItemMeta() &&
|
||||
item.getItemMeta().hasDisplayName() &&
|
||||
item.getItemMeta().getDisplayName().contains(":")) {
|
||||
try {
|
||||
int result = Integer.parseInt(item.getItemMeta().getDisplayName().replace("§", "").split(":")[0]);
|
||||
|
||||
return result == -99 ? -1 : result;
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Chunk visualization */
|
||||
|
||||
@Override
|
||||
public boolean toggleChunkVisualized(Player p) {
|
||||
boolean visualize = !hasChunksVisualized(p);
|
||||
|
||||
|
@ -408,6 +368,7 @@ public class AnchorManager {
|
|||
return visualize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunksVisualized(Player p, boolean visualize) {
|
||||
if (visualize) {
|
||||
this.visualizedChunk.add(p);
|
||||
|
@ -416,6 +377,7 @@ public class AnchorManager {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
public boolean hasChunksVisualized(Player p) {
|
||||
return this.visualizedChunk.contains(p);
|
||||
|
@ -423,6 +385,7 @@ public class AnchorManager {
|
|||
|
||||
/* Holograms */
|
||||
|
||||
@Override
|
||||
public void updateHolograms(List<Anchor> anchors) {
|
||||
// are holograms enabled?
|
||||
if (!Settings.HOLOGRAMS.getBoolean() || !HologramManager.getManager().isEnabled()) return;
|
||||
|
@ -473,6 +436,41 @@ public class AnchorManager {
|
|||
return TextUtils.formatText(Settings.NAME_TAG.getString().replace("{REMAINING}", remaining));
|
||||
}
|
||||
|
||||
public static int getTicksFromItem(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NBTItem nbtItem = new NBTItem(item);
|
||||
|
||||
if (nbtItem.hasTag(NBT_TICKS_KEY)) {
|
||||
return nbtItem.getInteger(NBT_TICKS_KEY);
|
||||
}
|
||||
|
||||
// Legacy code (pre v2) to stay cross-version compatible
|
||||
if (Settings.MATERIAL.getMaterial().parseMaterial() == item.getType()) {
|
||||
if (nbtItem.hasTag("ticks")) {
|
||||
int result = nbtItem.getInteger("ticks");
|
||||
|
||||
return result == -99 ? -1 : result;
|
||||
}
|
||||
|
||||
// Tries to get the ticks remaining from hidden text
|
||||
if (item.hasItemMeta() &&
|
||||
item.getItemMeta().hasDisplayName() &&
|
||||
item.getItemMeta().getDisplayName().contains(":")) {
|
||||
try {
|
||||
int result = Integer.parseInt(item.getItemMeta().getDisplayName().replace("§", "").split(":")[0]);
|
||||
|
||||
return result == -99 ? -1 : result;
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void removeHologram(Anchor anchor) {
|
||||
HologramManager.removeHologram("Anchor#" + anchor.getDbId());
|
||||
}
|
|
@ -10,6 +10,7 @@ import com.craftaro.core.database.SQLiteConnector;
|
|||
import com.craftaro.core.gui.GuiManager;
|
||||
import com.craftaro.core.hooks.EconomyManager;
|
||||
import com.craftaro.core.hooks.HologramManager;
|
||||
import com.songoda.epicanchors.api.AnchorManager;
|
||||
import com.songoda.epicanchors.commands.EpicAnchorsCommand;
|
||||
import com.songoda.epicanchors.commands.sub.GiveCommand;
|
||||
import com.songoda.epicanchors.commands.sub.ReloadCommand;
|
||||
|
@ -35,7 +36,7 @@ import java.util.logging.Level;
|
|||
|
||||
public final class EpicAnchors extends SongodaPlugin {
|
||||
private GuiManager guiManager;
|
||||
private AnchorManager anchorManager;
|
||||
private AnchorManagerImpl anchorManager;
|
||||
|
||||
private DataManager dataManager;
|
||||
|
||||
|
@ -55,7 +56,8 @@ public final class EpicAnchors extends SongodaPlugin {
|
|||
anchorMigration.runMigrations();
|
||||
|
||||
anchorMigration.migrateLegacyData(this);
|
||||
this.anchorManager = new AnchorManager(this, this.dataManager);
|
||||
this.anchorManager = new AnchorManagerImpl(this, this.dataManager);
|
||||
EpicAnchorsApi.initApi(this.anchorManager);
|
||||
|
||||
// Economy [1/2]
|
||||
EconomyManager.load();
|
||||
|
|
|
@ -38,7 +38,7 @@ public class EpicAnchorsCommand extends AbstractCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender commandSender, String... strings) {
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public class GiveCommand extends AbstractCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender commandSender, String... args) {
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
if (args.length == 1) {
|
||||
Set<String> players = new HashSet<>();
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ public class SettingsCommand extends AbstractCommand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected List<String> onTab(CommandSender commandSender, String... strings) {
|
||||
protected List<String> onTab(CommandSender sender, String... args) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@ package com.songoda.epicanchors.files;
|
|||
|
||||
import com.craftaro.core.database.DataManagerAbstract;
|
||||
import com.craftaro.core.database.DatabaseConnector;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.api.Anchor;
|
||||
import com.songoda.epicanchors.AnchorImpl;
|
||||
import com.songoda.epicanchors.files.migration.AnchorMigration;
|
||||
import com.songoda.epicanchors.utils.Callback;
|
||||
import com.songoda.epicanchors.utils.UpdateCallback;
|
||||
|
@ -247,7 +248,7 @@ public class DataManager extends DataManagerAbstract {
|
|||
private Anchor extractAnchor(ResultSet rs) throws SQLException {
|
||||
String ownerStr = rs.getString("owner");
|
||||
|
||||
return new Anchor(rs.getInt("id"),
|
||||
return new AnchorImpl(rs.getInt("id"),
|
||||
ownerStr != null ? UUID.fromString(ownerStr) : null,
|
||||
new Location(Bukkit.getWorld(rs.getString("world_name")),
|
||||
rs.getInt("x"),
|
||||
|
|
|
@ -8,8 +8,8 @@ import com.craftaro.core.gui.GuiUtils;
|
|||
import com.craftaro.core.hooks.EconomyManager;
|
||||
import com.craftaro.core.utils.TextUtils;
|
||||
import com.craftaro.core.utils.TimeUtils;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.api.Anchor;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
@ -112,7 +112,7 @@ public class AnchorGui extends Gui {
|
|||
ChatColor.GRAY + TimeUtils.makeReadable((long) ((anchor.getTicksLeft() / 20.0) * 1000)) + " remaining.";
|
||||
|
||||
gui.setItem(13, GuiUtils.createButtonItem(plugin.getAnchorManager().createAnchorItem(
|
||||
anchor.getTicksLeft(), anchor.getLocation().getBlock().getType()),
|
||||
anchor.getTicksLeft(), anchor.getLocation().getBlock().getType()),
|
||||
itemName, itemLore));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ import com.craftaro.core.gui.Gui;
|
|||
import com.craftaro.core.gui.GuiUtils;
|
||||
import com.craftaro.core.gui.methods.Closable;
|
||||
import com.craftaro.core.utils.TextUtils;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.api.Anchor;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.songoda.epicanchors.utils.Callback;
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@ package com.songoda.epicanchors.listener;
|
|||
import com.craftaro.core.compatibility.CompatibleHand;
|
||||
import com.craftaro.core.compatibility.CompatibleParticleHandler;
|
||||
import com.craftaro.core.compatibility.CompatibleSound;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.AnchorManager;
|
||||
import com.songoda.epicanchors.AnchorManagerImpl;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.api.Anchor;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import com.songoda.epicanchors.guis.AnchorGui;
|
||||
import com.songoda.epicanchors.guis.DestroyConfirmationGui;
|
||||
|
@ -36,12 +36,12 @@ public class AnchorListener implements Listener {
|
|||
|
||||
if (item.hasItemMeta() &&
|
||||
item.getItemMeta().hasDisplayName() &&
|
||||
Settings.MATERIAL.getMaterial().getMaterial() == e.getBlock().getType()) {
|
||||
Settings.MATERIAL.getMaterial().parseMaterial() == e.getBlock().getType()) {
|
||||
if (!this.plugin.getAnchorManager().isReady(e.getBlock().getWorld())) {
|
||||
e.setCancelled(true);
|
||||
e.getPlayer().sendMessage("Anchors are still being initialized - Please wait a moment"); // TODO
|
||||
} else {
|
||||
int ticksLeft = AnchorManager.getTicksFromItem(item);
|
||||
int ticksLeft = AnchorManagerImpl.getTicksFromItem(item);
|
||||
|
||||
if (ticksLeft != 0) {
|
||||
boolean dropOnErr = e.getPlayer().getGameMode() != GameMode.CREATIVE;
|
||||
|
@ -81,7 +81,7 @@ public class AnchorListener implements Listener {
|
|||
e.setCancelled(true);
|
||||
|
||||
if (p.hasPermission("EpicAnchors.admin") ||
|
||||
this.plugin.getAnchorManager().hasAccess(anchor, p)) {
|
||||
this.plugin.getAnchorManager().hasAccess(anchor, p.getUniqueId())) {
|
||||
if (e.getAction() == Action.LEFT_CLICK_BLOCK) { // Destroy anchor
|
||||
this.plugin.getGuiManager().showGUI(e.getPlayer(),
|
||||
new DestroyConfirmationGui(this.plugin, anchor, (ex, result) -> {
|
||||
|
@ -96,7 +96,7 @@ public class AnchorListener implements Listener {
|
|||
}));
|
||||
} else if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { // Manage anchor
|
||||
ItemStack item = CompatibleHand.MAIN_HAND.getItem(e.getPlayer());
|
||||
int itemTicks = AnchorManager.getTicksFromItem(item);
|
||||
int itemTicks = AnchorManagerImpl.getTicksFromItem(item);
|
||||
|
||||
if (itemTicks != 0) {
|
||||
if (!anchor.isInfinite()) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.songoda.epicanchors.listener;
|
||||
|
||||
import com.songoda.epicanchors.AnchorManager;
|
||||
import com.songoda.epicanchors.api.AnchorManager;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
@ -67,8 +67,8 @@ public class BlockListener implements Listener {
|
|||
public void onPortalCreation(PortalCreateEvent e) {
|
||||
if (!this.manager.isReady(e.getWorld())) return;
|
||||
|
||||
for (Block b : e.getBlocks()) {
|
||||
if (this.manager.isAnchor(b)) {
|
||||
for (Block block : e.getBlocks()) {
|
||||
if (this.manager.isAnchor(block)) {
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -83,22 +83,22 @@ public class DebugListener implements Listener {
|
|||
if (e.isSneaking()) {
|
||||
e.getPlayer().sendMessage("§e§lEntities");
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
count.compute(entity.getType().name(), (k, v) -> v == null ? 1 : v + 1);
|
||||
count.compute(entity.getType().name(), (key, value) -> value == null ? 1 : value + 1);
|
||||
}
|
||||
} else {
|
||||
e.getPlayer().sendMessage("§e§lTileEntities");
|
||||
for (BlockState blockState : chunk.getTileEntities()) {
|
||||
count.compute(blockState.getType().name(), (k, v) -> v == null ? 1 : v + 1);
|
||||
count.compute(blockState.getType().name(), (key, value) -> value == null ? 1 : value + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Integer> m = count.entrySet().stream()
|
||||
Map<String, Integer> sortedEntitiyCount = count.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
|
||||
(e1, e2) -> e1, LinkedHashMap::new));
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
|
||||
for (Map.Entry<String, Integer> entry : m.entrySet()) {
|
||||
String entityName = WordUtils.capitalize(entry.getKey().toLowerCase(), new char[] {'_'}).replace("_", "");
|
||||
for (Map.Entry<String, Integer> entry : sortedEntitiyCount.entrySet()) {
|
||||
String entityName = WordUtils.capitalize(entry.getKey().toLowerCase(), new char[]{'_'}).replace("_", "");
|
||||
|
||||
e.getPlayer().sendMessage("§a" + entityName + "§7:§r " + entry.getValue());
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ package com.songoda.epicanchors.tasks;
|
|||
|
||||
import com.craftaro.core.nms.Nms;
|
||||
import com.craftaro.core.nms.UnsupportedServerVersionException;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.AnchorManager;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.api.Anchor;
|
||||
import com.songoda.epicanchors.api.AnchorManager;
|
||||
import com.songoda.epicanchors.utils.Utils;
|
||||
import com.songoda.epicanchors.utils.WorldUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.songoda.epicanchors.tasks;
|
||||
|
||||
import com.craftaro.core.compatibility.CompatibleParticleHandler;
|
||||
import com.songoda.epicanchors.Anchor;
|
||||
import com.songoda.epicanchors.api.Anchor;
|
||||
import com.songoda.epicanchors.EpicAnchors;
|
||||
import com.songoda.epicanchors.files.Settings;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -66,7 +66,7 @@ public class VisualizeTask extends BukkitRunnable {
|
|||
Chunk chunk = world.getChunkAt(cx, cz);
|
||||
|
||||
if (loadedChunks.contains(chunk)) {
|
||||
chunksToVisualize.computeIfAbsent(chunk, k -> new HashSet<>())
|
||||
chunksToVisualize.computeIfAbsent(chunk, key -> new HashSet<>())
|
||||
.add(p);
|
||||
}
|
||||
}
|
||||
|
@ -91,17 +91,17 @@ public class VisualizeTask extends BukkitRunnable {
|
|||
startY = maxY - 1;
|
||||
}
|
||||
|
||||
Block b = entry.getKey().getBlock(x, startY, z);
|
||||
Block block = entry.getKey().getBlock(x, startY, z);
|
||||
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
if (b.getType().isSolid()) break;
|
||||
if (block.getType().isSolid()) break;
|
||||
|
||||
b = b.getRelative(BlockFace.DOWN);
|
||||
block = block.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
|
||||
if (!b.isEmpty() && !b.getRelative(BlockFace.UP).getType().isOccluding()) {
|
||||
if (!block.isEmpty() && !block.getRelative(BlockFace.UP).getType().isOccluding()) {
|
||||
CompatibleParticleHandler.spawnParticles(particleType,
|
||||
b.getLocation().add(.5, 1.5, .5),
|
||||
block.getLocation().add(.5, 1.5, .5),
|
||||
0, 0, 0, 0, 1, p);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue