Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ tasks {
minecraftVersion(mcVersion)

downloadPlugins {
hangar("ViaVersion", "5.3.1")
hangar("ViaBackwards", "5.3.1")
hangar("ViaVersion", "5.3.2")
hangar("ViaBackwards", "5.3.2")

// For testing groups in config.yml
url("https://download.luckperms.net/1567/bukkit/loader/LuckPerms-Bukkit-5.4.150.jar")
modrinth("luckperms", "v5.4.145-bukkit")
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/com/mattmx/nametags/DependencyVersionChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.mattmx.nametags;

import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.util.PEVersion;
import net.kyori.adventure.text.Component;

public class DependencyVersionChecker {

public static void checkPacketEventsVersion() {
final PacketEventsAPI<?> api = PacketEvents.getAPI();

boolean isOutdated = api.getVersion().isOlderThan(PEVersion.fromString("2.7.0"));
boolean isUnsupported = api.getServerManager().getVersion().isNewerThan(ServerVersion.V_1_21_4);

if (isOutdated && isUnsupported) {
NameTags.getInstance().getComponentLogger().warn(Component.text("""

⚠ PacketEvents version 2.7.0 does not support versions newer than 1.21.4!

Please update to a development 2.8.0 build that adds 1.21.5+ support.
https://ci.codemc.io/job/retrooper/job/packetevents/

"""));
}
}

}
5 changes: 3 additions & 2 deletions src/main/java/com/mattmx/nametags/EventsListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.jetbrains.annotations.NotNull;
import org.spigotmc.event.player.PlayerSpawnLocationEvent;

import java.util.concurrent.TimeUnit;

Expand All @@ -25,15 +26,15 @@ public EventsListener(@NotNull NameTags plugin) {

@EventHandler
public void onPlayerJoin(@NotNull PlayerJoinEvent event) {
Bukkit.getAsyncScheduler().runDelayed(plugin, (task) -> {
Bukkit.getAsyncScheduler().runNow(plugin, (task) -> {
if (!event.getPlayer().isOnline()) {
return;
}

plugin.getEntityManager()
.getOrCreateNameTagEntity(event.getPlayer())
.updateVisibility();
}, 50L, TimeUnit.MILLISECONDS);
});

}

Expand Down
27 changes: 15 additions & 12 deletions src/main/java/com/mattmx/nametags/NameTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import com.mattmx.nametags.hook.NeznamyTABHook;
import com.mattmx.nametags.hook.SkinRestorerHook;
import com.mattmx.nametags.utils.Metrics;
import com.mattmx.nametags.utils.test.TestPassenger;
import com.mattmx.nametags.utils.test.TestPlaceholderExpansion;
import me.tofaa.entitylib.APIConfig;
import me.tofaa.entitylib.EntityLib;
import me.tofaa.entitylib.spigot.SpigotEntityLibPlatform;
Expand Down Expand Up @@ -40,6 +38,7 @@ public class NameTags extends JavaPlugin {
private EventsListener eventsListener;
private OutgoingPacketListener packetListener;
private Metrics metrics;
private @Nullable ConfigDefaultsListener defaultsListener = null;

@Override
public void onEnable() {
Expand All @@ -62,16 +61,8 @@ public void onEnable() {
.build()
);

ConfigurationSection defaults = getConfig().getConfigurationSection("defaults");
if (defaults != null && defaults.getBoolean("enabled")) {
Bukkit.getPluginManager().registerEvents(new ConfigDefaultsListener(this), this);
}

SpigotEntityLibPlatform platform = new SpigotEntityLibPlatform(this);
APIConfig settings = new APIConfig(PacketEvents.getAPI())
// .tickTickables()
// .trackPlatformEntities()
.usePlatformLogger();
APIConfig settings = new APIConfig(PacketEvents.getAPI()).usePlatformLogger();

EntityLib.init(platform, settings);

Expand All @@ -84,15 +75,27 @@ public void onEnable() {
SkinRestorerHook.inject(this);

Bukkit.getPluginManager().registerEvents(eventsListener, this);
Bukkit.getScheduler().runTaskLater(this, DependencyVersionChecker::checkPacketEventsVersion, 10L);

Objects.requireNonNull(Bukkit.getPluginCommand("nametags-reload")).setExecutor(new NameTagsCommand(this));

}

@Override
public void reloadConfig() {
super.reloadConfig();

ConfigurationSection defaults = getConfig().getConfigurationSection("defaults");
if (defaults != null && defaults.getBoolean("enabled")) {
getLogger().info("Using default behaviour from the config file.");

if (defaultsListener != null) {
HandlerList.unregisterAll(defaultsListener);
}

defaultsListener = new ConfigDefaultsListener(this);
Bukkit.getPluginManager().registerEvents(defaultsListener, this);
}

String textFormatterIdentifier = getConfig().getString("formatter", "minimessage");
formatter = TextFormatter.getById(textFormatterIdentifier)
.orElse(TextFormatter.MINI_MESSAGE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public ConfigDefaultsListener(@NotNull NameTags plugin) {
.getEntityManager()
.setDefaultProvider(((entity, meta) -> {
meta.setUseDefaultBackground(false);
meta.setTransformationInterpolationDuration(5);
meta.setPositionRotationInterpolationDuration(5);
TextDisplayMetaConfiguration.applyMeta(defaultSection(), meta);
}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
* Responsible for two things:
* <p>
* 1. Modifying the passenger entity Y offset, since Mojang changed the
* entity passenger origin by a small amount, which results in the name
* tags rendering inside a player's head in older versions.
* entity passenger origin by a small amount, which results in the name
* tags rendering inside a player's head in older versions.
* <p>
* To fix this, the function will apply an offset of +0.4f in the Y
* axis, which was the closest value found to how it should appear in
* modern versions.
* To fix this, the function will apply an offset of +0.4f in the Y
* axis, which was the closest value found to how it should appear in
* modern versions.
* <p>
* 2. Apply relational placeholders (off the netty thread) if there are
* any.
* any.
*/
public class PlayServerEntityMetaDataHandler {
private static final byte TEXT_DISPLAY_TEXT_INDEX = 23;
Expand All @@ -50,75 +50,80 @@ public class PlayServerEntityMetaDataHandler {

public static void handlePacket(@NotNull PacketSendEvent event) {
final NameTags plugin = NameTags.getInstance();
final WrapperPlayServerEntityMetadata packet = new WrapperPlayServerEntityMetadata(event);

final NameTagEntity nameTagEntity = plugin.getEntityManager().getNameTagEntityByTagEntityId(packet.getEntityId());
final PacketSendEvent eventClone = event.clone();
final WrapperPlayServerEntityMetadata packet0 = new WrapperPlayServerEntityMetadata(event);

if (nameTagEntity == null) return;
final NameTagEntity nameTagEntity = plugin.getEntityManager().getNameTagEntityByTagEntityId(packet0.getEntityId());

boolean isOldClient = event.getUser().getClientVersion().isOlderThan(ClientVersion.V_1_20_2);
boolean containsEntityOffset = false;
@Nullable EntityData textEntry = null;
if (nameTagEntity == null) {
eventClone.cleanUp();
return;
}

for (final EntityData entry : packet.getEntityMetadata()) {
if (containsEntityOffset && textEntry != null) {
break;
}
event.setCancelled(true);
final WrapperPlayServerEntityMetadata packet = new WrapperPlayServerEntityMetadata(eventClone);

// This could prove a concurrency issue, maybe we should keep track of if there is a newer packet processing?
plugin.getExecutor().execute(() -> {
boolean isOldClient = eventClone.getUser()
.getClientVersion()
.isOlderThan(ClientVersion.V_1_20_2);

boolean containsEntityOffset = false;
@Nullable EntityData textEntry = null;

for (final EntityData entry : packet.getEntityMetadata()) {
if (containsEntityOffset && textEntry != null) {
break;
}

if (isOldClient && entry.getIndex() == ENTITY_OFFSET_INDEX) {
Vector3f vec = (Vector3f) entry.getValue();
entry.setValue(vec.add(PRE_1_20_2_TRANSLATION_OFFSET));
if (isOldClient && entry.getIndex() == ENTITY_OFFSET_INDEX) {
Vector3f vec = (Vector3f) entry.getValue();
// If there is already an entity offset, and it's an old client, add to it.
entry.setValue(vec.add(PRE_1_20_2_TRANSLATION_OFFSET));

containsEntityOffset = true;
event.markForReEncode(true);
} else if (entry.getIndex() == TEXT_DISPLAY_TEXT_INDEX) {
textEntry = entry;
event.markForReEncode(true);
containsEntityOffset = true;
} else if (entry.getIndex() == TEXT_DISPLAY_TEXT_INDEX) {
textEntry = entry;
}
}
}

// Backwards compatibility for clients older than 1.20.2
// Mojank changed the passenger origin point when riding an entity so the tag appears inside their head.
if (isOldClient) {
// If there was no offset found then add one ourselves for the offset.
if (!containsEntityOffset) {
// Backwards compatibility for clients older than 1.20.2
// Mojank changed the passenger origin point when riding an entity so the tag appears inside their head.
if (isOldClient && !containsEntityOffset) {
// If there was no offset found then add one ourselves for the offset.
packet.getEntityMetadata().add(new EntityData(
ENTITY_OFFSET_INDEX,
EntityDataTypes.VECTOR3F,
PRE_1_20_2_TRANSLATION_OFFSET
));
event.markForReEncode(true);
}
}

// Apply relational placeholders to the text of an outgoing display entity
if (plugin.getConfig().getBoolean("options.relative-placeholders-support") &&
nameTagEntity.getBukkitEntity() instanceof Player from &&
textEntry != null
) {
final TextComponent originalText = (TextComponent) textEntry.getValue();
final Player to = event.getPlayer();

// If this proves to increase ping, since it does require string processing
// I recommend always withholding the packet if it contains the textEntry,
// then we can process all of this off the main thread
boolean containsRelativePlaceholder = ComponentUtils.startsWith(originalText, RELATIVE_ARG_PREFIX);
// Apply relational placeholders to the text of an outgoing display entity
if (plugin.getConfig().getBoolean("options.relative-placeholders-support") &&
nameTagEntity.getBukkitEntity() instanceof Player from &&
textEntry != null
) {
final TextComponent originalText = (TextComponent) textEntry.getValue();
final Player to = eventClone.getPlayer();

// If it doesn't have any placeholders in then stop
if (!containsRelativePlaceholder) return;
boolean containsRelativePlaceholder = ComponentUtils.startsWith(originalText, RELATIVE_ARG_PREFIX);

// Withhold the packet while we apply placeholders
event.setCancelled(true);
// If it doesn't have any placeholders in then stop
if (!containsRelativePlaceholder) {
eventClone.getUser().sendPacketSilently(packet);
return;
}

final PacketSendEvent clone = event.clone();
final EntityData finalTextEntry = textEntry;
plugin.getExecutor().execute(() -> {
final Component textWithRelativeApplied = PapiHook.setRelationalPlaceholders(from, to, originalText);

finalTextEntry.setValue(textWithRelativeApplied);
clone.getUser().sendPacket(packet);
});
}
textEntry.setValue(textWithRelativeApplied);
eventClone.getUser().sendPacketSilently(packet);
} else {
eventClone.getUser().sendPacketSilently(packet);
}
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import org.jetbrains.annotations.NotNull;

/**
* Responsible for appending the passenger packet with the
* name tag entity when sending a [WrapperPlayServerSpawnEntity]
* Responsible for appending the name tag spawn packet and
* passenger packet with the name tag entity when sending
* a [WrapperPlayServerSpawnEntity]
* packet to the client.
*/
public class PlayServerSpawnEntityHandler {
Expand Down
22 changes: 0 additions & 22 deletions src/test/java/com/mattmx/nametags/config/TextFormatterTest.java

This file was deleted.

Loading