feat: Implement forced nametag functionality for players
This commit is contained in:
1 parent
7fd168d6c2
commit
0006cf83a0
3 files changed
+128
-9
No files matched your search
+1
-1
@@ -1 +1 @@
|
||||
version = 1.6.10
|
||||
version = 1.6.11
|
||||
@@ -2,6 +2,7 @@ package org.alexdev.unlimitednametags.api;
|
||||
|
||||
|
||||
import me.tofaa.entitylib.meta.display.AbstractDisplayMeta;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.alexdev.unlimitednametags.UnlimitedNameTags;
|
||||
import org.alexdev.unlimitednametags.config.Settings;
|
||||
import org.alexdev.unlimitednametags.hook.hat.HatHook;
|
||||
@@ -359,6 +360,60 @@ public class UNTAPI {
|
||||
plugin.getNametagManager().setNametagOverride(player, modified);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a specific component as the nametag for a player.
|
||||
* This overrides any existing nametag configuration or overrides.
|
||||
*
|
||||
* @param player the player whose nametag should be forced
|
||||
* @param component the component to display as the nametag
|
||||
*/
|
||||
public void setForcedNametag(@NotNull Player player, @NotNull Component component) {
|
||||
plugin.getNametagManager().getPacketDisplayText(player).ifPresent(packetNameTag -> {
|
||||
packetNameTag.setForcedNameTag(component);
|
||||
packetNameTag.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a specific component as the nametag for a player, visible only to a specific viewer.
|
||||
* This overrides any existing nametag configuration or overrides for that specific viewer.
|
||||
*
|
||||
* @param player the player whose nametag should be forced
|
||||
* @param viewer the player who will see the forced nametag
|
||||
* @param component the component to display as the nametag
|
||||
*/
|
||||
public void setForcedNametag(@NotNull Player player, @NotNull Player viewer, @NotNull Component component) {
|
||||
plugin.getNametagManager().getPacketDisplayText(player).ifPresent(packetNameTag -> {
|
||||
packetNameTag.setForcedNameTag(viewer.getUniqueId(), component);
|
||||
packetNameTag.refreshForPlayer(viewer);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the forced nametag for a player.
|
||||
*
|
||||
* @param player the player whose forced nametag should be cleared
|
||||
*/
|
||||
public void clearForcedNametag(@NotNull Player player) {
|
||||
plugin.getNametagManager().getPacketDisplayText(player).ifPresent(packetNameTag -> {
|
||||
packetNameTag.clearForcedNameTag();
|
||||
packetNameTag.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the forced nametag for a player, for a specific viewer.
|
||||
*
|
||||
* @param player the player whose forced nametag should be cleared
|
||||
* @param viewer the player who was seeing the forced nametag
|
||||
*/
|
||||
public void clearForcedNametag(@NotNull Player player, @NotNull Player viewer) {
|
||||
plugin.getNametagManager().getPacketDisplayText(player).ifPresent(packetNameTag -> {
|
||||
packetNameTag.clearForcedNameTag(viewer.getUniqueId());
|
||||
packetNameTag.refreshForPlayer(viewer);
|
||||
});
|
||||
}
|
||||
|
||||
static final class NotRegisteredException extends IllegalStateException {
|
||||
|
||||
private static final String MESSAGE = """
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
@@ -43,6 +44,9 @@ public class PacketNameTag {
|
||||
private final Set<UUID> blocked;
|
||||
@NotNull
|
||||
private final Map<UUID, Component> relationalCache;
|
||||
private final Map<UUID, Component> calculatedTextCache = Maps.newConcurrentMap();
|
||||
private final Map<UUID, Component> forcedRelationalText = Maps.newConcurrentMap();
|
||||
private volatile Component forcedGlobalText = null;
|
||||
private long lastUpdate;
|
||||
@Setter
|
||||
private boolean visible;
|
||||
@@ -51,7 +55,7 @@ public class PacketNameTag {
|
||||
private float scale;
|
||||
private float offset;
|
||||
private float increasedOffset;
|
||||
private boolean removed;
|
||||
private volatile boolean removed;
|
||||
@Setter
|
||||
private boolean sneaking;
|
||||
|
||||
@@ -84,6 +88,16 @@ public class PacketNameTag {
|
||||
return false;
|
||||
}
|
||||
|
||||
calculatedTextCache.put(player.getUniqueId(), text);
|
||||
|
||||
if (forcedRelationalText.containsKey(player.getUniqueId()) || forcedGlobalText != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return applyText(player, text);
|
||||
}
|
||||
|
||||
private boolean applyText(@NotNull Player player, @NotNull Component text) {
|
||||
if (text.equals(relationalCache.get(player.getUniqueId()))) {
|
||||
return false;
|
||||
}
|
||||
@@ -99,7 +113,7 @@ public class PacketNameTag {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void modify(User user, Consumer<TextDisplayMeta> consumer) {
|
||||
public void modify(@Nullable User user, @NotNull Consumer<TextDisplayMeta> consumer) {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
@@ -114,7 +128,7 @@ public class PacketNameTag {
|
||||
});
|
||||
}
|
||||
|
||||
public void modifyOwner(Consumer<TextDisplayMeta> consumer) {
|
||||
public void modifyOwner(@NotNull Consumer<TextDisplayMeta> consumer) {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
@@ -127,7 +141,7 @@ public class PacketNameTag {
|
||||
modify(owner, consumer);
|
||||
}
|
||||
|
||||
public void modifyOwnerEntity(Consumer<WrapperEntity> consumer) {
|
||||
public void modifyOwnerEntity(@NotNull Consumer<WrapperEntity> consumer) {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
@@ -140,7 +154,7 @@ public class PacketNameTag {
|
||||
modifyEntity(owner, consumer);
|
||||
}
|
||||
|
||||
public void modify(Consumer<TextDisplayMeta> consumer) {
|
||||
public void modify(@NotNull Consumer<TextDisplayMeta> consumer) {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
@@ -151,7 +165,7 @@ public class PacketNameTag {
|
||||
});
|
||||
}
|
||||
|
||||
public void modifyEntity(User user, Consumer<WrapperEntity> consumer) {
|
||||
public void modifyEntity(@Nullable User user, @NotNull Consumer<WrapperEntity> consumer) {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
@@ -159,7 +173,7 @@ public class PacketNameTag {
|
||||
perPlayerEntity.modify(user, consumer);
|
||||
}
|
||||
|
||||
public void modifyEntity(Consumer<WrapperEntity> consumer) {
|
||||
public void modifyEntity(@NotNull Consumer<WrapperEntity> consumer) {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
@@ -354,7 +368,7 @@ public class PacketNameTag {
|
||||
}
|
||||
|
||||
private boolean hasRequiredPermissions(@NotNull Player player) {
|
||||
boolean isOwner = isOwner(player);
|
||||
final boolean isOwner = isOwner(player);
|
||||
if (!isOwner && !player.hasPermission("unt.shownametags")) {
|
||||
return false;
|
||||
}
|
||||
@@ -439,6 +453,7 @@ public class PacketNameTag {
|
||||
|
||||
}
|
||||
relationalCache.remove(player.getUniqueId());
|
||||
calculatedTextCache.remove(player.getUniqueId());
|
||||
|
||||
plugin.getPacketManager().removePassenger(player, entityId);
|
||||
}
|
||||
@@ -463,6 +478,7 @@ public class PacketNameTag {
|
||||
}
|
||||
perPlayerEntity.getEntities().remove(player.getUniqueId());
|
||||
relationalCache.remove(player.getUniqueId());
|
||||
calculatedTextCache.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
public boolean canPlayerSee(@NotNull Player player) {
|
||||
@@ -520,6 +536,9 @@ public class PacketNameTag {
|
||||
|
||||
plugin.getPacketManager().removePassenger(entityId);
|
||||
relationalCache.clear();
|
||||
calculatedTextCache.clear();
|
||||
forcedRelationalText.clear();
|
||||
forcedGlobalText = null;
|
||||
}
|
||||
|
||||
public void handleQuit(@NotNull Player player) {
|
||||
@@ -571,6 +590,51 @@ public class PacketNameTag {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setForcedNameTag(@NotNull Component component) {
|
||||
this.forcedGlobalText = component;
|
||||
updateAllViewers();
|
||||
}
|
||||
|
||||
public void setForcedNameTag(@NotNull UUID viewer, @NotNull Component component) {
|
||||
this.forcedRelationalText.put(viewer, component);
|
||||
updateViewer(viewer);
|
||||
}
|
||||
|
||||
public void clearForcedNameTag() {
|
||||
this.forcedGlobalText = null;
|
||||
updateAllViewers();
|
||||
}
|
||||
|
||||
public void clearForcedNameTag(@NotNull UUID viewer) {
|
||||
this.forcedRelationalText.remove(viewer);
|
||||
updateViewer(viewer);
|
||||
}
|
||||
|
||||
private void updateAllViewers() {
|
||||
for (final UUID uuid : getViewers()) {
|
||||
updateViewer(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateViewer(@NotNull UUID uuid) {
|
||||
final Player player = Bukkit.getPlayer(uuid);
|
||||
if (player == null) return;
|
||||
|
||||
Component textToUse = calculatedTextCache.get(uuid);
|
||||
|
||||
if (forcedRelationalText.containsKey(uuid)) {
|
||||
textToUse = forcedRelationalText.get(uuid);
|
||||
} else if (forcedGlobalText != null) {
|
||||
textToUse = forcedGlobalText;
|
||||
}
|
||||
|
||||
if (textToUse != null) {
|
||||
if (applyText(player, textToUse)) {
|
||||
refreshForPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable set containing the viewers of the nametag.
|
||||
*
|
||||
|
||||
Reference in new issue
Block a user