diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/config/CosmeticSettings.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/config/CosmeticSettings.java index 48123cc6..e9a55907 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/config/CosmeticSettings.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/config/CosmeticSettings.java @@ -22,6 +22,7 @@ public class CosmeticSettings { private static final String REQUIRE_EMPTY_PANTS_PATH = "require-empty-pants"; private static final String REQUIRE_EMPTY_BOOTS_PATH = "require-empty-boots"; private static final String BALLOON_OFFSET = "balloon-offset"; + private static final String FIRST_PERSON_BACKPACK_MODE = "first-person-backpack-mode"; private static final transient String LOOK_DOWN_PITCH_PATH = "look-down-backpack-remove"; private static final String VIEW_DISTANCE_PATH = "view-distance"; @@ -35,6 +36,7 @@ public class CosmeticSettings { private int lookDownPitch; private int viewDistance; private Vector balloonOffset; + private boolean firstPersonBackpackMode; public void load(final FileConfiguration config) { this.defaultMenu = Utils.replaceIf(config.getString(DEFAULT_MENU), CosmeticsMenu.DEFAULT_MAIN_MENU, null, ""); @@ -47,6 +49,8 @@ public class CosmeticSettings { this.lookDownPitch = config.getInt(COSMETIC_SETTINGS_PATH + "." + LOOK_DOWN_PITCH_PATH); this.viewDistance = config.getInt(COSMETIC_SETTINGS_PATH + "." + VIEW_DISTANCE_PATH); + this.firstPersonBackpackMode = config.getBoolean(COSMETIC_SETTINGS_PATH + "." + FIRST_PERSON_BACKPACK_MODE, false); + final var balloonSection = config.getConfigurationSection(COSMETIC_SETTINGS_PATH + "." + BALLOON_OFFSET); if (balloonSection != null) { @@ -114,6 +118,10 @@ public class CosmeticSettings { return defaultMenu; } + public boolean isFirstPersonBackpackMode() { + return firstPersonBackpackMode; + } + public boolean requireEmpty(final EquipmentSlot slot) { return switch (slot) { case OFF_HAND -> this.isRequireEmptyOffHand(); diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/cosmetic/CosmeticManager.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/cosmetic/CosmeticManager.java index 41a6d054..bdc0a1b4 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/cosmetic/CosmeticManager.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/cosmetic/CosmeticManager.java @@ -1,17 +1,26 @@ package io.github.fisher2911.hmccosmetics.cosmetic; +import io.github.fisher2911.hmccosmetics.HMCCosmetics; +import io.github.fisher2911.hmccosmetics.config.ArmorItemSerializer; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.gui.Token; +import io.github.fisher2911.hmccosmetics.gui.WrappedGuiItem; import io.github.fisher2911.hmccosmetics.util.Keys; import org.bukkit.inventory.ItemStack; import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.Nullable; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; import java.util.Collection; import java.util.Map; public class CosmeticManager { + private final Path ITEMS_PATH = Path.of(HMCCosmetics.getPlugin(HMCCosmetics.class).getDataFolder().getPath(), "items.yml"); + private final Map tokenMap; private final Map armorItemMap; @@ -68,4 +77,36 @@ public class CosmeticManager { public void clearTokens() { this.tokenMap.clear(); } + + public void clearItems() { + this.armorItemMap.clear(); + } + + public void load() { + this.clearItems(); + try { + final File file = ITEMS_PATH.toFile(); + if (!file.exists()) { + file.getParentFile().mkdirs(); + file.createNewFile(); + } + final YamlConfigurationLoader loader = YamlConfigurationLoader. + builder(). + path(ITEMS_PATH). + defaultOptions(opts -> + opts.serializers(build -> + build.register(WrappedGuiItem.class, ArmorItemSerializer.INSTANCE)) + ) + .build(); + for (var node : loader.load().childrenMap().values()) { + final WrappedGuiItem item = ArmorItemSerializer.INSTANCE.deserialize(WrappedGuiItem.class, node); + if (item instanceof ArmorItem armorItem) { + armorItem.setAction(null); + this.armorItemMap.put(armorItem.getId(), armorItem); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/dao/CitizenDAO.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/dao/CitizenDAO.java index ce357638..344392f5 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/dao/CitizenDAO.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/dao/CitizenDAO.java @@ -5,6 +5,7 @@ import com.j256.ormlite.table.DatabaseTable; import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; +import io.github.fisher2911.hmccosmetics.user.Backpack; import io.github.fisher2911.hmccosmetics.user.EntityIds; import io.github.fisher2911.hmccosmetics.user.NPCUser; import org.jetbrains.annotations.Nullable; @@ -33,7 +34,8 @@ public class CitizenDAO { public NPCUser toUser( final CosmeticManager cosmeticManager, final EntityIds entityIds, - final List armorItems + final List armorItems, + Backpack backpack ) { final PlayerArmor playerArmor = PlayerArmor.empty(); @@ -45,7 +47,7 @@ public class CitizenDAO { playerArmor.setItem(armorItem); } - return new NPCUser(this.citizensId, playerArmor, entityIds); + return new NPCUser(this.citizensId, playerArmor, backpack, entityIds); } @Override diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/dao/UserDAO.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/dao/UserDAO.java index f7e71201..f0052427 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/dao/UserDAO.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/dao/UserDAO.java @@ -5,6 +5,7 @@ import com.j256.ormlite.table.DatabaseTable; import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; +import io.github.fisher2911.hmccosmetics.user.Backpack; import io.github.fisher2911.hmccosmetics.user.EntityIds; import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.Wardrobe; @@ -36,6 +37,7 @@ public class UserDAO { final CosmeticManager cosmeticManager, final EntityIds entityIds, final List armorItems, + final Backpack backpack, final Wardrobe wardrobe ) { final PlayerArmor playerArmor = PlayerArmor.empty(); @@ -48,7 +50,7 @@ public class UserDAO { playerArmor.setItem(armorItem); } - return new User(this.uuid, playerArmor, wardrobe, entityIds); + return new User(this.uuid, playerArmor, backpack, wardrobe, entityIds); } @Override 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 2846f9d1..551c37f1 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 @@ -11,6 +11,7 @@ import io.github.fisher2911.hmccosmetics.dao.CitizenDAO; import io.github.fisher2911.hmccosmetics.dao.UserDAO; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; +import io.github.fisher2911.hmccosmetics.user.Backpack; import io.github.fisher2911.hmccosmetics.user.EntityIds; import io.github.fisher2911.hmccosmetics.user.NPCUser; import io.github.fisher2911.hmccosmetics.user.User; @@ -62,6 +63,7 @@ public class Database { public void loadUser(final Entity entity, final Consumer onComplete) { final UUID uuid = entity.getUniqueId(); final int armorStandId = getNextEntityId(); + final int firstPersonId = getNextEntityId(); final int balloonId = getNextEntityId(); final int wardrobeViewerId = getNextEntityId(); final Wardrobe wardrobe = this.createNewWardrobe(uuid); @@ -81,10 +83,12 @@ public class Database { new EntityIds( entity.getEntityId(), armorStandId, + firstPersonId, balloonId, wardrobeViewerId ), armorItems, + new Backpack(armorStandId, firstPersonId), wardrobe ); Bukkit.getScheduler().runTask(this.plugin, @@ -98,13 +102,15 @@ public class Database { onComplete.accept(new User( uuid, PlayerArmor.empty(), + new Backpack(armorStandId, firstPersonId), wardrobe, - new EntityIds(entity.getEntityId(), armorStandId, balloonId, wardrobeViewerId) + new EntityIds(entity.getEntityId(), armorStandId, firstPersonId, balloonId, wardrobeViewerId) )); } public void loadNPCUser(final int id, final Entity entity, final Consumer onComplete) { final int armorStandId = getNextEntityId(); + final int firstPersonId = getNextEntityId(); final int balloonId = getNextEntityId(); final int wardrobeViewerId = getNextEntityId(); Threads.getInstance().execute( @@ -123,10 +129,12 @@ public class Database { new EntityIds( entity.getEntityId(), armorStandId, + firstPersonId, balloonId, wardrobeViewerId ), - armorItems + armorItems, + new Backpack(armorStandId, firstPersonId) ); Bukkit.getScheduler().runTask(this.plugin, @@ -141,7 +149,8 @@ public class Database { onComplete.accept(new NPCUser( id, PlayerArmor.empty(), - new EntityIds(entity.getEntityId(), armorStandId, balloonId, wardrobeViewerId) + new Backpack(armorStandId, firstPersonId), + new EntityIds(entity.getEntityId(), armorStandId, firstPersonId, balloonId, wardrobeViewerId) ) ); } @@ -211,14 +220,18 @@ public class Database { } public Wardrobe createNewWardrobe(final UUID ownerUUID) { + final int armorStandId = getNextEntityId(); + final int firstPersonId = getNextEntityId(); return new Wardrobe( this.plugin, UUID.randomUUID(), ownerUUID, PlayerArmor.empty(), + new Backpack(armorStandId, firstPersonId), new EntityIds( getNextEntityId(), - getNextEntityId(), + armorStandId, + firstPersonId, getNextEntityId(), getNextEntityId() ), diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/database/DatabaseConverter.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/database/DatabaseConverter.java index 5fe5afdf..ac8ce19e 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/database/DatabaseConverter.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/database/DatabaseConverter.java @@ -3,6 +3,7 @@ package io.github.fisher2911.hmccosmetics.database; import io.github.fisher2911.hmccosmetics.HMCCosmetics; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; +import io.github.fisher2911.hmccosmetics.user.Backpack; import io.github.fisher2911.hmccosmetics.user.EntityIds; import io.github.fisher2911.hmccosmetics.user.User; import org.bukkit.configuration.file.YamlConfiguration; @@ -86,13 +87,17 @@ public class DatabaseConverter { while (results.next()) { final PlayerArmor playerArmor = PlayerArmor.empty(); final UUID uuid = UUID.fromString(results.getString(1)); + final int armorStandId = Database.getNextEntityId(); + final int firstPersonId = Database.getNextEntityId(); final User user = new User( uuid, playerArmor, + new Backpack(armorStandId, firstPersonId), this.database.createNewWardrobe(uuid), new EntityIds( -1, - Database.getNextEntityId(), + armorStandId, + firstPersonId, Database.getNextEntityId(), Database.getNextEntityId() ) diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticsMenu.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticsMenu.java index 1c88b0d7..043e9d09 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticsMenu.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticsMenu.java @@ -123,6 +123,7 @@ public class CosmeticsMenu { public void load() { this.guiMap.clear(); this.cosmeticManager.clearTokens(); + this.cosmeticManager.load(); final File file = Path.of(this.plugin.getDataFolder().getPath(), "menus").toFile(); diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java index 2d2c516a..60d18876 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java @@ -1,7 +1,6 @@ package io.github.fisher2911.hmccosmetics.inventory; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; -import org.bukkit.Bukkit; import java.util.Collection; import java.util.EnumMap; @@ -35,9 +34,9 @@ public class PlayerArmor { return this.getItem(ArmorItem.Type.HAT); } - public ArmorItem getBackpack() { - return this.getItem(ArmorItem.Type.BACKPACK); - } +// public ArmorItem getBackpack() { +// return this.getItem(ArmorItem.Type.BACKPACK); +// } public ArmorItem getOffHand() { return this.getItem(ArmorItem.Type.OFF_HAND); 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 66955682..dbbf931a 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 @@ -18,7 +18,7 @@ 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.retrooper.packetevents.util.SpigotDataHelper; +import io.github.retrooper.packetevents.util.SpigotConversionUtil; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -193,7 +193,7 @@ public class CosmeticFixListener implements Listener { final ArmorItem.Type t = ArmorItem.Type.fromPacketSlot(s); if (t == null) return false; final ArmorItem armorItem = user.getPlayerArmor().getItem(t); - final ItemStack i = SpigotDataHelper.toBukkitItemStack(e.getItem()); + final ItemStack i = SpigotConversionUtil.toBukkitItemStack(e.getItem()); return armorItem.isEmpty() && i.equals(equipment.getItem(t.getSlot())); }); for (final Player other : Bukkit.getOnlinePlayers()) { @@ -231,15 +231,15 @@ public class CosmeticFixListener implements Listener { if (packetSlot == -1) continue; if (packetSlot >= size) continue; - final ItemStack current = SpigotDataHelper.toBukkitItemStack(itemStacks.get(packetSlot)); + final ItemStack current = SpigotConversionUtil.toBukkitItemStack(itemStacks.get(packetSlot)); final com.github.retrooper.packetevents.protocol.item.ItemStack setTo = - SpigotDataHelper.fromBukkitItemStack(userManager.getCosmeticItem( + SpigotConversionUtil.fromBukkitItemStack(userManager.getCosmeticItem( armorItem, current, ArmorItem.Status.APPLIED, slot )); - if (SpigotDataHelper.fromBukkitItemStack(current).equals(setTo)) continue; + if (SpigotConversionUtil.fromBukkitItemStack(current).equals(setTo)) continue; equipmentList.add(PacketManager.getEquipment(setTo, slot)); } userManager.sendUpdatePacket( diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/message/Messages.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/message/Messages.java index a8cd2db1..959e4ca4 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/message/Messages.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/message/Messages.java @@ -128,7 +128,7 @@ public class Messages { public static Message getSetMessage(final ArmorItem.Type type) { return switch (type) { case HAT -> Messages.SET_HAT; - case BACKPACK -> Messages.SET_BACKPACK; + case BACKPACK, SELF_BACKPACK -> Messages.SET_BACKPACK; case OFF_HAND -> Messages.SET_OFF_HAND; case CHEST_PLATE -> Messages.SET_CHEST_PLATE; case PANTS -> Messages.SET_PANTS; @@ -140,7 +140,7 @@ public class Messages { public static Message getRemovedMessage(final ArmorItem.Type type) { return switch (type) { case HAT -> Messages.REMOVED_HAT; - case BACKPACK -> Messages.REMOVED_BACKPACK; + case BACKPACK, SELF_BACKPACK -> Messages.REMOVED_BACKPACK; case OFF_HAND -> Messages.REMOVED_OFF_HAND; case CHEST_PLATE -> Messages.REMOVED_CHEST_PLATE; case PANTS -> Messages.REMOVED_PANTS; @@ -152,7 +152,7 @@ public class Messages { public static Message getSetOtherMessage(final ArmorItem.Type type) { return switch (type) { case HAT -> Messages.SET_OTHER_HAT; - case BACKPACK -> Messages.SET_OTHER_BACKPACK; + case BACKPACK, SELF_BACKPACK -> Messages.SET_OTHER_BACKPACK; case OFF_HAND -> Messages.SET_OTHER_OFF_HAND; case CHEST_PLATE -> Messages.SET_OTHER_CHEST_PLATE; case PANTS -> Messages.SET_OTHER_PANTS; 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 9882be1c..d31627c3 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 @@ -10,6 +10,7 @@ import com.github.retrooper.packetevents.protocol.player.GameMode; import com.github.retrooper.packetevents.protocol.player.TextureProperty; import com.github.retrooper.packetevents.protocol.player.UserProfile; import com.github.retrooper.packetevents.util.Vector3d; +import com.github.retrooper.packetevents.wrapper.PacketWrapper; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAttachEntity; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEquipment; @@ -22,8 +23,10 @@ import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPl import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetPassengers; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnLivingEntity; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPlayer; -import io.github.retrooper.packetevents.util.SpigotDataHelper; +import io.github.fisher2911.hmccosmetics.HMCCosmetics; +import io.github.retrooper.packetevents.util.SpigotConversionUtil; import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -56,7 +59,7 @@ public class PacketManager { public static void sendArmorStandMetaContainer(final int armorStandId, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityMetadata( + sendPacketAsync(p, new WrapperPlayServerEntityMetadata( armorStandId, List.of( new EntityData(0, EntityDataTypes.BYTE, (byte) 0x20), @@ -98,7 +101,7 @@ public class PacketManager { final UUID uuid, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerSpawnLivingEntity( + sendPacketAsync(p, new WrapperPlayServerSpawnLivingEntity( entityId, uuid, entityType, @@ -118,7 +121,7 @@ public class PacketManager { public static void sendInvisibilityPacket(final int entityId, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityMetadata( + sendPacketAsync(p, new WrapperPlayServerEntityMetadata( entityId, List.of(new EntityData(0, EntityDataTypes.BYTE, (byte) 0x20)) )); @@ -141,7 +144,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityTeleport( + sendPacketAsync(p, new WrapperPlayServerEntityTeleport( entityId, new Vector3d(location.getX(), location.getY(), location.getZ()), location.getYaw(), @@ -169,7 +172,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityRelativeMove( + sendPacketAsync(p, new WrapperPlayServerEntityRelativeMove( entityId, to.getX() - from.getX(), to.getY() - from.getY(), @@ -193,7 +196,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerAttachEntity( + sendPacketAsync(p, new WrapperPlayServerAttachEntity( balloonId, entityId, true @@ -215,7 +218,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityEquipment( + sendPacketAsync(p, new WrapperPlayServerEntityEquipment( entityId, equipmentList )); @@ -238,7 +241,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityRotation( + sendPacketAsync(p, new WrapperPlayServerEntityRotation( entityId, location.getYaw(), location.getPitch(), @@ -261,7 +264,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityHeadLook( + sendPacketAsync(p, new WrapperPlayServerEntityHeadLook( entityId, location.getYaw() )); @@ -282,7 +285,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerSetPassengers( + sendPacketAsync(p, new WrapperPlayServerSetPassengers( mountId, new int[]{passengerId} )); @@ -295,13 +298,13 @@ public class PacketManager { public static void sendEntityDestroyPacket(final int entityId, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerDestroyEntities(entityId)); + sendPacketAsync(p, new WrapperPlayServerDestroyEntities(entityId)); } } public static void sendCameraPacket(final int entityId, final Player... sendTo) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerCamera(entityId)); + sendPacketAsync(p, new WrapperPlayServerCamera(entityId)); } } @@ -363,7 +366,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerSpawnPlayer( + sendPacketAsync(p, new WrapperPlayServerSpawnPlayer( entityId, uuid, new com.github.retrooper.packetevents.protocol.world.Location( @@ -402,7 +405,7 @@ public class PacketManager { 0 ); for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerPlayerInfo( + sendPacketAsync(p, new WrapperPlayServerPlayerInfo( WrapperPlayServerPlayerInfo.Action.ADD_PLAYER, data )); @@ -422,7 +425,7 @@ public class PacketManager { ) { final byte mask = 0x01 | 0x02 | 0x04 | 0x08 | 0x010 | 0x020 | 0x40; for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerEntityMetadata( + sendPacketAsync(p, new WrapperPlayServerEntityMetadata( playerId, List.of( new EntityData(17, EntityDataTypes.BYTE, mask), @@ -446,7 +449,7 @@ public class PacketManager { final Player... sendTo ) { for (final Player p : sendTo) { - PacketEvents.getAPI().getPlayerManager().sendPacketAsync(p, new WrapperPlayServerPlayerInfo( + sendPacketAsync(p, new WrapperPlayServerPlayerInfo( WrapperPlayServerPlayerInfo.Action.REMOVE_PLAYER, new WrapperPlayServerPlayerInfo.PlayerData( Component.empty(), @@ -461,11 +464,17 @@ public class PacketManager { } } + public static void sendPacketAsync(final Player player, final PacketWrapper packet) { + Bukkit.getScheduler().runTaskAsynchronously(HMCCosmetics.getPlugin(HMCCosmetics.class), () -> + PacketEvents.getAPI().getPlayerManager().sendPacket(player, packet) + ); + } + 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); + return getEquipment(SpigotConversionUtil.fromBukkitItemStack(itemStack), slot); } public static com.github.retrooper.packetevents.protocol.player.Equipment getEquipment( diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Backpack.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Backpack.java new file mode 100644 index 00000000..11b6970a --- /dev/null +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/Backpack.java @@ -0,0 +1,101 @@ +package io.github.fisher2911.hmccosmetics.user; + +import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; +import com.github.retrooper.packetevents.protocol.item.type.ItemTypes; +import com.github.retrooper.packetevents.protocol.player.EquipmentSlot; +import io.github.fisher2911.hmccosmetics.HMCCosmetics; +import io.github.fisher2911.hmccosmetics.config.Settings; +import io.github.fisher2911.hmccosmetics.gui.ArmorItem; +import io.github.fisher2911.hmccosmetics.packet.PacketManager; +import io.github.retrooper.packetevents.util.SpigotConversionUtil; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class Backpack { + + private final int firstId; + private final int secondId; + + public Backpack(final int firstId, final int secondId) { + this.firstId = firstId; + this.secondId = secondId; + } + + public void spawn(BaseUser owner, Player other, Location location, Settings settings) { + PacketManager.sendEntitySpawnPacket(location, this.firstId, EntityTypes.AREA_EFFECT_CLOUD, other); + if (other.getUniqueId().equals(owner.getId()) && settings.getCosmeticSettings().isFirstPersonBackpackMode()) { + PacketManager.sendEntitySpawnPacket(location, this.secondId, EntityTypes.ARMOR_STAND, other); + } + Bukkit.getScheduler().runTaskLaterAsynchronously(HMCCosmetics.getPlugin(HMCCosmetics.class), () -> { +// PacketManager.sendArmorStandMetaContainer(this.firstId, other); + PacketManager.sendRidingPacket(owner.getEntityId(), this.firstId, other); + if (other.getUniqueId().equals(owner.getId()) && settings.getCosmeticSettings().isFirstPersonBackpackMode()) { + PacketManager.sendEntityDestroyPacket(this.firstId, other); + PacketManager.sendArmorStandMetaContainer(this.secondId, other); + PacketManager.sendRidingPacket(this.firstId, this.secondId, other); + } + }, 1L); + } + + public void despawn(Player player) { + PacketManager.sendEntityDestroyPacket(this.firstId, player); + PacketManager.sendEntityDestroyPacket(this.secondId, player); + } + + public void despawn() { + PacketManager.sendEntityDestroyPacket(this.firstId, Bukkit.getOnlinePlayers()); + PacketManager.sendEntityDestroyPacket(this.secondId, Bukkit.getOnlinePlayers()); + } + + public void updateBackpack(BaseUser owner, Player other, Settings settings) { + final Location location = owner.getLocation(); + if (location == null) return; + final boolean isSelf = owner.getId().equals(other.getUniqueId()); + final boolean firstPersonMode = settings.getCosmeticSettings().isFirstPersonBackpackMode(); + final ArmorItem.Type type = isSelf && firstPersonMode ? ArmorItem.Type.SELF_BACKPACK : ArmorItem.Type.BACKPACK; + final List equipment = new ArrayList<>(); + final int lookDownPitch = settings.getCosmeticSettings().getLookDownPitch(); + final boolean hidden = !owner.shouldShow(other); + final boolean isLookingDown = + !firstPersonMode && + isSelf && + lookDownPitch != -1 && + owner.isFacingDown(location, lookDownPitch); + if (hidden || isLookingDown) { + equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment( + EquipmentSlot.HELMET, + new com.github.retrooper.packetevents.protocol.item.ItemStack.Builder(). + type(ItemTypes.AIR). + build() + )); + PacketManager.sendEquipmentPacket(equipment, this.firstId, other); + return; + } + final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack = + SpigotConversionUtil.fromBukkitItemStack(owner.getPlayerArmor().getItem(type).getItemStack(ArmorItem.Status.APPLIED)); + equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment( + EquipmentSlot.HELMET, + itemStack + )); + + PacketManager.sendEquipmentPacket(equipment, isSelf && firstPersonMode ? this.secondId : this.firstId, other); + +// PacketManager.sendArmorStandMetaContainer(this.firstId, other); + PacketManager.sendRidingPacket(owner.getEntityId(), this.firstId, other); + PacketManager.sendRotationPacket(this.firstId, location, false, other); + PacketManager.sendLookPacket(firstId, location, other); + other.sendMessage("Backpack type: " + type + " item: " + owner.getPlayerArmor().getItem(type).getId() + " " + owner.getPlayerArmor().getItem(type).getItemStack(ArmorItem.Status.APPLIED).getType()); + other.sendMessage("isSelf " + isSelf + " firstPersonMode: " + firstPersonMode); + if (isSelf && firstPersonMode) { + PacketManager.sendArmorStandMetaContainer(this.secondId, other); +// PacketManager.sendRidingPacket(this.firstId, this.secondId, other); + PacketManager.sendRotationPacket(this.secondId, location, false, other); + PacketManager.sendLookPacket(secondId, location, other); + } + } + +} 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 3b07ca36..cc71b18d 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 @@ -2,8 +2,6 @@ package io.github.fisher2911.hmccosmetics.user; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; -import com.github.retrooper.packetevents.protocol.item.type.ItemTypes; -import com.github.retrooper.packetevents.protocol.player.EquipmentSlot; import io.github.fisher2911.hmccosmetics.config.CosmeticSettings; import io.github.fisher2911.hmccosmetics.config.Settings; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; @@ -13,7 +11,6 @@ import io.github.fisher2911.hmccosmetics.hook.ModelEngineHook; import io.github.fisher2911.hmccosmetics.hook.entity.BalloonEntity; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; import io.github.fisher2911.hmccosmetics.packet.PacketManager; -import io.github.retrooper.packetevents.util.SpigotDataHelper; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -22,9 +19,7 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.UUID; @@ -34,6 +29,7 @@ public abstract class BaseUser { protected final EntityIds entityIds; protected final BalloonEntity balloon; protected final PlayerArmor playerArmor; + protected final Backpack backpack; // for setting multiple items protected boolean armorUpdated; @@ -43,10 +39,11 @@ public abstract class BaseUser { protected final Set viewingArmorStand = new HashSet<>(); protected final Set viewingBalloon = new HashSet<>(); - public BaseUser(final T id, final PlayerArmor playerArmor, final EntityIds entityIds) { + public BaseUser(final T id, final PlayerArmor playerArmor, final Backpack backpack, final EntityIds entityIds) { this.id = id; this.entityIds = entityIds; this.playerArmor = playerArmor; + this.backpack = backpack; if (!HookManager.getInstance().isEnabled(ModelEngineHook.class)) { this.balloon = null; } else { @@ -174,9 +171,8 @@ public abstract class BaseUser { PacketManager.sendLeashPacket(balloonId, this.getEntityId(), other); } - private void spawnArmorStand(final Player other, final Location location) { - PacketManager.sendEntitySpawnPacket(location, this.getArmorStandId(), EntityTypes.ARMOR_STAND, other); - PacketManager.sendArmorStandMetaContainer(this.getArmorStandId(), other); + private void spawnArmorStand(final Player other, final Location location, Settings settings) { + this.backpack.spawn(this, other, location, settings); } public void updateOutsideCosmetics(final Settings settings) { @@ -188,33 +184,7 @@ public abstract class BaseUser { } public void updateBackpack(final Player other, final Settings settings) { - final Location location = this.getLocation(); - if (location == null) return; - final List equipment = new ArrayList<>(); - final boolean hidden = !this.shouldShow(other); - final int lookDownPitch = settings.getCosmeticSettings().getLookDownPitch(); - final boolean isLookingDown = - this.id.equals(other.getUniqueId()) && lookDownPitch - != -1 && - this.isFacingDown(location, lookDownPitch); - if (hidden || isLookingDown) { - equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment( - EquipmentSlot.HELMET, - new com.github.retrooper.packetevents.protocol.item.ItemStack.Builder(). - type(ItemTypes.AIR). - build() - )); - } else { - final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack = - SpigotDataHelper.fromBukkitItemStack(this.playerArmor.getBackpack().getItemStack(ArmorItem.Status.APPLIED)); - equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment( - EquipmentSlot.HELMET, - itemStack - )); - } - - final int armorStandId = this.getArmorStandId(); - PacketManager.sendEquipmentPacket(equipment, armorStandId, other); + this.backpack.updateBackpack(this, other, settings); } public void updateOutsideCosmetics(final Player other, final Location location, final Settings settings) { @@ -230,7 +200,7 @@ public abstract class BaseUser { return; } if (hasBackpack) { - this.spawnArmorStand(other, location); + this.spawnArmorStand(other, location, settings); this.viewingArmorStand.add(otherUUID); } } else if (!inViewDistance || !shouldShow) { @@ -247,34 +217,8 @@ public abstract class BaseUser { this.despawnBalloon(other); } - final List equipment = new ArrayList<>(); + this.updateBackpack(other, settings); final boolean hidden = !this.shouldShow(other); - final int lookDownPitch = settings.getCosmeticSettings().getLookDownPitch(); - final boolean isLookingDown = - this.id.equals(other.getUniqueId()) && lookDownPitch - != -1 && - this.isFacingDown(location, lookDownPitch); - if (hidden || isLookingDown) { - equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment( - EquipmentSlot.HELMET, - new com.github.retrooper.packetevents.protocol.item.ItemStack.Builder(). - type(ItemTypes.AIR). - build() - )); - } else { - final com.github.retrooper.packetevents.protocol.item.ItemStack itemStack = - SpigotDataHelper.fromBukkitItemStack(this.playerArmor.getBackpack().getItemStack(ArmorItem.Status.APPLIED)); - equipment.add(new com.github.retrooper.packetevents.protocol.player.Equipment( - EquipmentSlot.HELMET, - itemStack - )); - } - - final int armorStandId = this.getArmorStandId(); - PacketManager.sendRotationPacket(armorStandId, location, false, other); - PacketManager.sendLookPacket(armorStandId, location, other); - PacketManager.sendRidingPacket(this.getEntityId(), armorStandId, other); - PacketManager.sendEquipmentPacket(equipment, armorStandId, other); if (hidden) return; this.updateBalloon(other, location, settings.getCosmeticSettings()); } @@ -291,12 +235,12 @@ public abstract class BaseUser { } public void despawnAttached(final Player other) { - PacketManager.sendEntityDestroyPacket(this.getArmorStandId(), other); + this.backpack.despawn(other); this.viewingArmorStand.remove(other.getUniqueId()); } public void despawnAttached() { - PacketManager.sendEntityDestroyPacket(this.getArmorStandId(), Bukkit.getOnlinePlayers()); + this.backpack.despawn(); this.viewingArmorStand.clear(); } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/EntityIds.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/EntityIds.java index 60a53b0c..bf50e020 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/EntityIds.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/EntityIds.java @@ -11,10 +11,11 @@ public class EntityIds { this.ids = ids; } - public EntityIds(final int self, final int armorStand, final int balloon, final int wardrobeViewer) { + public EntityIds(final int self, final int armorStand, final int firstPersonId, final int balloon, final int wardrobeViewer) { final Map ids = new EnumMap<>(Type.class); ids.put(Type.SELF, self); ids.put(Type.ARMOR_STAND, armorStand); + ids.put(Type.FIRST_PERSON_ARMOR_STAND, firstPersonId); ids.put(Type.BALLOON, balloon); ids.put(Type.WARDROBE_VIEWER, wardrobeViewer); this.ids = ids; @@ -28,6 +29,10 @@ public class EntityIds { return this.ids.getOrDefault(Type.ARMOR_STAND, -1); } + public int firstPersonArmorStand() { + return this.ids.getOrDefault(Type.FIRST_PERSON_ARMOR_STAND, -1); + } + public int balloon() { return this.ids.getOrDefault(Type.BALLOON, -1); } @@ -40,6 +45,7 @@ public class EntityIds { SELF, ARMOR_STAND, + FIRST_PERSON_ARMOR_STAND, BALLOON, WARDROBE_VIEWER 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 0f28c3e2..d5ecf8df 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 @@ -15,13 +15,13 @@ public class NPCUser extends BaseUser { private final CitizensHook hook; - public NPCUser(final int id, final PlayerArmor playerArmor, final EntityIds entityIds) { - super(id, playerArmor, entityIds); + public NPCUser(final int id, final PlayerArmor playerArmor, Backpack backpack, final EntityIds entityIds) { + super(id, playerArmor, backpack, entityIds); this.hook = HookManager.getInstance().getCitizensHook(); } - public NPCUser(final PlayerArmor playerArmor, final NPC npc, final EntityIds entityIds) { - this(npc.getId(), playerArmor, entityIds); + public NPCUser(final PlayerArmor playerArmor, Backpack backpack, final NPC npc, final EntityIds entityIds) { + this(npc.getId(), playerArmor, backpack, entityIds); } @Nullable 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 7caebc44..bd34d56d 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 @@ -25,14 +25,14 @@ public class User extends BaseUser { private boolean hidden; private WeakReference playerReference; - public User(final UUID uuid, final PlayerArmor playerArmor, final Wardrobe wardrobe, final EntityIds entityIds) { - super(uuid, playerArmor, entityIds); + public User(final UUID uuid, final PlayerArmor playerArmor, Backpack backpack, final Wardrobe wardrobe, final EntityIds entityIds) { + super(uuid, playerArmor, backpack, 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); + public User(final UUID uuid, final PlayerArmor playerArmor, Backpack backpack, final EntityIds entityIds) { + super(uuid, playerArmor, backpack, entityIds); this.playerReference = new WeakReference<>(Bukkit.getPlayer(uuid)); } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserFactory.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserFactory.java index a309fbd8..ca1b36ae 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserFactory.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserFactory.java @@ -25,6 +25,7 @@ public class UserFactory { final Class type, final Entity entity, final int armorStandId, + final int firstPersonId, final int balloonId, final int wardrobeViewerId ) { @@ -34,10 +35,12 @@ public class UserFactory { return (T) new User( uuid, PlayerArmor.empty(), + new Backpack(armorStandId, firstPersonId), plugin.getDatabase().createNewWardrobe(uuid), new EntityIds( entityId, armorStandId, + firstPersonId, balloonId, wardrobeViewerId ) @@ -50,9 +53,11 @@ public class UserFactory { return (T) new NPCUser( citizensId, PlayerArmor.empty(), + new Backpack(armorStandId, firstPersonId), new EntityIds( entityId, armorStandId, + firstPersonId, balloonId, wardrobeViewerId ) 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 abe7e242..b3f64712 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 @@ -34,9 +34,10 @@ public class Wardrobe extends User { final UUID uuid, final UUID ownerUUID, final PlayerArmor playerArmor, + final Backpack backpack, final EntityIds entityIds, final boolean active) { - super(uuid, playerArmor, entityIds); + super(uuid, playerArmor, backpack, entityIds); this.plugin = plugin; this.ownerUUID = ownerUUID; this.active = active;