From 1198dfc5be602b97247a7411e43fd83c37a4c733 Mon Sep 17 00:00:00 2001 From: Martin Sulikowski Date: Sat, 18 Jan 2025 14:27:28 +0100 Subject: [PATCH] GH-891 Fix removing catboy using butcher, remove catboy on server shutdown, add catboy config. (#891) * Fix removing catboy using butcher, remove catboy on server shutdown, add catboy config. Add catboy persistance. * GH-579 Add repository for language. Remove user settings. (#890) * Add repository for language. Remove user settings. * Simplify API * Provide catboy speed from config. * Create CatBoyEntityService --------- Co-authored-by: Norbert Dejlich --- .../butcher/ButcherEntityRemoveEvent.java | 41 +++++++++++++++++ .../implementation/PluginConfiguration.java | 19 ++++++++ .../mob => butcher}/ButcherArgument.java | 4 +- .../mob => butcher}/ButcherCommand.java | 17 ++++--- .../mob => butcher}/MobEntity.java | 2 +- .../mob => butcher}/MobEntityArgument.java | 2 +- .../mob => butcher}/MobFilter.java | 2 +- .../{essentials/mob => butcher}/MobType.java | 2 +- .../feature/catboy/CatBoyEntityService.java | 40 +++++++++++++++++ .../core/feature/catboy/CatBoySettings.java | 7 +++ .../core/feature/catboy/CatboyController.java | 45 ++++++++++++++++--- .../feature/catboy/CatboyServiceImpl.java | 31 +++++++------ 12 files changed, 182 insertions(+), 30 deletions(-) create mode 100644 eternalcore-api/src/main/java/com/eternalcode/core/feature/butcher/ButcherEntityRemoveEvent.java rename eternalcore-core/src/main/java/com/eternalcode/core/feature/{essentials/mob => butcher}/ButcherArgument.java (98%) rename eternalcore-core/src/main/java/com/eternalcode/core/feature/{essentials/mob => butcher}/ButcherCommand.java (86%) rename eternalcore-core/src/main/java/com/eternalcode/core/feature/{essentials/mob => butcher}/MobEntity.java (95%) rename eternalcore-core/src/main/java/com/eternalcode/core/feature/{essentials/mob => butcher}/MobEntityArgument.java (97%) rename eternalcore-core/src/main/java/com/eternalcode/core/feature/{essentials/mob => butcher}/MobFilter.java (69%) rename eternalcore-core/src/main/java/com/eternalcode/core/feature/{essentials/mob => butcher}/MobType.java (91%) create mode 100644 eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatBoyEntityService.java create mode 100644 eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatBoySettings.java diff --git a/eternalcore-api/src/main/java/com/eternalcode/core/feature/butcher/ButcherEntityRemoveEvent.java b/eternalcore-api/src/main/java/com/eternalcode/core/feature/butcher/ButcherEntityRemoveEvent.java new file mode 100644 index 000000000..7fb661f75 --- /dev/null +++ b/eternalcore-api/src/main/java/com/eternalcode/core/feature/butcher/ButcherEntityRemoveEvent.java @@ -0,0 +1,41 @@ +package com.eternalcode.core.feature.butcher; + +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ButcherEntityRemoveEvent extends Event implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private boolean cancelled; + private final Entity entity; + + public ButcherEntityRemoveEvent(Entity entity) { + this.entity = entity; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public Entity getEntity() { + return entity; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/configuration/implementation/PluginConfiguration.java b/eternalcore-core/src/main/java/com/eternalcode/core/configuration/implementation/PluginConfiguration.java index 30be682dd..778160135 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/configuration/implementation/PluginConfiguration.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/configuration/implementation/PluginConfiguration.java @@ -4,6 +4,7 @@ import com.eternalcode.core.database.DatabaseType; import com.eternalcode.core.feature.afk.AfkSettings; import com.eternalcode.core.feature.automessage.AutoMessageSettings; +import com.eternalcode.core.feature.catboy.CatBoySettings; import com.eternalcode.core.feature.chat.ChatSettings; import com.eternalcode.core.feature.helpop.HelpOpSettings; import com.eternalcode.core.feature.jail.JailSettings; @@ -421,6 +422,24 @@ public Set allowedCommands() { } } + @Bean + @Description({ " ", "# 4fun Section" }) + FunSection fun = new FunSection(); + + @Contextual + public static class FunSection implements CatBoySettings { + @Description({ + "# Speed of player walk speed while using /catboy feature", + "# Default minecraft walk speed is 0.2" + }) + public float catboyWalkSpeed = 0.4F; + + @Override + public float getCatboyWalkSpeed() { + return this.catboyWalkSpeed; + } + } + @Override public Resource resource(File folder) { return Source.of(folder, "config.yml"); diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/ButcherArgument.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/ButcherArgument.java similarity index 98% rename from eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/ButcherArgument.java rename to eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/ButcherArgument.java index adf37ca18..d32a11b46 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/ButcherArgument.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/ButcherArgument.java @@ -1,15 +1,15 @@ -package com.eternalcode.core.feature.essentials.mob; +package com.eternalcode.core.feature.butcher; import com.eternalcode.core.bridge.litecommand.argument.AbstractViewerArgument; import com.eternalcode.core.configuration.implementation.PluginConfiguration; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.injector.annotations.lite.LiteArgument; +import com.eternalcode.core.viewer.ViewerService; import com.eternalcode.multification.notice.NoticeBroadcast; import com.eternalcode.core.notice.NoticeService; import com.eternalcode.core.translation.Translation; import com.eternalcode.core.translation.TranslationManager; import com.eternalcode.core.viewer.Viewer; -import com.eternalcode.core.viewer.ViewerService; import dev.rollczi.litecommands.argument.Argument; import dev.rollczi.litecommands.argument.parser.ParseResult; import dev.rollczi.litecommands.invocation.Invocation; diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/ButcherCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/ButcherCommand.java similarity index 86% rename from eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/ButcherCommand.java rename to eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/ButcherCommand.java index 0e64ff1f4..997837031 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/ButcherCommand.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/ButcherCommand.java @@ -1,7 +1,7 @@ -package com.eternalcode.core.feature.essentials.mob; +package com.eternalcode.core.feature.butcher; import com.eternalcode.annotations.scan.command.DescriptionDocs; -import com.eternalcode.core.configuration.implementation.PluginConfiguration; +import com.eternalcode.core.event.EventCaller; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.notice.NoticeService; import dev.rollczi.litecommands.annotations.argument.Arg; @@ -25,10 +25,12 @@ class ButcherCommand { private final NoticeService noticeService; + private final EventCaller eventCaller; @Inject - ButcherCommand(NoticeService noticeService, PluginConfiguration pluginConfiguration) { + ButcherCommand(NoticeService noticeService, EventCaller eventCaller) { this.noticeService = noticeService; + this.eventCaller = eventCaller; } @Execute @@ -51,16 +53,21 @@ void execute(@Context Player player, @Arg(ButcherArgument.KEY) int chunks, @Arg( private void killMobs(Player player, int chunksNumber, MobFilter mobFilter) { Collection chunks = this.getChunksNearPlayer(player, chunksNumber); - int killedMobs = 0; for (Chunk chunk : chunks) { for (Entity entity : chunk.getEntities()) { - if (!mobFilter.filterMob(entity)) { continue; } + ButcherEntityRemoveEvent event = new ButcherEntityRemoveEvent(entity); + this.eventCaller.callEvent(event); + + if (event.isCancelled()) { + continue; + } + entity.remove(); killedMobs++; } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobEntity.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobEntity.java similarity index 95% rename from eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobEntity.java rename to eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobEntity.java index 5d437e92b..18689cca2 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobEntity.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobEntity.java @@ -1,4 +1,4 @@ -package com.eternalcode.core.feature.essentials.mob; +package com.eternalcode.core.feature.butcher; import com.eternalcode.core.util.EntityUtil; import org.bukkit.entity.Animals; diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobEntityArgument.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobEntityArgument.java similarity index 97% rename from eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobEntityArgument.java rename to eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobEntityArgument.java index ebdcb491b..ef4228ebb 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobEntityArgument.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobEntityArgument.java @@ -1,4 +1,4 @@ -package com.eternalcode.core.feature.essentials.mob; +package com.eternalcode.core.feature.butcher; import com.eternalcode.core.bridge.litecommand.argument.AbstractViewerArgument; import com.eternalcode.core.injector.annotations.Inject; diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobFilter.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobFilter.java similarity index 69% rename from eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobFilter.java rename to eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobFilter.java index 21a5c60aa..53f0bc76c 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobFilter.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobFilter.java @@ -1,4 +1,4 @@ -package com.eternalcode.core.feature.essentials.mob; +package com.eternalcode.core.feature.butcher; import org.bukkit.entity.Entity; diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobType.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobType.java similarity index 91% rename from eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobType.java rename to eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobType.java index 1bc4ac2b7..1952d29c3 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/essentials/mob/MobType.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/butcher/MobType.java @@ -1,4 +1,4 @@ -package com.eternalcode.core.feature.essentials.mob; +package com.eternalcode.core.feature.butcher; enum MobType { diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatBoyEntityService.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatBoyEntityService.java new file mode 100644 index 000000000..70c5a627e --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatBoyEntityService.java @@ -0,0 +1,40 @@ +package com.eternalcode.core.feature.catboy; + +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.injector.annotations.component.Service; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Cat; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.plugin.Plugin; + +@Service +class CatBoyEntityService { + + private final NamespacedKey catboyNamespacedKey; + + @Inject + CatBoyEntityService(Plugin plugin) { + this.catboyNamespacedKey = new NamespacedKey(plugin, "catboy"); + } + + Cat createCatboyEntity(Player player, Cat.Type type) { + Cat cat = (Cat) player.getWorld().spawnEntity(player.getLocation(), EntityType.CAT); + cat.setInvulnerable(true); + cat.setOwner(player); + cat.setAI(false); + cat.setCatType(type); + + PersistentDataContainer persistentDataContainer = cat.getPersistentDataContainer(); + persistentDataContainer.set(catboyNamespacedKey, PersistentDataType.BOOLEAN, true); + + return cat; + } + + boolean isCatboy(Cat cat) { + return cat.getPersistentDataContainer().has(catboyNamespacedKey, PersistentDataType.BOOLEAN); + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatBoySettings.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatBoySettings.java new file mode 100644 index 000000000..d11434300 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatBoySettings.java @@ -0,0 +1,7 @@ +package com.eternalcode.core.feature.catboy; + +public interface CatBoySettings { + + float getCatboyWalkSpeed(); + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatboyController.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatboyController.java index 253922a27..776aa418a 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatboyController.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatboyController.java @@ -1,9 +1,15 @@ package com.eternalcode.core.feature.catboy; import com.eternalcode.commons.scheduler.Scheduler; +import com.eternalcode.core.feature.butcher.ButcherEntityRemoveEvent; import com.eternalcode.core.feature.teleport.event.EternalTeleportEvent; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.injector.annotations.component.Controller; +import com.eternalcode.core.publish.Subscribe; +import com.eternalcode.core.publish.event.EternalShutdownEvent; +import java.time.Duration; +import java.util.Optional; +import org.bukkit.Server; import org.bukkit.Sound; import org.bukkit.World; import org.bukkit.entity.Cat; @@ -15,21 +21,27 @@ import org.bukkit.event.entity.EntityDismountEvent; import org.bukkit.event.player.PlayerQuitEvent; -import java.time.Duration; -import java.util.Optional; - @Controller class CatboyController implements Listener { private static final Duration TICK = Duration.ofMillis(50L); private final CatboyService catboyService; + private final CatBoyEntityService catBoyEntityService; private final Scheduler scheduler; + private final Server server; @Inject - CatboyController(CatboyService catboyService, Scheduler scheduler) { + CatboyController( + CatboyService catboyService, + CatBoyEntityService catBoyEntityService, + Scheduler scheduler, + Server server + ) { this.catboyService = catboyService; + this.catBoyEntityService = catBoyEntityService; this.scheduler = scheduler; + this.server = server; } @EventHandler @@ -60,7 +72,9 @@ void onTeleport(EternalTeleportEvent event) { Catboy catboy = optionalCatboy.get(); this.catboyService.unmarkAsCatboy(event.getPlayer()); - this.scheduler.runLater(() -> this.catboyService.markAsCatboy(event.getPlayer(), catboy.selectedType()), TICK); + this.scheduler.runLater( + () -> this.catboyService.markAsCatboy(event.getPlayer(), catboy.selectedType()), + TICK); } } @@ -85,4 +99,25 @@ void onHit(EntityDamageByEntityEvent event) { } } + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + void onEntityRemoveFromWorld(ButcherEntityRemoveEvent event) { + if (!(event.getEntity() instanceof Cat cat)) { + return; + } + + if (this.catBoyEntityService.isCatboy(cat)) { + event.setCancelled(true); + } + } + + @Subscribe + void onServerShutdown(EternalShutdownEvent event) { + for (Player onlinePlayer : this.server.getOnlinePlayers()) { + boolean catboy = this.catboyService.isCatboy(onlinePlayer.getUniqueId()); + + if (catboy) { + this.catboyService.unmarkAsCatboy(onlinePlayer); + } + } + } } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatboyServiceImpl.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatboyServiceImpl.java index 92c6dcdb8..bbe9a0cf8 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatboyServiceImpl.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/catboy/CatboyServiceImpl.java @@ -5,26 +5,34 @@ import com.eternalcode.core.feature.catboy.event.CatboySwitchEvent; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.injector.annotations.component.Service; -import org.bukkit.entity.Cat; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; - import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.UUID; +import org.bukkit.entity.Cat; +import org.bukkit.entity.Player; @Service class CatboyServiceImpl implements CatboyService { + private static final float DEFAULT_WALK_SPEED = 0.2F; private final Map catboys = new HashMap<>(); private final EventCaller eventCaller; + private final CatBoyEntityService catBoyEntityService; + private final CatBoySettings catBoySettings; + @Inject - CatboyServiceImpl(EventCaller eventCaller) { + CatboyServiceImpl( + EventCaller eventCaller, + CatBoyEntityService catBoyEntityService, + CatBoySettings catBoySettings + ) { this.eventCaller = eventCaller; + this.catBoyEntityService = catBoyEntityService; + this.catBoySettings = catBoySettings; } @Override @@ -32,13 +40,9 @@ public void markAsCatboy(Player player, Cat.Type type) { Catboy catboy = new Catboy(player.getUniqueId(), type); this.catboys.put(player.getUniqueId(), catboy); - Cat entity = (Cat) player.getWorld().spawnEntity(player.getLocation(), EntityType.CAT); - entity.setInvulnerable(true); - entity.setOwner(player); - entity.setCatType(type); - - player.addPassenger(entity); - player.setWalkSpeed(0.4F); + Cat cat = this.catBoyEntityService.createCatboyEntity(player, type); + player.addPassenger(cat); + player.setWalkSpeed(this.catBoySettings.getCatboyWalkSpeed()); this.eventCaller.callEvent(new CatboySwitchEvent(player, true)); } @@ -48,7 +52,7 @@ public void unmarkAsCatboy(Player player) { this.catboys.remove(player.getUniqueId()); player.getPassengers().forEach(entity -> entity.remove()); player.getPassengers().clear(); - player.setWalkSpeed(0.2F); + player.setWalkSpeed(DEFAULT_WALK_SPEED); this.eventCaller.callEvent(new CatboySwitchEvent(player, false)); } @@ -90,5 +94,4 @@ public Optional getCatboy(UUID uuid) { public Collection getCatboys() { return Collections.unmodifiableCollection(this.catboys.values()); } - }