diff --git a/readme.md b/readme.md index 7a03050..9f26a44 100644 --- a/readme.md +++ b/readme.md @@ -42,7 +42,6 @@ Tamed wolves will not attack players with pvp off.

TODO

diff --git a/src/main/java/eu/endermite/togglepvp/TogglePvP.java b/src/main/java/eu/endermite/togglepvp/TogglePvP.java index 10917d9..e292242 100644 --- a/src/main/java/eu/endermite/togglepvp/TogglePvP.java +++ b/src/main/java/eu/endermite/togglepvp/TogglePvP.java @@ -3,8 +3,10 @@ package eu.endermite.togglepvp; import eu.endermite.togglepvp.commands.MainCommand; import eu.endermite.togglepvp.config.ConfigCache; import eu.endermite.togglepvp.listeners.player.*; -import eu.endermite.togglepvp.listeners.wolf.WolfAttackPlayerListener; -import eu.endermite.togglepvp.listeners.wolf.WolfTargettingListener; +import eu.endermite.togglepvp.listeners.player.WolfAttackPlayerListener; +import eu.endermite.togglepvp.listeners.player.WolfTargettingPlayerListener; +import eu.endermite.togglepvp.listeners.wolf.PlayerAttackWolfListener; +import eu.endermite.togglepvp.listeners.wolf.PlayerHitWolfByProjectile; import eu.endermite.togglepvp.players.PlayerManager; import eu.endermite.togglepvp.players.SmartCache; import eu.endermite.togglepvp.util.DatabaseSQLite; @@ -46,10 +48,12 @@ public final class TogglePvP extends JavaPlugin { getServer().getPluginManager().registerEvents(new LavaDumpAndIgniteListener(), this); getServer().getPluginManager().registerEvents(new PlayerPlaceWitherRoseListener(), this); getServer().getPluginManager().registerEvents(new PlayerHitByExplosionListener(), this); - - getServer().getPluginManager().registerEvents(new WolfTargettingListener(), this); + getServer().getPluginManager().registerEvents(new WolfTargettingPlayerListener(), this); getServer().getPluginManager().registerEvents(new WolfAttackPlayerListener(), this); + getServer().getPluginManager().registerEvents(new PlayerAttackWolfListener(), this); + getServer().getPluginManager().registerEvents(new PlayerHitWolfByProjectile(), this); + Objects.requireNonNull(getCommand("pvp")).setExecutor(new MainCommand()); Objects.requireNonNull(getCommand("pvp")).setTabCompleter(new MainCommand()); } diff --git a/src/main/java/eu/endermite/togglepvp/config/ConfigCache.java b/src/main/java/eu/endermite/togglepvp/config/ConfigCache.java index 4fda211..e62e648 100644 --- a/src/main/java/eu/endermite/togglepvp/config/ConfigCache.java +++ b/src/main/java/eu/endermite/togglepvp/config/ConfigCache.java @@ -12,6 +12,8 @@ public class ConfigCache { @Getter private final String pvp_disabled; @Getter private final String cannot_attack_victim; @Getter private final String cannot_attack_attacker; + @Getter private final String cannot_attack_pets_victim; + @Getter private final String cannot_attack_pets_attacker; @Getter private final String no_permission; @Getter private final String no_such_command; @Getter private final String pvp_enabled_other; @@ -39,6 +41,8 @@ public class ConfigCache { this.pvp_disabled = config.getString("messages.pvp_disabled", "&cYou disabled PvP!"); this.cannot_attack_victim = config.getString("messages.cannot_attack_victim", "&cYou can't attack players that have PvP turned off!"); this.cannot_attack_attacker = config.getString("messages.cannot_attack_attacker", "&cYou can't attack players while you have PvP turned off!"); + this.cannot_attack_pets_victim = config.getString("messages.cannot_attack_pets_victim", "&cYou can't attack pets while you have PvP turned off"); + this.cannot_attack_pets_attacker = config.getString("messages.cannot_attack_pets_attacker", "&cYou can't attack pets of players that have PvP turned off"); this.no_permission = config.getString("messages.no_permission", "&cYou don't have permission to use that."); this.no_such_command = config.getString("messages.no_such_command", "&cNo such command."); this.pvp_enabled_other = config.getString("messages.pvp_enabled_others", "&cYou've enabled %player%'s PvP."); diff --git a/src/main/java/eu/endermite/togglepvp/listeners/player/PlayerHitByExplosionListener.java b/src/main/java/eu/endermite/togglepvp/listeners/player/PlayerHitByExplosionListener.java index 7af89e5..413d335 100644 --- a/src/main/java/eu/endermite/togglepvp/listeners/player/PlayerHitByExplosionListener.java +++ b/src/main/java/eu/endermite/togglepvp/listeners/player/PlayerHitByExplosionListener.java @@ -2,8 +2,8 @@ package eu.endermite.togglepvp.listeners.player; import eu.endermite.togglepvp.TogglePvP; import eu.endermite.togglepvp.config.ConfigCache; +import eu.endermite.togglepvp.players.SmartCache; import eu.endermite.togglepvp.util.PluginMessages; -import org.bukkit.Bukkit; import org.bukkit.entity.*; import org.bukkit.entity.minecart.ExplosiveMinecart; import org.bukkit.event.EventHandler; @@ -24,26 +24,23 @@ public class PlayerHitByExplosionListener implements Listener { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPlayerHitByExplosion(org.bukkit.event.entity.EntityDamageByEntityEvent event) { if (event.getEntity() instanceof Player) { - if (!event.getCause().equals(EntityDamageEvent.DamageCause.ENTITY_EXPLOSION)) { return; } - Player victim = (Player) event.getEntity(); try { - UUID playeruuid = UUID.fromString(event.getDamager().getMetadata("PLAYEREXPLODED").get(0).asString()); - Player damager = Bukkit.getPlayer(playeruuid); - if (victim != damager) { + UUID damageruuid = UUID.fromString(event.getDamager().getMetadata("PLAYEREXPLODED").get(0).asString()); + if (!victim.getUniqueId().equals(damageruuid)) { ConfigCache config = TogglePvP.getPlugin().getConfigCache(); - boolean damagerPvpEnabled = TogglePvP.getPlugin().getPlayerManager().getPlayerPvPState(damager.getUniqueId()); + boolean damagerPvpEnabled = (boolean) SmartCache.getPlayerData(damageruuid).get("pvpenabled"); if (!damagerPvpEnabled) { - PluginMessages.sendActionBar(damager, config.getCannot_attack_attacker()); + PluginMessages.sendActionBar(damageruuid, config.getCannot_attack_attacker()); event.setCancelled(true); return; } boolean victimPvpEnabled = TogglePvP.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId()); if (!victimPvpEnabled) { - PluginMessages.sendActionBar(damager, config.getCannot_attack_victim()); + PluginMessages.sendActionBar(damageruuid, config.getCannot_attack_victim()); event.setCancelled(true); return; } @@ -55,6 +52,7 @@ public class PlayerHitByExplosionListener implements Listener { /** * Tags ender crystal with exploder uuid */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPlayerHitEnderCrystal(org.bukkit.event.entity.EntityDamageByEntityEvent event) { if (event.getEntity() instanceof EnderCrystal) { @@ -94,6 +92,7 @@ public class PlayerHitByExplosionListener implements Listener { /** * Tag TNT minecart with placing player uuid */ + @SuppressWarnings("deprecation") @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPlayerPlacedTntMinecart(org.bukkit.event.entity.EntityPlaceEvent event) { if (event.getEntityType().equals(EntityType.MINECART_TNT)) { diff --git a/src/main/java/eu/endermite/togglepvp/listeners/player/PlayerHitByProjectileListener.java b/src/main/java/eu/endermite/togglepvp/listeners/player/PlayerHitByProjectileListener.java index 4276fee..7e1dc89 100644 --- a/src/main/java/eu/endermite/togglepvp/listeners/player/PlayerHitByProjectileListener.java +++ b/src/main/java/eu/endermite/togglepvp/listeners/player/PlayerHitByProjectileListener.java @@ -42,10 +42,8 @@ public class PlayerHitByProjectileListener implements Listener { event.setCancelled(true); PluginMessages.sendActionBar(damager, config.getCannot_attack_victim()); } - } } - } } diff --git a/src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfAttackPlayerListener.java b/src/main/java/eu/endermite/togglepvp/listeners/player/WolfAttackPlayerListener.java similarity index 53% rename from src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfAttackPlayerListener.java rename to src/main/java/eu/endermite/togglepvp/listeners/player/WolfAttackPlayerListener.java index 5758674..cd513b5 100644 --- a/src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfAttackPlayerListener.java +++ b/src/main/java/eu/endermite/togglepvp/listeners/player/WolfAttackPlayerListener.java @@ -1,6 +1,7 @@ -package eu.endermite.togglepvp.listeners.wolf; +package eu.endermite.togglepvp.listeners.player; import eu.endermite.togglepvp.TogglePvP; +import eu.endermite.togglepvp.players.SmartCache; import org.bukkit.entity.Player; import org.bukkit.entity.Wolf; import org.bukkit.event.EventHandler; @@ -18,14 +19,16 @@ public class WolfAttackPlayerListener implements Listener { if (event.getDamager() instanceof Wolf) { Wolf wolf = (Wolf) event.getDamager(); if (wolf.getOwner() != null && event.getEntity() instanceof Player) { - - //TODO check if offline wolf owner has pvp on or off and cancel this accordingly - - Player victim = (Player) event.getEntity(); - boolean victimPvpEnabled = TogglePvP.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId()); - if (!victimPvpEnabled) { - wolf.setAngry(false); - event.setCancelled(true); + try { + boolean damagerPvpEnabled = (boolean) SmartCache.getPlayerData(wolf.getOwner().getUniqueId()).get("pvpenabled"); + Player victim = (Player) event.getEntity(); + boolean victimPvpEnabled = TogglePvP.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId()); + if (!victimPvpEnabled || !damagerPvpEnabled) { + wolf.setAngry(false); + event.setCancelled(true); + } + } catch (NullPointerException e) { + return; } } } diff --git a/src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfTargettingListener.java b/src/main/java/eu/endermite/togglepvp/listeners/player/WolfTargettingPlayerListener.java similarity index 80% rename from src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfTargettingListener.java rename to src/main/java/eu/endermite/togglepvp/listeners/player/WolfTargettingPlayerListener.java index 5b95158..dd23eae 100644 --- a/src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfTargettingListener.java +++ b/src/main/java/eu/endermite/togglepvp/listeners/player/WolfTargettingPlayerListener.java @@ -1,6 +1,7 @@ -package eu.endermite.togglepvp.listeners.wolf; +package eu.endermite.togglepvp.listeners.player; import eu.endermite.togglepvp.TogglePvP; +import eu.endermite.togglepvp.players.SmartCache; import org.bukkit.entity.Fox; import org.bukkit.entity.Player; import org.bukkit.entity.Wolf; @@ -8,7 +9,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -public class WolfTargettingListener implements Listener { +public class WolfTargettingPlayerListener implements Listener { /** * Stops wolves with owners targetting players with pvp off @@ -19,9 +20,11 @@ public class WolfTargettingListener implements Listener { Wolf wolf = (Wolf) event.getEntity(); if (wolf.getOwner() != null) { if (event.getTarget() instanceof Player) { + + boolean attackerPvPEnabled = (boolean) SmartCache.getPlayerData(wolf.getOwner().getUniqueId()).get("pvpenabled"); Player victim = (Player) event.getTarget(); boolean victimPvpEnabled = TogglePvP.getPlugin().getPlayerManager().getPlayerPvPState(victim.getUniqueId()); - if (!victimPvpEnabled) { + if (!attackerPvPEnabled || !victimPvpEnabled) { event.setCancelled(true); } } diff --git a/src/main/java/eu/endermite/togglepvp/listeners/wolf/PlayerAttackWolfListener.java b/src/main/java/eu/endermite/togglepvp/listeners/wolf/PlayerAttackWolfListener.java new file mode 100644 index 0000000..6fd8c7b --- /dev/null +++ b/src/main/java/eu/endermite/togglepvp/listeners/wolf/PlayerAttackWolfListener.java @@ -0,0 +1,48 @@ +package eu.endermite.togglepvp.listeners.wolf; + +import eu.endermite.togglepvp.TogglePvP; +import eu.endermite.togglepvp.config.ConfigCache; +import eu.endermite.togglepvp.players.SmartCache; +import eu.endermite.togglepvp.util.PluginMessages; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wolf; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +public class PlayerAttackWolfListener implements Listener { + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerAttackWolf(org.bukkit.event.entity.EntityDamageByEntityEvent event) { + + if (event.getDamager() instanceof Player && event.getEntity() instanceof Wolf) { + Wolf wolf = (Wolf) event.getEntity(); + if (wolf.getOwner() != null) { + Player damager = (Player) event.getDamager(); + + if (damager.getUniqueId() == wolf.getOwner().getUniqueId()) { + return; + } + + ConfigCache config = TogglePvP.getPlugin().getConfigCache(); + boolean damagerPvpState = TogglePvP.getPlugin().getPlayerManager().getPlayerPvPState(damager.getUniqueId()); + + if (!damagerPvpState) { + PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker()); + event.setCancelled(true); + return; + } + boolean victimPvpEnabled = (boolean) SmartCache.getPlayerData(wolf.getOwner().getUniqueId()).get("pvpenabled"); + if (!victimPvpEnabled) { + PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim()); + event.setCancelled(true); + } + + + } + + } + + } + +} diff --git a/src/main/java/eu/endermite/togglepvp/listeners/wolf/PlayerHitWolfByProjectile.java b/src/main/java/eu/endermite/togglepvp/listeners/wolf/PlayerHitWolfByProjectile.java new file mode 100644 index 0000000..1c0953e --- /dev/null +++ b/src/main/java/eu/endermite/togglepvp/listeners/wolf/PlayerHitWolfByProjectile.java @@ -0,0 +1,47 @@ +package eu.endermite.togglepvp.listeners.wolf; + +import eu.endermite.togglepvp.TogglePvP; +import eu.endermite.togglepvp.config.ConfigCache; +import eu.endermite.togglepvp.util.PluginMessages; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Wolf; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +public class PlayerHitWolfByProjectile implements Listener { + + /** + * Cancels damage done by projectiles to pets of players with pvp off + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onWolfHitByProjectile(org.bukkit.event.entity.EntityDamageByEntityEvent event) { + + if (event.getEntity() instanceof Wolf && event.getDamager() instanceof Projectile) { + Projectile projectile = (Projectile) event.getDamager(); + if (projectile.getShooter() instanceof Player) { + Wolf victim = (Wolf) event.getEntity(); + + if (victim.getOwner() == null) { + return; + } + Player damager = (Player) projectile.getShooter(); + ConfigCache config = TogglePvP.getPlugin().getConfigCache(); + boolean damagerPvpEnabled = TogglePvP.getPlugin().getPlayerManager().getPlayerPvPState(damager.getUniqueId()); + boolean victimPvpEnabled = TogglePvP.getPlugin().getPlayerManager().getPlayerPvPState(victim.getOwner().getUniqueId()); + + if (!damagerPvpEnabled) { + event.setCancelled(true); + PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_attacker()); + return; + } + if (!victimPvpEnabled) { + event.setCancelled(true); + PluginMessages.sendActionBar(damager, config.getCannot_attack_pets_victim()); + } + } + } + } + +} diff --git a/src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfTargettingWolfListener.java b/src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfTargettingWolfListener.java new file mode 100644 index 0000000..9b54246 --- /dev/null +++ b/src/main/java/eu/endermite/togglepvp/listeners/wolf/WolfTargettingWolfListener.java @@ -0,0 +1,31 @@ +package eu.endermite.togglepvp.listeners.wolf; + +import eu.endermite.togglepvp.players.SmartCache; +import org.bukkit.entity.Wolf; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +public class WolfTargettingWolfListener implements Listener { + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onWolfAttackWolf(org.bukkit.event.entity.EntityDamageByEntityEvent event) { + if (event.getDamager() instanceof Wolf && event.getEntity() instanceof Wolf) { + Wolf damager = (Wolf) event.getDamager(); + Wolf victim = (Wolf) event.getEntity(); + if (damager.getOwner() != null && damager.getOwner() != null) { + try { + boolean damagerPvpEnabled = (boolean) SmartCache.getPlayerData(damager.getOwner().getUniqueId()).get("pvpenabled"); + boolean victimPvpEnabled = (boolean) SmartCache.getPlayerData(victim.getOwner().getUniqueId()).get("pvpenabled"); + if (!victimPvpEnabled || !damagerPvpEnabled) { + damager.setAngry(false); + event.setCancelled(true); + } + } catch (NullPointerException e) { + return; + } + } + } + } + +} diff --git a/src/main/java/eu/endermite/togglepvp/players/SmartCache.java b/src/main/java/eu/endermite/togglepvp/players/SmartCache.java index 131a793..9e47e09 100644 --- a/src/main/java/eu/endermite/togglepvp/players/SmartCache.java +++ b/src/main/java/eu/endermite/togglepvp/players/SmartCache.java @@ -28,17 +28,33 @@ public class SmartCache { } // Check for entries that should be invalidated - long now = Instant.now().getEpochSecond(); - Iterator>> it = TogglePvP.getPlugin().getPlayerManager().getPlayerList().entrySet().iterator(); - while(it.hasNext()) { - Map.Entry> cacheEntry = it.next(); - if ((Long) cacheEntry.getValue().get("cachetime") < now) { - TogglePvP.getPlugin().getPlayerManager().removePlayer(cacheEntry.getKey()); - } - } + try { + long now = Instant.now().getEpochSecond(); + TogglePvP.getPlugin().getPlayerManager().getPlayerList().entrySet().removeIf(cacheEntry -> (Long) cacheEntry.getValue().get("cachetime") < now); + } catch (Exception ignored) {} } }.runTaskTimerAsynchronously(TogglePvP.getPlugin(), 100, 100); } + public static HashMap getPlayerData(UUID uuid) { + // Try to get data from cache and refresh it + try { + TogglePvP.getPlugin().getPlayerManager().refreshPlayersCacheTime(uuid); + return TogglePvP.getPlugin().getPlayerManager().getPlayer(uuid); + } catch (NullPointerException e) { + // If player data is not in cache get it from database and put into cache + try { + HashMap playerData; + playerData = TogglePvP.getPlugin().getSqLite().getPlayerInfo(uuid); + playerData.put("cachetime", TogglePvP.getPlugin().getPlayerManager().refreshedCacheTime()); + TogglePvP.getPlugin().getPlayerManager().addPlayer(uuid, playerData); + return playerData; + } catch (NullPointerException ex) { + // Return null if database call fails + return null; + } + } + } + } diff --git a/src/main/java/eu/endermite/togglepvp/util/PluginMessages.java b/src/main/java/eu/endermite/togglepvp/util/PluginMessages.java index db3e249..ca754a3 100644 --- a/src/main/java/eu/endermite/togglepvp/util/PluginMessages.java +++ b/src/main/java/eu/endermite/togglepvp/util/PluginMessages.java @@ -3,9 +3,12 @@ package eu.endermite.togglepvp.util; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; +import java.util.UUID; + public class PluginMessages { @@ -19,6 +22,13 @@ public class PluginMessages { player.spigot().sendMessage(ChatMessageType.ACTION_BAR, component); } + public static void sendActionBar(UUID uuid, String message) { + try { + Player player = Bukkit.getPlayer(uuid); + sendActionBar(player, message); + } catch (NullPointerException ignored) {} + } + public static String parsePlayerName(Player player, String message) { message = message.replaceAll("%player%", player.getDisplayName()); return parseMessage(message); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f2aa2d1..fefab2d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -21,6 +21,8 @@ messages: pvp_disabled: "&cYou disabled PvP!" cannot_attack_victim: "&cYou can't attack players that have PvP turned off!" cannot_attack_attacker: "&cYou can't attack players while you have PvP turned off!" + cannot_attack_pets_victim: "&cYou can't attack pets of players that have PvP turned off" + cannot_attack_pets_attacker: "&cYou can't attack pets while you have PvP turned off" no_permission: "&cYou don't have permission to use that." no_such_command: "&cNo such command." pvp_enabled_others: "&cYou've enabled %player%'s PvP."