From cc0bb1ff174cd968bf0005ec6bcfa2dd462541fd Mon Sep 17 00:00:00 2001 From: 4o4E <869951226@qq.com> Date: Wed, 6 Jul 2022 02:14:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=87=B32.0.5,=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=98=BB=E6=AD=A2=E7=8E=A9=E5=AE=B6=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E5=AE=9E=E4=BD=93/=E6=96=B9=E5=9D=97=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 4 +- src/main/kotlin/Boom.kt | 1 + src/main/kotlin/config/Config.kt | 50 +++++++- src/main/kotlin/listener/ClickListener.kt | 145 ++++++++++++++++++++++ src/main/resources/config.yml | 24 ++++ src/main/resources/lang.yml | 4 + 6 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/listener/ClickListener.kt diff --git a/build.gradle.kts b/build.gradle.kts index ad0c402..8a20fcd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "top.e404" -version = "2.0.4" +version = "2.0.5" repositories { maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") @@ -20,7 +20,7 @@ dependencies { // spigot compileOnly("org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT") // eplugin - implementation("top.e404:eplugin:1.0.1") + implementation("top.e404:eplugin:1.0.2") } tasks { diff --git a/src/main/kotlin/Boom.kt b/src/main/kotlin/Boom.kt index 03ed45a..930c228 100644 --- a/src/main/kotlin/Boom.kt +++ b/src/main/kotlin/Boom.kt @@ -43,6 +43,7 @@ class Boom : EPlugin() { ArmorStandListener.register() StickListener.register() DeathListener.register() + ClickListener.register() Update.init() for (line in logo) info(line) info("&a加载完成, 作者404E, 感谢使用") diff --git a/src/main/kotlin/config/Config.kt b/src/main/kotlin/config/Config.kt index 3e3806f..a46488f 100644 --- a/src/main/kotlin/config/Config.kt +++ b/src/main/kotlin/config/Config.kt @@ -71,6 +71,8 @@ object Config : EConfig( val preventUseCommand: PreventUseCommand?, val transformUseCommand: TransformUseCommandConfig?, val limitEntitySpawn: Map?, + val preventClickBlock: List, + val preventClickEntity: List, ) fun ConfigurationSection.getWorldConfig(path: String) = @@ -100,9 +102,14 @@ object Config : EConfig( transformUseCommand = cfg.getTransformUseCommand("transform_use_command"), limitEntitySpawn = cfg.getConfigurationSection("limit_entity_spawn")?.let { limit -> limit.getKeys(false).associate { key -> key.formatAsConst() to (limit.getIntOrNull(key) ?: 100) } - } + }, + preventClickBlock = cfg.getMapList("prevent_click_block").mapNotNull { map -> + map.asClickBlockConfig() + }, + preventClickEntity = cfg.getMapList("prevent_click_entity").mapNotNull { map -> + map.asClickEntityConfig() + }, ) - } fun ConfigurationSection.getExplosionConfig(path: String) = @@ -253,4 +260,43 @@ object Config : EConfig( } } } + + + fun Map<*, *>.asClickBlockConfig(): ClickBlockConfig? { + val item = this["item"]?.toString()?.toRegex() ?: return null + val block = this["block"]?.toString()?.toRegex() ?: return null + val type = this["type"]?.toString()?.asClickType() ?: return null + return ClickBlockConfig(item, block, type) + } + + data class ClickBlockConfig( + val item: Regex, + val block: Regex, + val type: ClickType + ) + + fun Map<*, *>.asClickEntityConfig(): ClickEntityConfig? { + val item = this["item"]?.toString()?.toRegex() ?: return null + val entity = this["entity"]?.toString()?.toRegex() ?: return null + val type = this["type"]?.toString()?.asClickType() ?: return null + return ClickEntityConfig(item, entity, type) + } + + data class ClickEntityConfig( + val item: Regex, + val entity: Regex, + val type: ClickType + ) + + fun String.asClickType() = ClickType.values().firstOrNull { it.regex.matches(this) } + + enum class ClickType( + regex: String + ) { + LEFT("(?i)l|left"), + RIGHT("(?i)r|right"), + ALL("(?i)a|all"); + + val regex = Regex(regex) + } } \ No newline at end of file diff --git a/src/main/kotlin/listener/ClickListener.kt b/src/main/kotlin/listener/ClickListener.kt new file mode 100644 index 0000000..9e27fec --- /dev/null +++ b/src/main/kotlin/listener/ClickListener.kt @@ -0,0 +1,145 @@ +package top.e404.boom.listener + +import org.bukkit.entity.Player +import org.bukkit.event.EventHandler +import org.bukkit.event.block.Action +import org.bukkit.event.entity.EntityDamageByEntityEvent +import org.bukkit.event.player.PlayerInteractEntityEvent +import org.bukkit.event.player.PlayerInteractEvent +import top.e404.boom.PL +import top.e404.boom.config.Config +import top.e404.boom.config.Lang +import top.e404.eplugin.listener.EListener + +object ClickListener : EListener(PL) { + @EventHandler + fun PlayerInteractEvent.onEvent() { + val block = clickedBlock ?: return + val hand = hand ?: return + val cfg = Config.getEachOrGlobal(player.world.name) { preventClickBlock } ?: return + val item = player.inventory.getItem(hand).type.name + for ((itemRegex, blockRegex, type) in cfg) { + // 检测破坏 && 动作不是破坏 + if (type == Config.ClickType.LEFT && action != Action.LEFT_CLICK_BLOCK) continue + // 检测点击 && 动作不是点击 + if (type == Config.ClickType.RIGHT && action != Action.RIGHT_CLICK_BLOCK) continue + // 物品或方块不匹配 + if (!blockRegex.matches(block.type.name) + || !itemRegex.matches(item) + ) continue + isCancelled = true + plugin.debug { + Lang[ + "click.prevent", + "player" to player.name, + "item" to item, + "target" to block.type.name, + "world" to player.world.name, + "x" to block.x, + "y" to block.y, + "z" to block.z, + ] + } + return + } + plugin.debug { + Lang[ + "click.pass", + "player" to player.name, + "item" to item, + "target" to block.type.name, + "world" to player.world.name, + "x" to block.x, + "y" to block.y, + "z" to block.z, + ] + } + } + + @EventHandler + fun PlayerInteractEntityEvent.onEvent() { + val cfg = Config.getEachOrGlobal(player.world.name) { preventClickEntity } ?: return + val item = player.inventory.getItem(hand).type.name + val entity = rightClicked.type.name + for ((itemRegex, entityRegex, type) in cfg) { + // 忽略left, 检测right/all + if (type == Config.ClickType.LEFT) continue + // 物品或方块不匹配 + if (!entityRegex.matches(entity) + || !itemRegex.matches(item) + ) continue + isCancelled = true + plugin.debug { + val l = rightClicked.location + Lang[ + "click.prevent", + "player" to player.name, + "item" to item, + "target" to entity, + "world" to player.world.name, + "x" to l.blockX, + "y" to l.blockY, + "z" to l.blockZ, + ] + } + return + } + plugin.debug { + val l = rightClicked.location + Lang[ + "click.pass", + "player" to player.name, + "item" to item, + "target" to entity, + "world" to player.world.name, + "x" to l.blockX, + "y" to l.blockY, + "z" to l.blockZ, + ] + } + } + + @EventHandler + fun EntityDamageByEntityEvent.onEvent() { + val damager = damager + if (damager !is Player) return + val cfg = Config.getEachOrGlobal(damager.world.name) { preventClickEntity } ?: return + val item = damager.inventory.itemInMainHand.type.name + for ((itemRegex, entityRegex, type) in cfg) { + // 忽略right, 检测left/all + if (type == Config.ClickType.RIGHT) continue + // 物品或方块不匹配 + if (!entityRegex.matches(entityType.name) + || !itemRegex.matches(item) + ) continue + isCancelled = true + plugin.debug { + val l = entity.location + Lang[ + "click.prevent", + "player" to damager.name, + "item" to item, + "target" to entityType.name, + "world" to damager.world.name, + "x" to l.blockX, + "y" to l.blockY, + "z" to l.blockZ, + ] + } + return + } + plugin.debug { + val l = entity.location + Lang[ + "click.pass", + "player" to damager.name, + "item" to item, + "target" to entityType.name, + "world" to damager.world.name, + "x" to l.blockX, + "y" to l.blockY, + "z" to l.blockZ, + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0889512..bde5047 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -200,6 +200,30 @@ global: # bat: 0 # 意为阻止所有的蝙蝠生成(几率0%) # zombified_piglin: 50 # 意为僵尸猪灵只有50%的几率生成(其他的生成会被取消) + # 阻止玩家使用物品点击方块 + # 空手时item为AIR + prevent_click_block: + # 以下这条配置的效果是阻止玩家使用刷怪蛋点击刷怪笼 +# - # 玩家点击方块时的物品类型匹配正则 +# item: "(?i)[a-z]+_spawn_egg" +# # 玩家点击的方块类型匹配正则 +# block: "(?i)spawner" +# # 点击的类型 (left/right/all) +# # left对应挖掘, right对应点击 +# type: right + + # 阻止玩家使用物品点击实体 + # 空手时item为AIR + prevent_click_entity: + # 以下这条配置的效果是阻止玩家使用胡萝卜点击猪 +# - # 玩家点击方块时的物品类型匹配正则 +# item: "(?i)carrot" +# # 玩家点击的方块类型匹配正则 +# entity: "(?i)pig" +# # 点击的类型 (left/right/all) +# # left对应伤害, right对应点击 +# type: right + # 单独世界设置 # 可以自行扩展, 配置格式与global的一致 # 缺失的内容将使用global的 diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index 4e3064e..91ededb 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -106,6 +106,10 @@ weather: sun: "晴" thunder: "雷暴" +click: + prevent: "阻止玩家{player}手持{item}点击{target}(world: {world}, x: {x}, y: {y}, z: {z})" + pass: "未处理玩家{player}手持{item}点击{target}(world: {world}, x: {x}, y: {y}, z: {z})" + plugin_command: reload_done: "&a重载完成" stick_give: "&a已给予"