From 66a77bd59a1ef312d007f2aa7f239d6df40405f0 Mon Sep 17 00:00:00 2001 From: hdvt Date: Tue, 15 Jul 2025 16:36:46 +0300 Subject: [PATCH] some improvments, bugs and bugfixed ) --- .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .../hdvtdev/blockAndSeek/BlockAndSeek.java | 2 +- .../blockAndSeek/BlockAndSeekGame.java | 57 +++++---- .../hdvtdev/blockAndSeek/CommandListener.java | 29 +++-- src/main/java/hdvtdev/blockAndSeek/Keys.java | 1 + src/main/java/hdvtdev/blockAndSeek/Utils.java | 11 +- .../eventListeners/DefaultEventListener.java | 40 ++++--- .../ForceControlEventListener.java | 10 +- .../blockAndSeek/managers/GamesManager.java | 10 +- .../blockAndSeek/managers/ItemManager.java | 10 ++ .../{FreezeManager.java => PropManager.java} | 32 ++++- .../blockAndSeek/managers/WorldManager.java | 113 ++++++++++++++++++ .../roulette/RouletteCreator.java | 37 +++--- 13 files changed, 272 insertions(+), 80 deletions(-) rename src/main/java/hdvtdev/blockAndSeek/managers/{FreezeManager.java => PropManager.java} (79%) create mode 100644 src/main/java/hdvtdev/blockAndSeek/managers/WorldManager.java diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index b657368383e40b23266403c44d9ffefb5b5c1716..b4911b7cea05239fff644153733695f1d185bd69 100644 GIT binary patch literal 17 VcmZQhY`Gk`{>!NV1~AY#0RTKR1-bwL literal 17 VcmZQhY`Gk`{>!NV1~5=>002Ab1#tiX diff --git a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java index 54478eb..01e97ac 100644 --- a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java +++ b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java @@ -74,11 +74,11 @@ public class BlockAndSeek extends JavaPlugin { manager.registerEvents(ConfigManager.getConfig().forceControl() ? new ForceControlEventListener() : new EventListener(), this); manager.registerEvents(new DefaultEventListener(), this); + } @Override public void onDisable() { - } } diff --git a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java index 227b703..071e9c9 100644 --- a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java +++ b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java @@ -1,9 +1,9 @@ package hdvtdev.blockAndSeek; import hdvtdev.blockAndSeek.managers.ConfigManager; -import hdvtdev.blockAndSeek.managers.FreezeManager; import hdvtdev.blockAndSeek.managers.GamesManager; import hdvtdev.blockAndSeek.managers.ItemManager; +import hdvtdev.blockAndSeek.managers.PropManager; import hdvtdev.blockAndSeek.roulette.RouletteCreator; import me.libraryaddict.disguise.DisguiseAPI; import org.bukkit.*; @@ -16,13 +16,13 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; public class BlockAndSeekGame { - private final ConcurrentHashMap players = new ConcurrentHashMap<>(); + private final Map players = new ConcurrentHashMap<>(); + private final Map hiderRoulette = new HashMap<>(); - private final AtomicBoolean started = new AtomicBoolean(false); + private volatile boolean started = false; private final BlockAndSeekMap map; private final Location lobby; private final Location spawn; @@ -45,12 +45,16 @@ public class BlockAndSeekGame { return players.size(); } + public boolean isStarted() { + return started; + } + public int maxPlayers() { return map.getMaxPlayers(); } public boolean addPlayer(Player player) { - if (!started.get()) { + if (!started) { players.put(player, PlayerType.HIDER); player.getPersistentDataContainer().set(Keys.GAME, PersistentDataType.STRING, name); player.teleport(lobby); @@ -88,7 +92,7 @@ public class BlockAndSeekGame { true, "player-leave", "{player}", player.getName(), - "{players}", started.get() ? "" : players.size() + "/" + map.getMaxPlayers() + "{players}", started ? "" : players.size() + "/" + map.getMaxPlayers() ); } @@ -127,7 +131,7 @@ public class BlockAndSeekGame { } private void start() { - started.set(true); + started = true; selectRandomSeekers((int) Math.round(players.size() * 0.25)); List hiders = getHiders(); for (Player hider : hiders) { @@ -137,26 +141,27 @@ public class BlockAndSeekGame { PlayerInventory inventory = hider.getInventory(); inventory.clear(); inventory.addItem(Localization.translateItem(hider, ItemManager.getFreezeItem())); - new RouletteCreator(hider, map.getBlocks()); + inventory.addItem(Localization.translateItem(hider, ItemManager.getFaceChangingItem())); + hiderRoulette.put(hider, new RouletteCreator(hider, map.getBlocks())); } } private void end(boolean force) { GamesManager.remove(name); if (!force) { - Location serverLobby = ConfigManager.getConfig().defaultSpawn(); - boolean defaultInventory = ConfigManager.getConfig().forceControl(); + Config config = ConfigManager.getConfig(); + Location serverLobby = config.defaultSpawn(); + boolean defaultInventory = config.forceControl(); for (Player player : players.keySet()) { - PersistentDataContainer container = player.getPersistentDataContainer(); - container.remove(Keys.HIDER); - container.remove(Keys.SEEKER); - container.remove(Keys.GAME); + + DisguiseAPI.undisguiseToAll(player); if (defaultInventory) ItemManager.defaultInventory(player); player.setGlowing(false); player.setInvulnerable(false); Utils.setLevelWithBar(player, 0); player.setVisibleByDefault(true); + player.setHealth(20); player.setGameMode(GameMode.SURVIVAL); player.teleport(serverLobby); @@ -166,16 +171,23 @@ public class BlockAndSeekGame { private void preEnd() { for (Player player : players.keySet()) { + PersistentDataContainer container = player.getPersistentDataContainer(); player.setInvulnerable(true); + container.remove(Keys.HIDER); + container.remove(Keys.SEEKER); + container.remove(Keys.GAME); } for (Player hider : getHiders()) { hider.getInventory().clear(); - FreezeManager.unfreezeIfFrozen(hider); + PropManager.unfreezeIfFrozen(hider); hider.setGlowing(true); + RouletteCreator rouletteCreator = hiderRoulette.get(hider); + rouletteCreator.getTask().cancelBoth(); + rouletteCreator.closeInventory(); } } - public void selectRandomSeekers(int count) { + private void selectRandomSeekers(int count) { ArrayList rawSeekers = new ArrayList<>(); Set playerSet = players.keySet(); for (Player player : playerSet) { @@ -224,11 +236,15 @@ public class BlockAndSeekGame { waitTime = defaultWaitTime; } } else { - if (!started.get()) { + if (!started) { start(); } else { - if (players.isEmpty()) end(false); + if (players.isEmpty()) { + end(false); + this.cancel(); + return; + } if (duration > 0 && getHidersCount() == 0) { Localization.sendTitle( @@ -236,6 +252,7 @@ public class BlockAndSeekGame { false, "seekers-won" ); + preEnd(); duration = -1; } @@ -245,7 +262,7 @@ public class BlockAndSeekGame { } } - if (getSeekersCount() == 0) duration = 0; + if (duration > 0 && getSeekersCount() == 0) duration = 0; if (duration == 0) { @@ -274,8 +291,8 @@ public class BlockAndSeekGame { ); duration--; } else if (duration == -10) { - this.cancel(); end(false); + this.cancel(); } else { duration--; } diff --git a/src/main/java/hdvtdev/blockAndSeek/CommandListener.java b/src/main/java/hdvtdev/blockAndSeek/CommandListener.java index 33edc39..82c565f 100644 --- a/src/main/java/hdvtdev/blockAndSeek/CommandListener.java +++ b/src/main/java/hdvtdev/blockAndSeek/CommandListener.java @@ -20,6 +20,7 @@ import org.bukkit.command.TabExecutor; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,15 +46,12 @@ public class CommandListener implements TabExecutor { switch (args[0]) { case "test" -> { - switch (GamesManager.createGame("dust2")) { - case 1 -> { - sender.sendMessage("Game already exist"); - GamesManager.get("dust2").addPlayer((Player) sender); - } - case 2 -> sender.sendMessage("Could not find world"); - default -> GamesManager.get("dust2").addPlayer((Player) sender); + if (sender instanceof Player player) { + GamesManager.createGame("dust2"); + GamesManager.get("dust2").addPlayer(player); } + } case "locale" -> { if (sender instanceof Player player) { @@ -72,7 +70,7 @@ public class CommandListener implements TabExecutor { if (sender instanceof Player player && args.length == 2) { Material material = Material.valueOf(args[1].toUpperCase()); - FreezeManager.addPlayerDisguise(player, material.createBlockData()); + PropManager.addPlayerDisguise(player, material.createBlockData()); DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, new ItemStack(material))); } } @@ -115,9 +113,16 @@ public class CommandListener implements TabExecutor { player.getInventory().addItem(foo); } } + case "bbb" -> { + if (sender instanceof Player player) { + PropManager.changePropDirection(player); + } + } case "container" -> { if (sender instanceof Player player) { - player.sendMessage(String.valueOf(player.getPersistentDataContainer().has(Keys.GAME))); + var container = player.getPersistentDataContainer(); + player.sendMessage("containers: " + container.getKeys()); + } } case "def" -> { @@ -130,8 +135,12 @@ public class CommandListener implements TabExecutor { player.clearActivePotionEffects(); player.setHealth(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getDefaultValue()); player.setFoodLevel(20); + Utils.setLevelWithBar(player, 0); DisguiseAPI.undisguiseToAll(player); - + PersistentDataContainer dataContainer = player.getPersistentDataContainer(); + for (var key : dataContainer.getKeys()) { + dataContainer.remove(key); + } } } case "map" -> { diff --git a/src/main/java/hdvtdev/blockAndSeek/Keys.java b/src/main/java/hdvtdev/blockAndSeek/Keys.java index 11aa27e..2803800 100644 --- a/src/main/java/hdvtdev/blockAndSeek/Keys.java +++ b/src/main/java/hdvtdev/blockAndSeek/Keys.java @@ -9,6 +9,7 @@ public class Keys { public static final NamespacedKey SOUND_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekSoundItem"); public static final NamespacedKey FREEZE_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekFreezeItem"); + public static final NamespacedKey FACE_CHANGING_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekFaceChangingItem"); public static final NamespacedKey MENU_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekMenuItem"); public static final NamespacedKey LEAVE_ITEM = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekLeaveItem"); public static final NamespacedKey GAME_PAGE = new NamespacedKey(BlockAndSeek.getInstance(), "BlockAndSeekGamePage"); diff --git a/src/main/java/hdvtdev/blockAndSeek/Utils.java b/src/main/java/hdvtdev/blockAndSeek/Utils.java index 91319ba..1e84563 100644 --- a/src/main/java/hdvtdev/blockAndSeek/Utils.java +++ b/src/main/java/hdvtdev/blockAndSeek/Utils.java @@ -1,11 +1,12 @@ package hdvtdev.blockAndSeek; -import hdvtdev.blockAndSeek.managers.FreezeManager; +import hdvtdev.blockAndSeek.managers.PropManager; import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.MiscDisguise; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; public final class Utils { @@ -29,7 +30,13 @@ public final class Utils { public static void firstDisguise(Player player, ItemStack prop) { DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, prop)); - FreezeManager.addPlayerDisguise(player, prop.getType().createBlockData()); + PropManager.addPlayerDisguise(player, prop.getType().createBlockData()); + } + + public static boolean hasPermsToDamage(Player p1, Player p2) { + PersistentDataContainer c1 = p1.getPersistentDataContainer(); + PersistentDataContainer c2 = p2.getPersistentDataContainer(); + return (c1.has(Keys.SEEKER) || c1.has(Keys.HIDER)) && (c2.has(Keys.SEEKER) || c2.has(Keys.HIDER)); } } diff --git a/src/main/java/hdvtdev/blockAndSeek/eventListeners/DefaultEventListener.java b/src/main/java/hdvtdev/blockAndSeek/eventListeners/DefaultEventListener.java index df9d59f..4ee9152 100644 --- a/src/main/java/hdvtdev/blockAndSeek/eventListeners/DefaultEventListener.java +++ b/src/main/java/hdvtdev/blockAndSeek/eventListeners/DefaultEventListener.java @@ -3,9 +3,9 @@ package hdvtdev.blockAndSeek.eventListeners; import hdvtdev.blockAndSeek.BlockAndSeek; import hdvtdev.blockAndSeek.Keys; import hdvtdev.blockAndSeek.Utils; -import hdvtdev.blockAndSeek.managers.FreezeManager; import hdvtdev.blockAndSeek.managers.GamesManager; import hdvtdev.blockAndSeek.managers.GuiManager; +import hdvtdev.blockAndSeek.managers.PropManager; import hdvtdev.blockAndSeek.roulette.RouletteCreator; import org.bukkit.Bukkit; import org.bukkit.entity.ArmorStand; @@ -75,7 +75,7 @@ public class DefaultEventListener implements Listener { public void onBlockDamage(BlockDamageEvent event) { Player player = event.getPlayer(); if (player.getPersistentDataContainer().has(Keys.SEEKER)) { - if (FreezeManager.unfreeze(event.getBlock().getBlockData())) { + if (PropManager.unfreeze(event.getBlock().getBlockData())) { event.setCancelled(true); } else { player.damage(2); @@ -100,7 +100,7 @@ public class DefaultEventListener implements Listener { if (itemData.has(Keys.FREEZE_ITEM) && playerInGame(player)) { coolDown.add(player); scheduler.runTaskLater(BlockAndSeek.getInstance(), () -> coolDown.remove(player), 3L); - FreezeManager.freeze(player); + PropManager.freeze(player); event.setCancelled(true); } else if (itemData.has(Keys.MENU_ITEM)) { GuiManager.Menu.open(player); @@ -109,6 +109,9 @@ public class DefaultEventListener implements Listener { String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING); GamesManager.get(game).removePlayer(player); event.setCancelled(true); + } else if (itemData.has(Keys.FACE_CHANGING_ITEM)) { + PropManager.changePropDirection(player); + event.setCancelled(true); } } @@ -121,7 +124,7 @@ public class DefaultEventListener implements Listener { public void onEntityDismount(EntityDismountEvent event) { Player player = (Player) event.getEntity(); if (event.getDismounted() instanceof ArmorStand armorStand && armorStand.getPersistentDataContainer().has(Keys.FROZEN_PLAYER)) { - FreezeManager.freeze(player); + PropManager.freeze(player); } } @@ -133,7 +136,7 @@ public class DefaultEventListener implements Listener { String arena = container.get(Keys.GAME, PersistentDataType.STRING); if (arena != null) { GamesManager.get(arena).removePlayer(player); - FreezeManager.removePlayerDisguise(player); + PropManager.removePlayerDisguise(player); } } @@ -158,15 +161,20 @@ public class DefaultEventListener implements Listener { if (holder instanceof RouletteCreator rouletteCreator) { - if (rouletteCreator.isClosedByPlayer()) { + + Boolean isClosedByPlayer = rouletteCreator.isClosedByPlayer(); + + if (isClosedByPlayer != null) { RouletteCreator.Task task = rouletteCreator.getTask(); - - if (!task.rouletteTask().isCancelled()) { + if (isClosedByPlayer) { + if (!task.rouletteTask().isCancelled()) { + Utils.firstDisguise(player, rouletteCreator.randomPropItem()); + } else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem()); task.cancelBoth(); - Utils.firstDisguise(player, rouletteCreator.randomPropItem()); - } else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem()); //FIXME THIS FUCKING LINE AAAA + } else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem()); + } + - } else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem()); } @@ -191,13 +199,13 @@ public class DefaultEventListener implements Listener { if (slot == 21 || slot == 23 || slot == 25) { task.autoCloseTask().cancel(); Utils.firstDisguise(player, inventory.getItem(slot)); - rouletteCreator.closeInventoryByPlayer(); + rouletteCreator.closeInventory(); } event.setCancelled(true); return; } else { if (slot == 36) { - task.rouletteTask().cancel(); + task.cancelBoth(); Utils.firstDisguise(player, rouletteCreator.randomPropItem()); rouletteCreator.closeInventory(); event.setCancelled(true); @@ -240,13 +248,15 @@ public class DefaultEventListener implements Listener { @EventHandler public void onRegainHealth(EntityRegainHealthEvent event) { if (event.getEntity() instanceof Player player) { - if (player.getPersistentDataContainer().has(Keys.SEEKER)) { + PersistentDataContainer container = player.getPersistentDataContainer(); + if (container.has(Keys.SEEKER)) { event.setCancelled(true); + } else if (container.has(Keys.HIDER)) { + if (!PropManager.isPlayerDisguised(player)) event.setCancelled(true); } } } - @EventHandler public void onPlayerDamage(EntityDamageByEntityEvent event) { if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) { diff --git a/src/main/java/hdvtdev/blockAndSeek/eventListeners/ForceControlEventListener.java b/src/main/java/hdvtdev/blockAndSeek/eventListeners/ForceControlEventListener.java index 8b461a6..bce174d 100644 --- a/src/main/java/hdvtdev/blockAndSeek/eventListeners/ForceControlEventListener.java +++ b/src/main/java/hdvtdev/blockAndSeek/eventListeners/ForceControlEventListener.java @@ -1,6 +1,6 @@ package hdvtdev.blockAndSeek.eventListeners; -import hdvtdev.blockAndSeek.Keys; +import hdvtdev.blockAndSeek.Utils; import hdvtdev.blockAndSeek.managers.ItemManager; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -13,15 +13,9 @@ import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.weather.WeatherChangeEvent; import org.bukkit.event.world.TimeSkipEvent; -import org.bukkit.persistence.PersistentDataContainer; public class ForceControlEventListener implements Listener { - private static boolean hasPermsToDamage(Player p1, Player p2) { - PersistentDataContainer c1 = p1.getPersistentDataContainer(); - PersistentDataContainer c2 = p2.getPersistentDataContainer(); - return (c1.has(Keys.SEEKER) || c1.has(Keys.HIDER)) && (c2.has(Keys.SEEKER) || c2.has(Keys.HIDER)); - } @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { @@ -65,7 +59,7 @@ public class ForceControlEventListener implements Listener { @EventHandler public void onPlayerDamage(EntityDamageByEntityEvent event) { if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) { - if (!hasPermsToDamage(damager, victim)) { + if (!Utils.hasPermsToDamage(damager, victim)) { event.setCancelled(true); } } diff --git a/src/main/java/hdvtdev/blockAndSeek/managers/GamesManager.java b/src/main/java/hdvtdev/blockAndSeek/managers/GamesManager.java index 2ce45a7..970f6fd 100644 --- a/src/main/java/hdvtdev/blockAndSeek/managers/GamesManager.java +++ b/src/main/java/hdvtdev/blockAndSeek/managers/GamesManager.java @@ -6,6 +6,7 @@ import hdvtdev.blockAndSeek.BlockAndSeekMap; import org.bukkit.Bukkit; import org.bukkit.WorldCreator; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.Set; @@ -28,20 +29,20 @@ public class GamesManager { return games.keySet(); } - public static int createGame(String name) { - if (games.containsKey(name)) return 1; + public static @Nullable String createGame(String name) { + if (games.containsKey(name)) return name; //TODO use copy or create copy if (Bukkit.getWorld(name) == null) { if (new File(BlockAndSeek.getServerDataFolder(), name).exists()) { Bukkit.createWorld(new WorldCreator(name)); - } else return 2; + } else return null; } BlockAndSeekMap map = MapsManager.getMap(name); BlockAndSeekGame game = new BlockAndSeekGame(name, map); games.put(name, game); - return 0; + return null; } public static void remove(String name) { @@ -52,4 +53,5 @@ public class GamesManager { return games.get(name); } + } diff --git a/src/main/java/hdvtdev/blockAndSeek/managers/ItemManager.java b/src/main/java/hdvtdev/blockAndSeek/managers/ItemManager.java index 2fb6783..375433c 100644 --- a/src/main/java/hdvtdev/blockAndSeek/managers/ItemManager.java +++ b/src/main/java/hdvtdev/blockAndSeek/managers/ItemManager.java @@ -17,6 +17,7 @@ import org.bukkit.persistence.PersistentDataType; public class ItemManager { private static final ItemStack freezeItem = new ItemStack(Material.HEART_OF_THE_SEA); + private static final ItemStack faceChangingItem = new ItemStack(Material.NETHER_STAR); private static final ItemStack seekerSword = new ItemStack(Material.WOODEN_SWORD); private static final ItemStack seekerHelmet = new ItemStack(Material.LEATHER_HELMET); @@ -37,6 +38,11 @@ public class ItemManager { freezeMeta.getPersistentDataContainer().set(Keys.FREEZE_ITEM, PersistentDataType.BOOLEAN, true); freezeItem.setItemMeta(freezeMeta); + ItemMeta faceChangingMeta = faceChangingItem.getItemMeta(); + faceChangingMeta.displayName(Component.text("face-changing-item")); + faceChangingMeta.getPersistentDataContainer().set(Keys.FACE_CHANGING_ITEM, PersistentDataType.BOOLEAN, true); + faceChangingItem.setItemMeta(faceChangingMeta); + ItemMeta swordMeta = seekerSword.getItemMeta(); swordMeta.displayName(Component.text("seeker-sword")); swordMeta.addEnchant(Enchantment.DAMAGE_ALL, 2, false); @@ -106,6 +112,10 @@ public class ItemManager { inventory.addItem(Localization.translateItem(player, menuItem)); } + public static ItemStack getFaceChangingItem() { + return faceChangingItem; + } + public static ItemStack getLeaveItem() { return leaveItem; } diff --git a/src/main/java/hdvtdev/blockAndSeek/managers/FreezeManager.java b/src/main/java/hdvtdev/blockAndSeek/managers/PropManager.java similarity index 79% rename from src/main/java/hdvtdev/blockAndSeek/managers/FreezeManager.java rename to src/main/java/hdvtdev/blockAndSeek/managers/PropManager.java index 3302709..165a781 100644 --- a/src/main/java/hdvtdev/blockAndSeek/managers/FreezeManager.java +++ b/src/main/java/hdvtdev/blockAndSeek/managers/PropManager.java @@ -7,7 +7,9 @@ import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.MiscDisguise; import org.bukkit.Location; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Player; import org.bukkit.persistence.PersistentDataType; @@ -16,7 +18,7 @@ import org.bukkit.util.Vector; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -public class FreezeManager { +public class PropManager { private static final Map frozenPlayers = new ConcurrentHashMap<>(); private static final Map playerDisguise = new ConcurrentHashMap<>(); @@ -25,6 +27,10 @@ public class FreezeManager { private static final Disguise hideDisguise = new MiscDisguise(DisguiseType.LLAMA_SPIT); private static final Vector zeroVelocity = new Vector(0, 0, 0); + public static boolean isPlayerDisguised(Player player) { + return frozenPlayers.containsKey(player); + } + public static void addPlayerDisguise(Player player, BlockData blockData) { disguisePlayer.put(blockData, player); playerDisguise.put(player, blockData); @@ -34,6 +40,30 @@ public class FreezeManager { disguisePlayer.remove(playerDisguise.remove(player)); } + public static void changePropDirection(Player player) { + + if (frozenPlayers.containsKey(player)) { + Block block = player.getLocation().getBlock(); + BlockData blockData = block.getBlockData(); + if (blockData instanceof Directional directional) { + + BlockFace face = switch (directional.getFacing()) { + case NORTH -> BlockFace.EAST; + case EAST -> BlockFace.SOUTH; + case SOUTH -> BlockFace.WEST; + case WEST -> directional.getFaces().contains(BlockFace.UP) ? BlockFace.UP : BlockFace.NORTH; + case UP -> BlockFace.DOWN; + case DOWN -> BlockFace.NORTH; + default -> null; + }; + if (face != null && directional.getFaces().contains(face)) { + directional.setFacing(face); + block.setBlockData(blockData); + } + } + } + } + public static void unfreezeIfFrozen(Player player) { Location location = player.getLocation(); FreezeData data = frozenPlayers.remove(player); diff --git a/src/main/java/hdvtdev/blockAndSeek/managers/WorldManager.java b/src/main/java/hdvtdev/blockAndSeek/managers/WorldManager.java new file mode 100644 index 0000000..5194145 --- /dev/null +++ b/src/main/java/hdvtdev/blockAndSeek/managers/WorldManager.java @@ -0,0 +1,113 @@ +package hdvtdev.blockAndSeek.managers; + + +import hdvtdev.blockAndSeek.BlockAndSeek; +import io.papermc.paper.threadedregions.scheduler.AsyncScheduler; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.WorldCreator; +import org.bukkit.scheduler.BukkitRunnable; +import org.codehaus.plexus.util.FileUtils; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; + + +@ApiStatus.Experimental +public final class WorldManager { + + private static final File serverFolder = BlockAndSeek.getServerDataFolder(); + + private static final AsyncScheduler asyncScheduler = Bukkit.getAsyncScheduler(); + + private static final ConcurrentHashMap worldManagers = new ConcurrentHashMap<>(); + + static { + //TODO + } + + + private final File originalWorld; + + private final ConcurrentLinkedQueue freeCopies = new ConcurrentLinkedQueue<>(); + private final AtomicInteger copyIndex = new AtomicInteger(1); + private final int reservedCopies; + + private WorldManager(String worldName, int reservedCopies) { + this.originalWorld = new File(serverFolder, worldName + "_copy"); + this.reservedCopies = reservedCopies; + + new BukkitRunnable() { + + boolean unloading = false; + + @Override + public void run() { + if (!Bukkit.isTickingWorlds() && !unloading) { + unloading = true; + Bukkit.unloadWorld(worldName, true); + asyncScheduler.runNow(BlockAndSeek.getInstance(), task -> { + try { + FileUtils.copyDirectoryStructure(new File(serverFolder, worldName), originalWorld); + createCopy(); + } catch (IOException e) { + BlockAndSeek.getPluginLogger().severe("Failed to copy world \"" + worldName + "\": " + e.getMessage()); + this.cancel(); + } + }); + this.cancel(); + } + } + }.runTaskTimer(BlockAndSeek.getInstance(), 0, 1); + + + } + + public static void createWorldManager(String existingWorld, int reservedCopies) { + worldManagers.put(existingWorld, new WorldManager(existingWorld, reservedCopies)); + } + + public static @Nullable WorldManager get(String worldName) { + return worldManagers.get(worldName); + } + + + /** + * @return {@link World} if a free copy is available or a new one has been created. + * Returns {@code null} if there are currently no free copies and a new copy is still being created. + */ + public @Nullable World acquire() { + if (freeCopies.size() <= 1) { + createCopy(); //TODO + } + return freeCopies.poll(); + } + + public void release() { + + } + + + private void createCopy() { + String worldName = originalWorld.getName() + copyIndex.incrementAndGet(); + try { + File worldCopy = new File(serverFolder, worldName); + if (!worldCopy.exists()) copyDirectoryToDirectory(originalWorld, worldCopy); + freeCopies.add(Bukkit.createWorld(WorldCreator.name(worldName))); + } catch (IOException e) { + BlockAndSeek.getPluginLogger().severe("Failed to copy world \"" + worldName + "\": " + e.getMessage()); + } + } + + private static void copyDirectoryToDirectory(File source, File destination) throws IOException { + File finalDestination = new File(destination, source.getName()); + finalDestination.mkdirs(); + FileUtils.copyDirectory(source, finalDestination); + } + +} diff --git a/src/main/java/hdvtdev/blockAndSeek/roulette/RouletteCreator.java b/src/main/java/hdvtdev/blockAndSeek/roulette/RouletteCreator.java index ee88f4c..f8fa4d6 100644 --- a/src/main/java/hdvtdev/blockAndSeek/roulette/RouletteCreator.java +++ b/src/main/java/hdvtdev/blockAndSeek/roulette/RouletteCreator.java @@ -13,6 +13,7 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -27,7 +28,7 @@ public final class RouletteCreator implements InventoryHolder { private final Inventory roulette; private Task task; - private volatile boolean closedByPlayer = true; + private volatile Boolean closedByPlayer = true; public RouletteCreator(@NotNull Player player, List blocks) { roulette = Bukkit.createInventory(this, 45, Localization.getComponent(player, "roulette-title")); @@ -38,7 +39,7 @@ public final class RouletteCreator implements InventoryHolder { return task; } - public boolean isClosedByPlayer() { + public @Nullable Boolean isClosedByPlayer() { return closedByPlayer; } @@ -47,13 +48,13 @@ public final class RouletteCreator implements InventoryHolder { return roulette; } - public void closeInventory() { + public void closeInventoryBySystem() { closedByPlayer = false; roulette.close(); } - public void closeInventoryByPlayer() { - closedByPlayer = true; + public void closeInventory() { + closedByPlayer = null; roulette.close(); } @@ -104,23 +105,21 @@ public final class RouletteCreator implements InventoryHolder { long now = System.currentTimeMillis(); double elapsed = (now - startTime) / 1000.0; - if (elapsed >= 9.5) { + if (elapsed >= 5) { this.cancel(); } double speed; - if (elapsed < 3.0) speed = 1.0; - else if (elapsed < 3.5) speed = 0.8; - else if (elapsed < 4.0) speed = 0.6; - else if (elapsed < 4.5) speed = 0.5; - else if (elapsed < 5.0) speed = 0.4; - else if (elapsed < 5.5) speed = 0.33; - else if (elapsed < 6.0) speed = 0.28; - else if (elapsed < 6.5) speed = 0.25; - else if (elapsed < 7.0) speed = 0.22; - else if (elapsed < 7.5) speed = 0.2; - else if (elapsed < 8.0) speed = 0.12; - else speed = 0.05; + if (elapsed < 2) speed = 1.0; + else if (elapsed < 2.2) speed = 0.8; + else if (elapsed < 2.4) speed = 0.6; + else if (elapsed < 2.6) speed = 0.5; + else if (elapsed < 2.8) speed = 0.4; + else if (elapsed < 3) speed = 0.33; + else if (elapsed < 3.2) speed = 0.28; + else if (elapsed < 3.5) speed = 0.22; + else if (elapsed < 3.8) speed = 0.15; + else speed = 0.1; task(speed); @@ -154,7 +153,7 @@ public final class RouletteCreator implements InventoryHolder { }.runTaskTimer(BlockAndSeek.getInstance(), 0, 1); - task = new Task(rouletteTask, Bukkit.getScheduler().runTaskLater(BlockAndSeek.getInstance(), this::closeInventory, 300)); + task = new Task(rouletteTask, Bukkit.getScheduler().runTaskLater(BlockAndSeek.getInstance(), this::closeInventoryBySystem, 300)); player.openInventory(gui); }