From c96787592d661d4f02699ac086b752496d402999 Mon Sep 17 00:00:00 2001 From: tanyaofei Date: Wed, 4 Dec 2024 16:33:48 +0800 Subject: [PATCH] New feature: wolverine, make fake players super heal --- README.md | 91 ++++++++++--------- README_zh.md | 6 +- .../fakeplayer/core/entity/SpawnOption.java | 4 +- .../core/manager/FakeplayerManager.java | 19 ++-- .../core/repository/model/Feature.java | 25 ++++- fakeplayer-core/src/main/resources/config.yml | 1 + .../main/resources/message/message.properties | 1 + .../resources/message/message_zh.properties | 1 + .../message/message_zh_HK.properties | 3 +- .../message/message_zh_TW.properties | 3 +- 10 files changed, 92 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index fd61252..3c2a01c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ This is a server side plugin inspired by [Carpet-Mod](https://github.com/gnembon [Click me](https://youtu.be/NePaDz-P5nI) to visit a demo video. - ## Features + Lets you spawn fake players who look like real to the server, they can keep chunk loading @@ -22,60 +21,59 @@ This is a server side plugin inspired by [Carpet-Mod](https://github.com/gnembon + [Paper](https://papermc.io) or [Purpur](http://purpurmc.org) software + [CommandAPI](https://commandapi.jorel.dev) Plugin - ## Config file + **Fakeplayer only generates a template config file named `config.tmpl.yml`.** You need to rename this file to `config.yml` as your configuration file. This approach can let you preview new content when you are upgrading it. [Click to visit file content](fakeplayer-core/src/main/resources/config.yml) - ## Commands -| Command | Description | Permission | Note | -|---------------|-------------------------------------------|------------------------------|--------------------------------------------------------------------| -| /fp spawn | Spawn a fake player | fakeplayer.command.spawn | | -| /fp kill | Kill a fake player | fakeplayer.command.kill | | -| /fp killall | Kill all fake players on the server | OP | | -| /fp select | Select a fake player as default | fakeplayer.command.select | Appears only when player spawned more then 1 fake players | -| /fp selection | View selected fake player | fakeplayer.command.selection | Appears only when player spawned more then 1 fake players | -| /fp list | List spawned fake players | fakeplayer.command.list | | -| /fp distance | Show distance to a fake player | fakeplayer.command.distance | | -| /fp drop | Drop held item | fakeplayer.command.drop | | -| /fp dropstack | Drop entire stack of the held item | fakeplayer.command.dropstack | | -| /fp dropinv | Drop all items in the inventory | fakeplayer.command.dropinv | | -| /fp skin | Copy skin from another player | fakeplayer.command.skin | 60 seconds cooldown if copy from a offline player | -| /fp invsee | Open an inventory of a fake player | fakeplayer.command.invsee | Right-clicking on fake players has the same effect | -| /fp sleep | Sleep | fakeplayer.command.sleep | | -| /fp wakeup | Wake up | fakeplayer.command.wakeup | | -| /fp status | Show player status | fakeplayer.command.status | | -| /fp respawn | Respawn a dead fake player | fakeplayer.command.respawn | Appears only when server config does not kick on fake player death | -| /fp tp | Teleport to a fake player | fakeplayer.command.tp | | -| /fp tphere | Teleport a fake player to you | fakeplayer.command.tphere | | -| /fp tps | Swap positions with fake player | fakeplayer.command.tps | | -| /fp set | Change the configuration of a fake player | fakeplayer.command.set | | -| /fp config | Change default configuration | fakeplayer.command.config | | -| /fp expme | Transfer exp to you | fakeplayer.command.expme | | -| /fp attack | Attack | fakeplayer.command.attack | | -| /fp mine | Mine | fakeplayer.command.mine | | -| /fp use | Use/Interact/Place | fakeplayer.command.use | | -| /fp jump | Jump | fakeplayer.command.jump | | -| /fp stop | Stop all actions | fakeplayer.command.stop | | -| /fp turn | Turn around | fakeplayer.command.turn | | -| /fp look | Look at specified location | fakeplayer.command.look | | -| /fp move | Move | fakeplayer.command.mvoe | | -| /fp ride | Ride | fakeplayer.command.ride | | -| /fp sneak | Sneak | fakeplayer.command.sneak | | -| /fp sprint | Sprinting | fakeplayer.command.sprint | | -| /fp swap | Swap main and off-hand items | fakeplayer.command.swap | | -| /fp hold | Hold corresponding hotbar item | fakeplayer.command.hold | | -| /fp cmd | Execute command | fakeplayer.command.cmd | | -| /fp reload | Reload config file | OP | | +| Command | Description | Permission | Note | +|---------------|-------------------------------------------|------------------------------|-----------------------------------------------------------------| +| /fp spawn | Spawn a fake player | fakeplayer.command.spawn | | +| /fp kill | Kill a fake player | fakeplayer.command.kill | | +| /fp killall | Kill all fake players on the server | OP | | +| /fp select | Select a fake player as default | fakeplayer.command.select | Available when player spawned more then 1 fake players | +| /fp selection | View selected fake player | fakeplayer.command.selection | Available only when player spawned more then 1 fake players | +| /fp list | List spawned fake players | fakeplayer.command.list | | +| /fp distance | Show distance to a fake player | fakeplayer.command.distance | | +| /fp drop | Drop held item | fakeplayer.command.drop | | +| /fp dropstack | Drop entire stack of the held item | fakeplayer.command.dropstack | | +| /fp dropinv | Drop all items in the inventory | fakeplayer.command.dropinv | | +| /fp skin | Copy skin from another player | fakeplayer.command.skin | 60 seconds cooldown if copy from a offline player | +| /fp invsee | Open an inventory of a fake player | fakeplayer.command.invsee | Right-clicking on fake players has the same effect | +| /fp sleep | Sleep | fakeplayer.command.sleep | | +| /fp wakeup | Wake up | fakeplayer.command.wakeup | | +| /fp status | Show player status | fakeplayer.command.status | | +| /fp respawn | Respawn a dead fake player | fakeplayer.command.respawn | Available when server config does not kick on fake player death | +| /fp tp | Teleport to a fake player | fakeplayer.command.tp | | +| /fp tphere | Teleport a fake player to you | fakeplayer.command.tphere | | +| /fp tps | Swap positions with fake player | fakeplayer.command.tps | | +| /fp set | Change the configuration of a fake player | fakeplayer.command.set | | +| /fp config | Change default configuration | fakeplayer.command.config | | +| /fp expme | Transfer exp to you | fakeplayer.command.expme | | +| /fp attack | Attack | fakeplayer.command.attack | | +| /fp mine | Mine | fakeplayer.command.mine | | +| /fp use | Use/Interact/Place | fakeplayer.command.use | | +| /fp jump | Jump | fakeplayer.command.jump | | +| /fp stop | Stop all actions | fakeplayer.command.stop | | +| /fp turn | Turn around | fakeplayer.command.turn | | +| /fp look | Look at specified location | fakeplayer.command.look | | +| /fp move | Move | fakeplayer.command.mvoe | | +| /fp ride | Ride | fakeplayer.command.ride | | +| /fp sneak | Sneak | fakeplayer.command.sneak | | +| /fp sprint | Sprinting | fakeplayer.command.sprint | | +| /fp swap | Swap main and off-hand items | fakeplayer.command.swap | | +| /fp hold | Hold corresponding hotbar item | fakeplayer.command.hold | | +| /fp cmd | Execute command | fakeplayer.command.cmd | | +| /fp reload | Reload config file | OP | | ## Personal Configuration -Each player can configure his own configuration, it will take effect on the next spawning +**Each player** can configure his **own** configuration, it will take effect on the next spawning Command examples: @@ -86,13 +84,13 @@ Command examples: |--------------------|-------------------------------------------------------------------------------------------------------------------------------------| | collidable | Whether collision box is enabled | | invulnerable | Whether invincible mode is enabled | +| wolverine | Whether super heal mode is enabled | | look_at_entity | Automatically look at nearby attackable entities (including players), can be combined with `attack` to automatically fight monsters | | pickup_items | Whether to pick up items | | skin | Whether to use your skin | | replenish | Whether to auto-replenish | | autofish | Whether to autofish | - ## Permissions
@@ -156,11 +154,13 @@ If your server does not restrict various player commands, you can use this direc
## Placeholder Variables + + `%fakeplayer_total%`: Total count of fake players + `%fakeplayer_creator%`: The creator name of a fake player + `%fakeplayer_actions`: Active actions of a fake player such as : `USE|ATTACK` # Custom Translation + 1. Create a `message` folder in `plugins/fakeplayer` 2. Copy [this file](fakeplayer-core/src/main/resources/message/message.properties) to `message` folder 3. Rename the file to `message_language_region.properties` such as `message_en_us.properties` @@ -172,7 +172,9 @@ If your server does not restrict various player commands, you can use this direc # FAQs ## xxx lost connection: PacketEvents 2.0 failed to inject + Some plugin change the `Connection` of the fake player, You can set `prevent-kicking` to `ALWAYS` to solve it. + ```yaml # config.yml prevent-kicking: ALWAYS @@ -196,6 +198,7 @@ self-commands: ``` # Build Project + See the [introduction](./BUILD.md). diff --git a/README_zh.md b/README_zh.md index 1a9b93b..84fc823 100644 --- a/README_zh.md +++ b/README_zh.md @@ -13,7 +13,6 @@ + 支持 `1.20`, `1.20.2`, `1.20.3`, `1.20.4`, `1.20.5`, `1.20.6` + 支持 `1.21` - ## 特性 1. 你可以召唤假人来帮你保持区块加载、怪物刷新 @@ -22,13 +21,12 @@ 4. 你可以控制假人执行一些动作比如: 跳跃、攻击、进食、睡觉等等。不仅如此,你还可以将这些行为设置为周期性的。 5. 发挥你的想象~ - ## 前置插件: - [CommandAPI](https://commandapi.jorel.dev) - ## 配置文件 + 与其他插件不同,Fakeplayer 只会生成一份名为 `config.tmpl.yml` 的**模版**配置文件,你需要将它重命名为 `config.yml` 才能用作配置文件。这样的好处是升级的时候可以提前知道新的内容。 ## 命令 @@ -157,6 +155,7 @@ _此外,假人是一个模拟玩家,因此可以被任何指令所识别比 |----------------|-------------------------------------------| | collidable | 是否开启碰撞箱 | | invulnerable | 是否无敌模式 | +| wolverine | 金刚狼超强再生模式 | | look_at_entity | 是否自动看向附近的可攻击的实体(包括玩家), 可以配合 `attack` 自动打怪 | | pickup_items | 是否能够拾取物品 | | skin | 是否使用你的皮肤 | @@ -234,7 +233,6 @@ allow-commands: 如果你的服务器 `spigot.yml` 里的 `bungeecord` 设置值为 `true`, 那么此插件将会进行兼容, 只要玩家在任意一个服务器里游玩,即使切换服务器他创建的假人都不会触发`跟随下线 - # 构建项目 看这个[指引](./BUILD.md) diff --git a/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/entity/SpawnOption.java b/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/entity/SpawnOption.java index 4f59ee9..c9360f3 100644 --- a/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/entity/SpawnOption.java +++ b/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/entity/SpawnOption.java @@ -28,7 +28,9 @@ public record SpawnOption( boolean replenish, - boolean autofish + boolean autofish, + + boolean wolverine ) { } diff --git a/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/manager/FakeplayerManager.java b/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/manager/FakeplayerManager.java index a26044c..e33b1d8 100644 --- a/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/manager/FakeplayerManager.java +++ b/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/manager/FakeplayerManager.java @@ -67,14 +67,14 @@ public class FakeplayerManager { this.lagMonitor = Executors.newSingleThreadScheduledExecutor(); this.lagMonitor.scheduleWithFixedDelay(() -> { - if (Bukkit.getServer().getTPS()[1] < config.getKaleTps()) { - Bukkit.getScheduler().runTask(Main.getInstance(), () -> { - if (this.removeAll("low tps") > 0) { - Bukkit.broadcast(translatable("fakeplayer.manager.remove-all-on-low-tps", GRAY, ITALIC)); - } - }); - } - }, 0, 60, TimeUnit.SECONDS + if (Bukkit.getServer().getTPS()[1] < config.getKaleTps()) { + Bukkit.getScheduler().runTask(Main.getInstance(), () -> { + if (this.removeAll("low tps") > 0) { + Bukkit.broadcast(translatable("fakeplayer.manager.remove-all-on-low-tps", GRAY, ITALIC)); + } + }); + } + }, 0, 60, TimeUnit.SECONDS ); } @@ -117,7 +117,8 @@ public class FakeplayerManager { configs.get(Feature.pickup_items).asBoolean(), configs.get(Feature.skin).asBoolean(), configs.get(Feature.replenish).asBoolean(), - configs.get(Feature.autofish).asBoolean() + configs.get(Feature.autofish).asBoolean(), + configs.get(Feature.wolverine).asBoolean() ); }) .thenComposeAsync(fp::spawnAsync) diff --git a/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/repository/model/Feature.java b/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/repository/model/Feature.java index 6e62da6..04c746a 100644 --- a/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/repository/model/Feature.java +++ b/fakeplayer-core/src/main/java/io/github/hello09x/fakeplayer/core/repository/model/Feature.java @@ -8,10 +8,13 @@ import lombok.Getter; import net.kyori.adventure.translation.Translatable; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Function; @@ -42,17 +45,35 @@ public enum Feature implements Translatable, Singletons { "fakeplayer.config.invulnerable", List.of(Permission.config), List.of("true", "false"), - "true", + "false", faker -> String.valueOf(faker.isInvulnerable()), (faker, value) -> faker.setInvulnerable(Boolean.parseBoolean(value)) ), + /** + * 金刚狼模式 -> 超强的再生能力 + */ + wolverine( + "fakeplayer.config.wolverine", + List.of(Permission.config), + List.of("true", "false"), + "false", + fake -> String.valueOf(Optional.ofNullable(fake.getPotionEffect(PotionEffectType.REGENERATION)).map(PotionEffect::isInfinite).orElse(false)), + (faker, value) -> { + if (Boolean.parseBoolean(value)) { + faker.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, PotionEffect.INFINITE_DURATION, 4, true, true)); + } else { + faker.removePotionEffect(PotionEffectType.REGENERATION); + } + } + ), + /** * 是否自动看向实体 */ look_at_entity( "fakeplayer.config.look_at_entity", - List.of(Permission.config), + List.of(Permission.config, Permission.look), List.of("true", "false"), "false", faker -> String.valueOf(actionManager.get().hasActiveAction(faker, ActionType.LOOK_AT_NEAREST_ENTITY)), diff --git a/fakeplayer-core/src/main/resources/config.yml b/fakeplayer-core/src/main/resources/config.yml index 19e56ae..9fac5be 100644 --- a/fakeplayer-core/src/main/resources/config.yml +++ b/fakeplayer-core/src/main/resources/config.yml @@ -264,6 +264,7 @@ default-features: invulnerable: false replenish: false autofish: false + wolverine: false # 检测更新 diff --git a/fakeplayer-core/src/main/resources/message/message.properties b/fakeplayer-core/src/main/resources/message/message.properties index a109f42..5343f66 100644 --- a/fakeplayer-core/src/main/resources/message/message.properties +++ b/fakeplayer-core/src/main/resources/message/message.properties @@ -149,5 +149,6 @@ fakeplayer.spawn.error.name.too-short=Requires a name has more than {0} characte fakeplayer.spawn.error.name.used=Name {0} was used by a real player({1}) fakeplayer.command.ride.entity.error.too-far=Entity is too far away from {0} fakeplayer.command.ride.entity.description=Ride specified entity +fakeplayer.config.wolverine=Super heal diff --git a/fakeplayer-core/src/main/resources/message/message_zh.properties b/fakeplayer-core/src/main/resources/message/message_zh.properties index 14c22c9..87f4fb7 100644 --- a/fakeplayer-core/src/main/resources/message/message_zh.properties +++ b/fakeplayer-core/src/main/resources/message/message_zh.properties @@ -149,5 +149,6 @@ fakeplayer.spawn.error.name.too-short=\u540D\u79F0\u6700\u5C11 {0} \u4E2A\u5B57\ fakeplayer.spawn.error.name.used=\u540D\u79F0 {0} \u88AB\u771F\u5B9E\u73A9\u5BB6({1})\u4F7F\u7528\u8FC7\u4E86 fakeplayer.command.ride.entity.error.too-far=\u6307\u5B9A\u7684\u5B9E\u4F53\u79BB {0} \u592A\u8FDC\u4E86 fakeplayer.command.ride.entity.description=\u9A91\u6307\u5B9A\u5B9E\u4F53 +fakeplayer.config.wolverine=\u8D85\u5F3A\u518D\u751F diff --git a/fakeplayer-core/src/main/resources/message/message_zh_HK.properties b/fakeplayer-core/src/main/resources/message/message_zh_HK.properties index d65646e..a42ffa7 100644 --- a/fakeplayer-core/src/main/resources/message/message_zh_HK.properties +++ b/fakeplayer-core/src/main/resources/message/message_zh_HK.properties @@ -148,4 +148,5 @@ fakeplayer.spawn.error.name.too-long=\u540D\u7A31\u81F3\u591A {0} \u500B\u5B57 fakeplayer.spawn.error.name.too-short=\u540D\u7A31\u81F3\u5C11 {0} \u500B\u5B57 fakeplayer.spawn.error.name.used=\u540D\u7A31 {0} \u88AB\u771F\u5BE6\u73A9\u5BB6({1})\u4F7F\u7528\u904E\u4E86 fakeplayer.command.ride.entity.error.too-far=\u6307\u5B9A\u7684\u5BE6\u9AD4\u96E2 {0} \u592A\u9060\u4E86 -fakeplayer.command.ride.entity.description=\u9A0E\u6307\u5B9A\u5BE6\u9AD4 \ No newline at end of file +fakeplayer.command.ride.entity.description=\u9A0E\u6307\u5B9A\u5BE6\u9AD4 +fakeplayer.config.wolverine=\u8D85\u5F37\u518D\u751F \ No newline at end of file diff --git a/fakeplayer-core/src/main/resources/message/message_zh_TW.properties b/fakeplayer-core/src/main/resources/message/message_zh_TW.properties index a45b95c..e27cb7c 100644 --- a/fakeplayer-core/src/main/resources/message/message_zh_TW.properties +++ b/fakeplayer-core/src/main/resources/message/message_zh_TW.properties @@ -148,4 +148,5 @@ fakeplayer.spawn.error.name.too-long=\u540D\u7A31\u6700\u591A {0} \u500B\u5B57\u fakeplayer.spawn.error.name.too-short=\u540D\u7A31\u6700\u5C11 {0} \u500B\u5B57\u7B26 fakeplayer.spawn.error.name.used=\u540D\u7A31 {0} \u88AB\u771F\u5BE6\u73A9\u5BB6({1})\u4F7F\u7528\u904E\u4E86 fakeplayer.command.ride.entity.error.too-far=\u6307\u5B9A\u7684\u5BE6\u9AD4\u96E2 {0} \u592A\u9060\u4E86 -fakeplayer.command.ride.entity.description=\u9A0E\u6307\u5B9A\u5BE6\u9AD4 \ No newline at end of file +fakeplayer.command.ride.entity.description=\u9A0E\u6307\u5B9A\u5BE6\u9AD4 +fakeplayer.config.wolverine=\u8D85\u5F37\u518D\u751F \ No newline at end of file