From 5489c6e9aaf8511d58d807267b7c62c767c0d129 Mon Sep 17 00:00:00 2001 From: Illusion Date: Mon, 22 Apr 2024 20:52:28 +0100 Subject: [PATCH 1/2] NPC Draft --- .../de/minebench/tresor/services/npc/NPC.java | 19 ++++ .../tresor/services/npc/NPCMetadata.java | 31 ++++++ .../minebench/tresor/services/npc/NPCs.java | 24 +++++ .../tresor/services/npc/skin/NPCSkinData.java | 20 ++++ providers/citizens/pom.xml | 40 ++++++++ .../providers/citizens/CitizensNPCs.java | 94 +++++++++++++++++++ .../tresor/providers/citizens/WrappedNPC.java | 72 ++++++++++++++ providers/pom.xml | 3 + 8 files changed, 303 insertions(+) create mode 100644 api/src/main/java/de/minebench/tresor/services/npc/NPC.java create mode 100644 api/src/main/java/de/minebench/tresor/services/npc/NPCMetadata.java create mode 100644 api/src/main/java/de/minebench/tresor/services/npc/NPCs.java create mode 100644 api/src/main/java/de/minebench/tresor/services/npc/skin/NPCSkinData.java create mode 100644 providers/citizens/pom.xml create mode 100644 providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/CitizensNPCs.java create mode 100644 providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/WrappedNPC.java diff --git a/api/src/main/java/de/minebench/tresor/services/npc/NPC.java b/api/src/main/java/de/minebench/tresor/services/npc/NPC.java new file mode 100644 index 0000000..165e09f --- /dev/null +++ b/api/src/main/java/de/minebench/tresor/services/npc/NPC.java @@ -0,0 +1,19 @@ +package de.minebench.tresor.services.npc; + +import java.util.UUID; +import org.bukkit.Location; + +public interface NPC { + + UUID getUniqueId(); + + boolean isPersistent(); + + NPCMetadata getMetadata(); + void updateMetadata(NPCMetadata metadata); + + Location getLocation(); + void teleport(Location location); + + void destroy(); +} diff --git a/api/src/main/java/de/minebench/tresor/services/npc/NPCMetadata.java b/api/src/main/java/de/minebench/tresor/services/npc/NPCMetadata.java new file mode 100644 index 0000000..9afe7d2 --- /dev/null +++ b/api/src/main/java/de/minebench/tresor/services/npc/NPCMetadata.java @@ -0,0 +1,31 @@ +package de.minebench.tresor.services.npc; + +import de.minebench.tresor.services.npc.skin.NPCSkinData; + +public class NPCMetadata { + + private String displayName; + private NPCSkinData skinData; + + public NPCMetadata(String displayName, NPCSkinData skinData) { + this.displayName = displayName; + this.skinData = skinData; + } + + public String getDisplayName() { + return displayName; + } + + public NPCSkinData getSkinData() { + return skinData; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public void setSkinData(NPCSkinData skinData) { + this.skinData = skinData; + } + +} diff --git a/api/src/main/java/de/minebench/tresor/services/npc/NPCs.java b/api/src/main/java/de/minebench/tresor/services/npc/NPCs.java new file mode 100644 index 0000000..b0c979b --- /dev/null +++ b/api/src/main/java/de/minebench/tresor/services/npc/NPCs.java @@ -0,0 +1,24 @@ +package de.minebench.tresor.services.npc; + +import de.minebench.tresor.services.TresorServiceProvider; +import java.util.UUID; +import org.bukkit.Location; + +public interface NPCs extends TresorServiceProvider { + + default NPC createNPC(String name, Location location) { + return createNPC(name, location, true); + } + + NPC createNPC(String name, Location location, boolean persistent); + NPC getNPC(UUID uniqueId); + + void removeNPC(UUID uniqueId); + + boolean supports(Feature feature); + + enum Feature { + PERSISTENT + } + +} diff --git a/api/src/main/java/de/minebench/tresor/services/npc/skin/NPCSkinData.java b/api/src/main/java/de/minebench/tresor/services/npc/skin/NPCSkinData.java new file mode 100644 index 0000000..a8fe008 --- /dev/null +++ b/api/src/main/java/de/minebench/tresor/services/npc/skin/NPCSkinData.java @@ -0,0 +1,20 @@ +package de.minebench.tresor.services.npc.skin; + +public class NPCSkinData { + + private final String texture; + private final String signature; + + public NPCSkinData(String texture, String signature) { + this.texture = texture; + this.signature = signature; + } + + public String getTexture() { + return texture; + } + + public String getSignature() { + return signature; + } +} diff --git a/providers/citizens/pom.xml b/providers/citizens/pom.xml new file mode 100644 index 0000000..8492e07 --- /dev/null +++ b/providers/citizens/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + de.minebench.tresor.providers + citizens + + + de.minebench.tresor + tresor-providers + 1.0-SNAPSHOT + + + + + citizens-repo + https://maven.citizensnpcs.co/repo + + + + + + net.citizensnpcs + citizens-main + 2.0.33-SNAPSHOT + jar + provided + + + * + * + + + + + + + \ No newline at end of file diff --git a/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/CitizensNPCs.java b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/CitizensNPCs.java new file mode 100644 index 0000000..f021578 --- /dev/null +++ b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/CitizensNPCs.java @@ -0,0 +1,94 @@ +package de.minebench.tresor.providers.citizens; + +import de.minebench.tresor.Provider; +import de.minebench.tresor.services.npc.NPC; +import de.minebench.tresor.services.npc.NPCs; +import java.util.UUID; +import net.citizensnpcs.api.CitizensPlugin; +import net.citizensnpcs.api.npc.MemoryNPCDataStore; +import net.citizensnpcs.api.npc.NPCRegistry; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; + +public class CitizensNPCs extends Provider implements NPCs { + + private NPCRegistry persistentRegistry; + private NPCRegistry temporaryRegistry; + + private CitizensPlugin hooked; + + public CitizensNPCs() { + super(NPCs.class); + } + + @Override + public boolean isEnabled() { + return getHooked() != null && getHooked().isEnabled(); + } + + @Override + public NPC createNPC(String name, Location location, boolean persistent) { + NPCRegistry registry = persistent ? persistentRegistry : temporaryRegistry; + net.citizensnpcs.api.npc.NPC rawNPC = registry.createNPC(EntityType.PLAYER, name); + rawNPC.spawn(location); + + return new WrappedNPC(rawNPC, persistent); + } + + @Override + public NPC getNPC(UUID uniqueId) { + net.citizensnpcs.api.npc.NPC rawNPC = persistentRegistry.getByUniqueIdGlobal(uniqueId); + boolean isPersistent = true; + + if (rawNPC == null) { + rawNPC = temporaryRegistry.getByUniqueIdGlobal(uniqueId); + isPersistent = false; + } + + if (rawNPC == null) { + return null; + } + + return new WrappedNPC(rawNPC, isPersistent); + } + + @Override + public void removeNPC(UUID uniqueId) { + NPC npc = getNPC(uniqueId); + + if (npc != null) { + npc.destroy(); + } + } + + @Override + public boolean supports(Feature feature) { + return feature == Feature.PERSISTENT; + } + + @Override + public CitizensPlugin getHooked() { + if(hooked == null) { + hooked = (CitizensPlugin) Bukkit.getPluginManager().getPlugin("Citizens"); + ensureRegistries(); + } + + return hooked; + } + + @Override + public String getName() { + return "Citizens"; + } + + private void ensureRegistries() { + if (persistentRegistry == null) { + persistentRegistry = hooked.getNPCRegistry(); + } + + if (temporaryRegistry == null) { + temporaryRegistry = hooked.createAnonymousNPCRegistry(new MemoryNPCDataStore()); + } + } +} diff --git a/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/WrappedNPC.java b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/WrappedNPC.java new file mode 100644 index 0000000..8152667 --- /dev/null +++ b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/WrappedNPC.java @@ -0,0 +1,72 @@ +package de.minebench.tresor.providers.citizens; + +import de.minebench.tresor.services.npc.NPC; +import de.minebench.tresor.services.npc.NPCMetadata; +import de.minebench.tresor.services.npc.skin.NPCSkinData; +import java.util.UUID; +import net.citizensnpcs.trait.SkinTrait; +import org.bukkit.Location; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + +public class WrappedNPC implements NPC { + + private final net.citizensnpcs.api.npc.NPC npc; + private final boolean persistent; + + public WrappedNPC(net.citizensnpcs.api.npc.NPC npc, boolean persistent) { + this.npc = npc; + this.persistent = persistent; + } + + @Override + public UUID getUniqueId() { + return npc.getUniqueId(); + } + + @Override + public boolean isPersistent() { + return persistent; + } + + @Override + public NPCMetadata getMetadata() { + String displayName = npc.getName(); + SkinTrait skinTrait = npc.getTraitNullable(SkinTrait.class); + + if (skinTrait == null) { + return new NPCMetadata(displayName, null); + } + + NPCSkinData skinData = new NPCSkinData(skinTrait.getTexture(), skinTrait.getSignature()); + return new NPCMetadata(displayName, skinData); + } + + @Override + public void updateMetadata(NPCMetadata metadata) { + npc.setName(metadata.getDisplayName()); + + NPCSkinData skinData = metadata.getSkinData(); + + if (skinData == null) { + return; + } + + SkinTrait skinTrait = npc.getOrAddTrait(SkinTrait.class); + skinTrait.setTexture(skinData.getTexture(), skinData.getSignature()); + } + + @Override + public Location getLocation() { + return npc.getStoredLocation(); + } + + @Override + public void teleport(Location location) { + npc.teleport(location, TeleportCause.PLUGIN); + } + + @Override + public void destroy() { + npc.destroy(); + } +} diff --git a/providers/pom.xml b/providers/pom.xml index c065288..5f7205e 100644 --- a/providers/pom.xml +++ b/providers/pom.xml @@ -27,6 +27,9 @@ decentholograms + + + citizens From eb2eaf03be9d9709729b631b39be1c7b1b0c722c Mon Sep 17 00:00:00 2001 From: Illusion Date: Tue, 23 Apr 2024 15:57:11 +0100 Subject: [PATCH 2/2] First wave of changes --- .../de/minebench/tresor/services/npc/NPC.java | 7 ++- .../tresor/services/npc/data/Interaction.java | 34 +++++++++++++ .../services/npc/{ => data}/NPCMetadata.java | 4 +- .../npc/{skin => data}/NPCSkinData.java | 2 +- .../providers/citizens/CitizensNPCs.java | 17 ++++++- .../tresor/providers/citizens/WrappedNPC.java | 22 ++++++-- .../listener/CitizensNPCListener.java | 50 +++++++++++++++++++ 7 files changed, 126 insertions(+), 10 deletions(-) create mode 100644 api/src/main/java/de/minebench/tresor/services/npc/data/Interaction.java rename api/src/main/java/de/minebench/tresor/services/npc/{ => data}/NPCMetadata.java (85%) rename api/src/main/java/de/minebench/tresor/services/npc/{skin => data}/NPCSkinData.java (88%) create mode 100644 providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/listener/CitizensNPCListener.java diff --git a/api/src/main/java/de/minebench/tresor/services/npc/NPC.java b/api/src/main/java/de/minebench/tresor/services/npc/NPC.java index 165e09f..b9d921b 100644 --- a/api/src/main/java/de/minebench/tresor/services/npc/NPC.java +++ b/api/src/main/java/de/minebench/tresor/services/npc/NPC.java @@ -1,6 +1,9 @@ package de.minebench.tresor.services.npc; +import de.minebench.tresor.services.npc.data.Interaction; +import de.minebench.tresor.services.npc.data.NPCMetadata; import java.util.UUID; +import java.util.function.Consumer; import org.bukkit.Location; public interface NPC { @@ -15,5 +18,7 @@ public interface NPC { Location getLocation(); void teleport(Location location); - void destroy(); + void onInteract(Consumer action); + + void remove(); } diff --git a/api/src/main/java/de/minebench/tresor/services/npc/data/Interaction.java b/api/src/main/java/de/minebench/tresor/services/npc/data/Interaction.java new file mode 100644 index 0000000..c863676 --- /dev/null +++ b/api/src/main/java/de/minebench/tresor/services/npc/data/Interaction.java @@ -0,0 +1,34 @@ +package de.minebench.tresor.services.npc.data; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class Interaction { + + private final Player player; + private final Type type; + private final ItemStack heldItem; + + public Interaction(Player player, Type type, ItemStack heldItem) { + this.player = player; + this.type = type; + this.heldItem = heldItem; + } + + public Player getPlayer() { + return player; + } + + public Type getType() { + return type; + } + + public ItemStack getHeldItem() { + return heldItem; + } + + public enum Type { + LEFT_CLICK, + RIGHT_CLICK + } +} diff --git a/api/src/main/java/de/minebench/tresor/services/npc/NPCMetadata.java b/api/src/main/java/de/minebench/tresor/services/npc/data/NPCMetadata.java similarity index 85% rename from api/src/main/java/de/minebench/tresor/services/npc/NPCMetadata.java rename to api/src/main/java/de/minebench/tresor/services/npc/data/NPCMetadata.java index 9afe7d2..8d664ae 100644 --- a/api/src/main/java/de/minebench/tresor/services/npc/NPCMetadata.java +++ b/api/src/main/java/de/minebench/tresor/services/npc/data/NPCMetadata.java @@ -1,6 +1,4 @@ -package de.minebench.tresor.services.npc; - -import de.minebench.tresor.services.npc.skin.NPCSkinData; +package de.minebench.tresor.services.npc.data; public class NPCMetadata { diff --git a/api/src/main/java/de/minebench/tresor/services/npc/skin/NPCSkinData.java b/api/src/main/java/de/minebench/tresor/services/npc/data/NPCSkinData.java similarity index 88% rename from api/src/main/java/de/minebench/tresor/services/npc/skin/NPCSkinData.java rename to api/src/main/java/de/minebench/tresor/services/npc/data/NPCSkinData.java index a8fe008..a7daf21 100644 --- a/api/src/main/java/de/minebench/tresor/services/npc/skin/NPCSkinData.java +++ b/api/src/main/java/de/minebench/tresor/services/npc/data/NPCSkinData.java @@ -1,4 +1,4 @@ -package de.minebench.tresor.services.npc.skin; +package de.minebench.tresor.services.npc.data; public class NPCSkinData { diff --git a/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/CitizensNPCs.java b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/CitizensNPCs.java index f021578..1c25aeb 100644 --- a/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/CitizensNPCs.java +++ b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/CitizensNPCs.java @@ -1,6 +1,7 @@ package de.minebench.tresor.providers.citizens; import de.minebench.tresor.Provider; +import de.minebench.tresor.providers.citizens.listener.CitizensNPCListener; import de.minebench.tresor.services.npc.NPC; import de.minebench.tresor.services.npc.NPCs; import java.util.UUID; @@ -22,6 +23,18 @@ public CitizensNPCs() { super(NPCs.class); } + @Override + public void register() { + super.register(); + Bukkit.getPluginManager().registerEvents(new CitizensNPCListener(this), getHooked()); + } + + @Override + public void unregister() { + super.unregister(); + // TODO + } + @Override public boolean isEnabled() { return getHooked() != null && getHooked().isEnabled(); @@ -58,7 +71,7 @@ public void removeNPC(UUID uniqueId) { NPC npc = getNPC(uniqueId); if (npc != null) { - npc.destroy(); + npc.remove(); } } @@ -70,7 +83,7 @@ public boolean supports(Feature feature) { @Override public CitizensPlugin getHooked() { if(hooked == null) { - hooked = (CitizensPlugin) Bukkit.getPluginManager().getPlugin("Citizens"); + hooked = (CitizensPlugin) Bukkit.getPluginManager().getPlugin(getName()); ensureRegistries(); } diff --git a/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/WrappedNPC.java b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/WrappedNPC.java index 8152667..7294f6b 100644 --- a/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/WrappedNPC.java +++ b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/WrappedNPC.java @@ -1,15 +1,20 @@ package de.minebench.tresor.providers.citizens; import de.minebench.tresor.services.npc.NPC; -import de.minebench.tresor.services.npc.NPCMetadata; -import de.minebench.tresor.services.npc.skin.NPCSkinData; +import de.minebench.tresor.services.npc.data.Interaction; +import de.minebench.tresor.services.npc.data.NPCMetadata; +import de.minebench.tresor.services.npc.data.NPCSkinData; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; +import java.util.function.Consumer; import net.citizensnpcs.trait.SkinTrait; import org.bukkit.Location; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; public class WrappedNPC implements NPC { + private final List> interactActions = new ArrayList<>(); private final net.citizensnpcs.api.npc.NPC npc; private final boolean persistent; @@ -66,7 +71,18 @@ public void teleport(Location location) { } @Override - public void destroy() { + public void onInteract(Consumer action) { + interactActions.add(action); + } + + @Override + public void remove() { npc.destroy(); } + + public void handleInteraction(Interaction interaction) { // I don't think this should be exposed + for (Consumer action : interactActions) { + action.accept(interaction); + } + } } diff --git a/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/listener/CitizensNPCListener.java b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/listener/CitizensNPCListener.java new file mode 100644 index 0000000..ac1f982 --- /dev/null +++ b/providers/citizens/src/main/java/de/minebench/tresor/providers/citizens/listener/CitizensNPCListener.java @@ -0,0 +1,50 @@ +package de.minebench.tresor.providers.citizens.listener; + +import de.minebench.tresor.providers.citizens.CitizensNPCs; +import de.minebench.tresor.providers.citizens.WrappedNPC; +import de.minebench.tresor.services.npc.data.Interaction; +import de.minebench.tresor.services.npc.data.Interaction.Type; +import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCRightClickEvent; +import net.citizensnpcs.api.npc.NPC; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; + +public class CitizensNPCListener implements Listener { + + private final CitizensNPCs citizensNPCs; + + public CitizensNPCListener(CitizensNPCs citizensNPCs) { + this.citizensNPCs = citizensNPCs; + } + + @EventHandler + public void onLeftClick(NPCLeftClickEvent event) { + handleInteraction(event.getClicker(), event.getNPC(), Type.LEFT_CLICK); + } + + @EventHandler + public void onRightClick(NPCRightClickEvent event) { + handleInteraction(event.getClicker(), event.getNPC(), Type.RIGHT_CLICK); + } + + private void handleInteraction(Player player, NPC citizensNPC, Type interactionType) { + ItemStack item = player.getInventory().getItemInMainHand(); + de.minebench.tresor.services.npc.NPC wrappedNPC = citizensNPCs.getNPC(citizensNPC.getUniqueId()); + + if(!(wrappedNPC instanceof WrappedNPC)) { // Doubles as a null check + return; + } + + WrappedNPC wrappedCitizensNPC = (WrappedNPC) wrappedNPC; + Interaction interaction = new Interaction(player, interactionType, item); + wrappedCitizensNPC.handleInteraction(interaction); + + } + + + + +}