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
- combat timer - deny players changing pvp state mid combat
-- smart cache - way to check offline players pvp state without constant I/O
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."