From ade20ac869733f8978de642f28dd7273a2f4d0a4 Mon Sep 17 00:00:00 2001 From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com> Date: Sun, 16 Jul 2023 09:48:33 +0530 Subject: [PATCH 1/8] changed ItemStack in property from PE to Bukkit --- .../znpcsplus/commands/property/PropertySetCommand.java | 7 +++---- .../pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java | 2 +- .../entity/serializers/ItemStackPropertySerializer.java | 7 +++---- .../java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java | 5 +++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java index a24714e..1813ea4 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java @@ -1,10 +1,8 @@ package lol.pyr.znpcsplus.commands.property; -import com.github.retrooper.packetevents.protocol.item.ItemStack; import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; import com.github.retrooper.packetevents.protocol.world.states.type.StateType; import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes; -import io.github.retrooper.packetevents.util.SpigotConversionUtil; import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.adventure.command.CommandHandler; import lol.pyr.director.common.command.CommandExecutionException; @@ -18,6 +16,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Color; import org.bukkit.DyeColor; +import org.bukkit.inventory.ItemStack; import java.util.Collections; import java.util.List; @@ -43,12 +42,12 @@ public class PropertySetCommand implements CommandHandler { Object value; String valueName; if (type == ItemStack.class) { - org.bukkit.inventory.ItemStack bukkitStack = context.ensureSenderIsPlayer().getInventory().getItemInHand(); + ItemStack bukkitStack = context.ensureSenderIsPlayer().getInventory().getItemInHand(); if (bukkitStack.getAmount() == 0) { value = null; valueName = "EMPTY"; } else { - value = SpigotConversionUtil.fromBukkitItemStack(bukkitStack); + value = bukkitStack; valueName = bukkitStack.toString(); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java index 2b7132a..8e89b46 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -1,6 +1,6 @@ package lol.pyr.znpcsplus.entity; -import com.github.retrooper.packetevents.protocol.item.ItemStack; +import org.bukkit.inventory.ItemStack; import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/ItemStackPropertySerializer.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/ItemStackPropertySerializer.java index c6f1cb5..d9f59d2 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/ItemStackPropertySerializer.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/ItemStackPropertySerializer.java @@ -1,19 +1,18 @@ package lol.pyr.znpcsplus.entity.serializers; -import com.github.retrooper.packetevents.protocol.item.ItemStack; -import io.github.retrooper.packetevents.util.SpigotConversionUtil; import lol.pyr.znpcsplus.entity.PropertySerializer; import lol.pyr.znpcsplus.util.ItemSerializationUtil; +import org.bukkit.inventory.ItemStack; public class ItemStackPropertySerializer implements PropertySerializer { @Override public String serialize(ItemStack property) { - return ItemSerializationUtil.itemToB64(SpigotConversionUtil.toBukkitItemStack(property)); + return ItemSerializationUtil.itemToB64(property); } @Override public ItemStack deserialize(String property) { - return SpigotConversionUtil.fromBukkitItemStack(ItemSerializationUtil.itemFromB64(property)); + return ItemSerializationUtil.itemFromB64(property); } @Override diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java index 2db3255..4535149 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java @@ -6,7 +6,8 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.type.EntityType; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; -import com.github.retrooper.packetevents.protocol.item.ItemStack; +import io.github.retrooper.packetevents.util.SpigotConversionUtil; +import org.bukkit.inventory.ItemStack; import com.github.retrooper.packetevents.protocol.player.*; import com.github.retrooper.packetevents.util.Vector3d; import com.github.retrooper.packetevents.wrapper.PacketWrapper; @@ -279,7 +280,7 @@ public class V1_8PacketFactory implements PacketFactory { for (Map.Entry entry : equipmentSlotMap.entrySet()) { if (!properties.hasProperty(propertyRegistry.getByName(entry.getKey()))) continue; - equipements.add(new Equipment(entry.getValue(), properties.getProperty(propertyRegistry.getByName(entry.getKey(), ItemStack.class)))); + equipements.add(new Equipment(entry.getValue(), SpigotConversionUtil.fromBukkitItemStack(properties.getProperty(propertyRegistry.getByName(entry.getKey(), ItemStack.class))))); } return equipements; } From fd0e57e7fe4bce7126ee17e4213eb6b0c4c431b5 Mon Sep 17 00:00:00 2001 From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com> Date: Tue, 18 Jul 2023 16:46:53 +0530 Subject: [PATCH 2/8] remove redundant method isShown --- .../main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java | 6 +++--- plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java index 426a854..1e91139 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java @@ -37,20 +37,20 @@ public class NpcProcessorTask extends BukkitRunnable { Player closest = null; for (Player player : Bukkit.getOnlinePlayers()) { if (!player.getWorld().equals(npc.getWorld())) { - if (npc.isShown(player)) npc.hide(player); + if (npc.isVisibleTo(player)) npc.hide(player); continue; } double distance = player.getLocation().distanceSquared(npc.getBukkitLocation()); // visibility boolean inRange = distance <= distSq; - if (!inRange && npc.isShown(player)) { + if (!inRange && npc.isVisibleTo(player)) { NpcDespawnEvent event = new NpcDespawnEvent(player, entry); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) npc.hide(player); } if (inRange) { - if (!npc.isShown(player)) { + if (!npc.isVisibleTo(player)) { NpcSpawnEvent event = new NpcSpawnEvent(player, entry); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) continue; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java b/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java index 8bd8f56..b1be5f1 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java @@ -37,10 +37,6 @@ public abstract class Viewable { viewers.remove(player); } - public boolean isShown(Player player) { - return viewers.contains(player); - } - protected void UNSAFE_hideAll() { for (Player viewer : viewers) UNSAFE_hide(viewer); } From fef68e663bfa7bf64a758998f9b2b89483e7a274 Mon Sep 17 00:00:00 2001 From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com> Date: Sun, 23 Jul 2023 23:18:48 +0530 Subject: [PATCH 3/8] fixed shoulder entity property for 1.8-1.11 --- .../java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java index 4535149..37d3ccb 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java @@ -152,8 +152,10 @@ public class V1_8PacketFactory implements PacketFactory { properties.getProperty(propertyRegistry.getByName("skin_right_leg", Boolean.class)), properties.getProperty(propertyRegistry.getByName("skin_hat", Boolean.class)) )); - add(data, metadataFactory.shoulderEntityLeft(properties.getProperty(propertyRegistry.getByName("shoulder_entity_left", ParrotVariant.class)))); - add(data, metadataFactory.shoulderEntityRight(properties.getProperty(propertyRegistry.getByName("shoulder_entity_right", ParrotVariant.class)))); + if (packetEvents.getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_12)) { + add(data, metadataFactory.shoulderEntityLeft(properties.getProperty(propertyRegistry.getByName("shoulder_entity_left", ParrotVariant.class)))); + add(data, metadataFactory.shoulderEntityRight(properties.getProperty(propertyRegistry.getByName("shoulder_entity_right", ParrotVariant.class)))); + } } else if (entity.getType().equals(EntityTypes.ARMOR_STAND)) { add(data, metadataFactory.armorStandProperties( From a92de1817d32ca6f38c5c39cda4c552f58effc49 Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Tue, 25 Jul 2023 03:14:41 +0200 Subject: [PATCH 4/8] update viewers list before showing the npc to prevent the show/hide methods from being called multiple times by the processor task when the method needs extra time to grab skins which causes some problems including multiple teams being created resulting in client warnings/kicks on BungeeCord --- plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java b/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java index b1be5f1..e042e2e 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java @@ -27,14 +27,14 @@ public abstract class Viewable { public void show(Player player) { if (viewers.contains(player)) return; - UNSAFE_show(player); viewers.add(player); + UNSAFE_show(player); } public void hide(Player player) { if (!viewers.contains(player)) return; - UNSAFE_hide(player); viewers.remove(player); + UNSAFE_hide(player); } protected void UNSAFE_hideAll() { From 580478173f5a6863af9ba0b71063c1b59d87968e Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Tue, 25 Jul 2023 16:53:50 +0200 Subject: [PATCH 5/8] fix weird NPE --- .../lol/pyr/znpcsplus/interaction/InteractionPacketListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java index 6169b60..1f59e15 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/interaction/InteractionPacketListener.java @@ -28,6 +28,7 @@ public class InteractionPacketListener implements PacketListener { public void onPacketReceive(PacketReceiveEvent event) { if (event.getPacketType() != PacketType.Play.Client.INTERACT_ENTITY) return; Player player = (Player) event.getPlayer(); + if (player == null) return; WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event); User user = userManager.get(player); From 31e64a15fef869d7acb3789e6c21a1f9b68fef90 Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Sat, 5 Aug 2023 20:53:10 +0200 Subject: [PATCH 6/8] properly import skins that weren't set with a player name --- .../pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java | 5 +++++ .../znpcsplus/conversion/znpcs/model/ZNpcsModel.java | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java index 0acc01e..e733538 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java @@ -27,8 +27,10 @@ import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl; import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.scheduling.TaskScheduler; +import lol.pyr.znpcsplus.skin.Skin; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor; +import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor; import lol.pyr.znpcsplus.util.BungeeConnector; import lol.pyr.znpcsplus.util.ItemSerializationUtil; import lol.pyr.znpcsplus.util.NpcLocation; @@ -123,6 +125,9 @@ public class ZNpcImporter implements DataImporter { if (model.getSkinName() != null) { npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new FetchingDescriptor(skinCache, model.getSkinName())); } + else if (model.getSkin() != null && model.getSignature() != null) { + npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new PrefetchedDescriptor(new Skin(model.getSkin(), model.getSignature()))); + } NpcEntryImpl entry = new NpcEntryImpl(String.valueOf(model.getId()), npc); entry.enableEverything(); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java index 8ab73a3..4502b23 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java @@ -10,6 +10,9 @@ public class ZNpcsModel { private UUID uuid; private double hologramHeight; private String skinName; + private String skin; + private String signature; + private String glowName; private ZNpcsLocation location; private String npcType; @@ -57,4 +60,12 @@ public class ZNpcsModel { public Map getCustomizationMap() { return customizationMap; } + + public String getSkin() { + return skin; + } + + public String getSignature() { + return signature; + } } \ No newline at end of file From c244cb6bab8411e7f3e75762f4dca0a229495e04 Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Sat, 5 Aug 2023 21:01:04 +0200 Subject: [PATCH 7/8] only auto-convert legacy data if the new data directory doesn't exist --- plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index 2a93cee..a136171 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -103,7 +103,7 @@ public class ZNpcsPlus extends JavaPlugin { PluginManager pluginManager = Bukkit.getPluginManager(); long before = System.currentTimeMillis(); - boolean legacy = new File(getDataFolder(), "data.json").isFile(); + boolean legacy = new File(getDataFolder(), "data.json").isFile() && !new File(getDataFolder(), "data").isDirectory(); if (legacy) try { Files.move(getDataFolder().toPath(), new File(getDataFolder().getParentFile(), "ZNPCsPlusLegacy").toPath()); } catch (IOException e) { From 3e226505e3bba9c514dc57c3352e77d5119da817 Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Mon, 7 Aug 2023 23:12:56 +0200 Subject: [PATCH 8/8] add jenkins info to the readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d9a0c05..9c7d345 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ZNPCsPlus [![](https://img.shields.io/discord/1099449144948555957?label=Discord&logo=Discord&style=plastic)](https://discord.gg/MAZz6XpPcg) +# ZNPCsPlus [![](https://img.shields.io/discord/1099449144948555957?label=Discord&logo=Discord&style=plastic)](https://discord.gg/MAZz6XpPcg) [![](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.pyr.lol%2Fjob%2FZNPCsPlus%2F&style=plastic&logo=jenkins)](https://ci.pyr.lol/job/ZNPCsPlus/) [![](https://img.shields.io/bstats/players/18244?style=plastic&label=bStats%20Players)]((https://bstats.org/plugin/bukkit/ZNPCsPlus/18244/)) [![](https://img.shields.io/bstats/servers/18244?style=plastic&label=bStats%20Servers)]((https://bstats.org/plugin/bukkit/ZNPCsPlus/18244/)) [![](https://img.shields.io/spiget/downloads/109380?style=plastic&label=Spigot%20Downloads)]((https://www.spigotmc.org/resources/znpcsplus.109380/)) [ZNPCsPlus](https://www.spigotmc.org/resources/znpcsplus.109380/) is a Spigot plugin that is used to create fake entities @@ -7,6 +7,8 @@ that players can interact with to perform actions like switching servers on a ne This plugin is a remake of a plugin called ZNPCs, we originally started because the maintainer of ZNPCs decided to announce that he was [dropping support for the plugin](https://media.discordapp.net/attachments/1093914615873806477/1098409384855474237/znpc.png). +Looking for up-to-date builds of the plugin? Check out our [Jenkins](https://ci.pyr.lol/job/ZNPCsPlus/) + ## Why is it so good? - 100% Packet Based - Nothing is ran on the main thread - Performance & stability oriented code