Change VisibilityManager into VisibilitySettings and improve implementation

This commit is contained in:
filoghost 2021-05-19 20:41:15 +02:00
parent d67480749b
commit e8c4f58d9a
8 changed files with 251 additions and 255 deletions

View File

@ -178,14 +178,14 @@ public interface Hologram {
/**
* Returns the {@link VisibilityManager} of this hologram.
* <br><b style = "color: red">Note</b>: the usage of the VisibilityManager requires ProtocolLib.
* Returns the {@link VisibilitySettings} of this hologram.
* <br><b style = "color: red">Note</b>: the usage of the VisibilitySettings requires ProtocolLib.
* Without the plugin, holograms will be always visible.
*
* @return the VisibilityManager of this hologram
* @return the VisibilitySettings of this hologram
* @since 1
*/
@NotNull VisibilityManager getVisibilityManager();
@NotNull VisibilitySettings getVisibilitySettings();
/**

View File

@ -1,82 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.api;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* This object is used to manage the visibility of a hologram.
* It allows to hide/show the hologram to certain players, and the default behaviour
* (when a hologram is not specifically being hidden/shown to a player) can be customized.
*
* @since 1
*/
public interface VisibilityManager {
/**
* Returns if the hologram is visible by default. If not changed, this value
* is true by default so the hologram is visible to everyone.
*
* @return if the hologram hologram is visible by default
* @since 1
*/
boolean isVisibleByDefault();
/**
* Sets if the hologram is visible by default. If not changed, this value
* is true by default so the hologram is visible to everyone.
*
* @param visibleByDefault the new behaviour
* @since 1
*/
void setVisibleByDefault(boolean visibleByDefault);
/**
* Shows the hologram to a player, overriding the value of {@link #isVisibleByDefault()}.
* This is persistent if the players goes offline.
*
* @param player the involved player
* @since 1
*/
void showTo(@NotNull Player player);
/**
* Hides the hologram to a player, overriding the value of {@link #isVisibleByDefault()}.
* This is persistent if the players goes offline.
*
* @param player the involved player
* @since 1
*/
void hideTo(@NotNull Player player);
/**
* Checks if a hologram is visible to a player.
*
* @param player the involved player
* @return if the player can see the hologram
* @since 1
*/
boolean isVisibleTo(@NotNull Player player);
/**
* Resets the visibility to the default value. If you previously called {@link #showTo(Player)}
* or {@link #hideTo(Player)} to override the default visibility, this method will reset it
* to reflect the value of {@link #isVisibleByDefault()}.
*
* @param player the involved player
* @since 1
*/
void resetVisibility(@NotNull Player player);
/**
* Resets the visibility for all the players. See {@link #resetVisibility(Player)} for more details.
*
* @since 1
*/
void resetVisibilityAll();
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.api;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Settings to manage the visibility of a hologram to players. Allows to set both the default visibility and the
* visibility to a specific player.
* <p>
* <b>Warning</b>: changing the visibility requires ProtocolLib, otherwise methods of this class have no effect.
*
* @since 1
*/
public interface VisibilitySettings {
/**
* Returns the default visibility of the hologram. The initial value is {@link Visibility#VISIBLE}, meaning that the
* hologram is visible to everyone.
*
* @return the default visibility
* @since 1
*/
@NotNull Visibility getDefaultVisibility();
/**
* Sets the default visibility. This value affects player which do not have an individual visibility set with {@link
* #setIndividualVisibility(Player, Visibility)} and player whose individual visibility has been reset with {@link
* #resetIndividualVisibility(Player)}.
*
* @param defaultVisibility the new default visibility
* @since 1
*/
void setDefaultVisibility(@NotNull Visibility defaultVisibility);
/**
* Sets the visibility for a specific player, overriding the default value ({@link #getDefaultVisibility()}).
* The individual visibility value can be reverted with {@link #resetIndividualVisibility(Player)}.
*
* @since 1
*/
void setIndividualVisibility(@NotNull Player player, @NotNull Visibility visibility);
/**
* Resets the visibility for a specific player to the default value ({@link #getDefaultVisibility()}).
*
* @since 1
*/
void resetIndividualVisibility(@NotNull Player player);
/**
* Resets the visibility for all players to the default value ({@link #getDefaultVisibility()}).
*
* @since 1
*/
void resetIndividualVisibilityAll();
/**
* Checks if a hologram is visible to a player, taking into account the individual visibility for the specific
* player and the default visibility.
*
* @param player the player
* @return if the player can see the hologram
* @since 1
*/
boolean isVisibleTo(@NotNull Player player);
/**
* The available statuses for the visibility of a hologram.
*/
enum Visibility {
VISIBLE,
HIDDEN
}
}

View File

@ -106,7 +106,7 @@ public class V2HologramAdapter implements Hologram {
@Override
public VisibilityManager getVisibilityManager() {
return newHologram.getVisibilityManager().getV2Adapter();
return newHologram.getVisibilitySettings().getV2Adapter();
}
@Override

View File

@ -6,51 +6,52 @@
package me.filoghost.holographicdisplays.legacy.api.v2;
import com.gmail.filoghost.holographicdisplays.api.VisibilityManager;
import me.filoghost.holographicdisplays.object.api.DefaultVisibilityManager;
import me.filoghost.holographicdisplays.api.VisibilitySettings.Visibility;
import me.filoghost.holographicdisplays.object.api.DefaultVisibilitySettings;
import org.bukkit.entity.Player;
@SuppressWarnings("deprecation")
public class V2VisibilityManagerAdapter implements VisibilityManager {
private final DefaultVisibilityManager newVisibilityManager;
private final DefaultVisibilitySettings newVisibilitySettings;
public V2VisibilityManagerAdapter(DefaultVisibilityManager newVisibilityManager) {
this.newVisibilityManager = newVisibilityManager;
public V2VisibilityManagerAdapter(DefaultVisibilitySettings newVisibilitySettings) {
this.newVisibilitySettings = newVisibilitySettings;
}
@Override
public boolean isVisibleByDefault() {
return newVisibilityManager.isVisibleByDefault();
return newVisibilitySettings.getDefaultVisibility() == Visibility.VISIBLE;
}
@Override
public void setVisibleByDefault(boolean visibleByDefault) {
newVisibilityManager.setVisibleByDefault(visibleByDefault);
newVisibilitySettings.setDefaultVisibility(visibleByDefault ? Visibility.VISIBLE : Visibility.HIDDEN);
}
@Override
public void showTo(Player player) {
newVisibilityManager.showTo(player);
newVisibilitySettings.setIndividualVisibility(player, Visibility.VISIBLE);
}
@Override
public void hideTo(Player player) {
newVisibilityManager.hideTo(player);
newVisibilitySettings.setIndividualVisibility(player, Visibility.HIDDEN);
}
@Override
public boolean isVisibleTo(Player player) {
return newVisibilityManager.isVisibleTo(player);
return newVisibilitySettings.isVisibleTo(player);
}
@Override
public void resetVisibility(Player player) {
newVisibilityManager.resetVisibility(player);
newVisibilitySettings.resetIndividualVisibility(player);
}
@Override
public void resetVisibilityAll() {
newVisibilityManager.resetVisibilityAll();
newVisibilitySettings.resetIndividualVisibilityAll();
}
@Override
@ -63,17 +64,17 @@ public class V2VisibilityManagerAdapter implements VisibilityManager {
}
V2VisibilityManagerAdapter other = (V2VisibilityManagerAdapter) obj;
return this.newVisibilityManager.equals(other.newVisibilityManager);
return this.newVisibilitySettings.equals(other.newVisibilitySettings);
}
@Override
public final int hashCode() {
return newVisibilityManager.hashCode();
return newVisibilitySettings.hashCode();
}
@Override
public final String toString() {
return newVisibilityManager.toString();
return newVisibilitySettings.toString();
}
}

View File

@ -25,7 +25,7 @@ public class APIHologram extends BaseHologram<APIHologramLine> implements Hologr
private final Plugin plugin;
private final APIHologramManager apiHologramManager;
private final DefaultVisibilityManager visibilityManager;
private final DefaultVisibilitySettings visibilitySettings;
private final long creationTimestamp;
private final V2HologramAdapter v2Adapter;
@ -41,7 +41,7 @@ public class APIHologram extends BaseHologram<APIHologramLine> implements Hologr
Preconditions.notNull(plugin, "plugin");
this.plugin = plugin;
this.apiHologramManager = apiHologramManager;
this.visibilityManager = new DefaultVisibilityManager(this);
this.visibilitySettings = new DefaultVisibilitySettings(this);
this.creationTimestamp = System.currentTimeMillis();
this.v2Adapter = new V2HologramAdapter(this);
}
@ -113,7 +113,7 @@ public class APIHologram extends BaseHologram<APIHologramLine> implements Hologr
@Override
public boolean isVisibleTo(Player player) {
return visibilityManager.isVisibleTo(player);
return visibilitySettings.isVisibleTo(player);
}
@Override
@ -139,8 +139,8 @@ public class APIHologram extends BaseHologram<APIHologramLine> implements Hologr
}
@Override
public @NotNull DefaultVisibilityManager getVisibilityManager() {
return visibilityManager;
public @NotNull DefaultVisibilitySettings getVisibilitySettings() {
return visibilitySettings;
}
@Override

View File

@ -1,149 +0,0 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.object.api;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.api.VisibilityManager;
import me.filoghost.holographicdisplays.bridge.protocollib.ProtocolLibHook;
import me.filoghost.holographicdisplays.core.hologram.StandardHologram;
import me.filoghost.holographicdisplays.legacy.api.v2.V2VisibilityManagerAdapter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class DefaultVisibilityManager implements VisibilityManager {
private final StandardHologram hologram;
private final V2VisibilityManagerAdapter v2Adapter;
private Map<UUID, Boolean> playersVisibilityMap;
private boolean visibleByDefault;
public DefaultVisibilityManager(StandardHologram hologram) {
Preconditions.notNull(hologram, "hologram");
this.hologram = hologram;
this.v2Adapter = new V2VisibilityManagerAdapter(this);
this.visibleByDefault = true;
}
@Override
public boolean isVisibleByDefault() {
return visibleByDefault;
}
@Override
public void setVisibleByDefault(boolean visibleByDefault) {
if (this.visibleByDefault == visibleByDefault) {
return;
}
this.visibleByDefault = visibleByDefault;
for (Player player : Bukkit.getOnlinePlayers()) {
if (playersVisibilityMap != null && playersVisibilityMap.containsKey(player.getUniqueId())) {
// Has a specific value set
continue;
}
sendVisibilityChangePacket(hologram, player, visibleByDefault);
}
}
@Override
public void showTo(@NotNull Player player) {
Preconditions.notNull(player, "player");
setVisibleTo(player, true);
}
@Override
public void hideTo(@NotNull Player player) {
Preconditions.notNull(player, "player");
setVisibleTo(player, false);
}
private void setVisibleTo(Player player, boolean visible) {
boolean wasVisible = isVisibleTo(player);
// Lazy initialization
if (playersVisibilityMap == null) {
playersVisibilityMap = new HashMap<>();
}
playersVisibilityMap.put(player.getUniqueId(), visible);
if (wasVisible != visible) {
sendVisibilityChangePacket(hologram, player, visible);
}
}
@Override
public boolean isVisibleTo(@NotNull Player player) {
Preconditions.notNull(player, "player");
if (playersVisibilityMap != null) {
Boolean visible = playersVisibilityMap.get(player.getUniqueId());
if (visible != null) {
return visible;
}
}
return visibleByDefault;
}
@Override
public void resetVisibility(@NotNull Player player) {
Preconditions.notNull(player, "player");
if (playersVisibilityMap == null) {
return;
}
Boolean wasVisible = playersVisibilityMap.remove(player.getUniqueId());
if (wasVisible != null && visibleByDefault != wasVisible) {
sendVisibilityChangePacket(hologram, player, visibleByDefault);
}
}
@Override
public void resetVisibilityAll() {
if (playersVisibilityMap == null) {
return;
}
for (Player player : Bukkit.getOnlinePlayers()) {
boolean wasVisible = isVisibleTo(player);
if (visibleByDefault != wasVisible) {
sendVisibilityChangePacket(hologram, player, visibleByDefault);
}
}
playersVisibilityMap = null;
}
private void sendVisibilityChangePacket(StandardHologram hologram, Player player, boolean visible) {
if (ProtocolLibHook.isEnabled()) {
if (visible) {
ProtocolLibHook.sendCreateEntitiesPacket(player, hologram);
} else {
ProtocolLibHook.sendDestroyEntitiesPacket(player, hologram);
}
}
}
@Override
public String toString() {
return "VisibilityManager [playersMap=" + playersVisibilityMap + ", visibleByDefault=" + visibleByDefault + "]";
}
public V2VisibilityManagerAdapter getV2Adapter() {
return v2Adapter;
}
}

View File

@ -0,0 +1,143 @@
/*
* Copyright (C) filoghost and contributors
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package me.filoghost.holographicdisplays.object.api;
import me.filoghost.fcommons.Preconditions;
import me.filoghost.holographicdisplays.api.VisibilitySettings;
import me.filoghost.holographicdisplays.bridge.protocollib.ProtocolLibHook;
import me.filoghost.holographicdisplays.core.hologram.StandardHologram;
import me.filoghost.holographicdisplays.legacy.api.v2.V2VisibilityManagerAdapter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class DefaultVisibilitySettings implements VisibilitySettings {
private final StandardHologram hologram;
private final V2VisibilityManagerAdapter v2Adapter;
private Map<UUID, Visibility> visibilityByPlayer;
private Visibility defaultVisibility;
public DefaultVisibilitySettings(StandardHologram hologram) {
Preconditions.notNull(hologram, "hologram");
this.hologram = hologram;
this.v2Adapter = new V2VisibilityManagerAdapter(this);
this.defaultVisibility = Visibility.VISIBLE;
}
@Override
public @NotNull Visibility getDefaultVisibility() {
return defaultVisibility;
}
@Override
public void setDefaultVisibility(@NotNull Visibility defaultVisibility) {
if (this.defaultVisibility == defaultVisibility) {
return;
}
this.defaultVisibility = defaultVisibility;
for (Player player : Bukkit.getOnlinePlayers()) {
if (visibilityByPlayer != null && visibilityByPlayer.containsKey(player.getUniqueId())) {
// Has a specific value set
continue;
}
sendVisibilityChangePacket(hologram, player, defaultVisibility);
}
}
@Override
public void setIndividualVisibility(@NotNull Player player, @NotNull Visibility visibility) {
Visibility oldVisibility = getVisibility(player);
// Lazy initialization
if (visibilityByPlayer == null) {
visibilityByPlayer = new ConcurrentHashMap<>();
}
visibilityByPlayer.put(player.getUniqueId(), visibility);
if (oldVisibility != visibility) {
sendVisibilityChangePacket(hologram, player, visibility);
}
}
@Override
public boolean isVisibleTo(@NotNull Player player) {
Preconditions.notNull(player, "player");
return getVisibility(player) == Visibility.VISIBLE;
}
private Visibility getVisibility(Player player) {
if (visibilityByPlayer != null) {
Visibility visibility = visibilityByPlayer.get(player.getUniqueId());
if (visibility != null) {
return visibility;
}
}
return defaultVisibility;
}
@Override
public void resetIndividualVisibility(@NotNull Player player) {
Preconditions.notNull(player, "player");
if (visibilityByPlayer == null) {
return;
}
Visibility oldVisibility = visibilityByPlayer.remove(player.getUniqueId());
if (oldVisibility != null && oldVisibility != defaultVisibility) {
sendVisibilityChangePacket(hologram, player, defaultVisibility);
}
}
@Override
public void resetIndividualVisibilityAll() {
if (visibilityByPlayer == null) {
return;
}
for (Player player : Bukkit.getOnlinePlayers()) {
Visibility oldVisibility = getVisibility(player);
if (oldVisibility != defaultVisibility) {
sendVisibilityChangePacket(hologram, player, defaultVisibility);
}
}
visibilityByPlayer = null;
}
private void sendVisibilityChangePacket(StandardHologram hologram, Player player, Visibility visibility) {
if (ProtocolLibHook.isEnabled()) {
if (visibility == Visibility.VISIBLE) {
ProtocolLibHook.sendCreateEntitiesPacket(player, hologram);
} else {
ProtocolLibHook.sendDestroyEntitiesPacket(player, hologram);
}
}
}
@Override
public String toString() {
return "VisibilitySettings ["
+ "defaultVisibility=" + defaultVisibility
+ ", visibilityByPlayer=" + visibilityByPlayer
+ "]";
}
public V2VisibilityManagerAdapter getV2Adapter() {
return v2Adapter;
}
}