Allow holograms to be in non-loaded worlds

This commit is contained in:
filoghost 2021-08-07 18:39:19 +02:00
parent 5225d34cb6
commit 9b21ffdf76
20 changed files with 177 additions and 70 deletions

View File

@ -112,12 +112,12 @@ public interface Hologram {
@NotNull HologramPosition getPosition(); @NotNull HologramPosition getPosition();
/** /**
* Returns the world of the hologram position. * Returns the world name of the hologram position.
* *
* @return the world of the hologram position * @return the world name of the hologram position
* @since 1 * @since 1
*/ */
@NotNull World getPositionWorld(); @NotNull String getPositionWorldName();
/** /**
* Returns the X coordinate of the hologram position. * Returns the X coordinate of the hologram position.
@ -151,6 +151,17 @@ public interface Hologram {
*/ */
void setPosition(@NotNull HologramPosition position); void setPosition(@NotNull HologramPosition position);
/**
* Moves the hologram to the given position.
*
* @param worldName the world name where the hologram should be moved
* @param x the X coordinate
* @param y the Y coordinate
* @param z the Z coordinate
* @since 1
*/
void setPosition(@NotNull String worldName, double x, double y, double z);
/** /**
* Moves the hologram to the given position. * Moves the hologram to the given position.
* *

View File

@ -9,6 +9,7 @@ import me.filoghost.holographicdisplays.api.internal.HolographicDisplaysAPIProvi
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface HologramPosition { public interface HologramPosition {
@ -16,11 +17,19 @@ public interface HologramPosition {
return HolographicDisplaysAPIProvider.getImplementation().createHologramPosition(world, x, y, z); return HolographicDisplaysAPIProvider.getImplementation().createHologramPosition(world, x, y, z);
} }
static @NotNull HologramPosition create(@NotNull String worldName, double x, double y, double z) {
return HolographicDisplaysAPIProvider.getImplementation().createHologramPosition(worldName, x, y, z);
}
static @NotNull HologramPosition fromLocation(@NotNull Location location) { static @NotNull HologramPosition fromLocation(@NotNull Location location) {
return HolographicDisplaysAPIProvider.getImplementation().createHologramPosition(location); return HolographicDisplaysAPIProvider.getImplementation().createHologramPosition(location);
} }
@NotNull World getWorld(); @NotNull String getWorldName();
void setWorldName(@NotNull String worldName);
@Nullable World getWorldIfLoaded();
void setWorld(@NotNull World world); void setWorld(@NotNull World world);

View File

@ -35,6 +35,8 @@ public abstract class HolographicDisplaysAPIProvider {
public abstract HologramPosition createHologramPosition(World world, double x, double y, double z); public abstract HologramPosition createHologramPosition(World world, double x, double y, double z);
public abstract HologramPosition createHologramPosition(String worldName, double x, double y, double z);
public abstract HologramPosition createHologramPosition(Location location); public abstract HologramPosition createHologramPosition(Location location);
} }

View File

@ -110,7 +110,7 @@ public class HolographicDisplays extends FCommonsPlugin {
new DatabaseLegacyUpgrade(configManager, errorCollector).tryRun(); new DatabaseLegacyUpgrade(configManager, errorCollector).tryRun();
// Load the configuration // Load the configuration
load(true, errorCollector); load(errorCollector);
// Add packet listener for currently online players (may happen if the plugin is disabled and re-enabled) // Add packet listener for currently online players (may happen if the plugin is disabled and re-enabled)
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
@ -155,7 +155,7 @@ public class HolographicDisplays extends FCommonsPlugin {
HologramsAPIProvider.setImplementation(new V2HologramsAPIProvider(apiHologramManager, placeholderRegistry)); HologramsAPIProvider.setImplementation(new V2HologramsAPIProvider(apiHologramManager, placeholderRegistry));
} }
public void load(boolean deferHologramsCreation, ErrorCollector errorCollector) { public void load(ErrorCollector errorCollector) {
internalHologramManager.clearAll(); internalHologramManager.clearAll();
configManager.reloadStaticReplacements(errorCollector); configManager.reloadStaticReplacements(errorCollector);
@ -167,13 +167,8 @@ public class HolographicDisplays extends FCommonsPlugin {
bungeeServerTracker.restart(Settings.bungeeRefreshSeconds, TimeUnit.SECONDS); bungeeServerTracker.restart(Settings.bungeeRefreshSeconds, TimeUnit.SECONDS);
HologramDatabase hologramDatabase = configManager.loadHologramDatabase(errorCollector); HologramDatabase hologramDatabase = configManager.loadHologramDatabase(errorCollector);
if (deferHologramsCreation) {
// For the initial load: holograms are loaded later, when the worlds are ready
Bukkit.getScheduler().runTask(this, () -> hologramDatabase.createHolograms(internalHologramManager, errorCollector));
} else {
hologramDatabase.createHolograms(internalHologramManager, errorCollector); hologramDatabase.createHolograms(internalHologramManager, errorCollector);
} }
}
@Override @Override
public void onDisable() { public void onDisable() {

View File

@ -43,7 +43,13 @@ public class DefaultHolographicDisplaysAPIProvider extends HolographicDisplaysAP
@Override @Override
public HologramPosition createHologramPosition(World world, double x, double y, double z) { public HologramPosition createHologramPosition(World world, double x, double y, double z) {
return new APIHologramPosition(world, x, y, z); Preconditions.notNull(world, "world");
return new APIHologramPosition(world.getName(), x, y, z);
}
@Override
public HologramPosition createHologramPosition(String worldName, double x, double y, double z) {
return new APIHologramPosition(worldName, x, y, z);
} }
@Override @Override

View File

@ -81,7 +81,7 @@ public class V2HologramAdapter implements Hologram {
@Override @Override
public Location getLocation() { public Location getLocation() {
return new Location(v3Hologram.getPositionWorld(), v3Hologram.getPositionX(), v3Hologram.getPositionY(), v3Hologram.getPositionZ()); return new Location(v3Hologram.getPositionWorldIfLoaded(), v3Hologram.getPositionX(), v3Hologram.getPositionY(), v3Hologram.getPositionZ());
} }
@Override @Override
@ -101,7 +101,7 @@ public class V2HologramAdapter implements Hologram {
@Override @Override
public World getWorld() { public World getWorld() {
return v3Hologram.getPositionWorld(); return v3Hologram.getPositionWorldIfLoaded();
} }
@Override @Override

View File

@ -59,7 +59,7 @@ public class ListCommand extends HologramSubCommand {
sender.sendMessage(ColorScheme.SECONDARY_DARKER + "- " + ColorScheme.SECONDARY_BOLD + hologram.getName() sender.sendMessage(ColorScheme.SECONDARY_DARKER + "- " + ColorScheme.SECONDARY_BOLD + hologram.getName()
+ " " + ColorScheme.SECONDARY_DARKER + "at" + " " + ColorScheme.SECONDARY_DARKER + "at"
+ " x: " + position.getBlockX() + ", y: " + position.getBlockY() + ", z: " + position.getBlockZ() + " x: " + position.getBlockX() + ", y: " + position.getBlockY() + ", z: " + position.getBlockZ()
+ " (lines: " + hologram.getLineCount() + ", world: \"" + position.getWorld().getName() + "\")"); + " (lines: " + hologram.getLineCount() + ", world: \"" + position.getWorldName() + "\")");
} }
} }

View File

@ -45,7 +45,7 @@ public class NearCommand extends HologramSubCommand {
for (InternalHologram hologram : hologramEditor.getHolograms()) { for (InternalHologram hologram : hologramEditor.getHolograms()) {
BaseHologramPosition position = hologram.getBasePosition(); BaseHologramPosition position = hologram.getBasePosition();
if (position.getWorld().equals(world) && position.distance(player.getLocation()) <= radius) { if (position.isInWorld(world) && position.distance(player.getLocation()) <= radius) {
nearHolograms.add(hologram); nearHolograms.add(hologram);
} }
} }

View File

@ -29,7 +29,7 @@ public class ReloadCommand extends HologramSubCommand {
@Override @Override
public void execute(CommandSender sender, String[] args, SubCommandContext context) { public void execute(CommandSender sender, String[] args, SubCommandContext context) {
PrintableErrorCollector errorCollector = new PrintableErrorCollector(); PrintableErrorCollector errorCollector = new PrintableErrorCollector();
holographicDisplays.load(false, errorCollector); holographicDisplays.load(errorCollector);
if (!errorCollector.hasErrors()) { if (!errorCollector.hasErrors()) {
sender.sendMessage(ColorScheme.PRIMARY + "Configuration reloaded successfully."); sender.sendMessage(ColorScheme.PRIMARY + "Configuration reloaded successfully.");

View File

@ -11,8 +11,6 @@ import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPositio
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram; import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramLine; import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramLine;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramManager; import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramManager;
import org.bukkit.Bukkit;
import org.bukkit.World;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -38,7 +36,7 @@ public class HologramConfig {
BaseHologramPosition position = hologram.getBasePosition(); BaseHologramPosition position = hologram.getBasePosition();
this.positionConfigSection = new ConfigSection(); this.positionConfigSection = new ConfigSection();
positionConfigSection.setString("world", position.getWorld().getName()); positionConfigSection.setString("world", position.getWorldName());
positionConfigSection.setDouble("x", position.getX()); positionConfigSection.setDouble("x", position.getX());
positionConfigSection.setDouble("y", position.getY()); positionConfigSection.setDouble("y", position.getY());
positionConfigSection.setDouble("z", position.getZ()); positionConfigSection.setDouble("z", position.getZ());
@ -81,14 +79,7 @@ public class HologramConfig {
double x = positionConfigSection.getRequiredDouble("x"); double x = positionConfigSection.getRequiredDouble("x");
double y = positionConfigSection.getRequiredDouble("y"); double y = positionConfigSection.getRequiredDouble("y");
double z = positionConfigSection.getRequiredDouble("z"); double z = positionConfigSection.getRequiredDouble("z");
return new BaseHologramPosition(worldName, x, y, z);
World world = Bukkit.getWorld(worldName);
if (world == null) {
throw new HologramLoadException("world \"" + worldName + "\" is not currently loaded");
}
return new BaseHologramPosition(world, x, y, z);
} catch (ConfigValueException e) { } catch (ConfigValueException e) {
throw new HologramLoadException("invalid position attribute \"" + e.getConfigPath() + "\"", e); throw new HologramLoadException("invalid position attribute \"" + e.getConfigPath() + "\"", e);
} }

View File

@ -136,12 +136,12 @@ public class APIHologram extends BaseHologram<APIHologramLine> implements Hologr
@Override @Override
public @NotNull HologramPosition getPosition() { public @NotNull HologramPosition getPosition() {
return new APIHologramPosition(getPositionWorld(), getPositionX(), getPositionY(), getPositionZ()); return new APIHologramPosition(getPositionWorldName(), getPositionX(), getPositionY(), getPositionZ());
} }
@Override @Override
public void setPosition(@NotNull HologramPosition position) { public void setPosition(@NotNull HologramPosition position) {
super.setPosition(position.getWorld(), position.getX(), position.getY(), position.getZ()); super.setPosition(position.getWorldName(), position.getX(), position.getY(), position.getZ());
} }
@Override @Override

View File

@ -8,12 +8,11 @@ package me.filoghost.holographicdisplays.plugin.hologram.api;
import me.filoghost.holographicdisplays.api.hologram.HologramPosition; import me.filoghost.holographicdisplays.api.hologram.HologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition; import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World;
public class APIHologramPosition extends BaseHologramPosition implements HologramPosition { public class APIHologramPosition extends BaseHologramPosition implements HologramPosition {
public APIHologramPosition(World world, double x, double y, double z) { public APIHologramPosition(String worldName, double x, double y, double z) {
super(world, x, y, z); super(worldName, x, y, z);
} }
public APIHologramPosition(Location location) { public APIHologramPosition(Location location) {

View File

@ -9,17 +9,20 @@ import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.plugin.config.Settings; import me.filoghost.holographicdisplays.plugin.config.Settings;
import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager; import me.filoghost.holographicdisplays.plugin.hologram.tracking.LineTrackerManager;
import me.filoghost.holographicdisplays.plugin.util.CachedBoolean; import me.filoghost.holographicdisplays.plugin.util.CachedBoolean;
import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects;
public abstract class BaseHologram<T extends EditableHologramLine> extends BaseHologramComponent { public abstract class BaseHologram<T extends EditableHologramLine> extends BaseHologramComponent {
@ -27,16 +30,17 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
private final List<T> unmodifiableLinesView; private final List<T> unmodifiableLinesView;
private final LineTrackerManager lineTrackerManager; private final LineTrackerManager lineTrackerManager;
private World world; private @Nullable World world;
private String worldName;
private double x, y, z; private double x, y, z;
private int chunkX, chunkZ; private int chunkX, chunkZ;
private final CachedBoolean isInLoadedChunk = new CachedBoolean(() -> world.isChunkLoaded(chunkX, chunkZ)); private final CachedBoolean isInLoadedChunk = new CachedBoolean(() -> world != null && world.isChunkLoaded(chunkX, chunkZ));
public BaseHologram(BaseHologramPosition position, LineTrackerManager lineTrackerManager) { public BaseHologram(BaseHologramPosition position, LineTrackerManager lineTrackerManager) {
this.lines = new ArrayList<>(); this.lines = new ArrayList<>();
this.unmodifiableLinesView = Collections.unmodifiableList(lines); this.unmodifiableLinesView = Collections.unmodifiableList(lines);
this.lineTrackerManager = lineTrackerManager; this.lineTrackerManager = lineTrackerManager;
setPosition(position.getWorld(), position.getX(), position.getY(), position.getZ()); setPosition(position);
} }
protected abstract boolean isVisibleTo(Player player); protected abstract boolean isVisibleTo(Player player);
@ -129,13 +133,17 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
} }
public BaseHologramPosition getBasePosition() { public BaseHologramPosition getBasePosition() {
return new BaseHologramPosition(getPositionWorld(), getPositionX(), getPositionY(), getPositionZ()); return new BaseHologramPosition(getPositionWorldName(), getPositionX(), getPositionY(), getPositionZ());
} }
public @NotNull World getPositionWorld() { public @Nullable World getPositionWorldIfLoaded() {
return world; return world;
} }
public @NotNull String getPositionWorldName() {
return worldName;
}
public double getPositionX() { public double getPositionX() {
return x; return x;
} }
@ -150,16 +158,22 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
public void setPosition(@NotNull BaseHologramPosition position) { public void setPosition(@NotNull BaseHologramPosition position) {
Preconditions.notNull(position, "position"); Preconditions.notNull(position, "position");
setPosition(position.getWorld(), position.getX(), position.getY(), position.getZ()); setPosition(position.getWorldName(), position.getX(), position.getY(), position.getZ());
} }
public void setPosition(@NotNull Location location) { public void setPosition(@NotNull Location location) {
Preconditions.notNull(location, "location"); Preconditions.notNull(location, "location");
setPosition(location.getWorld(), location.getX(), location.getY(), location.getZ()); Preconditions.notNull(location.getWorld(), "location's world");
setPosition(location.getWorld().getName(), location.getX(), location.getY(), location.getZ());
} }
public void setPosition(@NotNull World world, double x, double y, double z) { public void setPosition(@NotNull World world, double x, double y, double z) {
Preconditions.notNull(world, "world"); Preconditions.notNull(world, "world");
setPosition(world.getName(), x, y, z);
}
public void setPosition(@NotNull String worldName, double x, double y, double z) {
Preconditions.notNull(worldName, "worldName");
checkNotDeleted(); checkNotDeleted();
this.x = x; this.x = x;
@ -168,8 +182,9 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
int chunkX = getChunkCoordinate(x); int chunkX = getChunkCoordinate(x);
int chunkZ = getChunkCoordinate(z); int chunkZ = getChunkCoordinate(z);
if (this.world != world || this.chunkX != chunkX || this.chunkZ != chunkZ) { if (!Objects.equals(this.worldName, worldName) || this.chunkX != chunkX || this.chunkZ != chunkZ) {
this.world = world; this.world = Bukkit.getWorld(worldName);
this.worldName = worldName;
this.chunkX = chunkX; this.chunkX = chunkX;
this.chunkZ = chunkZ; this.chunkZ = chunkZ;
this.isInLoadedChunk.invalidate(); this.isInLoadedChunk.invalidate();
@ -201,6 +216,20 @@ public abstract class BaseHologram<T extends EditableHologramLine> extends BaseH
} }
} }
protected void onWorldLoad(World world) {
if (BaseHologramPosition.isSameWorld(world, this.worldName)) {
this.world = world;
isInLoadedChunk.invalidate();
}
}
protected void onWorldUnload(World world) {
if (BaseHologramPosition.isSameWorld(world, this.worldName)) {
this.world = null;
isInLoadedChunk.set(false);
}
}
protected void onChunkLoad(Chunk chunk) { protected void onChunkLoad(Chunk chunk) {
if (world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) { if (world == chunk.getWorld() && chunkX == chunk.getX() && chunkZ == chunk.getZ()) {
isInLoadedChunk.set(true); isInLoadedChunk.set(true);

View File

@ -12,6 +12,7 @@ import org.bukkit.GameMode;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable;
public abstract class BaseHologramLine extends BaseHologramComponent implements EditableHologramLine { public abstract class BaseHologramLine extends BaseHologramComponent implements EditableHologramLine {
@ -44,6 +45,10 @@ public abstract class BaseHologramLine extends BaseHologramComponent implements
setChanged(); setChanged();
} }
public @Nullable World getWorldIfLoaded() {
return hologram.getPositionWorldIfLoaded();
}
public double getX() { public double getX() {
return x; return x;
} }
@ -56,10 +61,6 @@ public abstract class BaseHologramLine extends BaseHologramComponent implements
return z; return z;
} }
public World getWorld() {
return hologram.getPositionWorld();
}
public boolean isInLoadedChunk() { public boolean isInLoadedChunk() {
return hologram.isInLoadedChunk(); return hologram.isInLoadedChunk();
} }

View File

@ -6,6 +6,7 @@
package me.filoghost.holographicdisplays.plugin.hologram.base; package me.filoghost.holographicdisplays.plugin.hologram.base;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -39,6 +40,18 @@ public abstract class BaseHologramManager<H extends BaseHologram<?>> {
} }
} }
public void onWorldLoad(World world) {
for (H hologram : holograms) {
hologram.onWorldLoad(world);
}
}
public void onWorldUnload(World world) {
for (H hologram : holograms) {
hologram.onWorldUnload(world);
}
}
public void onChunkLoad(Chunk chunk) { public void onChunkLoad(Chunk chunk) {
for (H hologram : holograms) { for (H hologram : holograms) {
hologram.onChunkLoad(chunk); hologram.onChunkLoad(chunk);

View File

@ -6,19 +6,23 @@
package me.filoghost.holographicdisplays.plugin.hologram.base; package me.filoghost.holographicdisplays.plugin.hologram.base;
import me.filoghost.fcommons.Preconditions; import me.filoghost.fcommons.Preconditions;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.util.NumberConversions; import org.bukkit.util.NumberConversions;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
public class BaseHologramPosition { public class BaseHologramPosition {
private World world; private String worldName;
private double x, y, z; private double x, y, z;
public BaseHologramPosition(World world, double x, double y, double z) { public BaseHologramPosition(String worldName, double x, double y, double z) {
Preconditions.notNull(world, "world"); Preconditions.notNull(worldName, "worldName");
this.world = world; this.worldName = worldName;
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
@ -27,19 +31,32 @@ public class BaseHologramPosition {
public BaseHologramPosition(Location location) { public BaseHologramPosition(Location location) {
Preconditions.notNull(location, "location"); Preconditions.notNull(location, "location");
Preconditions.notNull(location.getWorld(), "location's world"); Preconditions.notNull(location.getWorld(), "location's world");
this.world = location.getWorld(); this.worldName = location.getWorld().getName();
this.x = location.getX(); this.x = location.getX();
this.y = location.getY(); this.y = location.getY();
this.z = location.getZ(); this.z = location.getZ();
} }
public @NotNull World getWorld() { public @NotNull String getWorldName() {
return world; return worldName;
}
public void setWorldName(@NotNull String worldName) {
Preconditions.notNull(worldName, "worldName");
this.worldName = worldName;
}
public boolean isInWorld(World world) {
return world != null && isSameWorld(world, this.worldName);
}
public @Nullable World getWorldIfLoaded() {
return Bukkit.getWorld(worldName);
} }
public void setWorld(@NotNull World world) { public void setWorld(@NotNull World world) {
Preconditions.notNull(world, "world"); Preconditions.notNull(world, "world");
this.world = world; this.worldName = world.getName();
} }
public double getX() { public double getX() {
@ -96,17 +113,22 @@ public class BaseHologramPosition {
} }
public @NotNull Location toLocation() { public @NotNull Location toLocation() {
return new Location(world, x, y, z); return new Location(getWorldIfLoaded(), x, y, z);
} }
@Override @Override
public String toString() { public String toString() {
return "HologramPosition{" return "HologramPosition{"
+ "world=" + world + "worldName=" + worldName
+ ", x=" + x + ", x=" + x
+ ", y=" + y + ", y=" + y
+ ", z=" + z + ", z=" + z
+ "}"; + "}";
} }
static boolean isSameWorld(World world, String worldName) {
// Use the same comparison used by Bukkit.getWorld(...)
return world.getName().toLowerCase(Locale.ENGLISH).equals(worldName.toLowerCase(Locale.ENGLISH));
}
} }

View File

@ -9,7 +9,6 @@ import me.filoghost.holographicdisplays.common.nms.NMSManager;
import me.filoghost.holographicdisplays.common.nms.NMSPacketList; import me.filoghost.holographicdisplays.common.nms.NMSPacketList;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramLine; import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramLine;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.MustBeInvokedByOverriders; import org.jetbrains.annotations.MustBeInvokedByOverriders;
@ -17,7 +16,6 @@ abstract class LocationBasedLineTracker<T extends BaseHologramLine> extends Line
private static final int ENTITY_VIEW_RANGE = 64; private static final int ENTITY_VIEW_RANGE = 64;
private World world;
protected double locationX; protected double locationX;
protected double locationY; protected double locationY;
protected double locationZ; protected double locationZ;
@ -30,12 +28,10 @@ abstract class LocationBasedLineTracker<T extends BaseHologramLine> extends Line
@MustBeInvokedByOverriders @MustBeInvokedByOverriders
@Override @Override
protected void detectChanges() { protected void detectChanges() {
World world = line.getWorld();
double locationX = line.getX(); double locationX = line.getX();
double locationY = line.getY(); double locationY = line.getY();
double locationZ = line.getZ(); double locationZ = line.getZ();
if (this.world != world || this.locationX != locationX || this.locationY != locationY || this.locationZ != locationZ) { if (this.locationX != locationX || this.locationY != locationY || this.locationZ != locationZ) {
this.world = world;
this.locationX = locationX; this.locationX = locationX;
this.locationY = locationY; this.locationY = locationY;
this.locationZ = locationZ; this.locationZ = locationZ;
@ -52,11 +48,14 @@ abstract class LocationBasedLineTracker<T extends BaseHologramLine> extends Line
@Override @Override
protected final boolean shouldTrackPlayer(Player player) { protected final boolean shouldTrackPlayer(Player player) {
Location playerLocation = player.getLocation(); Location playerLocation = player.getLocation();
if (playerLocation.getWorld() != line.getWorldIfLoaded()) {
return false;
}
double diffX = Math.abs(playerLocation.getX() - locationX); double diffX = Math.abs(playerLocation.getX() - locationX);
double diffZ = Math.abs(playerLocation.getZ() - locationZ); double diffZ = Math.abs(playerLocation.getZ() - locationZ);
return playerLocation.getWorld() == world return diffX <= (double) ENTITY_VIEW_RANGE
&& diffX <= (double) ENTITY_VIEW_RANGE
&& diffZ <= (double) ENTITY_VIEW_RANGE && diffZ <= (double) ENTITY_VIEW_RANGE
&& line.isVisibleTo(player); && line.isVisibleTo(player);
} }

View File

@ -14,6 +14,8 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
public class ChunkListener implements Listener { public class ChunkListener implements Listener {
@ -28,6 +30,16 @@ public class ChunkListener implements Listener {
this.apiHologramManager = apiHologramManager; this.apiHologramManager = apiHologramManager;
} }
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onWorldLoad(WorldUnloadEvent event) {
internalHologramManager.onWorldLoad(event.getWorld());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onWorldLoad(WorldLoadEvent event) {
internalHologramManager.onWorldUnload(event.getWorld());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onChunkUnload(ChunkUnloadEvent event) { public void onChunkUnload(ChunkUnloadEvent event) {
internalHologramManager.onChunkUnload(event.getChunk()); internalHologramManager.onChunkUnload(event.getChunk());

View File

@ -10,12 +10,13 @@ import com.gmail.filoghost.holographicdisplays.api.line.TextLine;
import me.filoghost.holographicdisplays.api.hologram.ClickListener; import me.filoghost.holographicdisplays.api.hologram.ClickListener;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologram; import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologram;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager; import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.api.APITextLine; import me.filoghost.holographicdisplays.plugin.hologram.api.APITextLine;
import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.test.Mocks; import me.filoghost.holographicdisplays.plugin.test.Mocks;
import me.filoghost.holographicdisplays.plugin.test.TestAPIHologramManager; import me.filoghost.holographicdisplays.plugin.test.TestAPIHologramManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
@ -26,10 +27,15 @@ class V2TouchableLineAdapterTest {
APIHologramManager apiHologramManager = new TestAPIHologramManager(); APIHologramManager apiHologramManager = new TestAPIHologramManager();
APIHologram hologram = apiHologramManager.createHologram( APIHologram hologram = apiHologramManager.createHologram(
new BaseHologramPosition(Mocks.WORLD, 0, 0, 0), new BaseHologramPosition("world", 0, 0, 0),
Mocks.PLUGIN Mocks.PLUGIN
); );
@BeforeAll
static void beforeAll() {
Mocks.prepareEnvironment();
}
@Test @Test
void setNullV2TouchHandler() { void setNullV2TouchHandler() {
APITextLine v3Line = hologram.appendTextLine(""); APITextLine v3Line = hologram.appendTextLine("");

View File

@ -5,20 +5,32 @@
*/ */
package me.filoghost.holographicdisplays.plugin.test; package me.filoghost.holographicdisplays.plugin.test;
import org.bukkit.World; import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.util.logging.Logger;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
public class Mocks { public class Mocks {
private static final Logger SERVER_LOGGER;
public static final Server SERVER;
public static final Plugin PLUGIN; public static final Plugin PLUGIN;
public static final World WORLD;
static { static {
SERVER_LOGGER = mock(Logger.class);
SERVER = mock(Server.class);
when(SERVER.getLogger()).thenReturn(SERVER_LOGGER);
PLUGIN = mock(Plugin.class); PLUGIN = mock(Plugin.class);
when(PLUGIN.getName()).thenReturn("HolographicDisplays"); when(PLUGIN.getName()).thenReturn("HolographicDisplays");
WORLD = mock(World.class); }
when(WORLD.getName()).thenReturn("world");
public static void prepareEnvironment() {
if (Bukkit.getServer() == null) {
Bukkit.setServer(Mocks.SERVER);
} }
} }
}