diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java index d0ce232b..d80a5ad0 100644 --- a/common/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java @@ -11,6 +11,7 @@ import com.hibiscusmc.hmccosmetics.config.serializer.LocationSerializer; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.database.Database; +import com.hibiscusmc.hmccosmetics.emotes.EmoteManager; import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.hooks.Hooks; import com.hibiscusmc.hmccosmetics.hooks.worldguard.WGHook; @@ -20,15 +21,11 @@ import com.hibiscusmc.hmccosmetics.listener.PlayerGameListener; import com.hibiscusmc.hmccosmetics.nms.NMSHandlers; import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; -import com.hibiscusmc.hmccosmetics.user.manager.UserEmoteManager; import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.TranslationUtil; import com.jeff_media.updatechecker.UpdateCheckSource; import com.jeff_media.updatechecker.UpdateChecker; import com.ticxo.playeranimator.PlayerAnimatorImpl; -import com.ticxo.playeranimator.api.PlayerAnimator; -import com.ticxo.playeranimator.api.animation.pack.AnimationPack; -import org.apache.commons.io.FilenameUtils; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -44,7 +41,6 @@ import org.spongepowered.configurate.yaml.YamlConfigurationLoader; import java.io.File; import java.nio.file.Path; -import java.util.Map; public final class HMCCosmeticsPlugin extends JavaPlugin { @@ -241,23 +237,7 @@ public final class HMCCosmeticsPlugin extends JavaPlugin { } } - File emoteFolder = new File(getInstance().getDataFolder().getPath() + "/emotes/"); - if (emoteFolder.exists()) { - PlayerAnimator.api.getAnimationManager().clearRegistry(); - File[] emotesFiles = emoteFolder.listFiles(); - for (File emoteFile : emotesFiles) { - if (!emoteFile.getName().contains("bbmodel")) continue; - String animationName = FilenameUtils.removeExtension(emoteFile.getName()); - PlayerAnimator.api.getAnimationManager().importAnimations(animationName, emoteFile); - MessagesUtil.sendDebugMessages("Added '" + animationName + "' to Player Animator "); - } - - /* - for (Map.Entry packEntry : PlayerAnimator.api.getAnimationManager().getRegistry().entrySet()) { - Set animationNames = packEntry.getValue().getAnimations().keySet().stream().map(animation -> packEntry.getKey().replace(":", ".") + "." + animation).collect(Collectors.toSet()); - } - */ - } + EmoteManager.loadEmotes(); getInstance().getLogger().info("Successfully Enabled HMCCosmetics"); getInstance().getLogger().info(Cosmetics.values().size() + " Cosmetics Successfully Setup"); diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/command/CosmeticCommand.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/command/CosmeticCommand.java index 46f65cd7..60fb4aaa 100644 --- a/common/src/main/java/com/hibiscusmc/hmccosmetics/command/CosmeticCommand.java +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/command/CosmeticCommand.java @@ -8,6 +8,7 @@ import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; import com.hibiscusmc.hmccosmetics.cosmetic.types.CosmeticEmoteType; import com.hibiscusmc.hmccosmetics.database.Database; +import com.hibiscusmc.hmccosmetics.emotes.EmoteManager; import com.hibiscusmc.hmccosmetics.gui.Menu; import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.gui.special.DyeMenu; @@ -15,7 +16,6 @@ import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.ServerUtils; -import com.ticxo.playeranimator.api.PlayerAnimator; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.apache.commons.lang3.EnumUtils; @@ -428,12 +428,10 @@ public class CosmeticCommand implements CommandExecutor { return true; } - if (args.length >= 2) { - if (!PlayerAnimator.api.getAnimationManager().getRegistry().keySet().contains(args[1])) { - MessagesUtil.sendDebugMessages("Did not contain " + args[1]); - if (!silent) MessagesUtil.sendMessage(sender, "emote-invalid"); - return true; - } + if (!EmoteManager.has(args[1])) { + MessagesUtil.sendDebugMessages("Did not contain " + args[1]); + if (!silent) MessagesUtil.sendMessage(sender, "emote-invalid"); + return true; } if (sender.hasPermission("hmccosmetics.cmd.playemote.other")) { @@ -444,7 +442,7 @@ public class CosmeticCommand implements CommandExecutor { return true; } CosmeticUser user = CosmeticUsers.getUser(player); - user.getUserEmoteManager().playEmote(args[1]); + user.getUserEmoteManager().playEmote(EmoteManager.get(args[1])); return true; } } diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/command/CosmeticCommandTabComplete.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/command/CosmeticCommandTabComplete.java index 563e79ed..03445bdd 100644 --- a/common/src/main/java/com/hibiscusmc/hmccosmetics/command/CosmeticCommandTabComplete.java +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/command/CosmeticCommandTabComplete.java @@ -3,11 +3,11 @@ package com.hibiscusmc.hmccosmetics.command; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetic; import com.hibiscusmc.hmccosmetics.cosmetic.CosmeticSlot; import com.hibiscusmc.hmccosmetics.cosmetic.Cosmetics; +import com.hibiscusmc.hmccosmetics.emotes.EmoteManager; import com.hibiscusmc.hmccosmetics.gui.Menu; import com.hibiscusmc.hmccosmetics.gui.Menus; import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; -import com.ticxo.playeranimator.api.PlayerAnimator; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -81,9 +81,7 @@ public class CosmeticCommandTabComplete implements TabCompleter { completions.add("viewerlocation"); completions.add("leavelocation"); } - case "playemote" -> { - completions.addAll(PlayerAnimator.api.getAnimationManager().getRegistry().keySet()); - } + case "playemote" -> completions.addAll(EmoteManager.getAllNames()); } StringUtil.copyPartialMatches(args[1], completions, finalCompletions); } diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/emotes/EmoteManager.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/emotes/EmoteManager.java new file mode 100644 index 00000000..ea0d8a39 --- /dev/null +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/emotes/EmoteManager.java @@ -0,0 +1,85 @@ +package com.hibiscusmc.hmccosmetics.emotes; + +import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; +import com.ticxo.playeranimator.api.PlayerAnimator; +import com.ticxo.playeranimator.api.animation.pack.AnimationPack; +import org.apache.commons.io.FilenameUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Manages Emotes + */ +@SuppressWarnings("SpellCheckingInspection") +public class EmoteManager { + private static final @NotNull Map<@NotNull String, @NotNull String> emotes = new HashMap<>(); + + /** + * Loads all BlockBench animations from the emotes folder and puts it into the animation manager registry and local registry + */ + public static void loadEmotes() { + // Clear the PlayerAnimator and local registries + PlayerAnimator.api.getAnimationManager().clearRegistry(); + emotes.clear(); + + // Get the emote directory and check if it exists + File emoteDir = new File(HMCCosmeticsPlugin.getInstance().getDataFolder().getPath() + "/emotes/"); + if (!emoteDir.exists()) return; + + // Get all the files inside the directory and check if it isn't 0 + File[] emoteFiles = emoteDir.listFiles(); + if (emoteFiles == null || emoteFiles.length == 0) return; + + // Remove any files that don't have the file extension ".bbmodel" and check if there are still resulting files + emoteFiles = Arrays.stream(emoteFiles).filter(file -> file.getPath().endsWith(".bbmodel")).distinct().toArray(File[]::new); + if (emoteFiles.length == 0) return; + + // Loop through all files, importing all block bench animations into the registry + for (File animationFile : emoteFiles) { + String animationKey = FilenameUtils.removeExtension(animationFile.getName()); + PlayerAnimator.api.getAnimationManager().importAnimations(animationKey, animationFile); + } + + // Loops through all the entries in the registries and unpacks any animation packs to ensure if there were multiple animations + // inside a singular file, that they are added to the local registry individually for tab completion + for (Map.Entry packEntry : PlayerAnimator.api.getAnimationManager().getRegistry().entrySet()) { + packEntry.getValue().getAnimations().keySet().forEach(animationName -> { + // API key is the format "animationKey.animationFileName.animationName" + String apiKey = packEntry.getKey().replace(":", ".") + "." + animationName; + emotes.put(animationName, apiKey); + }); + } + } + + /** + * Returns true if there is an animation with the specified name + * @param animationName Name whose presence is to be tested + * @return True if this registry contains a mapping for the specified name + */ + public static boolean has(@NotNull String animationName) { + return emotes.containsKey(animationName); + } + + /** + * Returns the {@code API key} to which the specified name is mapped, or {@code null} if this map contains no mapping for the name. + * @param animationName Name whose {@code API key} is to be fetched + * @return The {@code API key} of the specified name or {@code null} if there was no animation name found + */ + public static @Nullable String get(@NotNull String animationName) { + return emotes.get(animationName); + } + + /** + * Gets a set of all the laoded animation names + * @return A set of all loaded animation names + */ + public static @NotNull Set getAllNames() { + return emotes.keySet(); + } +}