diff --git a/hamster-chain-break/build.gradle b/hamster-chain-break/build.gradle new file mode 100644 index 0000000..b4e77c4 --- /dev/null +++ b/hamster-chain-break/build.gradle @@ -0,0 +1,2 @@ +version = '1.0.0' +setArchivesBaseName("HamsterChainBreak") diff --git a/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/ChainBreakPlugin.java b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/ChainBreakPlugin.java new file mode 100644 index 0000000..3486b58 --- /dev/null +++ b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/ChainBreakPlugin.java @@ -0,0 +1,26 @@ +package cn.hamster3.mc.plugin.chain.breaks; + +import cn.hamster3.mc.plugin.chain.breaks.core.ConfigManager; +import cn.hamster3.mc.plugin.chain.breaks.listener.MainListener; +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +public class ChainBreakPlugin extends JavaPlugin { + private static ChainBreakPlugin instance; + + public static ChainBreakPlugin getInstance() { + return instance; + } + + @Override + public void onLoad() { + instance = this; + ConfigManager.init(); + } + + @Override + public void onEnable() { + Bukkit.getPluginManager().registerEvents(MainListener.INSTANCE, this); + } + +} diff --git a/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/config/ToolGroup.java b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/config/ToolGroup.java new file mode 100644 index 0000000..6f9d2c8 --- /dev/null +++ b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/config/ToolGroup.java @@ -0,0 +1,22 @@ +package cn.hamster3.mc.plugin.chain.breaks.config; + +import lombok.Getter; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +@Getter +public class ToolGroup { + private final String name; + private final List toolTypes; + private final List blockTypes; + private final List skipBlockTypes; + + public ToolGroup(@NotNull ConfigurationSection config) { + name = config.getName(); + toolTypes = config.getStringList("tool-types"); + blockTypes = config.getStringList("block-types"); + skipBlockTypes = config.getStringList("skip-block-types"); + } +} diff --git a/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/core/ConfigManager.java b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/core/ConfigManager.java new file mode 100644 index 0000000..f23bc79 --- /dev/null +++ b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/core/ConfigManager.java @@ -0,0 +1,34 @@ +package cn.hamster3.mc.plugin.chain.breaks.core; + +import cn.hamster3.mc.plugin.chain.breaks.ChainBreakPlugin; +import cn.hamster3.mc.plugin.chain.breaks.config.ToolGroup; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.ArrayList; +import java.util.List; + +public final class ConfigManager { + private static List toolGroups; + + private ConfigManager() { + } + + public static void init() { + ChainBreakPlugin plugin = ChainBreakPlugin.getInstance(); + plugin.saveDefaultConfig(); + plugin.reloadConfig(); + FileConfiguration pluginConfig = plugin.getConfig(); + + toolGroups = new ArrayList<>(); + ConfigurationSection toolGroupsConfig = pluginConfig.getConfigurationSection("tool-groups"); + for (String key : toolGroupsConfig.getKeys(false)) { + ToolGroup group = new ToolGroup(toolGroupsConfig.getConfigurationSection(key)); + toolGroups.add(group); + } + } + + public static List getToolGroups() { + return toolGroups; + } +} diff --git a/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/listener/MainListener.java b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/listener/MainListener.java new file mode 100644 index 0000000..e5ffa2d --- /dev/null +++ b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/listener/MainListener.java @@ -0,0 +1,106 @@ +package cn.hamster3.mc.plugin.chain.breaks.listener; + +import cn.hamster3.mc.plugin.chain.breaks.config.ToolGroup; +import cn.hamster3.mc.plugin.chain.breaks.util.ChainBreakUtils; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class MainListener implements Listener { + public static final MainListener INSTANCE = new MainListener(); + private static final BlockFace[] BLOCK_FACES = new BlockFace[]{ + BlockFace.NORTH, + BlockFace.EAST, + BlockFace.SOUTH, + BlockFace.WEST, + BlockFace.UP, + BlockFace.DOWN + }; + + private MainListener() { + } + + @EventHandler(ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + Player player = event.getPlayer(); + if (player.isSneaking()) { + return; + } + ItemStack stack = player.getInventory().getItemInMainHand(); + ToolGroup group = ChainBreakUtils.getToolGroup(stack); + if (group == null) { + return; + } + if (!ChainBreakUtils.isToolGroupBlock(group, event.getBlock())) { + return; + } + List resultBlocks = new ArrayList<>(); + bfsSearchBlock(group, resultBlocks, Collections.singletonList(event.getBlock())); + resultBlocks.remove(event.getBlock()); + if (resultBlocks.isEmpty()) { + return; + } + if (player.getGameMode() == GameMode.CREATIVE) { + for (Block block : resultBlocks) { + block.breakNaturally(stack); + } + return; + } + short maxDurability = stack.getType().getMaxDurability(); + short durability = stack.getDurability(); + for (Block block : resultBlocks) { + if (block.breakNaturally(stack)) { + durability++; + if (durability >= maxDurability) { + break; + } + } + } + if (durability >= maxDurability) { + player.getInventory().setItemInMainHand(null); + player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1); + } else { + stack.setDurability(durability); + } + } + + private void bfsSearchBlock(@NotNull ToolGroup group, @NotNull List result, @NotNull List searchBlocks) { + ArrayList nextSearchBlocks = new ArrayList<>(); + for (Block block : searchBlocks) { + for (BlockFace face : BLOCK_FACES) { + Block relative = block.getRelative(face); + if (relative.getType() == Material.AIR) { + continue; + } + if (result.contains(relative)) { + continue; + } + if (!ChainBreakUtils.isToolGroupBlock(group, relative)) { + continue; + } + result.add(relative); + nextSearchBlocks.add(relative); + if (result.size() > 300) { + return; + } + } + } + if (nextSearchBlocks.isEmpty()) { + return; + } + bfsSearchBlock(group, result, nextSearchBlocks); + } + +} diff --git a/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/util/ChainBreakUtils.java b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/util/ChainBreakUtils.java new file mode 100644 index 0000000..95ac26a --- /dev/null +++ b/hamster-chain-break/src/main/java/cn/hamster3/mc/plugin/chain/breaks/util/ChainBreakUtils.java @@ -0,0 +1,38 @@ +package cn.hamster3.mc.plugin.chain.breaks.util; + +import cn.hamster3.mc.plugin.chain.breaks.config.ToolGroup; +import cn.hamster3.mc.plugin.chain.breaks.core.ConfigManager; +import org.bukkit.block.Block; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ChainBreakUtils { + + @Nullable + public static ToolGroup getToolGroup(@Nullable ItemStack stack) { + if (stack == null) { + return null; + } + String name = stack.getType().name().toLowerCase(); + for (ToolGroup group : ConfigManager.getToolGroups()) { + for (String type : group.getToolTypes()) { + if (name.matches(type)) { + return group; + } + } + } + return null; + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public static boolean isToolGroupBlock(@NotNull ToolGroup group, @NotNull Block block) { + String name = block.getType().name().toLowerCase(); + for (String type : group.getBlockTypes()) { + if (name.matches(type)) { + return true; + } + } + return false; + } +} diff --git a/hamster-chain-break/src/main/resources/config.yml b/hamster-chain-break/src/main/resources/config.yml new file mode 100644 index 0000000..fddca96 --- /dev/null +++ b/hamster-chain-break/src/main/resources/config.yml @@ -0,0 +1,17 @@ +# 方块破坏的间隔时间 +# 单位: tick +break-interval: 5 + +tool-groups: + axe: + tool-types: + - ".*_axe" + block-types: + - ".*_wood" + - ".*_log" + - ".*_leaves" + pickaxe: + tool-types: + - ".*_pickaxe" + block-types: + - ".*_ore" diff --git a/hamster-chain-break/src/main/resources/plugin.yml b/hamster-chain-break/src/main/resources/plugin.yml new file mode 100644 index 0000000..442d420 --- /dev/null +++ b/hamster-chain-break/src/main/resources/plugin.yml @@ -0,0 +1,8 @@ +name: HamsterChainBreak +main: cn.hamster3.mc.plugin.chain.breaks.ChainBreakPlugin +version: ${version} +api-version: 1.13 + +author: MiniDay +website: https://github.com/MiniDay/hamster-little-plugins +description: 仓鼠连锁破坏:一键挖矿 & 砍树