From ffd15345d2ff6d7764267c19ed8d2556e0c4e297 Mon Sep 17 00:00:00 2001 From: MasterOfTheFish Date: Sat, 19 Feb 2022 19:37:38 -0500 Subject: [PATCH] Added citizens support --- common/build.gradle.kts | 2 +- .../generated/plugin-yml/Bukkit/plugin.yml | 1 + common/build/resources/main/plugin.yml | 1 + .../fisher2911/hmccosmetics/HMCCosmetics.java | 21 +- .../api/event/CosmeticChangeEvent.java | 11 +- .../command/CosmeticsCommand.java | 90 ++++++++- .../hmccosmetics/database/Database.java | 95 +++++++-- .../hmccosmetics/database/dao/CitizenDAO.java | 66 +++++++ .../hmccosmetics/database/dao/UserDAO.java | 7 +- .../hmccosmetics/gui/ArmorItem.java | 6 +- .../hmccosmetics/gui/CosmeticGui.java | 8 +- .../hmccosmetics/gui/DyeSelectorGui.java | 2 + .../hmccosmetics/hook/HookManager.java | 19 +- .../hmccosmetics/hook/item/CitizensHook.java | 181 ++++++++++++++++++ .../hmccosmetics/listener/JoinListener.java | 26 +-- .../hmccosmetics/message/Messages.java | 7 + .../hmccosmetics/message/Placeholder.java | 1 + .../hmccosmetics/user/BaseUser.java | 18 +- .../hmccosmetics/user/Equipment.java | 1 + .../fisher2911/hmccosmetics/user/NPCUser.java | 60 ++++++ .../fisher2911/hmccosmetics/user/User.java | 23 ++- .../hmccosmetics/user/UserFactory.java | 55 ++++++ .../hmccosmetics/user/UserManager.java | 67 ++----- .../hmccosmetics/user/Wardrobe.java | 8 +- 24 files changed, 663 insertions(+), 113 deletions(-) create mode 100644 common/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/CitizenDAO.java create mode 100644 common/src/main/java/io/github/fisher2911/hmccosmetics/hook/item/CitizensHook.java create mode 100644 common/src/main/java/io/github/fisher2911/hmccosmetics/user/NPCUser.java create mode 100644 common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserFactory.java diff --git a/common/build.gradle.kts b/common/build.gradle.kts index f72c1e62..0970e7d7 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -93,7 +93,7 @@ bukkit { apiVersion = "1.16" name = "HMCCosmetics" authors = listOf("MasterOfTheFish") - softDepend = listOf("Multiverse", "PlaceholderAPI", "Oraxen", "ItemsAdder") + softDepend = listOf("Multiverse", "PlaceholderAPI", "Oraxen", "ItemsAdder", "Citizens") depend = listOf("ProtocolLib") permissions { register("hmccosmetics.cmd.default") { diff --git a/common/build/generated/plugin-yml/Bukkit/plugin.yml b/common/build/generated/plugin-yml/Bukkit/plugin.yml index 5b181ccf..8dbf05d4 100644 --- a/common/build/generated/plugin-yml/Bukkit/plugin.yml +++ b/common/build/generated/plugin-yml/Bukkit/plugin.yml @@ -36,3 +36,4 @@ softdepend: - PlaceholderAPI - Oraxen - ItemsAdder + - Citizens diff --git a/common/build/resources/main/plugin.yml b/common/build/resources/main/plugin.yml index 5b181ccf..8dbf05d4 100644 --- a/common/build/resources/main/plugin.yml +++ b/common/build/resources/main/plugin.yml @@ -36,3 +36,4 @@ softdepend: - PlaceholderAPI - Oraxen - ItemsAdder + - Citizens diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java index 030db516..38c8c2f7 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java @@ -11,6 +11,7 @@ import io.github.fisher2911.hmccosmetics.database.DatabaseFactory; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu; import io.github.fisher2911.hmccosmetics.hook.HookManager; +import io.github.fisher2911.hmccosmetics.hook.item.CitizensHook; import io.github.fisher2911.hmccosmetics.hook.item.ItemsAdderHook; import io.github.fisher2911.hmccosmetics.listener.ClickListener; import io.github.fisher2911.hmccosmetics.listener.CosmeticFixListener; @@ -29,12 +30,14 @@ import io.github.fisher2911.hmccosmetics.user.UserManager; import java.nio.file.Path; import java.nio.file.Paths; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import me.mattstudios.mf.base.CommandManager; +import me.mattstudios.mf.base.CompletionHandler; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; @@ -102,10 +105,10 @@ public class HMCCosmetics extends JavaPlugin { this.saveTask.cancel(); this.database.saveAll(); this.messageHandler.close(); - this.userManager.cancelTeleportTask(); this.userManager.removeAll(); Threads.getInstance().onDisable(); this.database.close(); + this.taskManager.end(); } private void registerListeners() { @@ -127,6 +130,7 @@ public class HMCCosmetics extends JavaPlugin { private void registerCommands() { this.commandManager = new CommandManager(this, true); + final HookManager hookManager = HookManager.getInstance(); this.commandManager.getMessageHandler().register( "cmd.no.console", player -> this.messageHandler.sendMessage( @@ -134,17 +138,28 @@ public class HMCCosmetics extends JavaPlugin { Messages.MUST_BE_PLAYER ) ); - this.commandManager.getCompletionHandler().register("#types", + final CompletionHandler completionHandler = this.commandManager.getCompletionHandler(); + completionHandler.register("#types", resolver -> Arrays.stream(ArmorItem.Type. values()). map(ArmorItem.Type::toString). collect(Collectors.toList()) ); - this.commandManager.getCompletionHandler().register("#ids", + completionHandler.register("#ids", resolver -> this.cosmeticManager.getAll().stream().map(ArmorItem::getId) .collect(Collectors.toList())); + completionHandler.register("#npc-args", + resolver -> List.of(CosmeticsCommand.NPC_REMOVE, CosmeticsCommand.NPC_APPLY)); + completionHandler.register("#npcs", resolver -> { + final List ids = new ArrayList<>(); + if (!hookManager.isEnabled(CitizensHook.class)) return ids; + for (final int id : hookManager.getCitizensHook().getAllNPCS()) { + ids.add(String.valueOf(id)); + } + return ids; + }); this.commandManager.register(new CosmeticsCommand(this)); } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/api/event/CosmeticChangeEvent.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/api/event/CosmeticChangeEvent.java index f3012eb1..802edb6d 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/api/event/CosmeticChangeEvent.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/api/event/CosmeticChangeEvent.java @@ -1,6 +1,7 @@ package io.github.fisher2911.hmccosmetics.api.event; import io.github.fisher2911.hmccosmetics.api.CosmeticItem; +import io.github.fisher2911.hmccosmetics.user.BaseUser; import io.github.fisher2911.hmccosmetics.user.User; /** @@ -8,17 +9,19 @@ import io.github.fisher2911.hmccosmetics.user.User; */ public class CosmeticChangeEvent extends CosmeticItemEvent { - private final User user; + private final BaseUser user; private CosmeticItem removed; - public CosmeticChangeEvent(final CosmeticItem cosmeticItem, final CosmeticItem removed, - final User user) { + public CosmeticChangeEvent( + final CosmeticItem cosmeticItem, + final CosmeticItem removed, + final BaseUser user) { super(cosmeticItem); this.removed = removed; this.user = user; } - public User getUser() { + public BaseUser getUser() { return user; } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java index 6262927a..fe8b01f4 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java @@ -5,6 +5,8 @@ import io.github.fisher2911.hmccosmetics.config.Settings; import io.github.fisher2911.hmccosmetics.config.WardrobeSettings; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu; +import io.github.fisher2911.hmccosmetics.hook.HookManager; +import io.github.fisher2911.hmccosmetics.hook.item.CitizensHook; import io.github.fisher2911.hmccosmetics.message.Message; import io.github.fisher2911.hmccosmetics.message.MessageHandler; import io.github.fisher2911.hmccosmetics.message.Messages; @@ -14,10 +16,6 @@ import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.UserManager; import io.github.fisher2911.hmccosmetics.user.Wardrobe; import io.github.fisher2911.hmccosmetics.util.StringUtils; - -import java.util.Map; -import java.util.Optional; - import me.mattstudios.mf.annotations.Command; import me.mattstudios.mf.annotations.Completion; import me.mattstudios.mf.annotations.Default; @@ -25,11 +23,14 @@ import me.mattstudios.mf.annotations.Permission; import me.mattstudios.mf.annotations.SubCommand; import me.mattstudios.mf.base.CommandBase; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Color; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + @Command("cosmetics") public class CosmeticsCommand extends CommandBase { @@ -86,8 +87,11 @@ public class CosmeticsCommand extends CommandBase { @SubCommand("dye") @Permission(io.github.fisher2911.hmccosmetics.message.Permission.DYE_COMMAND) - public void dyeArmor(final Player player, @Completion("#types") String typeString, - final @me.mattstudios.mf.annotations.Optional String dyeColor) { + public void dyeArmor( + final Player player, + @Completion("#types") String typeString, + final @me.mattstudios.mf.annotations.Optional String dyeColor + ) { final Optional optionalUser = this.userManager.get(player.getUniqueId()); @@ -141,7 +145,8 @@ public class CosmeticsCommand extends CommandBase { final CommandSender sender, @Completion("#players") final Player player, @Completion("#ids") final String id, - final @me.mattstudios.mf.annotations.Optional String dyeColor) { + final @me.mattstudios.mf.annotations.Optional String dyeColor + ) { final Optional userOptional = this.userManager.get(player.getUniqueId()); if (userOptional.isEmpty()) { @@ -285,6 +290,75 @@ public class CosmeticsCommand extends CommandBase { }).execute(); } + public static final String NPC_APPLY = "apply"; + public static final String NPC_REMOVE = "remove"; + + @SubCommand("npc") + @Permission(io.github.fisher2911.hmccosmetics.message.Permission.SET_COSMETIC_COMMAND) + public void applyNpc( + final CommandSender sender, + @Completion("#npc-args") final String arg, + /*@Completion("#npcs")*/ final Integer npcId, + @Completion("#types") final String typeStr, + @me.mattstudios.mf.annotations.Optional @Completion("#ids") final String itemId + ) { + final CitizensHook citizensHook = HookManager.getInstance().getCitizensHook(); + if (citizensHook == null) { + this.messageHandler.sendMessage( + sender, + Messages.HOOK_NOT_ENABLED, + Map.of(Placeholder.TYPE, "Citizens") + ); + return; + } + final ArmorItem armorItem = this.plugin.getCosmeticManager().getArmorItem(itemId); + if (armorItem == null) { + this.messageHandler.sendMessage( + sender, + Messages.ITEM_NOT_FOUND + ); + return; + } + switch (arg.toLowerCase(Locale.ROOT)) { + case NPC_APPLY -> { + this.setNpcCosmetic(citizensHook, sender, npcId, armorItem); + } + + case NPC_REMOVE -> { + try { + final ArmorItem.Type type = ArmorItem.Type.valueOf(typeStr); + this.setNpcCosmetic(citizensHook, sender, npcId, ArmorItem.empty(type, "none")); + + } catch (final IllegalArgumentException exception) { + this.messageHandler.sendMessage( + sender, + Messages.INVALID_TYPE, + Map.of(Placeholder.TYPE, typeStr) + ); + } + } + }; + } + + private void setNpcCosmetic(final CitizensHook hook, final CommandSender sender, final int npcId, final ArmorItem item) { + final boolean isSet = hook.setNpcCosmetic(npcId, item); + if (!isSet) { + this.messageHandler.sendMessage( + sender, + Messages.NPC_NOT_FOUND, + Map.of(Placeholder.ID, String.valueOf(npcId)) + ); + return; + } + this.messageHandler.sendMessage( + sender, + Messages.SET_NPC_COSMETIC, + Map.of(Placeholder.TYPE, item.getType().toString(), + Placeholder.ITEM, item.getId(), + Placeholder.ID, String.valueOf(npcId)) + ); + } + private void setDyeColor(final String dyeColor, final ArmorItem armorItem, final CommandSender sender) { try { final java.awt.Color awtColor = java.awt.Color.decode(dyeColor); 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 d58d5cc8..15517c3e 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 @@ -7,9 +7,14 @@ import com.j256.ormlite.table.TableUtils; import io.github.fisher2911.hmccosmetics.HMCCosmetics; import io.github.fisher2911.hmccosmetics.concurrent.Threads; import io.github.fisher2911.hmccosmetics.database.dao.ArmorItemDAO; +import io.github.fisher2911.hmccosmetics.database.dao.CitizenDAO; import io.github.fisher2911.hmccosmetics.database.dao.UserDAO; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; +import io.github.fisher2911.hmccosmetics.hook.HookManager; +import io.github.fisher2911.hmccosmetics.hook.item.CitizensHook; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; +import io.github.fisher2911.hmccosmetics.user.BaseUser; +import io.github.fisher2911.hmccosmetics.user.NPCUser; import io.github.fisher2911.hmccosmetics.user.User; import java.sql.SQLException; @@ -18,15 +23,18 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; +import io.github.fisher2911.hmccosmetics.user.UserFactory; import io.github.fisher2911.hmccosmetics.user.Wardrobe; import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; public class Database { protected final HMCCosmetics plugin; final Dao userDao; - final Dao armorItemDao; + final Dao citizenDao; + final Dao armorItemDao; private final ConnectionSource dataSource; private final DatabaseType databaseType; AtomicInteger FAKE_ENTITY_ID = new AtomicInteger(Integer.MAX_VALUE); @@ -52,6 +60,7 @@ public class Database { this.plugin = plugin; this.dataSource = dataSource; this.userDao = DaoManager.createDao(this.dataSource, UserDAO.class); + this.citizenDao = DaoManager.createDao(this.dataSource, CitizenDAO.class); this.armorItemDao = DaoManager.createDao(this.dataSource, ArmorItemDAO.class); this.databaseType = databaseType; @@ -65,13 +74,14 @@ public class Database { try { TableUtils.createTableIfNotExists(this.dataSource, ArmorItemDAO.class); TableUtils.createTableIfNotExists(this.dataSource, UserDAO.class); + TableUtils.createTableIfNotExists(this.dataSource, CitizenDAO.class); } catch (final SQLException exception) { exception.printStackTrace(); } } - public void loadUser(final Player player, final Consumer onComplete) { - final UUID uuid = player.getUniqueId(); + public void loadUser(final Entity entity, final Consumer onComplete) { + final UUID uuid = entity.getUniqueId(); final int armorStandId = FAKE_ENTITY_ID.getAndDecrement(); final Wardrobe wardrobe = this.createNewWardrobe(uuid); Threads.getInstance().execute( @@ -83,22 +93,54 @@ public class Database { user = this.userDao.createIfNotExists(new UserDAO(uuid)); } - final List armorItems = this.armorItemDao.queryForEq("uuid", - uuid.toString()); + final List armorItems = this.armorItemDao.queryForEq("uuid", uuid.toString()); final User actualUser = user.toUser( this.plugin.getCosmeticManager(), - player.getEntityId(), + entity.getEntityId(), armorItems, wardrobe, - armorStandId); + armorStandId + ); Bukkit.getScheduler().runTask(this.plugin, - () -> { - this.plugin.getUserManager().add( - actualUser - ); - onComplete.accept(actualUser); - } + () -> onComplete.accept(actualUser) + ); + + } catch (final SQLException exception) { + exception.printStackTrace(); + } + }); + onComplete.accept(new User( + uuid, + entity.getEntityId(), + PlayerArmor.empty(), + wardrobe, + armorStandId + )); + } + + public void loadNPCUser(final int id, final Entity entity, final Consumer onComplete) { + final int armorStandId = FAKE_ENTITY_ID.getAndDecrement(); + Threads.getInstance().execute( + () -> { + try { + CitizenDAO citizen = this.citizenDao.queryForId(id); + + if (citizen == null) { + citizen = this.citizenDao.createIfNotExists(new CitizenDAO(id)); + } + + final List armorItems = this.armorItemDao.queryForEq("uuid", String.valueOf(id)); + + final NPCUser actualUser = citizen.toUser( + this.plugin.getCosmeticManager(), + entity.getEntityId(), + armorItems, + armorStandId + ); + + Bukkit.getScheduler().runTask(this.plugin, + () -> onComplete.accept(actualUser) ); } catch (final SQLException exception) { @@ -106,17 +148,15 @@ public class Database { } }); - final User user = new User(uuid, player.getEntityId(), PlayerArmor.empty(), wardrobe, armorStandId); - this.plugin.getUserManager().add(user); - onComplete.accept(user); + onComplete.accept(new NPCUser(id, entity.getEntityId(), PlayerArmor.empty(), armorStandId)); } public void saveUser(final User user) { try { - final UserDAO userDAO = new UserDAO(user.getUuid()); + final UserDAO userDAO = new UserDAO(user.getId()); this.userDao.createOrUpdate(userDAO); - final String uuid = user.getUuid().toString(); + final String uuid = user.getId().toString(); for (final ArmorItem armorItem : user.getPlayerArmor().getArmorItems()) { final ArmorItemDAO dao = ArmorItemDAO.fromArmorItem(armorItem); dao.setUuid(uuid); @@ -128,6 +168,23 @@ public class Database { } } + public void saveNPCUser(final NPCUser user) { + try { + final CitizenDAO citizenDAO = new CitizenDAO(user.getId()); + this.citizenDao.createOrUpdate(citizenDAO); + + final String id = user.getId().toString(); + for (final ArmorItem armorItem : user.getPlayerArmor().getArmorItems()) { + final ArmorItemDAO dao = ArmorItemDAO.fromArmorItem(armorItem); + dao.setUuid(id); + this.armorItemDao.createOrUpdate(dao); + } + + } catch (final SQLException exception) { + exception.printStackTrace(); + } + } + public void saveAll() { for (final User user : this.plugin.getUserManager().getAll()) { this.saveUser(user); @@ -154,7 +211,7 @@ public class Database { return userDao; } - public Dao getArmorItemDao() { + public Dao getArmorItemDao() { return armorItemDao; } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/CitizenDAO.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/CitizenDAO.java new file mode 100644 index 00000000..fd2452c3 --- /dev/null +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/CitizenDAO.java @@ -0,0 +1,66 @@ +package io.github.fisher2911.hmccosmetics.database.dao; + +import com.j256.ormlite.field.DatabaseField; +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.BaseUser; +import io.github.fisher2911.hmccosmetics.user.NPCUser; +import io.github.fisher2911.hmccosmetics.user.User; +import io.github.fisher2911.hmccosmetics.user.Wardrobe; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Objects; + +@DatabaseTable(tableName = "citizen") +public class CitizenDAO { + + @DatabaseField(id = true) + private int citizensId; + + public CitizenDAO() { + } + + public CitizenDAO(final int citizensId) { + this.citizensId = citizensId; + } + + public void setCitizensId(final int citizensId) { + this.citizensId = citizensId; + } + + @Nullable + public NPCUser toUser( + final CosmeticManager cosmeticManager, + final int entityId, + final List armorItems, + final int armorStandId + ) { + final PlayerArmor playerArmor = PlayerArmor.empty(); + + for (final ArmorItemDAO armorItemDao : armorItems) { + final ArmorItem armorItem = armorItemDao.toArmorItem(cosmeticManager); + if (armorItem == null) { + continue; + } + playerArmor.setItem(armorItem); + } + + return new NPCUser(this.citizensId, entityId, playerArmor, armorStandId); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final CitizenDAO that = (CitizenDAO) o; + return citizensId == that.citizensId; + } + + @Override + public int hashCode() { + return Objects.hash(citizensId); + } +} diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/UserDAO.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/UserDAO.java index 82aea7a4..8f7ba54d 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/UserDAO.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/database/dao/UserDAO.java @@ -5,8 +5,11 @@ 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.BaseUser; +import io.github.fisher2911.hmccosmetics.user.NPCUser; import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.Wardrobe; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Objects; @@ -29,12 +32,14 @@ public class UserDAO { this.uuid = uuid; } + @Nullable public User toUser( final CosmeticManager cosmeticManager, final int entityId, final List armorItems, final Wardrobe wardrobe, - final int armorStandId) { + final int armorStandId + ) { final PlayerArmor playerArmor = PlayerArmor.empty(); for (final ArmorItemDAO armorItemDao : armorItems) { diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/ArmorItem.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/ArmorItem.java index 8808bdc4..25fce1a8 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/ArmorItem.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/ArmorItem.java @@ -184,9 +184,13 @@ public class ArmorItem extends GuiItem { } public static ArmorItem empty(final Type type) { + return empty(type, ""); + } + + public static ArmorItem empty(final Type type, final String id) { return new ArmorItem( new ItemStack(Material.AIR), - "", + id, new ArrayList<>(), "", type, diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java index f4440cc0..c75c6b85 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java @@ -90,8 +90,14 @@ public class CosmeticGui { final ArmorItem.Type type = armorItem.getType(); + final User setUser; + if (user.isWardrobeActive()) { + setUser = user.getWardrobe(); + } else { + setUser = user; + } final ArmorItem setTo = this.plugin.getUserManager().setOrUnset( - user, + setUser, armorItem, Messages.getRemovedMessage(type), Messages.getSetMessage(type) diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/DyeSelectorGui.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/DyeSelectorGui.java index aa36e661..332335ad 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/DyeSelectorGui.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/gui/DyeSelectorGui.java @@ -8,6 +8,7 @@ import io.github.fisher2911.hmccosmetics.HMCCosmetics; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; import io.github.fisher2911.hmccosmetics.message.Placeholder; import io.github.fisher2911.hmccosmetics.user.User; +import io.github.fisher2911.hmccosmetics.user.Wardrobe; import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder; import java.util.HashMap; import java.util.Map; @@ -128,6 +129,7 @@ public class DyeSelectorGui extends CosmeticGui { armorItem.setDye(colorItem.getColor().asRGB()); + if (user.isWardrobeActive()) this.plugin.getUserManager().setItem(user, armorItem); this.updateSelected(user, player); }); diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/hook/HookManager.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/hook/HookManager.java index c928319a..bd72ed23 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/hook/HookManager.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/hook/HookManager.java @@ -1,6 +1,7 @@ package io.github.fisher2911.hmccosmetics.hook; import io.github.fisher2911.hmccosmetics.HMCCosmetics; +import io.github.fisher2911.hmccosmetics.hook.item.CitizensHook; import io.github.fisher2911.hmccosmetics.hook.item.ItemHook; import io.github.fisher2911.hmccosmetics.hook.item.ItemHooks; import io.github.fisher2911.hmccosmetics.hook.item.ItemsAdderHook; @@ -27,6 +28,7 @@ public class HookManager { private final HMCCosmetics plugin; private final ItemHooks itemHooks; private final PAPIHook papiHook; + private final CitizensHook citizensHook; private final Set> registeredHooks; private final Set listeners; @@ -45,13 +47,21 @@ public class HookManager { final Map itemHookMap = new HashMap<>(); final OraxenHook oraxenHook = new OraxenHook(); final ItemsAdderHook itemsAdderHook = new ItemsAdderHook(); + final CitizensHook citizensHook = new CitizensHook(this.plugin); if (pluginManager.getPlugin("Oraxen") != null) { - itemHookMap.put(oraxenHook.getIdentifier(), oraxenHook); + itemHookMap.put(oraxenHook.getId(), oraxenHook); } if (pluginManager.getPlugin("ItemsAdder") != null) { - itemHookMap.put(itemsAdderHook.getIdentifier(), itemsAdderHook); + itemHookMap.put(itemsAdderHook.getId(), itemsAdderHook); this.listeners.add(itemsAdderHook); } + if (pluginManager.getPlugin("Citizens") != null) { + this.registerHook(citizensHook.getClass()); + this.listeners.add(citizensHook); + this.citizensHook = citizensHook; + } else { + this.citizensHook = null; + } this.itemHooks = new ItemHooks(itemHookMap); itemHookMap.values().forEach(hook -> this.registerHook(hook.getClass())); @@ -87,6 +97,11 @@ public class HookManager { return papiHook; } + @Nullable + public CitizensHook getCitizensHook() { + return this.citizensHook; + } + public ItemHooks getItemHooks() { return itemHooks; } diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/hook/item/CitizensHook.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/hook/item/CitizensHook.java new file mode 100644 index 00000000..36ffed07 --- /dev/null +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/hook/item/CitizensHook.java @@ -0,0 +1,181 @@ +package io.github.fisher2911.hmccosmetics.hook.item; + +import io.github.fisher2911.hmccosmetics.HMCCosmetics; +import io.github.fisher2911.hmccosmetics.concurrent.Threads; +import io.github.fisher2911.hmccosmetics.config.Settings; +import io.github.fisher2911.hmccosmetics.database.Database; +import io.github.fisher2911.hmccosmetics.gui.ArmorItem; +import io.github.fisher2911.hmccosmetics.hook.Hook; +import io.github.fisher2911.hmccosmetics.task.InfiniteTask; +import io.github.fisher2911.hmccosmetics.user.NPCUser; +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCDeathEvent; +import net.citizensnpcs.api.event.NPCDespawnEvent; +import net.citizensnpcs.api.event.NPCRemoveEvent; +import net.citizensnpcs.api.event.NPCSpawnEvent; +import net.citizensnpcs.api.event.PlayerCreateNPCEvent; +import net.citizensnpcs.api.npc.NPC; +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class CitizensHook implements Hook, Listener { + + private static final String IDENTIFIER = "citizens"; + + private final HMCCosmetics plugin; + private final Database database; + + private final Map npcs = new HashMap<>(); + + public CitizensHook(final HMCCosmetics plugin) { + this.plugin = plugin; + this.database = this.plugin.getDatabase(); + final Settings settings = this.plugin.getSettings(); + this.plugin.getTaskManager().submit( + new InfiniteTask(() -> { + for (final NPCUser user : this.npcs.values()) { + if (!user.isValid()) { + continue; + } + user.updateArmorStand(settings); + } + }) + ); + } + + public List getAllNPCS() { + final Iterator iterator = CitizensAPI.getNPCRegistry().sorted().iterator(); + final List ids = new ArrayList<>(); + while (iterator.hasNext()) { + ids.add(iterator.next().getId()); + } + return ids; + } + + public int getCitizensId(final Entity entity) { + final NPC npc = CitizensAPI.getNPCRegistry().getNPC(entity); + if (npc == null) return -1; + return npc.getId(); + } + + public boolean setNpcCosmetic(final int id, final ArmorItem armorItem) { + final NPC npc = CitizensAPI.getNPCRegistry().getById(id); + if (npc == null) return false; + final NPCUser user = this.npcs.get(npc.getId()); + if (user == null) { + Threads.getInstance().execute(() -> { + this.database.loadNPCUser( + npc.getId(), + npc.getEntity(), + npcUser -> + Bukkit.getScheduler().runTask( + this.plugin, + () -> { + this.npcs.put(npc.getId(), npcUser); + this.setNpcCosmetic(npcUser, armorItem); + } + ) + ); + }); + return true; + } + return this.setNpcCosmetic(user, armorItem); + } + + public boolean setNpcCosmetic(final NPCUser user, final ArmorItem armorItem) { + if (user == null) return false; + final NPC npc = this.getNPC(user.getId()); + if (npc == null) return false; + if (!(npc.getEntity() instanceof final LivingEntity entity)) return false; + user.getPlayerArmor().setItem(armorItem); + final ArmorItem.Type type = armorItem.getType(); + if (type != ArmorItem.Type.BACKPACK) { + entity.getEquipment().setItem( + type.getSlot(), + armorItem.getItemStack(true) + ); + } + + return true; + } + + @Nullable + public NPC getNPC(final UUID uuid) { + return CitizensAPI.getNPCRegistry().getByUniqueIdGlobal(uuid); + } + + @Nullable + public NPC getNPC(final int id) { + return CitizensAPI.getNPCRegistry().getById(id); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onNpcLoad(final PlayerCreateNPCEvent event) { + this.loadNpc(event.getNPC()); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onNpcLoad(final NPCSpawnEvent event) { + this.loadNpc(event.getNPC()); + } + + private void loadNpc(final NPC npc) { + if (Bukkit.getPlayer(npc.getUniqueId()) != null) return; + + Bukkit.getScheduler().runTaskLater(this.plugin, + () -> Threads.getInstance().execute(() -> this.database.loadNPCUser( + npc.getId(), + npc.getEntity(), + user -> Bukkit.getScheduler().runTask( + this.plugin, + () -> { + this.npcs.put(npc.getId(), user); + for (final ArmorItem.Type type : ArmorItem.Type.values()) { + this.setNpcCosmetic(npc.getId(), user.getPlayerArmor().getItem(type)); + } + } + ) + )), + 1); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onNpcUnload(final NPCDespawnEvent event) { + this.unloadNpc(event.getNPC()); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onNpcUnload(final NPCRemoveEvent event) { + this.unloadNpc(event.getNPC()); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onNpcUnload(final NPCDeathEvent event) { + this.unloadNpc(event.getNPC()); + } + + private void unloadNpc(final NPC npc) { + final NPCUser user = this.npcs.remove(npc.getId()); + if (user == null) return; + user.despawnAttached(); + Threads.getInstance().execute(() -> this.database.saveNPCUser(user)); + } + + @Override + public String getId() { + return IDENTIFIER; + } +} diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java index 6b444240..b1ba22ad 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java @@ -3,6 +3,7 @@ package io.github.fisher2911.hmccosmetics.listener; import io.github.fisher2911.hmccosmetics.HMCCosmetics; import io.github.fisher2911.hmccosmetics.config.WardrobeSettings; import io.github.fisher2911.hmccosmetics.database.Database; +import io.github.fisher2911.hmccosmetics.task.TaskChain; import io.github.fisher2911.hmccosmetics.user.User; import io.github.fisher2911.hmccosmetics.user.UserManager; import io.github.fisher2911.hmccosmetics.user.Wardrobe; @@ -30,17 +31,20 @@ public class JoinListener implements Listener { @EventHandler public void onJoin(final PlayerJoinEvent event) { final Player player = event.getPlayer(); - this.database.loadUser(player, - user -> Bukkit.getScheduler().runTaskAsynchronously(this.plugin, - () -> { - this.userManager.resendCosmetics(player); - final WardrobeSettings settings = this.plugin.getSettings().getWardrobeSettings(); - if (settings.isAlwaysDisplay() && settings.getWardrobeLocation() != null) { - final Wardrobe wardrobe = user.getWardrobe(); - wardrobe.setCurrentLocation(settings.getWardrobeLocation()); - wardrobe.spawnFakePlayer(player); - } - })); + this.database.loadUser( + player, + user -> new TaskChain(this.plugin).chain( + () -> this.userManager.add(user) + ).chain(() -> { + this.userManager.resendCosmetics(player); + final WardrobeSettings settings = this.plugin.getSettings().getWardrobeSettings(); + if (settings.isAlwaysDisplay() && settings.getWardrobeLocation() != null) { + final Wardrobe wardrobe = user.getWardrobe(); + wardrobe.setCurrentLocation(settings.getWardrobeLocation()); + wardrobe.spawnFakePlayer(player); + } + }, true).execute() + ); } @EventHandler 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 2464b6be..b742fff2 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 @@ -47,6 +47,13 @@ public class Messages { new Message("invalid-user", ChatColor.RED + "That user's data cannot be found!"); public static final Message ITEM_NOT_FOUND = new Message("item-not-found", ChatColor.RED + "That item could not be found!"); + public static final Message HOOK_NOT_ENABLED = + new Message("hook-not-enabled", ChatColor.RED + Placeholder.TYPE + " is not enabled!"); + public static final Message NPC_NOT_FOUND = + new Message("npc-not-found", ChatColor.RED + "NPC with id " + Placeholder.ID + " not found!"); + public static final Message SET_NPC_COSMETIC = + new Message("set-npc-cosmetic", ChatColor.GREEN + "Set " + Placeholder.TYPE + " of " + + Placeholder.ID + " to " + Placeholder.ITEM); public static final Message HELP_COMMAND = new Message("help-command", """ diff --git a/common/src/main/java/io/github/fisher2911/hmccosmetics/message/Placeholder.java b/common/src/main/java/io/github/fisher2911/hmccosmetics/message/Placeholder.java index 4497bd24..3bba4dd8 100644 --- a/common/src/main/java/io/github/fisher2911/hmccosmetics/message/Placeholder.java +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/message/Placeholder.java @@ -16,6 +16,7 @@ public class Placeholder { public static final String PLAYER = "%player%"; public static final String ENABLED = "%enabled%"; public static final String ALLOWED = "%allowed%"; + public static final String ID = "%id%"; /** * @param message message being translated 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 c7828f4a..e07766a8 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 @@ -23,9 +23,9 @@ import java.util.Objects; import java.util.Set; import java.util.UUID; -public abstract class BaseUser { +public abstract class BaseUser { - protected final UUID uuid; + protected final T id; protected final int entityId; protected final PlayerArmor playerArmor; @@ -37,8 +37,8 @@ public abstract class BaseUser { // List of players that are currently viewing the armor stand protected final Set viewing = new HashSet<>(); - public BaseUser(final UUID uuid, final int entityId, final PlayerArmor playerArmor, final int armorStandId) { - this.uuid = uuid; + public BaseUser(final T id, final int entityId, final PlayerArmor playerArmor, final int armorStandId) { + this.id = id; this.entityId = entityId; this.playerArmor = playerArmor; this.armorStandId = armorStandId; @@ -47,8 +47,8 @@ public abstract class BaseUser { @Nullable public abstract Location getLocation(); - public UUID getUuid() { - return this.uuid; + public T getId() { + return this.id; } public PlayerArmor getPlayerArmor() { @@ -153,7 +153,7 @@ public abstract class BaseUser { new ItemStack(Material.AIR) )); - if (!this.uuid.equals(other.getUniqueId())) return; + if (!this.id.equals(other.getUniqueId())) return; PacketManager.sendPacket(other, PacketManager.getEquipmentPacket(equipmentList, this.armorStandId)); } } @@ -192,4 +192,8 @@ public abstract class BaseUser { return this.entityId; } + public abstract Equipment getEquipment(); + + public abstract boolean isWardrobeActive(); + } 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 10e107fc..e3e5623e 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 @@ -32,4 +32,5 @@ public class Equipment { public void setItem(final EquipmentSlot slot, @Nullable final ItemStack itemStack) { this.equipment.put(slot, itemStack); } + } 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 new file mode 100644 index 00000000..a3462170 --- /dev/null +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/NPCUser.java @@ -0,0 +1,60 @@ +package io.github.fisher2911.hmccosmetics.user; + +import io.github.fisher2911.hmccosmetics.hook.HookManager; +import io.github.fisher2911.hmccosmetics.hook.item.CitizensHook; +import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; +import net.citizensnpcs.api.npc.NPC; +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +public class NPCUser extends BaseUser { + + private final CitizensHook hook; + + public NPCUser(final int id, final int entityId, final PlayerArmor playerArmor, final int armorStandId) { + super(id, entityId, playerArmor, armorStandId); + this.hook = HookManager.getInstance().getCitizensHook(); + } + + public NPCUser(final PlayerArmor playerArmor, final int armorStandId, final NPC npc) { + this(npc.getId(), npc.getId(), playerArmor, armorStandId); + } + + @Nullable + public NPC getNpc() { + return this.hook.getNPC(this.getId()); + } + + @Override + @Nullable + public Location getLocation() { + final NPC npc = this.getNpc(); + if (npc == null) return null; + return npc.getEntity().getLocation(); + } + + public boolean isValid() { + return this.getNpc() != null; + } + + @Override + public boolean shouldShow(final Player other) { + return true; + } + + @Override + public Equipment getEquipment() { + final NPC npc = this.getNpc(); + if (npc == null) return new Equipment(); + if (!(npc.getEntity() instanceof final LivingEntity entity)) return new Equipment(); + return Equipment.fromEntityEquipment(entity.getEquipment()); + } + + @Override + public boolean isWardrobeActive() { + return false; + } + +} 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 7b029bc4..8d9e45b1 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 @@ -3,7 +3,6 @@ package io.github.fisher2911.hmccosmetics.user; import io.github.fisher2911.hmccosmetics.gui.ArmorItem; import io.github.fisher2911.hmccosmetics.gui.CosmeticGui; import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; -import net.minecraft.server.v1_16_R3.PacketPlayInAbilities; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; @@ -13,18 +12,22 @@ import org.jetbrains.annotations.Nullable; import java.util.UUID; -public class User extends BaseUser { +public class User extends BaseUser { protected Wardrobe wardrobe; private CosmeticGui openGui; - public User(final UUID uuid, final int entityId, final PlayerArmor playerArmor, final int armorStandId, final Wardrobe wardrobe) { + public User(final UUID uuid, final int entityId, final PlayerArmor playerArmor, final Wardrobe wardrobe, final int armorStandId) { super(uuid, entityId, playerArmor, armorStandId); this.wardrobe = wardrobe; } + public User(final UUID uuid, final int entityId, final PlayerArmor playerArmor, final int armorStandId) { + super(uuid, entityId, playerArmor, armorStandId); + } + public @Nullable Player getPlayer() { - return Bukkit.getPlayer(this.uuid); + return Bukkit.getPlayer(this.getId()); } public Wardrobe getWardrobe() { @@ -62,4 +65,16 @@ public class User extends BaseUser { if (player == null) return null; return player.getLocation(); } + + @Override + public Equipment getEquipment() { + final Player player = this.getPlayer(); + if (player == null) return new Equipment(); + return Equipment.fromEntityEquipment(player.getEquipment()); + } + + @Override + public boolean isWardrobeActive() { + return this.wardrobe.isActive(); + } } 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 new file mode 100644 index 00000000..9aae535d --- /dev/null +++ b/common/src/main/java/io/github/fisher2911/hmccosmetics/user/UserFactory.java @@ -0,0 +1,55 @@ +package io.github.fisher2911.hmccosmetics.user; + +import io.github.fisher2911.hmccosmetics.HMCCosmetics; +import io.github.fisher2911.hmccosmetics.hook.HookManager; +import io.github.fisher2911.hmccosmetics.hook.item.CitizensHook; +import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor; +import org.bukkit.entity.Entity; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; + +public class UserFactory { + + private static final HMCCosmetics plugin; + private static final UserManager userManager; + + static { + plugin = HMCCosmetics.getPlugin(HMCCosmetics.class); + userManager = plugin.getUserManager(); + } + + @SuppressWarnings("unchecked") + @Nullable + public static T createUser( + final Class type, + final Entity entity, + final int armorStandId + ) { + final UUID uuid = entity.getUniqueId(); + final int entityId = entity.getEntityId(); + if (type.equals(User.class)) { + return (T) new User( + uuid, + entityId, + PlayerArmor.empty(), + plugin.getDatabase().createNewWardrobe(uuid), + armorStandId + ); + } + + if (type.equals(NPCUser.class)) { + if (!HookManager.getInstance().isEnabled(CitizensHook.class)) return null; + final int citizensId = HookManager.getInstance().getCitizensHook().getCitizensId(entity); + return (T) new NPCUser( + citizensId, + entityId, + PlayerArmor.empty(), + armorStandId + ); + } + + return null; + } + +} 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 fbbf84ba..a5335333 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 @@ -22,6 +22,7 @@ import io.github.fisher2911.hmccosmetics.message.MessageHandler; 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.InfiniteTask; import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -46,10 +47,6 @@ public class UserManager { private final MessageHandler messageHandler; private final Map userMap = new HashMap<>(); - private final Map userEntityIdMap = new HashMap<>(); - private final Map armorStandIdMap = new HashMap<>(); - - private BukkitTask teleportTask; public UserManager(final HMCCosmetics plugin) { this.plugin = plugin; @@ -58,12 +55,7 @@ public class UserManager { } public void add(final User user) { - this.userMap.put(user.getUuid(), user); - final Player player = user.getPlayer(); - if (player != null) { - this.userEntityIdMap.put(user.getEntityId(), user); - } - this.armorStandIdMap.put(user.getArmorStandId(), user); + this.userMap.put(user.getId(), user); this.updateCosmetics(user); } @@ -80,9 +72,6 @@ public class UserManager { if (user == null) return; - this.armorStandIdMap.remove(user.getArmorStandId()); - this.userEntityIdMap.remove(user.getEntityId()); - final PlayerArmor copy = user.getPlayerArmor().copy(); user.removeAllCosmetics(); @@ -97,16 +86,13 @@ public class UserManager { public void startTeleportTask() { // throws an error on first load of registry if this isn't here WrappedDataWatcher.Registry.get(Byte.class); - this.teleportTask = Bukkit.getScheduler().runTaskTimerAsynchronously( - this.plugin, + this.plugin.getTaskManager().submit(new InfiniteTask( () -> { for (final User user : this.userMap.values()) { user.updateArmorStand(this.plugin.getSettings()); } - }, - 1, - 1 - ); + } + )); } public void resendCosmetics(final Player player) { @@ -123,21 +109,15 @@ public class UserManager { } - public void updateCosmetics(final User user) { + public void updateCosmetics(final BaseUser user) { for (final Player player : Bukkit.getOnlinePlayers()) { this.updateCosmetics(user, player); } } - public void updateCosmetics(final User user, final Player other) { - final Player player = user.getPlayer(); - - final Equipment equipment; - if (player == null) { - equipment = new Equipment(); - } else { - equipment = Equipment.fromEntityEquipment(player.getEquipment()); - } + public void updateCosmetics(final BaseUser user, final Player other) { +// final Player player = user.getPlayer(); + final Equipment equipment = user.getEquipment(); for (final ArmorItem.Type type : ArmorItem.Type.values()) { if (type.getSlot() == null) continue; @@ -151,7 +131,7 @@ public class UserManager { } private void sendUpdatePacket( - final User user, + final BaseUser user, final Player other, final Equipment equipment, final ArmorItem.Type type) { @@ -171,7 +151,7 @@ public class UserManager { } private ItemStack getCosmeticItem( - final User user, + final BaseUser user, final Equipment equipment, final ArmorItem armorItem, final EquipmentSlot slot) { @@ -200,36 +180,29 @@ public class UserManager { final ItemStack equipped = equipment.getItem(slot); - if (equipped != null && (equipped.getType() != Material.AIR && !user.getWardrobe().isActive())) { + if (equipped != null && (equipped.getType() != Material.AIR && !user.isWardrobeActive())) { return equipped; } return itemStack; } - public void setItem(final User user, final ArmorItem armorItem) { - final Wardrobe wardrobe = user.getWardrobe(); - final User setUser; - if (wardrobe.isActive()) { - setUser = wardrobe; - } else { - setUser = user; - } - ArmorItem previous = setUser.getPlayerArmor().getItem(armorItem.getType()); + public void setItem(final BaseUser user, final ArmorItem armorItem) { + ArmorItem previous = user.getPlayerArmor().getItem(armorItem.getType()); final CosmeticChangeEvent event = - new CosmeticChangeEvent(new CosmeticItem(armorItem.copy()), new CosmeticItem(previous.copy()), setUser); + new CosmeticChangeEvent(new CosmeticItem(armorItem.copy()), new CosmeticItem(previous.copy()), user); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; - setUser.setItem(event.getCosmeticItem().getArmorItem()); + user.setItem(event.getCosmeticItem().getArmorItem()); Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { switch (armorItem.getType()) { case HAT, OFF_HAND, CHEST_PLATE, PANTS, BOOTS -> { - this.updateCosmetics(setUser); + this.updateCosmetics(user); } case BACKPACK -> { - if (wardrobe.isActive()) setUser.updateArmorStand(settings); + if (user instanceof Wardrobe) user.updateArmorStand(settings); } } }); @@ -290,10 +263,6 @@ public class UserManager { this.userMap.clear(); } - public void cancelTeleportTask() { - this.teleportTask.cancel(); - } - @Nullable private EquipmentSlot slotFromInventorySlot(final int slot) { return switch (slot) { 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 9745eb9b..3fd33377 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 @@ -94,12 +94,12 @@ public class Wardrobe extends User { final PacketContainer playerSpawnPacket = PacketManager.getFakePlayerSpawnPacket( this.currentLocation, - this.getUuid(), + this.getId(), this.getEntityId() ); final PacketContainer playerInfoPacket = PacketManager.getFakePlayerInfoPacket( viewer, - this.getUuid() + this.getId() ); @@ -246,4 +246,8 @@ public class Wardrobe extends User { } } + @Override + public Equipment getEquipment() { + return new Equipment(); + } }