From 9ecd44019d67874006b57a70d59367400504d37e Mon Sep 17 00:00:00 2001 From: Simon Chuu Date: Sat, 30 Mar 2019 01:29:26 -0400 Subject: [PATCH] Refactor Code --- readme.md | 35 +++-- .../simonorj/mc/phantomsmp/ConfigSaver.java | 11 ++ .../mc/phantomsmp/PhantomListener.java | 136 +++++++++--------- .../simonorj/mc/phantomsmp/PhantomSMP.java | 7 +- src/main/resources/config.yml | 7 +- src/main/resources/plugin.yml | 6 +- 6 files changed, 122 insertions(+), 80 deletions(-) diff --git a/readme.md b/readme.md index 1b86686..13dd63a 100644 --- a/readme.md +++ b/readme.md @@ -3,18 +3,35 @@ Better Phantom handling for SMP # Configuration -There is only one option to configure. The configuration details are inside -the config file and will appear after first server run with this plugin. -```yml -# PhantomSMP by SimonOrJ +There are two configuration options that you can set. -# Remove phantoms that try to target player slept within three (Minecraft) days? -# true = remove phantom targeting rested player -# false = Keep phantoms (and make phantoms try to target another player) -remove-targeting-rested: true +* `remove-targeting-rested`: *Default: true.* Remove phantoms that try to + target players who recently rested. +* `remove-when-sleeping`: *Default: false.* Remove phantoms as soon as player + gets in the bed. +* `disallow-targeting-for`: *Default: 72000.* Ticks since player's last rest + before a phantom starts targeting them. -``` +For additional information, check [`config.yml`](src/main/resources/config.yml). + +## Permissions + +All permission nodes are not applied by default, even to server operators. + +* `phantomsmp.disallowspawn`: If given, phantoms will not spawn on this player. +* `phantomsmp.ignore`: If given, phantoms will essentially ignore this player. + +For additional information, check [`plugin.yml`](src/main/resources/plugin.yml). + +# Disallowing Phantom Spawn + +The Bukkit API does not allow for directly checking which player caused the +phantoms to spawn. Therefore, if `disallow-targeting-for` is greater than +72000, phantoms will spawn in for a few seconds until they start targeting a +player. When the very first target of the phantom is a well-rested player, +they will despawn immediately. The same happens when the player is given the +`phantomsmp.disallowspawn` permission. # External Links diff --git a/src/main/java/com/simonorj/mc/phantomsmp/ConfigSaver.java b/src/main/java/com/simonorj/mc/phantomsmp/ConfigSaver.java index 704e0d9..d6857a9 100644 --- a/src/main/java/com/simonorj/mc/phantomsmp/ConfigSaver.java +++ b/src/main/java/com/simonorj/mc/phantomsmp/ConfigSaver.java @@ -4,6 +4,7 @@ import org.bukkit.configuration.file.FileConfiguration; class ConfigSaver { static final String REMOVE_TARGETING_RESTED_NODE = "remove-targeting-rested"; + static final String REMOVE_WHEN_SLEEPING_NODE = "remove-when-sleeping"; static final String DISALLOW_SPAWNING_FOR_NODE = "disallow-targeting-for"; static final String CONFIG_VERSION_NODE = "config-version"; static final int version = 1; @@ -20,6 +21,11 @@ class ConfigSaver { "# true = remove phantom targeting rested player\n" + "# false = Keep phantoms (and make phantoms try to target another player)\n"; + private static final String REMOVE_WHEN_SLEEPING = + "# Remove phantoms right away when the player sleeps in bed?\n" + + "# true = remove phantoms as soon as player sleeps\n" + + "# false = Keep phantoms (and let the above option take care of it)\n"; + private static final String DISALLOW_SPAWNING_FOR = "# How many ticks since player rested should phantoms ignore the player?\n" + "# NOTE: Any value under 72000 (3 full Minecraft days) will essentially be\n" + @@ -31,6 +37,7 @@ class ConfigSaver { static String saveToString(FileConfiguration config) { boolean remove = config.getBoolean(REMOVE_TARGETING_RESTED_NODE, true); + boolean sleeping = config.getBoolean(REMOVE_WHEN_SLEEPING_NODE, true); int disallow = config.getInt(DISALLOW_SPAWNING_FOR_NODE, 72000); return HEADER + @@ -39,6 +46,10 @@ class ConfigSaver { REMOVE_TARGETING_RESTED_NODE + ": " + remove + "\n\n" + + REMOVE_WHEN_SLEEPING + + REMOVE_WHEN_SLEEPING_NODE + + ": " + sleeping + + "\n\n" + DISALLOW_SPAWNING_FOR + DISALLOW_SPAWNING_FOR_NODE + ": " + disallow + diff --git a/src/main/java/com/simonorj/mc/phantomsmp/PhantomListener.java b/src/main/java/com/simonorj/mc/phantomsmp/PhantomListener.java index 9c77ac4..3e44475 100644 --- a/src/main/java/com/simonorj/mc/phantomsmp/PhantomListener.java +++ b/src/main/java/com/simonorj/mc/phantomsmp/PhantomListener.java @@ -18,18 +18,16 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.world.ChunkLoadEvent; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Map; +import java.util.*; public class PhantomListener implements Listener { private static final String DISALLOW_SPAWN_PERM = "phantomsmp.disallowspawn"; private static final String IGNORE_PERM = "phantomsmp.ignore"; - private Map> playerPhantomMap = new HashMap<>(); - private Map phantomPlayerMap = new HashMap<>(); - private PhantomSMP plugin; + private final Map> playerPhantomMap = new HashMap<>(); + private final Map phantomPlayerMap = new HashMap<>(); + private final Set newPhantom = new LinkedHashSet<>(); + private final PhantomSMP plugin; PhantomListener() { this.plugin = PhantomSMP.getInstance(); @@ -44,75 +42,88 @@ public class PhantomListener implements Listener { for (Entity e : w.getLivingEntities()) if (e instanceof Phantom) - addPhantom((Phantom) e); + targeting((Phantom) e, null, null); } } - void disable() { - this.playerPhantomMap = null; - this.phantomPlayerMap = null; - this.plugin = null; + private boolean recentlyRested(Player p) { + return p.getStatistic(Statistic.TIME_SINCE_REST) < plugin.disallowSpawningFor; } - private boolean phantomSpawnAllowed(Player p) { - return p.getStatistic(Statistic.TIME_SINCE_REST) > plugin.disallowSpawningFor || p.hasPermission(DISALLOW_SPAWN_PERM); - } - - private boolean phantomIgnore(Player p) { - return plugin.removeTargetingRested || p.hasPermission(IGNORE_PERM); - } - - private void addPhantom(Phantom phantom) { - addPhantom(phantom, null); - } - - private void addPhantom(Phantom phantom, Cancellable e) { - addPhantom(phantom, null, e); - } - - private void addPhantom(Phantom phantom, Player newTarget, Cancellable e) { - if (newTarget == null && !(phantom.getTarget() instanceof Player)) { + private void targeting(Phantom phantom, Player newTarget, Cancellable e) { + plugin.getLogger().info("Targeting triggered"); + Player p; + if (newTarget != null) + p = newTarget; + else if (phantom.getTarget() instanceof Player) { + p = (Player) phantom.getTarget(); + } else { + plugin.getLogger().info("Target is null"); return; } - Player p = newTarget != null ? newTarget : (Player) phantom.getTarget(); + // If newly spawned phantom + if (newPhantom.remove(phantom)) { + if (p.hasPermission(DISALLOW_SPAWN_PERM) || recentlyRested(p)) { + if (e != null) + e.setCancelled(true); + phantom.remove(); + plugin.getLogger().info("Phantom removed"); + return; + } + } - // Player rested before - if (!phantomSpawnAllowed(p)) { + // If targeting is not allowed + boolean ignore = p.hasPermission(IGNORE_PERM); + if (ignore || recentlyRested(p)) { if (e != null) e.setCancelled(true); + else + phantom.setTarget(null); - if (phantomIgnore(p)) - if (phantom.getCustomName() == null) - phantom.remove(); + if (!ignore && plugin.removeTargetingRested && phantom.getCustomName() == null) + phantom.remove(); + + plugin.getLogger().info("Phantom targetting cancelled"); + return; } // Phantom spawn is legal playerPhantomMap.computeIfAbsent(p, k -> new LinkedHashSet<>()).add(phantom); phantomPlayerMap.put(phantom, p); + plugin.getLogger().info("Phantom is now targetting"); } - private void removePlayerPhantom(Player p) { + private void spawned(Phantom phantom) { + newPhantom.add(phantom); + plugin.getLogger().info("New phantom spawned"); + } + + private void untarget(Player p, boolean sleeping) { Iterator i = playerPhantomMap.get(p).iterator(); while(i.hasNext()) { Phantom phantom = i.next(); if (phantom.getTarget() == p) { phantomPlayerMap.remove(phantom); phantom.setTarget(null); + plugin.getLogger().info("Phantom no longer targets"); + } + + if (sleeping && plugin.removeWhenSleeping) { + phantom.remove(); + plugin.getLogger().info("Phantom removed"); } i.remove(); } } - // Initiate when player joins @EventHandler(priority = EventPriority.MONITOR) - public void playerJoin(PlayerJoinEvent e) { + public void onPlayerJoin(PlayerJoinEvent e) { playerPhantomMap.put(e.getPlayer(), new LinkedHashSet<>()); } - // Reset when player leaves @EventHandler - public void playerLeave(PlayerQuitEvent e) { + public void onPlayerLeave(PlayerQuitEvent e) { Player p = e.getPlayer(); for (Phantom phantom : playerPhantomMap.get(p)) { @@ -123,54 +134,51 @@ public class PhantomListener implements Listener { } } - // Remove phantoms when player sleeps @EventHandler - public void playerUseBed(PlayerBedEnterEvent e) { - if (e.isCancelled()) - return; - - removePlayerPhantom(e.getPlayer()); - } - - @EventHandler - public void playerDied(PlayerDeathEvent e) { - removePlayerPhantom(e.getEntity()); - } - - // Check phantom when they spawn wrongly - @EventHandler - public void phantomSpawn(CreatureSpawnEvent e) { + public void onPhantomSpawn(CreatureSpawnEvent e) { if (e.isCancelled() || !(e.getEntity() instanceof Phantom)) { return; } - addPhantom((Phantom) e.getEntity(), e); + spawned((Phantom) e.getEntity()); + } + + @EventHandler + public void onPlayerSleeping(PlayerBedEnterEvent e) { + if (e.isCancelled()) + return; + + untarget(e.getPlayer(), true); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent e) { + untarget(e.getEntity(), false); } // Remove phantom that targets player who slept @EventHandler - public void phantomTarget(EntityTargetLivingEntityEvent e) { + public void onPhantomTargeting(EntityTargetLivingEntityEvent e) { if (e.isCancelled() || !(e.getEntity() instanceof Phantom && e.getTarget() instanceof Player)) { return; } - addPhantom((Phantom) e.getEntity(), (Player) e.getTarget(), e); + targeting((Phantom) e.getEntity(), (Player) e.getTarget(), e); } // Check phantom in loaded chunks @EventHandler - public void phantomInLoadedChunk(ChunkLoadEvent e) { + public void onPhantomInLoadedChunk(ChunkLoadEvent e) { if (e.getWorld().getEnvironment() != World.Environment.NORMAL) return; for (Entity ent : e.getChunk().getEntities()) if (ent instanceof Phantom) - addPhantom((Phantom) ent); + targeting((Phantom) ent, null, null); } - // Check phantom on death @EventHandler - public void phantomDied(EntityDeathEvent e) { + public void onPhantomDeath(EntityDeathEvent e) { if (!(e.getEntity() instanceof Phantom)) return; diff --git a/src/main/java/com/simonorj/mc/phantomsmp/PhantomSMP.java b/src/main/java/com/simonorj/mc/phantomsmp/PhantomSMP.java index 30964ac..8e8d3f3 100644 --- a/src/main/java/com/simonorj/mc/phantomsmp/PhantomSMP.java +++ b/src/main/java/com/simonorj/mc/phantomsmp/PhantomSMP.java @@ -10,6 +10,7 @@ public class PhantomSMP extends JavaPlugin { private static PhantomSMP instance = null; private PhantomListener listener = null; boolean removeTargetingRested; + boolean removeWhenSleeping; int disallowSpawningFor; @Override @@ -21,6 +22,7 @@ public class PhantomSMP extends JavaPlugin { saveConfig(); this.removeTargetingRested = getConfig().getBoolean(ConfigSaver.REMOVE_TARGETING_RESTED_NODE, true); + this.removeWhenSleeping = getConfig().getBoolean(ConfigSaver.REMOVE_WHEN_SLEEPING_NODE, false); this.disallowSpawningFor= getConfig().getInt(ConfigSaver.DISALLOW_SPAWNING_FOR_NODE, 72000); this.listener = new PhantomListener(); @@ -29,9 +31,8 @@ public class PhantomSMP extends JavaPlugin { @Override public void onDisable() { - PhantomSMP.instance = null; - listener.disable(); listener = null; + PhantomSMP.instance = null; } @Override @@ -51,7 +52,7 @@ public class PhantomSMP extends JavaPlugin { } } - public static PhantomSMP getInstance() { + static PhantomSMP getInstance() { return instance; } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4c8dc4a..5663284 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -6,9 +6,14 @@ # Remove phantoms that try to target player slept within three (Minecraft) # days? # true = remove phantom targeting rested player -# false = Keep phantoms (and make phantoms try to target another player) +# false = Keep phantoms (and make phantoms ignore the player) remove-targeting-rested: true +# Remove phantoms right away when the player sleeps in bed? +# true = remove phantoms as soon as player sleeps +# false = Keep phantoms (and let the above option take care of it) +remove-when-sleeping: false + # How many ticks since player rested should phantoms ignore the player? # NOTE: Any value under 72000 (3 full Minecraft days) will essentially be # ignored for phantom spawning. It will only have an effect on already diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index e976fb2..7551dd6 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -8,11 +8,11 @@ api-version: 1.13 permissions: phantomsmp.disallowspawn: - description: Don't let phantom spawn on the player at all. + description: Don't let phantom spawn on the player. default: false phantomsmp.ignore: description: > - Don't let phantoms target the player or be removed. + Don't let phantoms target the player. This will ignore `remove-targeting-rested` configuration option for the - player and keep the phantom flying around. + player and keep the phantom flying around as if nothing happened. default: false