mirror of
https://github.com/chuushi/PhantomSMP.git
synced 2024-11-25 11:35:29 +01:00
Refactor Code
This commit is contained in:
parent
9f41e62de5
commit
9ecd44019d
35
readme.md
35
readme.md
@ -3,18 +3,35 @@
|
|||||||
Better Phantom handling for SMP
|
Better Phantom handling for SMP
|
||||||
|
|
||||||
# Configuration
|
# 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
|
There are two configuration options that you can set.
|
||||||
# PhantomSMP by SimonOrJ
|
|
||||||
|
|
||||||
# Remove phantoms that try to target player slept within three (Minecraft) days?
|
* `remove-targeting-rested`: *Default: true.* Remove phantoms that try to
|
||||||
# true = remove phantom targeting rested player
|
target players who recently rested.
|
||||||
# false = Keep phantoms (and make phantoms try to target another player)
|
* `remove-when-sleeping`: *Default: false.* Remove phantoms as soon as player
|
||||||
remove-targeting-rested: true
|
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
|
# External Links
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import org.bukkit.configuration.file.FileConfiguration;
|
|||||||
|
|
||||||
class ConfigSaver {
|
class ConfigSaver {
|
||||||
static final String REMOVE_TARGETING_RESTED_NODE = "remove-targeting-rested";
|
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 DISALLOW_SPAWNING_FOR_NODE = "disallow-targeting-for";
|
||||||
static final String CONFIG_VERSION_NODE = "config-version";
|
static final String CONFIG_VERSION_NODE = "config-version";
|
||||||
static final int version = 1;
|
static final int version = 1;
|
||||||
@ -20,6 +21,11 @@ class ConfigSaver {
|
|||||||
"# true = remove phantom targeting rested player\n" +
|
"# true = remove phantom targeting rested player\n" +
|
||||||
"# false = Keep phantoms (and make phantoms try to target another 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 =
|
private static final String DISALLOW_SPAWNING_FOR =
|
||||||
"# How many ticks since player rested should phantoms ignore the player?\n" +
|
"# 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" +
|
"# NOTE: Any value under 72000 (3 full Minecraft days) will essentially be\n" +
|
||||||
@ -31,6 +37,7 @@ class ConfigSaver {
|
|||||||
|
|
||||||
static String saveToString(FileConfiguration config) {
|
static String saveToString(FileConfiguration config) {
|
||||||
boolean remove = config.getBoolean(REMOVE_TARGETING_RESTED_NODE, true);
|
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);
|
int disallow = config.getInt(DISALLOW_SPAWNING_FOR_NODE, 72000);
|
||||||
|
|
||||||
return HEADER +
|
return HEADER +
|
||||||
@ -39,6 +46,10 @@ class ConfigSaver {
|
|||||||
REMOVE_TARGETING_RESTED_NODE +
|
REMOVE_TARGETING_RESTED_NODE +
|
||||||
": " + remove +
|
": " + remove +
|
||||||
"\n\n" +
|
"\n\n" +
|
||||||
|
REMOVE_WHEN_SLEEPING +
|
||||||
|
REMOVE_WHEN_SLEEPING_NODE +
|
||||||
|
": " + sleeping +
|
||||||
|
"\n\n" +
|
||||||
DISALLOW_SPAWNING_FOR +
|
DISALLOW_SPAWNING_FOR +
|
||||||
DISALLOW_SPAWNING_FOR_NODE +
|
DISALLOW_SPAWNING_FOR_NODE +
|
||||||
": " + disallow +
|
": " + disallow +
|
||||||
|
@ -18,18 +18,16 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
|||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class PhantomListener implements Listener {
|
public class PhantomListener implements Listener {
|
||||||
private static final String DISALLOW_SPAWN_PERM = "phantomsmp.disallowspawn";
|
private static final String DISALLOW_SPAWN_PERM = "phantomsmp.disallowspawn";
|
||||||
private static final String IGNORE_PERM = "phantomsmp.ignore";
|
private static final String IGNORE_PERM = "phantomsmp.ignore";
|
||||||
|
|
||||||
private Map<Player, LinkedHashSet<Phantom>> playerPhantomMap = new HashMap<>();
|
private final Map<Player, LinkedHashSet<Phantom>> playerPhantomMap = new HashMap<>();
|
||||||
private Map<Phantom, Player> phantomPlayerMap = new HashMap<>();
|
private final Map<Phantom, Player> phantomPlayerMap = new HashMap<>();
|
||||||
private PhantomSMP plugin;
|
private final Set<Phantom> newPhantom = new LinkedHashSet<>();
|
||||||
|
private final PhantomSMP plugin;
|
||||||
|
|
||||||
PhantomListener() {
|
PhantomListener() {
|
||||||
this.plugin = PhantomSMP.getInstance();
|
this.plugin = PhantomSMP.getInstance();
|
||||||
@ -44,75 +42,88 @@ public class PhantomListener implements Listener {
|
|||||||
|
|
||||||
for (Entity e : w.getLivingEntities())
|
for (Entity e : w.getLivingEntities())
|
||||||
if (e instanceof Phantom)
|
if (e instanceof Phantom)
|
||||||
addPhantom((Phantom) e);
|
targeting((Phantom) e, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable() {
|
private boolean recentlyRested(Player p) {
|
||||||
this.playerPhantomMap = null;
|
return p.getStatistic(Statistic.TIME_SINCE_REST) < plugin.disallowSpawningFor;
|
||||||
this.phantomPlayerMap = null;
|
|
||||||
this.plugin = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean phantomSpawnAllowed(Player p) {
|
private void targeting(Phantom phantom, Player newTarget, Cancellable e) {
|
||||||
return p.getStatistic(Statistic.TIME_SINCE_REST) > plugin.disallowSpawningFor || p.hasPermission(DISALLOW_SPAWN_PERM);
|
plugin.getLogger().info("Targeting triggered");
|
||||||
}
|
Player p;
|
||||||
|
if (newTarget != null)
|
||||||
private boolean phantomIgnore(Player p) {
|
p = newTarget;
|
||||||
return plugin.removeTargetingRested || p.hasPermission(IGNORE_PERM);
|
else if (phantom.getTarget() instanceof Player) {
|
||||||
}
|
p = (Player) phantom.getTarget();
|
||||||
|
} else {
|
||||||
private void addPhantom(Phantom phantom) {
|
plugin.getLogger().info("Target is null");
|
||||||
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)) {
|
|
||||||
return;
|
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 targeting is not allowed
|
||||||
if (!phantomSpawnAllowed(p)) {
|
boolean ignore = p.hasPermission(IGNORE_PERM);
|
||||||
|
if (ignore || recentlyRested(p)) {
|
||||||
if (e != null)
|
if (e != null)
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
|
else
|
||||||
|
phantom.setTarget(null);
|
||||||
|
|
||||||
if (phantomIgnore(p))
|
if (!ignore && plugin.removeTargetingRested && phantom.getCustomName() == null)
|
||||||
if (phantom.getCustomName() == null)
|
phantom.remove();
|
||||||
phantom.remove();
|
|
||||||
|
plugin.getLogger().info("Phantom targetting cancelled");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phantom spawn is legal
|
// Phantom spawn is legal
|
||||||
playerPhantomMap.computeIfAbsent(p, k -> new LinkedHashSet<>()).add(phantom);
|
playerPhantomMap.computeIfAbsent(p, k -> new LinkedHashSet<>()).add(phantom);
|
||||||
phantomPlayerMap.put(phantom, p);
|
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<Phantom> i = playerPhantomMap.get(p).iterator();
|
Iterator<Phantom> i = playerPhantomMap.get(p).iterator();
|
||||||
while(i.hasNext()) {
|
while(i.hasNext()) {
|
||||||
Phantom phantom = i.next();
|
Phantom phantom = i.next();
|
||||||
if (phantom.getTarget() == p) {
|
if (phantom.getTarget() == p) {
|
||||||
phantomPlayerMap.remove(phantom);
|
phantomPlayerMap.remove(phantom);
|
||||||
phantom.setTarget(null);
|
phantom.setTarget(null);
|
||||||
|
plugin.getLogger().info("Phantom no longer targets");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sleeping && plugin.removeWhenSleeping) {
|
||||||
|
phantom.remove();
|
||||||
|
plugin.getLogger().info("Phantom removed");
|
||||||
}
|
}
|
||||||
i.remove();
|
i.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate when player joins
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void playerJoin(PlayerJoinEvent e) {
|
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||||
playerPhantomMap.put(e.getPlayer(), new LinkedHashSet<>());
|
playerPhantomMap.put(e.getPlayer(), new LinkedHashSet<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset when player leaves
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void playerLeave(PlayerQuitEvent e) {
|
public void onPlayerLeave(PlayerQuitEvent e) {
|
||||||
Player p = e.getPlayer();
|
Player p = e.getPlayer();
|
||||||
|
|
||||||
for (Phantom phantom : playerPhantomMap.get(p)) {
|
for (Phantom phantom : playerPhantomMap.get(p)) {
|
||||||
@ -123,54 +134,51 @@ public class PhantomListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove phantoms when player sleeps
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void playerUseBed(PlayerBedEnterEvent e) {
|
public void onPhantomSpawn(CreatureSpawnEvent 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) {
|
|
||||||
if (e.isCancelled() || !(e.getEntity() instanceof Phantom)) {
|
if (e.isCancelled() || !(e.getEntity() instanceof Phantom)) {
|
||||||
return;
|
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
|
// Remove phantom that targets player who slept
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void phantomTarget(EntityTargetLivingEntityEvent e) {
|
public void onPhantomTargeting(EntityTargetLivingEntityEvent e) {
|
||||||
if (e.isCancelled() || !(e.getEntity() instanceof Phantom && e.getTarget() instanceof Player)) {
|
if (e.isCancelled() || !(e.getEntity() instanceof Phantom && e.getTarget() instanceof Player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addPhantom((Phantom) e.getEntity(), (Player) e.getTarget(), e);
|
targeting((Phantom) e.getEntity(), (Player) e.getTarget(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check phantom in loaded chunks
|
// Check phantom in loaded chunks
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void phantomInLoadedChunk(ChunkLoadEvent e) {
|
public void onPhantomInLoadedChunk(ChunkLoadEvent e) {
|
||||||
if (e.getWorld().getEnvironment() != World.Environment.NORMAL)
|
if (e.getWorld().getEnvironment() != World.Environment.NORMAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (Entity ent : e.getChunk().getEntities())
|
for (Entity ent : e.getChunk().getEntities())
|
||||||
if (ent instanceof Phantom)
|
if (ent instanceof Phantom)
|
||||||
addPhantom((Phantom) ent);
|
targeting((Phantom) ent, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check phantom on death
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void phantomDied(EntityDeathEvent e) {
|
public void onPhantomDeath(EntityDeathEvent e) {
|
||||||
if (!(e.getEntity() instanceof Phantom))
|
if (!(e.getEntity() instanceof Phantom))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ public class PhantomSMP extends JavaPlugin {
|
|||||||
private static PhantomSMP instance = null;
|
private static PhantomSMP instance = null;
|
||||||
private PhantomListener listener = null;
|
private PhantomListener listener = null;
|
||||||
boolean removeTargetingRested;
|
boolean removeTargetingRested;
|
||||||
|
boolean removeWhenSleeping;
|
||||||
int disallowSpawningFor;
|
int disallowSpawningFor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -21,6 +22,7 @@ public class PhantomSMP extends JavaPlugin {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
|
|
||||||
this.removeTargetingRested = getConfig().getBoolean(ConfigSaver.REMOVE_TARGETING_RESTED_NODE, true);
|
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.disallowSpawningFor= getConfig().getInt(ConfigSaver.DISALLOW_SPAWNING_FOR_NODE, 72000);
|
||||||
|
|
||||||
this.listener = new PhantomListener();
|
this.listener = new PhantomListener();
|
||||||
@ -29,9 +31,8 @@ public class PhantomSMP extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
PhantomSMP.instance = null;
|
|
||||||
listener.disable();
|
|
||||||
listener = null;
|
listener = null;
|
||||||
|
PhantomSMP.instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -51,7 +52,7 @@ public class PhantomSMP extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PhantomSMP getInstance() {
|
static PhantomSMP getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,14 @@
|
|||||||
# Remove phantoms that try to target player slept within three (Minecraft)
|
# Remove phantoms that try to target player slept within three (Minecraft)
|
||||||
# days?
|
# days?
|
||||||
# true = remove phantom targeting rested player
|
# 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-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?
|
# How many ticks since player rested should phantoms ignore the player?
|
||||||
# NOTE: Any value under 72000 (3 full Minecraft days) will essentially be
|
# NOTE: Any value under 72000 (3 full Minecraft days) will essentially be
|
||||||
# ignored for phantom spawning. It will only have an effect on already
|
# ignored for phantom spawning. It will only have an effect on already
|
||||||
|
@ -8,11 +8,11 @@ api-version: 1.13
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
phantomsmp.disallowspawn:
|
phantomsmp.disallowspawn:
|
||||||
description: Don't let phantom spawn on the player at all.
|
description: Don't let phantom spawn on the player.
|
||||||
default: false
|
default: false
|
||||||
phantomsmp.ignore:
|
phantomsmp.ignore:
|
||||||
description: >
|
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
|
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
|
default: false
|
||||||
|
Loading…
Reference in New Issue
Block a user