From 37dee3e5a43f05865525d7fc4dc7e5a8996f837c Mon Sep 17 00:00:00 2001 From: Logan Date: Sun, 21 Dec 2025 19:27:40 -0600 Subject: [PATCH] feat: add ability to choose search engine for players --- .../hmccosmetics/HMCCosmeticsPlugin.java | 10 +++--- .../hmccosmetics/config/Settings.java | 5 +++ .../util/search/BukkitPlayerSearchEngine.java | 23 ++++++++++++ .../OctreePlayerSearchEngine.java} | 28 ++++++++------- .../util/search/PlayerSearchEngine.java | 24 +++++++++++++ .../util/search/PlayerSearchManager.java | 36 +++++++++++++++++++ common/src/main/resources/config.yml | 4 +++ 7 files changed, 113 insertions(+), 17 deletions(-) create mode 100644 common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/BukkitPlayerSearchEngine.java rename common/src/main/java/com/hibiscusmc/hmccosmetics/util/{PlayerSearchManager.java => search/OctreePlayerSearchEngine.java} (84%) create mode 100644 common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/PlayerSearchEngine.java create mode 100644 common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/PlayerSearchManager.java diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java index 0f0adda9..e759267b 100644 --- a/common/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/HMCCosmeticsPlugin.java @@ -22,7 +22,7 @@ import com.hibiscusmc.hmccosmetics.listener.*; import com.hibiscusmc.hmccosmetics.packets.CosmeticPacketInterface; import com.hibiscusmc.hmccosmetics.user.CosmeticUser; import com.hibiscusmc.hmccosmetics.user.CosmeticUsers; -import com.hibiscusmc.hmccosmetics.util.PlayerSearchManager; +import com.hibiscusmc.hmccosmetics.util.search.PlayerSearchManager; import com.hibiscusmc.hmccosmetics.util.MessagesUtil; import com.hibiscusmc.hmccosmetics.util.TranslationUtil; import lombok.Getter; @@ -64,9 +64,6 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin { // Plugin startup logic instance = this; - // Search Service - this.playerSearchManager = new PlayerSearchManager(this); - // File setup saveDefaultConfig(); if (!Path.of(getDataFolder().getPath(), "messages.yml").toFile().exists()) saveResource("messages.yml", false); @@ -99,6 +96,9 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin { setup(); setPacketInterface(new CosmeticPacketInterface()); + // Search Service + this.playerSearchManager = new PlayerSearchManager(Settings.getEngine(), this); + // Commands getServer().getPluginCommand("cosmetic").setExecutor(new CosmeticCommand()); getServer().getPluginCommand("cosmetic").setTabCompleter(new CosmeticCommandTabComplete()); @@ -108,7 +108,7 @@ public final class HMCCosmeticsPlugin extends HibiscusPlugin { getServer().getPluginManager().registerEvents(new PlayerGameListener(), this); getServer().getPluginManager().registerEvents(new ServerListener(), this); getServer().getPluginManager().registerEvents(new PlayerMovementListener(), this); - getServer().getPluginManager().registerEvents(playerSearchManager, this); + getServer().getPluginManager().registerEvents(this.playerSearchManager.getEngine(), this); if (HibiscusCommonsPlugin.isOnPaper()) { getServer().getPluginManager().registerEvents(new PaperPlayerGameListener(), this); diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/config/Settings.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/config/Settings.java index e8814a34..e5d1c413 100644 --- a/common/src/main/java/com/hibiscusmc/hmccosmetics/config/Settings.java +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/config/Settings.java @@ -2,6 +2,7 @@ package com.hibiscusmc.hmccosmetics.config; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; import com.hibiscusmc.hmccosmetics.util.MessagesUtil; +import com.hibiscusmc.hmccosmetics.util.search.PlayerSearchManager; import lombok.Getter; import lombok.Setter; import me.lojosho.shaded.configurate.ConfigurationNode; @@ -68,6 +69,7 @@ public class Settings { private static final String BACKPACK_PREVENT_DARKNESS_PATH = "backpack-prevent-darkness"; private static final String BETTER_HUD_PATH = "betterhud"; private static final String BETTER_HUD_HIDE_IN_WARDROBE_PATH = "wardrobe-hide"; + private static final String PLAYER_SEARCH_IMPLEMENTATION = "player-search-implmentation"; @Getter private static String defaultMenu; @@ -152,6 +154,8 @@ public class Settings { private static boolean allPlayersHidden; @Getter private static boolean wardrobeHideHud; + @Getter + private static PlayerSearchManager.SearchEngine engine; public static void load(ConfigurationNode source) { @@ -204,6 +208,7 @@ public class Settings { }); tickPeriod = cosmeticSettings.node(TICK_PERIOD_PATH).getInt(-1); + engine = PlayerSearchManager.SearchEngine.valueOf(cosmeticSettings.node(PLAYER_SEARCH_IMPLEMENTATION).getString("BUKKIT").toUpperCase()); viewDistance = cosmeticSettings.node(VIEW_DISTANCE_PATH).getInt(-3); balloonHeadForward = cosmeticSettings.node(COSMETIC_BALLOON_HEAD_FORWARD_PATH).getBoolean(false); backpackPreventDarkness = cosmeticSettings.node(BACKPACK_PREVENT_DARKNESS_PATH).getBoolean(true); diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/BukkitPlayerSearchEngine.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/BukkitPlayerSearchEngine.java new file mode 100644 index 00000000..3e6ebb49 --- /dev/null +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/BukkitPlayerSearchEngine.java @@ -0,0 +1,23 @@ +package com.hibiscusmc.hmccosmetics.util.search; + +import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; +import com.hibiscusmc.hmccosmetics.util.Octree; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class BukkitPlayerSearchEngine extends PlayerSearchEngine { + + public BukkitPlayerSearchEngine(@NotNull HMCCosmeticsPlugin plugin) { + super(plugin); + } + + @Override + public List getPlayersInRange(Location location, double range) { + return location.getNearbyPlayers(range).stream().toList(); + } +} diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/util/PlayerSearchManager.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/OctreePlayerSearchEngine.java similarity index 84% rename from common/src/main/java/com/hibiscusmc/hmccosmetics/util/PlayerSearchManager.java rename to common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/OctreePlayerSearchEngine.java index 474373d3..96daf4c7 100644 --- a/common/src/main/java/com/hibiscusmc/hmccosmetics/util/PlayerSearchManager.java +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/OctreePlayerSearchEngine.java @@ -1,12 +1,12 @@ -package com.hibiscusmc.hmccosmetics.util; +package com.hibiscusmc.hmccosmetics.util.search; import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; +import com.hibiscusmc.hmccosmetics.util.Octree; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; @@ -15,21 +15,22 @@ import org.jetbrains.annotations.NotNull; import java.util.*; -public class PlayerSearchManager implements Listener { +public class OctreePlayerSearchEngine extends PlayerSearchEngine { + private final Map> worldOctrees = new HashMap<>(); private final Map playerPositions = new HashMap<>(); - //private static final double WORLD_HALF_SIZE = 30_000_000; // Previous built in value - private final double WORLD_HALF_SIZE; + private final int WORLD_HALF_SIZE; - public PlayerSearchManager(@NotNull HMCCosmeticsPlugin plugin) { - WORLD_HALF_SIZE = (double) plugin.getServer().getMaxWorldSize() / 2; + public OctreePlayerSearchEngine(@NotNull HMCCosmeticsPlugin instance) { + super(instance); + WORLD_HALF_SIZE = instance.getServer().getMaxWorldSize(); } private Octree getOrCreateOctree(World world) { return worldOctrees.computeIfAbsent(world.getUID(), $ -> { Octree.BoundingBox worldBoundary = new Octree.BoundingBox( - new Octree.Point3D(0, 160, 0), WORLD_HALF_SIZE + new Octree.Point3D(0, 160, 0), WORLD_HALF_SIZE ); return new Octree<>(worldBoundary); }); @@ -65,6 +66,7 @@ public class PlayerSearchManager implements Listener { addPlayer(player); } + @Override public List getPlayersInRange(Location location, double range) { Octree octree = worldOctrees.get(location.getWorld().getUID()); if (octree == null) return Collections.emptyList(); @@ -73,11 +75,12 @@ public class PlayerSearchManager implements Listener { Octree.BoundingBox searchArea = new Octree.BoundingBox(point, range); return octree.queryRange(searchArea) - .stream() - .filter(Objects::nonNull) - .toList(); + .stream() + .filter(Objects::nonNull) + .toList(); } + public void clear() { worldOctrees.clear(); playerPositions.clear(); @@ -102,4 +105,5 @@ public class PlayerSearchManager implements Listener { public void onPlayerJoin(PlayerJoinEvent event) { addPlayer(event.getPlayer()); } -} \ No newline at end of file + +} diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/PlayerSearchEngine.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/PlayerSearchEngine.java new file mode 100644 index 00000000..4c0f4268 --- /dev/null +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/PlayerSearchEngine.java @@ -0,0 +1,24 @@ +package com.hibiscusmc.hmccosmetics.util.search; + +import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class PlayerSearchEngine implements Listener { + + @Getter + private final HMCCosmeticsPlugin instance; + + public PlayerSearchEngine(@NotNull HMCCosmeticsPlugin plugin) { + this.instance = plugin; + } + + public List getPlayersInRange(Location location, double range) { + return List.of(); + } +} diff --git a/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/PlayerSearchManager.java b/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/PlayerSearchManager.java new file mode 100644 index 00000000..b8904efa --- /dev/null +++ b/common/src/main/java/com/hibiscusmc/hmccosmetics/util/search/PlayerSearchManager.java @@ -0,0 +1,36 @@ +package com.hibiscusmc.hmccosmetics.util.search; + +import com.hibiscusmc.hmccosmetics.HMCCosmeticsPlugin; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class PlayerSearchManager { + + @Getter + private final HMCCosmeticsPlugin plugin; + @Getter + private final PlayerSearchEngine engine; + + public PlayerSearchManager(@NotNull SearchEngine engine, @NotNull HMCCosmeticsPlugin plugin) { + this.plugin = plugin; + + // Choose Octree if set, otherwise just default to Bukkit + switch (engine) { + case OCTREE -> this.engine = new OctreePlayerSearchEngine(plugin); + default -> this.engine = new BukkitPlayerSearchEngine(plugin); + } + } + + public @NotNull List getPlayersInRange(@NotNull Location location, double range) { + return engine.getPlayersInRange(location, range); + } + + public enum SearchEngine { + BUKKIT, + OCTREE + } +} \ No newline at end of file diff --git a/common/src/main/resources/config.yml b/common/src/main/resources/config.yml index 771549da..25405699 100644 --- a/common/src/main/resources/config.yml +++ b/common/src/main/resources/config.yml @@ -24,6 +24,10 @@ cosmetic-settings: # Ticking periods is something that ensures new players near a player get the packets to actually apply to the user. tick-period: 20 + # The engine HMCCosmetics will use to find nearby players. + # Valid Options: BUKKIT, OCTREE + player-search-implmentation: BUKKIT + # If when a player dies, their cosmetics should be unapplied. If this is true, use hmccosmetics.unapplydeath.bypass to bypass unapply-on-death: false # Checks a player permission if they can have a cosmetic when they join the server.