Fix player relative placeholders and improve their performance

This commit is contained in:
filoghost 2018-09-29 14:29:37 +02:00
parent db06e24178
commit 485ea9feff
4 changed files with 153 additions and 53 deletions

View File

@ -14,6 +14,7 @@
*/
package com.gmail.filoghost.holographicdisplays.bridge.protocollib.current;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
@ -38,7 +39,6 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import com.gmail.filoghost.holographicdisplays.api.Hologram;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.ProtocolLibHook;
import com.gmail.filoghost.holographicdisplays.bridge.protocollib.current.WrapperPlayServerSpawnEntity.ObjectTypes;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.NMSManager;
@ -50,6 +50,7 @@ import com.gmail.filoghost.holographicdisplays.object.line.CraftItemLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftTextLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchSlimeLine;
import com.gmail.filoghost.holographicdisplays.object.line.CraftTouchableLine;
import com.gmail.filoghost.holographicdisplays.placeholder.RelativePlaceholder;
import com.gmail.filoghost.holographicdisplays.util.NMSVersion;
import com.gmail.filoghost.holographicdisplays.util.Utils;
@ -125,8 +126,9 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
Player player = event.getPlayer();
if (event.getPlayer().getClass().getName().equals("com.comphenix.net.sf.cglib.proxy.Factory")) {
if (player.getClass().getName().equals("com.comphenix.net.sf.cglib.proxy.Factory")) {
return; // Ignore temporary players (reference: https://github.com/dmulloy2/ProtocolLib/issues/349)
}
@ -136,44 +138,37 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
WrapperPlayServerSpawnEntityLiving spawnEntityPacket = new WrapperPlayServerSpawnEntityLiving(packet);
Entity entity = spawnEntityPacket.getEntity(event);
if (entity == null || !isHologramType(entity.getType())) {
CraftHologramLine hologramLine = getHologramLine(entity);
if (hologramLine == null) {
return;
}
Hologram hologram = getHologram(entity);
if (hologram == null) {
return;
}
Player player = event.getPlayer();
if (!hologram.getVisibilityManager().isVisibleTo(player)) {
if (!hologramLine.getParent().getVisibilityManager().isVisibleTo(player)) {
event.setCancelled(true);
return;
}
Collection<RelativePlaceholder> relativePlaceholders = hologramLine.getRelativePlaceholders();
if (relativePlaceholders == null || relativePlaceholders.isEmpty()) {
return;
}
spawnEntityPacket = new WrapperPlayServerSpawnEntityLiving(packet.deepClone());
WrappedWatchableObject customNameWatchableObject = spawnEntityPacket.getMetadata().getWatchableObject(customNameWatcherIndex);
replacePlayerRelativePlaceholders(customNameWatchableObject, event.getPlayer());
replaceRelativePlaceholders(customNameWatchableObject, player, relativePlaceholders);
event.setPacket(spawnEntityPacket.getHandle());
} else if (packet.getType() == PacketType.Play.Server.SPAWN_ENTITY) {
WrapperPlayServerSpawnEntity spawnEntityPacket = new WrapperPlayServerSpawnEntity(packet);
Entity entity = spawnEntityPacket.getEntity(event);
if (entity == null) {
CraftHologramLine hologramLine = getHologramLine(entity);
if (hologramLine == null) {
return;
}
if (!isHologramType(entity.getType())) {
return;
}
Hologram hologram = getHologram(entity);
if (hologram == null) {
return;
}
Player player = event.getPlayer();
if (!hologram.getVisibilityManager().isVisibleTo(player)) {
if (!hologramLine.getParent().getVisibilityManager().isVisibleTo(player)) {
event.setCancelled(true);
return;
}
@ -183,35 +178,34 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
WrapperPlayServerEntityMetadata entityMetadataPacket = new WrapperPlayServerEntityMetadata(packet);
Entity entity = entityMetadataPacket.getEntity(event);
if (entity == null) {
return;
}
if (!isHologramType(entity.getType())) {
CraftHologramLine hologramLine = getHologramLine(entity);
if (hologramLine == null) {
return;
}
Hologram hologram = getHologram(entity);
if (hologram == null) {
return;
}
Player player = event.getPlayer();
if (!hologram.getVisibilityManager().isVisibleTo(player)) {
if (!hologramLine.getParent().getVisibilityManager().isVisibleTo(player)) {
event.setCancelled(true);
return;
}
Collection<RelativePlaceholder> relativePlaceholders = hologramLine.getRelativePlaceholders();
if (relativePlaceholders == null || relativePlaceholders.isEmpty()) {
return;
}
entityMetadataPacket = new WrapperPlayServerEntityMetadata(packet.deepClone());
List<WrappedWatchableObject> dataWatcherValues = entityMetadataPacket.getEntityMetadata();
for (int i = 0; i < dataWatcherValues.size(); i++) {
WrappedWatchableObject watchableObject = dataWatcherValues.get(i);
if (watchableObject.getIndex() == customNameWatcherIndex) {
if (replacePlayerRelativePlaceholders(watchableObject, event.getPlayer())) {
entityMetadataPacket.setEntityMetadata(dataWatcherValues);
if (replaceRelativePlaceholders(watchableObject, player, relativePlaceholders)) {
event.setPacket(entityMetadataPacket.getHandle());
}
// No reason to check further.
return;
}
}
}
@ -222,7 +216,7 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
}
private boolean replacePlayerRelativePlaceholders(WrappedWatchableObject customNameWatchableObject, Player player) {
private boolean replaceRelativePlaceholders(WrappedWatchableObject customNameWatchableObject, Player player, Collection<RelativePlaceholder> relativePlaceholders) {
if (customNameWatchableObject == null) {
return true;
}
@ -251,11 +245,9 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
customName = (String) customNameWatchableObjectValue;
}
if (!customName.contains("{player}") && !customName.contains("{displayname}")) {
return false;
for (RelativePlaceholder relativePlaceholder : relativePlaceholders) {
customName = customName.replace(relativePlaceholder.getTextPlaceholder(), relativePlaceholder.getReplacement(player));
}
customName = customName.replace("{player}", player.getName()).replace("{displayname}", player.getDisplayName());
if (NMSVersion.isGreaterEqualThan(NMSVersion.v1_13_R1)) {
customNameWatchableObject.setValue(Optional.of(WrappedChatComponent.fromJson(customName).getHandle()));
@ -397,19 +389,21 @@ public class ProtocolLibHookImpl implements ProtocolLibHook {
attachPacket.sendPacket(receiver);
}
}
private boolean isHologramType(EntityType type) {
return type == EntityType.ARMOR_STAND || type == EntityType.DROPPED_ITEM || type == EntityType.SLIME;
}
private Hologram getHologram(Entity bukkitEntity) {
NMSEntityBase entity = nmsManager.getNMSEntityBase(bukkitEntity);
if (entity != null) {
return entity.getHologramLine().getParent();
private CraftHologramLine getHologramLine(Entity bukkitEntity) {
if (bukkitEntity != null && isHologramType(bukkitEntity.getType())) {
NMSEntityBase entity = nmsManager.getNMSEntityBase(bukkitEntity);
if (entity != null) {
return (CraftHologramLine) entity.getHologramLine();
}
}
return null;
}
private boolean isHologramType(EntityType type) {
return type == EntityType.ARMOR_STAND || type == EntityType.DROPPED_ITEM || type == EntityType.SLIME;
}
}

View File

@ -14,10 +14,13 @@
*/
package com.gmail.filoghost.holographicdisplays.object.line;
import java.util.Collection;
import org.bukkit.World;
import com.gmail.filoghost.holographicdisplays.api.line.HologramLine;
import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
import com.gmail.filoghost.holographicdisplays.placeholder.RelativePlaceholder;
import com.gmail.filoghost.holographicdisplays.util.Validator;
public abstract class CraftHologramLine implements HologramLine {
@ -64,6 +67,10 @@ public abstract class CraftHologramLine implements HologramLine {
public final boolean isSpawned() {
return isSpawned;
}
public Collection<RelativePlaceholder> getRelativePlaceholders() {
return null;
}
public abstract int[] getEntitiesIDs();

View File

@ -14,6 +14,9 @@
*/
package com.gmail.filoghost.holographicdisplays.object.line;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.Location;
import org.bukkit.World;
@ -24,11 +27,14 @@ import com.gmail.filoghost.holographicdisplays.api.line.TextLine;
import com.gmail.filoghost.holographicdisplays.nms.interfaces.entity.NMSNameable;
import com.gmail.filoghost.holographicdisplays.object.CraftHologram;
import com.gmail.filoghost.holographicdisplays.placeholder.PlaceholdersManager;
import com.gmail.filoghost.holographicdisplays.placeholder.RelativePlaceholder;
import com.gmail.filoghost.holographicdisplays.util.Offsets;
import com.gmail.filoghost.holographicdisplays.util.Utils;
public class CraftTextLine extends CraftTouchableLine implements TextLine {
private String text;
private List<RelativePlaceholder> relativePlaceholders;
private NMSNameable nmsNameble;
@ -60,6 +66,22 @@ public class CraftTextLine extends CraftTouchableLine implements TextLine {
}
}
}
if (text != null) {
for (RelativePlaceholder relativePlaceholder : RelativePlaceholder.getRegistry()) {
if (text.contains(relativePlaceholder.getTextPlaceholder())) {
if (relativePlaceholders == null) {
relativePlaceholders = Utils.newList();
}
relativePlaceholders.add(relativePlaceholder);
}
}
}
// Deallocate the list if unused
if (relativePlaceholders != null && relativePlaceholders.isEmpty()) {
relativePlaceholders = null;
}
}
@Override
@ -98,6 +120,12 @@ public class CraftTextLine extends CraftTouchableLine implements TextLine {
nmsNameble = null;
}
}
@Override
public Collection<RelativePlaceholder> getRelativePlaceholders() {
return relativePlaceholders;
}
@Override

View File

@ -0,0 +1,71 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.gmail.filoghost.holographicdisplays.placeholder;
import java.util.Collection;
import org.bukkit.entity.Player;
import com.gmail.filoghost.holographicdisplays.util.Utils;
public abstract class RelativePlaceholder {
private static final Collection<RelativePlaceholder> registry = Utils.newSet();
// The placeholder itself, something like {player}.
private final String textPlaceholder;
public RelativePlaceholder(String textPlaceholder) {
this.textPlaceholder = textPlaceholder;
}
public String getTextPlaceholder() {
return textPlaceholder;
}
public abstract String getReplacement(Player player);
public static void register(RelativePlaceholder relativePlaceholder) {
for (RelativePlaceholder existingPlaceholder : registry) {
if (existingPlaceholder.getTextPlaceholder().equals(relativePlaceholder.getTextPlaceholder())) {
throw new IllegalArgumentException("Relative placeholder already registered.");
}
}
registry.add(relativePlaceholder);
}
public static Collection<RelativePlaceholder> getRegistry() {
return registry;
}
static {
register(new RelativePlaceholder("{player}") {
@Override
public String getReplacement(Player player) {
return player.getName();
}
});
register(new RelativePlaceholder("{displayname}") {
@Override
public String getReplacement(Player player) {
return player.getDisplayName();
}
});
}
}