diff --git a/src/main/java/net/momirealms/customnameplates/commands/Execute.java b/src/main/java/net/momirealms/customnameplates/commands/Execute.java index cd98fc6..32f0f55 100644 --- a/src/main/java/net/momirealms/customnameplates/commands/Execute.java +++ b/src/main/java/net/momirealms/customnameplates/commands/Execute.java @@ -5,16 +5,21 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import com.sun.source.tree.BreakTree; import net.kyori.adventure.key.Key; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.momirealms.customnameplates.ConfigManager; import net.momirealms.customnameplates.AdventureManager; import net.momirealms.customnameplates.CustomNameplates; import net.momirealms.customnameplates.data.DataManager; +import net.momirealms.customnameplates.font.FontCache; +import net.momirealms.customnameplates.nameplates.NameplateUtil; import net.momirealms.customnameplates.scoreboard.NameplatesTeam; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -181,54 +186,20 @@ public class Execute implements CommandExecutor { } case "preview" -> { if (sender instanceof Player player){ - //指令冷却 - long time = System.currentTimeMillis(); - //冷却时间判断 - if (time - (coolDown.getOrDefault(player, time - ConfigManager.MainConfig.preview * 1050)) < ConfigManager.MainConfig.preview * 1050) { - AdventureManager.playerMessage(player, ConfigManager.Message.prefix + ConfigManager.Message.cooldown); - return true; - } - //重置冷却时间 - coolDown.put(player, time); if (player.hasPermission("customnameplates.preview") || player.isOp()){ + //指令冷却 + long time = System.currentTimeMillis(); + //冷却时间判断 + if (time - (coolDown.getOrDefault(player, time - ConfigManager.MainConfig.preview * 1050)) < ConfigManager.MainConfig.preview * 1050) { + AdventureManager.playerMessage(player, ConfigManager.Message.prefix + ConfigManager.Message.cooldown); + return true; + } + //重置冷却时间 + coolDown.put(player, time); AdventureManager.playerMessage(player,ConfigManager.Message.prefix + ConfigManager.Message.preview); - ArmorStand entity = player.getWorld().spawn(player.getLocation().add(0,0.8,0), ArmorStand.class, a -> { - a.setInvisible(true); - a.setCollidable(false); - a.setInvulnerable(true); - a.setVisible(false); - a.setCustomNameVisible(false); - a.setSmall(true); - a.setGravity(false); - }); - pCache.add(entity); NameplatesTeam team = this.plugin.getScoreBoardManager().getOrCreateTeam(player); - Component full = team.getPrefix().append(Component.text(player.getName()).font(Key.key("default")).append(team.getSuffix())); - - WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); - wrappedDataWatcher.setEntity(entity); - WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Boolean.class); - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(full)).getHandle())); - wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer), true); - PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); - packetContainer.getIntegers().write(0, entity.getEntityId()); - packetContainer.getWatchableCollectionModifier().write(0, wrappedDataWatcher.getWatchableObjects()); - - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packetContainer); - } - catch (Exception e) { - AdventureManager.consoleMessage("[CustomNameplates] Error! Failed to preview for "+ player.getName()+""); - e.printStackTrace(); - } - BukkitScheduler bukkitScheduler = Bukkit.getScheduler(); - for (int i = 1; i < ConfigManager.MainConfig.preview * 20; i++){ - bukkitScheduler.runTaskLater(CustomNameplates.instance,()-> entity.teleport(player.getLocation().add(0,0.8,0)), i); - } - bukkitScheduler.runTaskLater(CustomNameplates.instance, ()->{ - entity.remove(); - pCache.remove(entity); - }, ConfigManager.MainConfig.preview * 20L); + Component full = team.getPrefix().append(Component.text(player.getName()).color(TextColor.color(color2decimal(team.getColor()))).font(Key.key("default")).append(team.getSuffix())); + showNameplate(player, full); }else { AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.noPerm); } @@ -236,6 +207,56 @@ public class Execute implements CommandExecutor { AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.no_console); } } + case "forcepreview" -> { + if (sender.hasPermission("customnameplates.forcepreview") || sender.isOp()) { + if (args.length < 3){ + if(sender instanceof Player){ + AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.lackArgs); + }else { + AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.lackArgs); + } + return true; + } + Player player = Bukkit.getPlayer(args[1]); + if (player == null){ + if (sender instanceof Player){ + AdventureManager.playerMessage((Player) sender, ConfigManager.Message.prefix + ConfigManager.Message.not_online); + }else { + AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.not_online); + } + return true; + } + FontCache fontCache = plugin.getResourceManager().getNameplateInfo(args[2]); + if (fontCache == null){ + if(sender instanceof Player){ + AdventureManager.playerMessage((Player) sender,ConfigManager.Message.prefix + ConfigManager.Message.not_exist); + }else { + AdventureManager.consoleMessage(ConfigManager.Message.prefix + ConfigManager.Message.not_exist); + } + return true; + } + long time = System.currentTimeMillis(); + if (time - (coolDown.getOrDefault(player, time - ConfigManager.MainConfig.preview * 1050)) < ConfigManager.MainConfig.preview * 1050) { + AdventureManager.playerMessage(player, ConfigManager.Message.prefix + ConfigManager.Message.cooldown); + return true; + } + coolDown.put(player, time); + NameplateUtil nameplateUtil = new NameplateUtil(fontCache); + String playerPrefix; + String playerSuffix; + if (plugin.getHookManager().hasPlaceholderAPI()) { + playerPrefix = this.plugin.getHookManager().parsePlaceholders(player, ConfigManager.MainConfig.player_prefix); + playerSuffix = this.plugin.getHookManager().parsePlaceholders(player, ConfigManager.MainConfig.player_suffix); + }else { + playerPrefix = ConfigManager.MainConfig.player_prefix; + playerSuffix = ConfigManager.MainConfig.player_suffix; + } + Component prefix = Component.text(nameplateUtil.makeCustomNameplate(playerPrefix, args[1], playerSuffix)).font(ConfigManager.MainConfig.key).append(Component.text(playerPrefix).font(Key.key("default"))); + Component suffix = Component.text(playerSuffix).append(Component.text(nameplateUtil.getSuffixLength(playerPrefix + args[1] + playerSuffix)).font(ConfigManager.MainConfig.key)); + Component full = prefix.append(Component.text(player.getName()).color(TextColor.color(color2decimal(nameplateUtil.getColor()))).font(Key.key("default")).append(suffix)); + showNameplate(player, full); + } + } case "list" -> { if (sender instanceof Player player){ if (player.isOp()){ @@ -274,6 +295,7 @@ public class Execute implements CommandExecutor { AdventureManager.playerMessage(player,"/nameplates unequip - unequip your nameplate"); AdventureManager.playerMessage(player,"/nameplates forceunequip - force unequip a player's nameplate"); AdventureManager.playerMessage(player,"/nameplates preview - preview your nameplate"); + AdventureManager.playerMessage(player,"/nameplates forcepreview - force a player to preview a nameplate"); AdventureManager.playerMessage(player,"/nameplates list - list your available nameplates"); } }else { @@ -284,6 +306,7 @@ public class Execute implements CommandExecutor { AdventureManager.consoleMessage("/nameplates unequip - unequip your nameplate"); AdventureManager.consoleMessage("/nameplates forceunequip - force unequip a player's nameplate"); AdventureManager.consoleMessage("/nameplates preview - preview your nameplate"); + AdventureManager.consoleMessage("/nameplates forcepreview - force a player to preview a nameplate"); AdventureManager.consoleMessage("/nameplates list - list your available nameplates"); } return true; @@ -291,4 +314,95 @@ public class Execute implements CommandExecutor { } return true; } + + private void showNameplate(Player player, Component component) { + ArmorStand entity = player.getWorld().spawn(player.getLocation().add(0,0.8,0), ArmorStand.class, a -> { + a.setInvisible(true); + a.setCollidable(false); + a.setInvulnerable(true); + a.setVisible(false); + a.setCustomNameVisible(false); + a.setSmall(true); + a.setGravity(false); + }); + pCache.add(entity); + + WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); + wrappedDataWatcher.setEntity(entity); + WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Boolean.class); + wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(2, WrappedDataWatcher.Registry.getChatComponentSerializer(true)), Optional.of(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)).getHandle())); + wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(3, serializer), true); + PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + packetContainer.getIntegers().write(0, entity.getEntityId()); + packetContainer.getWatchableCollectionModifier().write(0, wrappedDataWatcher.getWatchableObjects()); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packetContainer); + } + catch (Exception e) { + AdventureManager.consoleMessage("[CustomNameplates] Error! Failed to preview for "+ player.getName()+""); + e.printStackTrace(); + } + BukkitScheduler bukkitScheduler = Bukkit.getScheduler(); + for (int i = 1; i < ConfigManager.MainConfig.preview * 20; i++){ + bukkitScheduler.runTaskLater(CustomNameplates.instance,()-> entity.teleport(player.getLocation().add(0,0.8,0)), i); + } + bukkitScheduler.runTaskLater(CustomNameplates.instance, ()->{ + entity.remove(); + pCache.remove(entity); + }, ConfigManager.MainConfig.preview * 20L); + } + + private int color2decimal(ChatColor color){ + switch (String.valueOf(color.getChar())){ + case "0" -> { + return 0; + } + case "c" -> { + return 16733525; + } + case "6" -> { + return 16755200; + } + case "4" -> { + return 11141120; + } + case "e" -> { + return 16777045; + } + case "2" -> { + return 43520; + } + case "a" -> { + return 5635925; + } + case "b" -> { + return 5636095; + } + case "3" -> { + return 43690; + } + case "1" -> { + return 170; + } + case "9" -> { + return 5592575; + } + case "d" -> { + return 16733695; + } + case "5" -> { + return 11141290; + } + case "8" -> { + return 5592405; + } + case "7" -> { + return 11184810; + } + default -> { + return 16777215; + } + } + } } diff --git a/src/main/java/net/momirealms/customnameplates/commands/TabComplete.java b/src/main/java/net/momirealms/customnameplates/commands/TabComplete.java index 6c891e4..7c32881 100644 --- a/src/main/java/net/momirealms/customnameplates/commands/TabComplete.java +++ b/src/main/java/net/momirealms/customnameplates/commands/TabComplete.java @@ -34,12 +34,12 @@ public class TabComplete implements TabCompleter { if (sender.hasPermission("customnameplates.forceequip")) tab.add("forceequip"); if (sender.hasPermission("customnameplates.unequip")) tab.add("unequip"); if (sender.hasPermission("customnameplates.forceunequip")) tab.add("forceunequip"); + if (sender.hasPermission("customnameplates.forcepreview")) tab.add("forcepreview"); if (sender.hasPermission("customnameplates.preview")) tab.add("preview"); if (sender.hasPermission("customnameplates.list")) tab.add("list"); return tab; } if(2 == args.length){ - List tab = new ArrayList<>(); if (args[0].equalsIgnoreCase("equip")){ return availableNameplates(sender); } @@ -49,11 +49,17 @@ public class TabComplete implements TabCompleter { if (args[0].equalsIgnoreCase("forceequip") && sender.hasPermission("customnameplates.forceequip")){ return online_players(); } + if (args[0].equalsIgnoreCase("forcepreview") && sender.hasPermission("customnameplates.forcepreview")){ + return online_players(); + } } if(3 == args.length){ if (args[0].equalsIgnoreCase("forceequip") && sender.hasPermission("customnameplates.forceequip")){ return nameplates(); } + if (args[0].equalsIgnoreCase("forcepreview") && sender.hasPermission("customnameplates.forcepreview")){ + return nameplates(); + } } return null; } diff --git a/src/main/java/net/momirealms/customnameplates/scoreboard/NameplatesTeam.java b/src/main/java/net/momirealms/customnameplates/scoreboard/NameplatesTeam.java index 3d008d7..4adc202 100644 --- a/src/main/java/net/momirealms/customnameplates/scoreboard/NameplatesTeam.java +++ b/src/main/java/net/momirealms/customnameplates/scoreboard/NameplatesTeam.java @@ -2,6 +2,8 @@ package net.momirealms.customnameplates.scoreboard; import net.kyori.adventure.key.Key; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.momirealms.customnameplates.ConfigManager; import net.momirealms.customnameplates.CustomNameplates; import net.momirealms.customnameplates.data.DataManager; @@ -64,6 +66,10 @@ public class NameplatesTeam { //根据铭牌名获取FontCache FontCache fontCache = this.plugin.getResourceManager().getNameplateInfo(nameplate); if (fontCache == null){ + this.prefix = Component.text(""); + this.suffix = Component.text(""); + this.color = ChatColor.WHITE; + this.team.setPrefix(""); DataManager.cache.get(player.getUniqueId()).equipNameplate("none"); return; } @@ -81,7 +87,7 @@ public class NameplatesTeam { } //最终prefix: 偏移 + 铭牌左 + 偏移 + 铭牌中 + 偏移 + 铭牌右 + 偏移 + 前缀 //最终suffix: 偏移 + 后缀 - this.prefix = Component.text(nameplateUtil.makeCustomNameplate(playerPrefix, name, playerSuffix)).font(ConfigManager.MainConfig.key).append(Component.text(playerPrefix).font(Key.key("default"))); + this.prefix = Component.text(nameplateUtil.makeCustomNameplate(playerPrefix, name, playerSuffix)).color(TextColor.color(255, 255, 255)).font(ConfigManager.MainConfig.key).append(Component.text(playerPrefix).font(Key.key("default"))); this.suffix = Component.text(playerSuffix).append(Component.text(nameplateUtil.getSuffixLength(playerPrefix + name + playerSuffix)).font(ConfigManager.MainConfig.key)); this.color = nameplateUtil.getColor(); this.team.setPrefix(""); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4664ef1..876e062 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,7 @@ config: # Language - lang: en + # en/cn + lang: cn # Your namespace namespace: "nameplates"