From 383ee49d67381b8967882fbe2c712282957e042a Mon Sep 17 00:00:00 2001 From: Fisher2911 Date: Tue, 22 Mar 2022 22:50:32 -0400 Subject: [PATCH] Progress so far with switching to PacketEvents --- .../hmccosmetics/database/Database.java | 5 +- .../listener/CosmeticFixListener.java | 289 ++++++++---------- .../listener/TeleportListener.java | 6 +- .../hmccosmetics/packet/PacketManager.java | 50 +-- .../hmccosmetics/task/TaskManager.java | 35 ++- .../hmccosmetics/user/BaseUser.java | 11 +- .../hmccosmetics/user/Equipment.java | 3 +- .../fisher2911/hmccosmetics/user/NPCUser.java | 10 + .../fisher2911/hmccosmetics/user/User.java | 20 +- .../hmccosmetics/user/UserManager.java | 68 +++-- .../hmccosmetics/user/Wardrobe.java | 6 + 11 files changed, 284 insertions(+), 219 deletions(-) diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java index 87fe7fed..1923231b 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java @@ -15,6 +15,8 @@ import io.github.fisher2911.hmccosmetics.user.EntityIds; import io.github.fisher2911.hmccosmetics.user.NPCUser; import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.Wardrobe; +import io.github.retrooper.packetevents.util.SpigotDataHelper; +import io.github.retrooper.packetevents.util.SpigotReflectionUtil; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; @@ -32,7 +34,6 @@ public class Database { private final Dao armorItemDao; private final ConnectionSource dataSource; private final DatabaseType databaseType; - private static final SplittableRandom RANDOM = new SplittableRandom(); public Database( final HMCCosmetics plugin, @@ -223,6 +224,6 @@ public class Database { } public static int getNextEntityId() { - return RANDOM.nextInt(50_000, 100_000); + return SpigotReflectionUtil.generateEntityId(); } } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/CosmeticFixListener.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/CosmeticFixListener.java index 6efaed68..7488febc 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/CosmeticFixListener.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/CosmeticFixListener.java @@ -11,8 +11,6 @@ import io.github.fisher2911.hmccosmetics.HMCCosmetics; import io.github.fisher2911.hmccosmetics.config.CosmeticSettings; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; -import io.github.fisher2911.hmccosmetics.message.Placeholder; -import io.github.fisher2911.hmccosmetics.message.Translation; import io.github.fisher2911.hmccosmetics.packet.PacketManager; import io.github.fisher2911.hmccosmetics.task.DelayedTask; import io.github.fisher2911.hmccosmetics.task.TaskManager; @@ -20,7 +18,6 @@ import io.github.fisher2911.hmccosmetics.user.Equipment; import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.UserManager; import io.github.fisher2911.hmccosmetics.util.Utils; -import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder; import io.github.retrooper.packetevents.util.SpigotDataHelper; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -42,6 +39,7 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -102,71 +100,10 @@ public class CosmeticFixListener implements Listener { this.registerInventoryClickListener(); } - private void registerClickAirListener() { -// PacketEvents.getAPI().getEventManager().registerListener( -// new PacketListener() { -// @Override -// public void onPacketReceive(PacketReceiveEvent event) { -// -// } -// }.asAbstract(PacketListenerPriority.HIGHEST, false, true) -// ); -// ProtocolLibrary.getProtocolManager().addPacketListener( -// new PacketAdapter(this.plugin, ListenerPriority.MONITOR, PacketType.Play.Client.BLOCK_PLACE) { -// @Override -// public void onPacketReceiving(PacketEvent event) { -// final Player player = event.getPlayer(); -// final Optional optionalUser = CosmeticFixListener.this.userManager.get(player.getUniqueId()); -// if (optionalUser.isEmpty()) return; -// final ItemStack inHand = player.getInventory().getItemInMainHand(); -// if (inHand == null || inHand.getType() == Material.AIR) return; -// final EquipmentSlot slot = getArmorSlot(inHand.getType()); -// if (slot == null) { -// return; -// } -// final ArmorItem.Type type = ArmorItem.Type.fromEquipmentSlot(slot); -// if (type == null) { -// return; -// } -// final User user = optionalUser.get(); -// final Location location = player.getLocation(); -// taskManager.submit(() -> { -// final EntityEquipment entityEquipment = player.getEquipment(); -// final Equipment equipment; -// if (entityEquipment == null) { -// equipment = Equipment.fromEntityEquipment(player.getEquipment()); -// } else { -// equipment = new Equipment(); -// } -// equipment.setItem( -// slot, -// getCosmeticItem( -// user.getPlayerArmor().getItem(type), -// inHand, -// ArmorItem.Status.APPLIED, -// slot -// ) -// ); -// final List> items = getItemList(player, user, equipment, Set.of(type)); -// for (final Player p : Bukkit.getOnlinePlayers()) { -// if (!settings.isInViewDistance(location, p.getLocation())) continue; -// sendUpdatePacket( -// user.getEntityId(), -// p, -// items -// ); -// } -// }); -// } -// } -// ); - } - @EventHandler public void onShiftClick(final InventoryClickEvent event) { if (event.getClick() != ClickType.SHIFT_LEFT && event.getClick() != ClickType.SHIFT_RIGHT) return; if (!(event.getWhoClicked() instanceof final Player player)) return; - final int clickedSlot = event.getSlot(); final ItemStack clicked = event.getCurrentItem(); if (clicked == null) return; final EquipmentSlot slot = this.getArmorSlot(clicked.getType()); @@ -206,7 +143,20 @@ public class CosmeticFixListener implements Listener { int slotClicked = packet.getSlot(); final WrapperPlayClientClickWindow.WindowClickType clickType = packet.getWindowClickType(); EquipmentSlot slot = getPacketArmorSlot(slotClicked); - if (slot == null) return; + if (slot == null) { +// final Equipment equipment = ; +// final var itemList = ; +// player.sendMessage("Sending delayed task"); +// taskManager.submit(new DelayedTask(() -> { +// userManager.sendUpdatePacket( +// player.getEntityId(), +// player, +// getItemList(user, Equipment.fromEntityEquipment(player.getEquipment()), Collections.emptySet()) +// ); +// player.sendMessage("In delayed task"); +// }, 40)); + return; + } final EntityEquipment entityEquipment = player.getEquipment(); if (entityEquipment == null) return; final ItemStack current = Utils.replaceIfNull(entityEquipment.getItem(slot), new ItemStack(Material.AIR)); @@ -223,12 +173,72 @@ public class CosmeticFixListener implements Listener { } ); } +// +// int i = 0; +// +// private void updateIfDifferent(final Player player, final EntityEquipment previous) { +// i++; +// this.taskManager.submit(() -> { +// final int copy = i; +// final EntityEquipment equipment = player.getEquipment(); +// if (equipment == null) return; +// if (this.equipmentEquals(equipment, previous)) { +// player.sendMessage("Same armor"); +// return; +// } +// player.sendMessage("Different armor"); +// final List equipmentList = new ArrayList<>(); +// final Optional optionalUser = this.userManager.get(player.getUniqueId()); +// if (optionalUser.isEmpty()) return; +// final User user = optionalUser.get(); +// final PlayerArmor playerArmor = user.getPlayerArmor(); +// for (final ArmorItem item : playerArmor.getArmorItems()) { +// final EquipmentSlot slot = item.getType().getSlot(); +// if (slot == null) continue; +// final ItemStack current = Utils.replaceIfNull(equipment.getItem(slot), new ItemStack(Material.AIR)); +// equipmentList.add( +// PacketManager.getEquipment( +// this.userManager.getCosmeticItem( +// item, +// current, +// ArmorItem.Status.APPLIED, +// slot +// ), +// slot +// ) +// ); +// } +// this.userManager.sendUpdatePacket( +// user, +// equipmentList +// ); +// }); +// } + + private boolean equipmentEquals(final EntityEquipment first, final EntityEquipment second) { + if (first == null && second == null) { + return true; + } + if (first == null) { + return false; + } + if (second == null) { + return false; + } + for (final EquipmentSlot slot : EquipmentSlot.values()) { + final ItemStack i = first.getItem(slot); + final ItemStack i2 = second.getItem(slot); + if (i == null && i2 == null) continue; + if (!Objects.equals(first.getItem(slot), second.getItem(slot))) return false; + } + return true; + } private void updateOnClick(final Player player, final EquipmentSlot slot, final User user, final ArmorItem.Type type, final ItemStack current) { taskManager.submit(() -> { final Location location = player.getLocation(); final Equipment equipment = Equipment.fromEntityEquipment(player.getEquipment()); - final ItemStack cosmetic = getCosmeticItem( + final ItemStack cosmetic = userManager.getCosmeticItem( user.getPlayerArmor().getItem(type), current, ArmorItem.Status.APPLIED, @@ -240,9 +250,8 @@ public class CosmeticFixListener implements Listener { getItemList(user, equipment, Set.of(type)); for (final Player other : Bukkit.getOnlinePlayers()) { if (!settings.isInViewDistance(location, other.getLocation())) continue; - sendUpdatePacket( - user.getEntityId(), - other, + userManager.sendUpdatePacket( + user, items ); } @@ -264,6 +273,7 @@ public class CosmeticFixListener implements Listener { final List itemStacks = packet.getItems(); final int size = itemStacks.size(); final PlayerArmor playerArmor = user.getPlayerArmor(); + final List equipmentList = new ArrayList<>(); for (final ArmorItem armorItem : playerArmor.getArmorItems()) { final ArmorItem.Type type = armorItem.getType(); final EquipmentSlot slot = type.getSlot(); @@ -271,33 +281,30 @@ public class CosmeticFixListener implements Listener { final int packetSlot = getPacketArmorSlot(slot); if (packetSlot == -1) continue; if (packetSlot >= size) continue; + final ItemStack current = SpigotDataHelper.toBukkitItemStack(itemStacks.get(packetSlot)); final com.github.retrooper.packetevents.protocol.item.ItemStack setTo = - SpigotDataHelper.fromBukkitItemStack(getCosmeticItem( - armorItem, - current, - ArmorItem.Status.APPLIED, - slot - )); - itemStacks.set(packetSlot, setTo); + SpigotDataHelper.fromBukkitItemStack(userManager.getCosmeticItem( + armorItem, + current, + ArmorItem.Status.APPLIED, + slot + )); +// itemStacks.set(packetSlot, setTo); + equipmentList.add(PacketManager.getEquipment(setTo, slot)); } - packet.setItems(itemStacks); + taskManager.submit(() -> { + userManager.sendUpdatePacket( + user, + equipmentList + ); + }); +// packet.setItems(itemStacks); } } ); } -// @EventHandler -// public void onBlockClick(final PlayerInteractEvent event) { -// if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; -// final Player player = event.getPlayer(); -// final Block block = event.getClickedBlock(); -// if (block != null && block.getType().isInteractable() && !player.isSneaking()) return; -// final ItemStack clickedWith = event.getItem(); -// if (clickedWith == null) return; -// this.checkFix(player, -1, clickedWith); -// } - private int getPacketArmorSlot(final EquipmentSlot slot) { return switch (slot) { case HEAD -> 5; @@ -321,14 +328,6 @@ public class CosmeticFixListener implements Listener { }; } -// @EventHandler -// public void onEntityMount(final EntityMountEvent event) { -// if (!(event.getEntity() instanceof final Player player)) { -// return; -// } -// this.fixCosmetics(player); -// } -// @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onOffhandSwap(final PlayerSwapHandItemsEvent event) { final ItemStack offHand = event.getOffHandItem(); @@ -354,15 +353,38 @@ public class CosmeticFixListener implements Listener { this.fixOffHand(event.getPlayer(), new ItemStack(Material.AIR)); } +// @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) +// public void onShiftInventoryClick(final InventoryClickEvent event) { +// final ClickType clickType = event.getClick(); +// if (clickType != ClickType.SHIFT_LEFT && clickType != ClickType.SHIFT_RIGHT) return; +// final ItemStack clicked = event.getCurrentItem(); +// if (clicked == null || clicked.getType() == Material.AIR) return; +// final EquipmentSlot slot = this.getArmorSlot(clicked.getType()); +// if (slot == null) return; +// if (!(event.getWhoClicked() instanceof final Player player)) return; +// final EntityEquipment entityEquipment = player.getEquipment(); +// if (entityEquipment == null) return; +// final Equipment equipment = Equipment.fromEntityEquipment(entityEquipment); +// final Optional optionalUser = this.userManager.get(player.getUniqueId()); +// if (optionalUser.isEmpty()) return; +// final User user = optionalUser.get(); +// player.sendMessage("Sent update packet in listener"); +// final var itemList = this.getItemList(user, equipment, Collections.emptySet()); +// this.taskManager.submit(() -> this.userManager.sendUpdatePacket( +// player.getEntityId(), +// player, +// itemList +// )); +// } + private void fixOffHand(final Player player, final ItemStack current) { final Optional optionalUser = this.userManager.get(player.getUniqueId()); if (optionalUser.isEmpty()) return; final User user = optionalUser.get(); final ArmorItem.Type type = ArmorItem.Type.OFF_HAND; final ArmorItem armorItem = user.getPlayerArmor().getItem(type); - this.taskManager.submit(new DelayedTask(() -> this.sendUpdatePacket( - player.getEntityId(), - player, + this.taskManager.submit(new DelayedTask(() -> this.userManager.sendUpdatePacket( + user, armorItem, current, type @@ -380,17 +402,17 @@ public class CosmeticFixListener implements Listener { final EquipmentSlot slot = type.getSlot(); if (slot == null) continue; if (ignored.contains(type)) { - items.add(this.getEquipment(equipment.getItem(slot), slot)); + items.add(PacketManager.getEquipment(equipment.getItem(slot), slot)); continue; } final ItemStack wearing = Utils.replaceIfNull(equipment.getItem(slot), new ItemStack(Material.AIR)); - final ItemStack itemStack = this.getCosmeticItem( + final ItemStack itemStack = this.userManager.getCosmeticItem( armor.getItem(type), wearing, ArmorItem.Status.APPLIED, slot ); - if (itemStack.getType() != Material.AIR) items.add(this.getEquipment(itemStack, slot)); + if (itemStack.getType() != Material.AIR) items.add(PacketManager.getEquipment(itemStack, slot)); } return items; } @@ -412,67 +434,4 @@ public class CosmeticFixListener implements Listener { () -> this.userManager.updateCosmetics(player.getUniqueId()), 2); } - private void sendUpdatePacket( - final int entityId, - final Player other, - final ArmorItem armorItem, - final ItemStack wearing, - final ArmorItem.Type type) { - final EquipmentSlot slot = type.getSlot(); - final ItemStack itemStack = this.getCosmeticItem(armorItem, wearing, ArmorItem.Status.APPLIED, slot); - final List itemList = new ArrayList<>(); - itemList.add(this.getEquipment(itemStack, slot)); - this.sendUpdatePacket(entityId, other, itemList); - } - - private void sendUpdatePacket( - final int entityId, - final Player other, - List items) { - PacketManager.sendEquipmentPacket( - items, - entityId, - other - ); - - } - - private com.github.retrooper.packetevents.protocol.player.Equipment getEquipment( - final ItemStack itemStack, - final EquipmentSlot slot - ) { - return new com.github.retrooper.packetevents.protocol.player.Equipment( - PacketManager.fromBukkitSlot(slot), - SpigotDataHelper.fromBukkitItemStack(itemStack) - ); - } - - private ItemStack getCosmeticItem( - final ArmorItem armorItem, - final ItemStack wearing, - final ArmorItem.Status status, - final EquipmentSlot slot - ) { - final Map placeholders = Map.of(Placeholder.ALLOWED, Translation.TRUE, - Placeholder.ENABLED, Translation.TRUE); - - if (armorItem.isEmpty()) return wearing; - - ItemStack itemStack = ItemBuilder.from(armorItem.getItemStack(status)). - namePlaceholders(placeholders). - lorePlaceholders(placeholders). - build(); - - if (wearing == null) return itemStack; - - final boolean isAir = wearing.getType().isAir(); - final boolean requireEmpty = settings.requireEmpty(slot); - - if (!isAir && requireEmpty) { - return wearing; - } - - return itemStack; - } - } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/TeleportListener.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/TeleportListener.java index 7ce6d545..83fe365f 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/TeleportListener.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/TeleportListener.java @@ -1,7 +1,6 @@ package io.github.fisher2911.hmccosmetics.listener; import io.github.fisher2911.hmccosmetics.HMCCosmetics; -import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.UserManager; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -23,7 +22,10 @@ public class TeleportListener implements Listener { public void onPlayerTeleport(final PlayerTeleportEvent event) { final Player player = event.getPlayer(); - this.userManager.get(player.getUniqueId()).ifPresent(User::despawnAttached); + this.userManager.get(player.getUniqueId()).ifPresent(user -> { + user.despawnBalloon(); + user.despawnBalloon(); + }); } } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/packet/PacketManager.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/packet/PacketManager.java index 7f401ad2..5e29aaee 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/packet/PacketManager.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/packet/PacketManager.java @@ -22,7 +22,6 @@ import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSp import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPlayer; import io.github.retrooper.packetevents.util.SpigotDataHelper; import net.kyori.adventure.text.Component; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -55,7 +54,7 @@ public class PacketManager { public static void sendArmorStandMetaContainer(final int armorStandId, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityMetadata( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityMetadata( armorStandId, List.of( new EntityData(0, EntityDataTypes.BYTE, (byte) 0x20), @@ -78,7 +77,7 @@ public class PacketManager { final int entityId, final EntityType entityType, final Player... sendTo) { - sendEntitySpawnPacket(location, entityId, entityType, UUID.randomUUID()); + sendEntitySpawnPacket(location, entityId, entityType, UUID.randomUUID(), sendTo); } public static void sendEntitySpawnPacket( @@ -97,7 +96,7 @@ public class PacketManager { final UUID uuid, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerSpawnLivingEntity( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerSpawnLivingEntity( entityId, uuid, entityType, @@ -117,7 +116,7 @@ public class PacketManager { public static void sendInvisibilityPacket(final int entityId, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityMetadata( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityMetadata( entityId, List.of(new EntityData(0, EntityDataTypes.BYTE, (byte) 0x20)) )); @@ -140,7 +139,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityTeleport( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityTeleport( entityId, new Vector3d(location.getX(), location.getY(), location.getZ()), location.getYaw(), @@ -168,7 +167,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityRelativeMove( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityRelativeMove( entityId, to.getX() - from.getX(), to.getY() - from.getY(), @@ -192,7 +191,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerAttachEntity( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerAttachEntity( balloonId, entityId, true @@ -217,7 +216,7 @@ public class PacketManager { final ItemStack itemStack = SpigotDataHelper.toBukkitItemStack(equipment.getItem()); } for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityEquipment( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityEquipment( entityId, equipmentList )); @@ -240,7 +239,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityRotation( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityRotation( entityId, location.getYaw(), location.getPitch(), @@ -263,7 +262,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityHeadLook( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityHeadLook( entityId, location.getYaw() )); @@ -284,7 +283,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerSetPassengers( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerSetPassengers( mountId, new int[]{passengerId} )); @@ -297,7 +296,7 @@ public class PacketManager { public static void sendEntityDestroyPacket(final int entityId, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerDestroyEntities(entityId)); + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerDestroyEntities(entityId)); } } @@ -355,7 +354,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerSpawnPlayer( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerSpawnPlayer( entityId, uuid, new com.github.retrooper.packetevents.protocol.world.Location( @@ -383,7 +382,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerPlayerInfo( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerPlayerInfo( WrapperPlayServerPlayerInfo.Action.ADD_PLAYER, new WrapperPlayServerPlayerInfo.PlayerData( Component.empty(), @@ -411,7 +410,7 @@ public class PacketManager { ) { final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40; for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerEntityMetadata( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityMetadata( playerId, List.of( new EntityData(17, EntityDataTypes.BYTE, mask), @@ -435,7 +434,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacket(p, new WrapperPlayServerPlayerInfo( + PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerPlayerInfo( WrapperPlayServerPlayerInfo.Action.REMOVE_PLAYER, new WrapperPlayServerPlayerInfo.PlayerData( Component.empty(), @@ -454,6 +453,23 @@ public class PacketManager { } + public static com.github.retrooper.packetevents.protocol.player.Equipment getEquipment( + final ItemStack itemStack, + final org.bukkit.inventory.EquipmentSlot slot + ) { + return getEquipment(SpigotDataHelper.fromBukkitItemStack(itemStack), slot); + } + + public static com.github.retrooper.packetevents.protocol.player.Equipment getEquipment( + final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack, + final org.bukkit.inventory.EquipmentSlot slot + ) { + return new com.github.retrooper.packetevents.protocol.player.Equipment( + PacketManager.fromBukkitSlot(slot), + itemStack + ); + } + public static EquipmentSlot fromBukkitSlot(final org.bukkit.inventory.EquipmentSlot slot) { return switch (slot) { case HEAD -> EquipmentSlot.HELMET; diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/task/TaskManager.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/task/TaskManager.java index 06a0d020..2f469a18 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/task/TaskManager.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/task/TaskManager.java @@ -5,25 +5,48 @@ import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitTask; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentLinkedDeque; public class TaskManager { private final HMCCosmetics plugin; private BukkitTask timer; - private final Queue tasks = new ConcurrentLinkedQueue<>(); + private final Queue tasks = new ConcurrentLinkedDeque<>(); public TaskManager(final HMCCosmetics plugin) { this.plugin = plugin; } public void start() { +// this.timer = Bukkit.getScheduler().runTaskTimerAsynchronously( +// this.plugin, +// () -> tasks.removeIf(task -> { +// task.run(); +// Bukkit.broadcastMessage("Task Size: " + this.tasks.size()); +// return task.isComplete(); +// }), +// 1, +// 1 +// ); this.timer = Bukkit.getScheduler().runTaskTimerAsynchronously( this.plugin, - () -> tasks.removeIf(task -> { - task.run(); - return task.isComplete(); - }), + () -> { + int currentTasks = this.tasks.size(); + Task task; + while ((task = this.tasks.peek()) != null && currentTasks > 0) { + // if an exception is thrown it will never end up removing the task + try { + task.run(); + } catch (final Exception e) { + e.printStackTrace(); + } + this.tasks.poll(); + if (!task.isComplete()) { + this.tasks.add(task); + } + currentTasks--; + } + }, 1, 1 ); diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/BaseUser.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/BaseUser.java index ee0eab5e..0bfe80b3 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/BaseUser.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/BaseUser.java @@ -19,6 +19,7 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -54,6 +55,9 @@ public abstract class BaseUser { @Nullable public abstract Location getLocation(); + @Nullable + public abstract Vector getVelocity(); + public T getId() { return this.id; } @@ -120,7 +124,6 @@ public abstract class BaseUser { final Location actual = location.clone().add(settings.getBalloonOffset()); final World world = location.getWorld(); if (world == null) return; - final BalloonItem balloonItem = (BalloonItem) this.playerArmor.getItem(ArmorItem.Type.BALLOON); final String id = balloonItem.getModelId(); final HookManager hookManager = HookManager.getInstance(); @@ -148,6 +151,8 @@ public abstract class BaseUser { } final Location actual = location.clone().add(settings.getBalloonOffset()); final Location previous = this.balloon.getLocation(); + final Vector vector = this.getVelocity(); + if (vector != null) actual.add(this.getVelocity().multiply(-1)); this.balloon.setLocation(actual); this.balloon.setVelocity(actual.clone().subtract(previous.clone()).toVector()); // hookManager.getModelEngineHook().updateModel(this.balloon); @@ -174,6 +179,7 @@ public abstract class BaseUser { final boolean shouldShow = shouldShow(other); final UUID otherUUID = other.getUniqueId(); final boolean hasBackpack = !this.playerArmor.getItem(ArmorItem.Type.BACKPACK).isEmpty(); + other.sendMessage(this.viewingArmorStand.toString()); if (!this.viewingArmorStand.contains(otherUUID)) { if (!inViewDistance || !shouldShow) { if (this.viewingBalloon.contains(otherUUID)) { @@ -213,6 +219,7 @@ public abstract class BaseUser { type(ItemTypes.AIR). build() )); + other.sendMessage("Air"); } else { final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack = SpigotDataHelper.fromBukkitItemStack(this.playerArmor.getBackpack().getItemStack(ArmorItem.Status.APPLIED)); @@ -220,6 +227,7 @@ public abstract class BaseUser { EquipmentSlot.HELMET, itemStack )); + other.sendMessage("Added " + this.playerArmor.getBackpack().getItemStack(ArmorItem.Status.APPLIED).getType()); } final int armorStandId = this.getArmorStandId(); @@ -227,6 +235,7 @@ public abstract class BaseUser { PacketManager.sendRotationPacket(armorStandId, location, false, other); PacketManager.sendRidingPacket(this.getEntityId(), armorStandId, other); PacketManager.sendArmorStandMetaContainer(armorStandId, other); + other.sendMessage("Spawned equipment: " + hidden + " : " + shouldShow); if (hidden) return; this.updateBalloon(other, location, settings.getCosmeticSettings()); diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Equipment.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Equipment.java index e3e5623e..e0633e54 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Equipment.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Equipment.java @@ -16,7 +16,8 @@ public class Equipment { public Equipment() { } - public static Equipment fromEntityEquipment(final EntityEquipment entityEquipment) { + public static Equipment fromEntityEquipment(@Nullable final EntityEquipment entityEquipment) { + if (entityEquipment == null) return new Equipment(); final Equipment equipment = new Equipment(); for (final EquipmentSlot slot : VALUES) { equipment.setItem(slot, entityEquipment.getItem(slot)); diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/NPCUser.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/NPCUser.java index 07381765..0f28c3e2 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/NPCUser.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/NPCUser.java @@ -8,6 +8,7 @@ import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; public class NPCUser extends BaseUser { @@ -38,6 +39,15 @@ public class NPCUser extends BaseUser { return entity.getLocation(); } + @Override + public @Nullable Vector getVelocity() { + final NPC npc = this.getNpc(); + if (npc == null) return null; + final Entity entity = npc.getEntity(); + if (entity == null) return null; + return entity.getVelocity(); + } + public boolean isValid() { final NPC npc = this.getNpc(); return npc != null && npc.getEntity() != null; diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java index 1c5d0cea..e364de68 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java @@ -12,8 +12,10 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; +import java.lang.ref.WeakReference; import java.util.UUID; public class User extends BaseUser { @@ -21,18 +23,26 @@ public class User extends BaseUser { protected Wardrobe wardrobe; private CosmeticGui openGui; private boolean hidden; + private WeakReference playerReference; public User(final UUID uuid, final PlayerArmor playerArmor, final Wardrobe wardrobe, final EntityIds entityIds) { super(uuid, playerArmor, entityIds); this.wardrobe = wardrobe; + this.playerReference = new WeakReference<>(Bukkit.getPlayer(uuid)); } public User(final UUID uuid, final PlayerArmor playerArmor, final EntityIds entityIds) { super(uuid, playerArmor, entityIds); + this.playerReference = new WeakReference<>(Bukkit.getPlayer(uuid)); } public @Nullable Player getPlayer() { - return Bukkit.getPlayer(this.getId()); + Player player = this.playerReference.get(); + if (player == null) { + player = Bukkit.getPlayer(this.getId()); + if (player != null) this.playerReference = new WeakReference<>(player); + } + return player; } public Wardrobe getWardrobe() { @@ -79,6 +89,14 @@ public class User extends BaseUser { return player.getLocation(); } + @Override + @Nullable + public Vector getVelocity() { + final Player player = this.getPlayer(); + if (player == null) return null; + return player.getVelocity(); + } + @Override public Equipment getEquipment() { final Player player = this.getPlayer(); diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java index 5754fbe9..6d6f1893 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java @@ -4,7 +4,6 @@ import io.github.fisher2911.hmccosmetics.HMCCosmetics; import io.github.fisher2911.hmccosmetics.api.CosmeticItem; import io.github.fisher2911.hmccosmetics.api.event.CosmeticChangeEvent; import io.github.fisher2911.hmccosmetics.concurrent.Threads; -import io.github.fisher2911.hmccosmetics.config.CosmeticSettings; import io.github.fisher2911.hmccosmetics.config.Settings; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; @@ -17,7 +16,6 @@ import io.github.fisher2911.hmccosmetics.task.InfiniteTask; import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder; import io.github.retrooper.packetevents.util.SpigotDataHelper; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -79,7 +77,7 @@ public class UserManager { this.plugin.getTaskManager().submit(new InfiniteTask( () -> { for (final User user : this.userMap.values()) { -// user.updateOutsideCosmetics(this.plugin.getSettings()); + user.updateOutsideCosmetics(this.plugin.getSettings()); } } )); @@ -125,7 +123,7 @@ public class UserManager { final ArmorItem.Type type) { final PlayerArmor playerArmor = user.getPlayerArmor(); final EquipmentSlot slot = type.getSlot(); - final ItemStack itemStack = this.getCosmeticItem(user, equipment, playerArmor.getItem(type), ArmorItem.Status.APPLIED, slot); + final ItemStack itemStack = this.getCosmeticItem(playerArmor.getItem(type), equipment.getItem(type.getSlot()), ArmorItem.Status.APPLIED, slot); if (itemStack != null && itemStack.equals(equipment.getItem(slot))) return; final List itemList = new ArrayList<>(); itemList.add(new com.github.retrooper.packetevents.protocol.player.Equipment( @@ -138,40 +136,29 @@ public class UserManager { ); } - private ItemStack getCosmeticItem( - final BaseUser user, - final Equipment equipment, + public ItemStack getCosmeticItem( final ArmorItem armorItem, + final ItemStack wearing, final ArmorItem.Status status, final EquipmentSlot slot ) { - final CosmeticSettings cosmeticSettings = this.settings.getCosmeticSettings(); - final Map placeholders = Map.of(Placeholder.ALLOWED, Translation.TRUE, Placeholder.ENABLED, Translation.TRUE); + if (armorItem.isEmpty()) return wearing; + ItemStack itemStack = ItemBuilder.from(armorItem.getItemStack(status)). namePlaceholders(placeholders). lorePlaceholders(placeholders). build(); + if (wearing == null) return itemStack; - final boolean isAir = itemStack.getType().isAir(); - final boolean requireEmpty = cosmeticSettings.requireEmpty(slot); + final boolean isAir = wearing.getType().isAir(); + final boolean requireEmpty = settings.getCosmeticSettings().requireEmpty(slot); - - if (!isAir && (!requireEmpty || user instanceof Wardrobe)) { - return itemStack; - } - - if (equipment == null) { - return itemStack; - } - - final ItemStack equipped = equipment.getItem(slot); - - if (equipped != null && (equipped.getType() != Material.AIR && !user.isWardrobeActive())) { - return equipped; + if (!isAir && requireEmpty) { + return wearing; } return itemStack; @@ -192,6 +179,7 @@ public class UserManager { switch (type) { case HAT, OFF_HAND, CHEST_PLATE, PANTS, BOOTS -> this.updateCosmetics(user); case BACKPACK -> { + user.despawnAttached(); if (user instanceof Wardrobe) user.updateOutsideCosmetics(settings); } } @@ -263,4 +251,36 @@ public class UserManager { default -> null; }; } + + public void sendUpdatePacket( + final User user, + final ArmorItem armorItem, + final ItemStack wearing, + final ArmorItem.Type type) { + final EquipmentSlot slot = type.getSlot(); + final ItemStack itemStack = this.getCosmeticItem(armorItem, wearing, ArmorItem.Status.APPLIED, slot); + final List itemList = new ArrayList<>(); + itemList.add(PacketManager.getEquipment(itemStack, slot)); + this.sendUpdatePacket(user, itemList); + } + + public void sendUpdatePacket( + final User user, + List items) { + final Player player = user.getPlayer(); + if (player == null) return; + final int entityId = user.getEntityId(); + for (final User otherUser : this.userMap.values()) { + final Player other = otherUser.getPlayer(); + if (other == null) continue; + if (!user.shouldShow(other)) continue; + if (!this.settings.getCosmeticSettings().isInViewDistance(player.getLocation(), other.getLocation())) continue; + PacketManager.sendEquipmentPacket( + items, + entityId, + other + ); + } + + } } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Wardrobe.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Wardrobe.java index fe706c66..11dc5da9 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Wardrobe.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Wardrobe.java @@ -11,6 +11,7 @@ import io.github.fisher2911.hmccosmetics.task.TaskChain; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -203,6 +204,11 @@ public class Wardrobe extends User { return currentLocation; } + @Override + public @Nullable Vector getVelocity() { + return new Vector(); + } + @Override @Nullable public Player getPlayer() {