diff --git a/.classpath b/.classpath index 0ed1de4..bb537a2 100644 --- a/.classpath +++ b/.classpath @@ -2,12 +2,8 @@ - - - - - - + + diff --git a/.gitignore b/.gitignore index 95fe00e..13a3cff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ -bukkit.jar -PhysicalShop.jar -craftbukkit.jar -*.class +bukkit.jar +PhysicalShop.jar +craftbukkit.jar +*.class +.idea +/craftbukkit-1.4.5-R0.3-SNAPSHOT.jar +/CombatTag.jar diff --git a/plugin.yml b/plugin.yml index f772bdc..4914806 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,92 +1,119 @@ -name: PrisonPearl -main: com.untamedears.PrisonPearl.PrisonPearlPlugin -version: 1.3 -soft-depend: [PhysicalShop] - -commands: - pplocate: - description: Locates your prison pearl - usage: / - aliases: ppl - - pplocateany: - description: Locates any prison pearl in the world - usage: / player - permission: prisonpearl.locateany - - ppfree: - description: Frees a prison pearl - usage: / [player] - aliases: ppf - - ppfreeany: - description: Frees any prison pearl in the world - usage: / player - permission: prisonpearl.freeany - - ppsummon: - description: Summons a player from their prison pearl, requiring them to stay within range of their pearl - usage: /ppsummon [player] [range] - aliases: pps - - ppreturn: - description: Returns a summoned player back to their prison pearl - usage: /ppbanish [player] - aliases: ppr - - ppkill: - description: Instantly kills a summoned player, sending them back to their prison pearl - usage: /ppkill [player] - aliases: ppk - - ppsave: - description: Saves all prisonpearl related data to disk - usage: /ppsave - permission: prisonpearl.save - - ppimprisonany: - description: Imprisons any player in the world - usage: /ppimprisonany player - permission: prisonpearl.imprisonany - - ppbroadcast: - description: Broadcast your pplocate commands to another player - usage: /ppbroadcast player - alias: ppb - - ppconfirm: - description: Confirm reception of pplocate commands from a player - usage: /ppconfirm [player] - - ppsilence: - description: Silence reception of pplocate commands from player - usage: /ppsilence player - - ppinfo: - description: Get information about player in a pearl - usage: /ppinfo [player] - alias: ppi - -permissions: - prisonpearl.*: - description: Gives full access to PrisonPearl commands - default: op - children: - prisonpearl.locateany: true - prisonpearl.freeany: true - prisonpearl.imprisonany: true - prisonpearl.save: true - - prisonpearl.locateany: - description: Allows user to use pplocateany to locate prison pearls other than his own - - prisonpearl.freeany: - description: Allows user to use ppfreeany to free prison pearls he does not possess - - prisonpearl.imprisonany: - description: Allows user to use ppimprisonany to imprison any player at will - - prisonpearl.save: - description: Allows user to use ppsave command - +name: PrisonPearl +main: com.untamedears.PrisonPearl.PrisonPearlPlugin +version: 1.5.1 +soft-depend: [PhysicalShop, CombatTag] + +commands: + pplocate: + description: Locates your prison pearl + usage: / + aliases: ppl + + pplocateany: + description: Locates any prison pearl in the world + usage: / player + permission: prisonpearl.locateany + + ppfree: + description: Frees a prison pearl + usage: / [player] + aliases: ppf + + ppfreeany: + description: Frees any prison pearl in the world + usage: / player + permission: prisonpearl.freeany + + ppsummon: + description: Summons a player from their prison pearl, requiring them to stay within range of their pearl + usage: /ppsummon [player] [range] + aliases: pps + + ppreturn: + description: Returns a summoned player back to their prison pearl + usage: /ppbanish [player] + aliases: ppr + + ppkill: + description: Instantly kills a summoned player, sending them back to their prison pearl + usage: /ppkill [player] + aliases: ppk + + ppsave: + description: Saves all prisonpearl related data to disk + usage: /ppsave + permission: prisonpearl.save + + ppimprisonany: + description: Imprisons any player in the world + usage: /ppimprisonany player + permission: prisonpearl.imprisonany + + ppbroadcast: + description: Broadcast your pplocate commands to another player + usage: /ppbroadcast player + alias: ppb + + ppconfirm: + description: Confirm reception of pplocate commands from a player + usage: /ppconfirm [player] + + ppsilence: + description: Silence reception of pplocate commands from player + usage: /ppsilence player + + ppinfo: + description: Get information about player in a pearl + usage: /ppinfo [player] + alias: ppi + pploadalts: + description: reload alt lists from file + usage: /pploadalts + ppcheckall: + description: checkban all accounts + usage: /ppcheckall + ppcheck: + description: checkban the player + usage: /ppcheck [player] + + ppsetdist: + description: Sets distance prisoner can move. + + ppsetdamage: + description: Sets damage prisoner receives. + + pptogglespeech: + description: Toggles whether prisoner can talk in public chat. + + pptoggledamage: + description: Toggles whether prisoner can damage players and mobs. + + pptoggleblocks: + description: Toggles whether prisoner can break blocks. + + ppsetmotd: + description: Sets prisoner's MOTD. + +permissions: + prisonpearl.*: + description: Gives full access to PrisonPearl commands + default: op + children: + prisonpearl.locateany: true + prisonpearl.freeany: true + prisonpearl.imprisonany: true + prisonpearl.save: true + + prisonpearl.locateany: + description: Allows user to use pplocateany to locate prison pearls other than his own + + prisonpearl.freeany: + description: Allows user to use ppfreeany to free prison pearls he does not possess + + prisonpearl.imprisonany: + description: Allows user to use ppimprisonany to imprison any player at will + + prisonpearl.save: + description: Allows user to use ppsave command + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..ead89c3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,63 @@ + + 4.0.0 + + com.untamedears.PrisonPearl + prisonpearl + 1.5-SNAPSHOT + jar + + PrisonPearl + Bukkit Server Plugin + 2012 + + ${basedir}/src + + + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + + CP1252 + + + + + org.bukkit + craftbukkit + 1.4.5 R0.3 SNAPSHOT + + + com.wolvereness.physicalshop + PhysicalShop + 9.2.1-SNAPSHOT + system + ${basedir}/lib/PhysicalShop.jar + + + com.trc202.CombatTag + CombatTag + 5.0.1-SNAPSHOT + system + ${basedir}/lib/CombatTag.jar + + + + + + bukkit-repo + http://repo.bukkit.org/content/groups/public/ + + + + + \ No newline at end of file diff --git a/src/com/untamedears/PrisonPearl/AltsList.java b/src/com/untamedears/PrisonPearl/AltsList.java new file mode 100644 index 0000000..e33d5b7 --- /dev/null +++ b/src/com/untamedears/PrisonPearl/AltsList.java @@ -0,0 +1,67 @@ +package com.untamedears.PrisonPearl; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Set; + +import org.bukkit.Bukkit; + +class AltsList { + private HashMap altsHash; + private boolean initialised = false; + + public AltsList() { + } + + public void load(File file) { + try { + loadAlts(file); + initialised = true; + } catch (IOException e) { + e.printStackTrace(); + Bukkit.getLogger().info("Failed to load file!"); + initialised = false; + } + } + + private void loadAlts(File file) throws IOException { + altsHash = new HashMap(); + FileInputStream fis; + fis = new FileInputStream(file); + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + String line; + while ((line = br.readLine()) != null) { + if (line.length() > 1) { + String parts[] = line.split(" "); + String[] newString = new String[parts.length]; + System.arraycopy(parts, 0, newString, 0, parts.length); + for (String part : parts) { + altsHash.put(part, newString); + } + } + } + } + + public String[] getAltsArray(String name){ + if (initialised && altsHash.containsKey(name)) { + String[] names = altsHash.get(name); + String[] alts = new String[names.length-1]; + for (int i = 0, j = 0; i < names.length; i++) { + if (!names[i].equals(name)) { + alts[j] = names[i]; + j++; + } + } + return alts; + } + return new String[0]; + } + + public Set getAllNames() { + return altsHash.keySet(); + } +} diff --git a/src/com/untamedears/PrisonPearl/BroadcastManager.java b/src/com/untamedears/PrisonPearl/BroadcastManager.java index 983a5ad..1982833 100644 --- a/src/com/untamedears/PrisonPearl/BroadcastManager.java +++ b/src/com/untamedears/PrisonPearl/BroadcastManager.java @@ -1,86 +1,86 @@ -package com.untamedears.PrisonPearl; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.player.PlayerQuitEvent; - -public class BroadcastManager { - private Map> broadcasts; - private Map quickconfirm; - - public BroadcastManager() { - broadcasts = new HashMap>(); - quickconfirm = new HashMap(); - } - - public boolean addBroadcast(Player player, Player receiver) { - Map receivers = broadcasts.get(player); - if (receivers == null) { - receivers = new HashMap(); - broadcasts.put(player, receivers); - } else { - if (receivers.containsKey(receiver)) - return false; - } - - receivers.put(receiver, false); - quickconfirm.put(receiver, player); - return true; - } - - public boolean confirmBroadcast(Player player, Player receiver) { - Map receivers = broadcasts.get(player); - if (receivers == null) - return false; - if (!receivers.containsKey(receiver)) - return false; - receivers.put(receiver, true); - quickconfirm.remove(receiver); - return true; - } - - public boolean silenceBroadcast(Player player, Player receiver) { - Map receivers = broadcasts.get(player); - if (receivers == null) - return false; - return receivers.remove(receiver) != null; - } - - public boolean removeBroadcasts(Player player) { - return broadcasts.remove(player) != null; - } - - public Player getQuickConfirmPlayer(Player receiver) { - return quickconfirm.get(receiver); - } - - public void broadcast(Player player, String msg) { - Map receivers = broadcasts.get(player); - if (receivers == null) - return; - - Iterator> i = receivers.entrySet().iterator(); - while (i.hasNext()) { - Entry entry = i.next(); - if (!entry.getKey().isOnline()) { - i.remove(); - continue; - } - - if (entry.getValue()) - entry.getKey().sendMessage(msg); - } - } - - @EventHandler(priority=EventPriority.MONITOR) - public void onPlayerQuit(PlayerQuitEvent event) { - broadcasts.remove(event.getPlayer()); - quickconfirm.remove(event.getPlayer()); - } -} +package com.untamedears.PrisonPearl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerQuitEvent; + +class BroadcastManager { + private final Map> broadcasts; + private final Map quickconfirm; + + public BroadcastManager() { + broadcasts = new HashMap>(); + quickconfirm = new HashMap(); + } + + public boolean addBroadcast(Player player, Player receiver) { + Map receivers = broadcasts.get(player); + if (receivers == null) { + receivers = new HashMap(); + broadcasts.put(player, receivers); + } else { + if (receivers.containsKey(receiver)) + return false; + } + + receivers.put(receiver, false); + quickconfirm.put(receiver, player); + return true; + } + + public boolean confirmBroadcast(Player player, Player receiver) { + Map receivers = broadcasts.get(player); + if (receivers == null) + return false; + if (!receivers.containsKey(receiver)) + return false; + receivers.put(receiver, true); + quickconfirm.remove(receiver); + return true; + } + + public boolean silenceBroadcast(Player player, Player receiver) { + Map receivers = broadcasts.get(player); + return receivers != null && receivers.remove(receiver) != null; + } + + @SuppressWarnings("UnusedDeclaration") + public boolean removeBroadcasts(Player player) { + return broadcasts.remove(player) != null; + } + + public Player getQuickConfirmPlayer(Player receiver) { + return quickconfirm.get(receiver); + } + + public void broadcast(Player player, String msg) { + Map receivers = broadcasts.get(player); + if (receivers == null) + return; + + Iterator> i = receivers.entrySet().iterator(); + while (i.hasNext()) { + Entry entry = i.next(); + if (!entry.getKey().isOnline()) { + i.remove(); + continue; + } + + if (entry.getValue()) + entry.getKey().sendMessage(msg); + } + } + + @SuppressWarnings("UnusedDeclaration") + @EventHandler(priority=EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + broadcasts.remove(event.getPlayer()); + quickconfirm.remove(event.getPlayer()); + } +} diff --git a/src/com/untamedears/PrisonPearl/CombatTagManager.java b/src/com/untamedears/PrisonPearl/CombatTagManager.java new file mode 100644 index 0000000..2a649f9 --- /dev/null +++ b/src/com/untamedears/PrisonPearl/CombatTagManager.java @@ -0,0 +1,44 @@ +package com.untamedears.PrisonPearl; + +import java.util.logging.Logger; + +import org.bukkit.Server; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import com.trc202.CombatTag.CombatTag; +import com.trc202.CombatTagApi.CombatTagApi; + +@SuppressWarnings("ALL") +class CombatTagManager { + private CombatTagApi combatTagApi; + private boolean combatTagEnabled = false; + + public CombatTagManager(Server server, Logger l) { + if(server.getPluginManager().getPlugin("CombatTag") != null) { + combatTagApi = new CombatTagApi((CombatTag)server.getPluginManager().getPlugin("CombatTag")); + combatTagEnabled = true; + } + } + + public boolean isCombatTagNPC(Entity player) { + return combatTagEnabled && combatTagApi != null && combatTagApi.isNPC(player); + } + + public boolean isCombatTagged(Player player) { + return combatTagEnabled && combatTagApi != null && combatTagApi.isInCombat(player); + } + + public boolean isCombatTagged(String playerName) { + return combatTagEnabled && combatTagApi != null && combatTagApi.isInCombat(playerName); + } + + public String getNPCPlayerName(Entity player) { + if (combatTagEnabled && combatTagApi != null) { + if (combatTagApi.isNPC(player)) { + return combatTagApi.getNPCPlayerName(player); + } + } + return ""; + } +} diff --git a/src/com/untamedears/PrisonPearl/DamageLog.java b/src/com/untamedears/PrisonPearl/DamageLog.java index 9e636e9..d28d682 100644 --- a/src/com/untamedears/PrisonPearl/DamageLog.java +++ b/src/com/untamedears/PrisonPearl/DamageLog.java @@ -1,83 +1,84 @@ -package com.untamedears.PrisonPearl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -public class DamageLog { - private String player; - private Map damagers; - - private long expirestick; - - public DamageLog(Player player) { - this.player = player.getName(); - this.damagers = new HashMap(); - } - - public String getName() { - return player; - } - - public Player getPlayer() { - return Bukkit.getPlayerExact(player); - } - - public int getDamage(Player player) { - return getDamage(player.getName()); - } - - public int getDamage(String name) { - Integer i = damagers.get(name); - if (i == null) - return 0; - else - return i; - } - - public void recordDamage(Player damager, int damage, long expirestick) { - Integer i = damagers.get(damager.getName()); - if (i == null) - i = damage; - else - i += damage; - damagers.put(damager.getName(), i); - this.expirestick = expirestick; - } - - public List getDamagers(int min) { - List players = new ArrayList(); - - for (Entry entry : damagers.entrySet()) { - Player player = Bukkit.getPlayerExact(entry.getKey()); - if (player != null && entry.getValue() > min) - players.add(player); - } - - Collections.sort(players, new Comparator() { - public int compare(Player p0, Player p1) { - int d0 = damagers.get(p0.getName()); - int d1 = damagers.get(p1.getName()); - if (d0 < d1) // descending order - return 1; - else if (d0 > d1) - return -1; - else - return 0; - } - }); - - return players; - } - - public long getExpiresTick() { - return expirestick; - } -} +package com.untamedears.PrisonPearl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +class DamageLog { + private final String player; + private final Map damagers; + + private long expirestick; + + public DamageLog(Player player) { + this.player = player.getName(); + this.damagers = new HashMap(); + } + + public String getName() { + return player; + } + + public Player getPlayer() { + return Bukkit.getPlayerExact(player); + } + + public int getDamage(Player player) { + return getDamage(player.getName()); + } + + @SuppressWarnings("WeakerAccess") + public int getDamage(String name) { + Integer i = damagers.get(name); + if (i == null) + return 0; + else + return i; + } + + public void recordDamage(Player damager, int damage, long expirestick) { + Integer i = damagers.get(damager.getName()); + if (i == null) + i = damage; + else + i += damage; + damagers.put(damager.getName(), i); + this.expirestick = expirestick; + } + + public List getDamagers(int min) { + List players = new ArrayList(); + + for (Entry entry : damagers.entrySet()) { + Player player = Bukkit.getPlayerExact(entry.getKey()); + if (player != null && entry.getValue() > min) + players.add(player); + } + + Collections.sort(players, new Comparator() { + public int compare(Player p0, Player p1) { + int d0 = damagers.get(p0.getName()); + int d1 = damagers.get(p1.getName()); + if (d0 < d1) // descending order + return 1; + else if (d0 > d1) + return -1; + else + return 0; + } + }); + + return players; + } + + public long getExpiresTick() { + return expirestick; + } +} diff --git a/src/com/untamedears/PrisonPearl/DamageLogManager.java b/src/com/untamedears/PrisonPearl/DamageLogManager.java index 76181e5..4d0950c 100644 --- a/src/com/untamedears/PrisonPearl/DamageLogManager.java +++ b/src/com/untamedears/PrisonPearl/DamageLogManager.java @@ -1,172 +1,172 @@ -package com.untamedears.PrisonPearl; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Arrow; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -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; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.entity.PotionSplashEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -public class DamageLogManager implements Runnable, Listener { - private PrisonPearlPlugin plugin; - - private boolean scheduled; - private Map logs; - - public DamageLogManager(PrisonPearlPlugin plugin) { - this.plugin = plugin; - - scheduled = false; - logs = new HashMap(); - - Bukkit.getPluginManager().registerEvents(this, plugin); - } - - public List getDamagers(Player player) { - DamageLog log = logs.get(player.getName()); - if (log != null) - return log.getDamagers(plugin.getConfig().getInt("damagelog_min")); - else - return new ArrayList(); - } - - public boolean hasDamageLog(Player player) { - return logs.containsKey(player.getName()); - } - - // Create damage logs - @EventHandler(priority=EventPriority.MONITOR) - public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { - if (!(event.getEntity() instanceof Player)) - return; - Player player = (Player)event.getEntity(); - - Player damager = null; - if (event.getDamager() instanceof Player) { - damager = (Player)event.getDamager(); - } else if (event.getDamager() instanceof Wolf) { - Wolf wolf = (Wolf)event.getDamager(); - if (wolf.getOwner() instanceof Player) - damager = (Player)wolf.getOwner(); - } else if (event.getDamager() instanceof Arrow) { - Arrow arrow = (Arrow)event.getDamager(); - if (!(arrow.getShooter() instanceof Player)) - return; - - damager = (Player)arrow.getShooter(); - } - - if (damager == null || damager == player) - return; - - recordDamage(player, damager, event.getDamage()); - } - - @EventHandler(priority=EventPriority.MONITOR) - public void onPotionSplashEvent(PotionSplashEvent event) { - LivingEntity shooter = event.getPotion().getShooter(); - if (!(shooter instanceof Player)) - return; - Player damager = (Player)shooter; - - // So, the idea here is because we can't really determine how much damage a potion actually caused - // somebody (like poison, weakness, or the API doesn't even seem to tell you the difference between harm I and harm II), - // we just award 6 damage points to the thrower as long as the potion is sufficiently bad. - int damage = 6; - - boolean badpotion=false; - for (PotionEffect effect : event.getPotion().getEffects()) { - // apparently these aren't really enums, because == doesn't work - if (effect.getType().equals(PotionEffectType.HARM) || effect.getType().equals(PotionEffectType.POISON) || effect.getType().equals(PotionEffectType.WEAKNESS)) { - badpotion = true; - break; - } - } - - if (!badpotion) // don't award damage for helpful or do-nothing potions, to prevent pearl stealing - return; - - for (Entity entity : event.getAffectedEntities()) { - if (!(entity instanceof Player)) - continue; - - recordDamage((Player)entity, damager, damage); - } - } - - private void recordDamage(Player player, Player damager, int amt) { - DamageLog log = logs.get(player.getName()); - if (log == null) { - log = new DamageLog(player); - logs.put(player.getName(), log); - } - - long ticks = plugin.getConfig().getInt("damagelog_ticks"); - log.recordDamage(damager, amt, getNowTick() + ticks); - scheduleExpireTask(ticks); - } - - // Reset damage logs on dead players - @EventHandler(priority=EventPriority.MONITOR) - public void onEntityDeath(EntityDeathEvent event) { - if (!(event.getEntity() instanceof Player)) - return; - - logs.remove(((Player)event.getEntity()).getName()); - } - - @EventHandler(priority=EventPriority.MONITOR) - public void onPlayerQuit(PlayerQuitEvent event) { - logs.remove(event.getPlayer().getName()); - } - - public void run() { - scheduled = false; - - long nowtick = getNowTick(); - - Iterator i = logs.values().iterator(); - long minremaining = Long.MAX_VALUE; - while (i.hasNext()) { - DamageLog log = i.next(); - long remaining = nowtick-log.getExpiresTick(); - - if (remaining <= plugin.getConfig().getInt("damagelog_ticks")/20) { - i.remove(); - continue; - } - - minremaining = Math.min(minremaining, remaining); - } - - if (minremaining < Long.MAX_VALUE) - scheduleExpireTask(minremaining); - } - - private void scheduleExpireTask(long ticks) { - if (scheduled) - return; - - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, this, ticks); - scheduled = true; - } - - private long getNowTick() { - return Bukkit.getWorlds().get(0).getFullTime(); - } -} +package com.untamedears.PrisonPearl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +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; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.PotionSplashEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +class DamageLogManager implements Runnable, Listener { + private final PrisonPearlPlugin plugin; + + private boolean scheduled; + private final Map logs; + + public DamageLogManager(PrisonPearlPlugin plugin) { + this.plugin = plugin; + + scheduled = false; + logs = new HashMap(); + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + public List getDamagers(Player player) { + DamageLog log = logs.get(player.getName()); + if (log != null) + return log.getDamagers(plugin.getConfig().getInt("damagelog_min")); + else + return new ArrayList(); + } + + public boolean hasDamageLog(Player player) { + return logs.containsKey(player.getName()); + } + + // Create damage logs + @EventHandler(priority=EventPriority.MONITOR) + public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + Player player = (Player)event.getEntity(); + + Player damager = null; + if (event.getDamager() instanceof Player) { + damager = (Player)event.getDamager(); + } else if (event.getDamager() instanceof Wolf) { + Wolf wolf = (Wolf)event.getDamager(); + if (wolf.getOwner() instanceof Player) + damager = (Player)wolf.getOwner(); + } else if (event.getDamager() instanceof Arrow) { + Arrow arrow = (Arrow)event.getDamager(); + if (!(arrow.getShooter() instanceof Player)) + return; + + damager = (Player)arrow.getShooter(); + } + + if (damager == null || damager == player) + return; + + recordDamage(player, damager, event.getDamage()); + } + + @EventHandler(priority=EventPriority.MONITOR) + public void onPotionSplashEvent(PotionSplashEvent event) { + LivingEntity shooter = event.getPotion().getShooter(); + if (!(shooter instanceof Player)) + return; + Player damager = (Player)shooter; + + // So, the idea here is because we can't really determine how much damage a potion actually caused + // somebody (like poison, weakness, or the API doesn't even seem to tell you the difference between harm I and harm II), + // we just award 6 damage points to the thrower as long as the potion is sufficiently bad. + int damage = 6; + + boolean badpotion=false; + for (PotionEffect effect : event.getPotion().getEffects()) { + // apparently these aren't really enums, because == doesn't work + if (effect.getType().equals(PotionEffectType.HARM) || effect.getType().equals(PotionEffectType.POISON) || effect.getType().equals(PotionEffectType.WEAKNESS)) { + badpotion = true; + break; + } + } + + if (!badpotion) // don't award damage for helpful or do-nothing potions, to prevent pearl stealing + return; + + for (Entity entity : event.getAffectedEntities()) { + if (!(entity instanceof Player)) + continue; + + recordDamage((Player)entity, damager, damage); + } + } + + private void recordDamage(Player player, Player damager, int amt) { + DamageLog log = logs.get(player.getName()); + if (log == null) { + log = new DamageLog(player); + logs.put(player.getName(), log); + } + + long ticks = plugin.getConfig().getInt("damagelog_ticks"); + log.recordDamage(damager, amt, getNowTick() + ticks); + scheduleExpireTask(ticks); + } + + // Reset damage logs on dead players + @EventHandler(priority=EventPriority.MONITOR) + public void onEntityDeath(EntityDeathEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + logs.remove(((Player)event.getEntity()).getName()); + } + + @EventHandler(priority=EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + logs.remove(event.getPlayer().getName()); + } + + public void run() { + scheduled = false; + + long nowtick = getNowTick(); + + Iterator i = logs.values().iterator(); + long minremaining = Long.MAX_VALUE; + while (i.hasNext()) { + DamageLog log = i.next(); + long remaining = nowtick-log.getExpiresTick(); + + if (remaining <= plugin.getConfig().getInt("damagelog_ticks")/20) { + i.remove(); + continue; + } + + minremaining = Math.min(minremaining, remaining); + } + + if (minremaining < Long.MAX_VALUE) + scheduleExpireTask(minremaining); + } + + private void scheduleExpireTask(long ticks) { + if (scheduled) + return; + + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, this, ticks); + scheduled = true; + } + + private long getNowTick() { + return Bukkit.getWorlds().get(0).getFullTime(); + } +} diff --git a/src/com/untamedears/PrisonPearl/PhysicalShopListener.java b/src/com/untamedears/PrisonPearl/PhysicalShopListener.java index 5a5d5cf..f54450d 100644 --- a/src/com/untamedears/PrisonPearl/PhysicalShopListener.java +++ b/src/com/untamedears/PrisonPearl/PhysicalShopListener.java @@ -1,42 +1,44 @@ -package com.untamedears.PrisonPearl; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; - -import com.wolvereness.physicalshop.Shop; -import com.wolvereness.physicalshop.ShopMaterial; -import com.wolvereness.physicalshop.events.ShopInteractEvent; - -public class PhysicalShopListener implements Listener { - PrisonPearlStorage pearls; - - public PhysicalShopListener(PrisonPearlPlugin plugin, PrisonPearlStorage pearls) { - this.pearls = pearls; - - Bukkit.getPluginManager().registerEvents(this, plugin); - } - - @EventHandler(priority=EventPriority.MONITOR) - public void onShopInteract(ShopInteractEvent event) { - if (event.getAction() != Action.LEFT_CLICK_BLOCK) - return; - - Shop shop = event.getShop(); - if (shop.getShopItems() == 0) - return; - - ShopMaterial mat = shop.getMaterial(); - if (mat == null || mat.getMaterial() != Material.ENDER_PEARL || mat.getDurability() == 0) - return; - - PrisonPearl pp = pearls.getByID(mat.getDurability()); - if (pp == null) - return; - - event.getPlayer().sendMessage("The pearl sold by the shop contains " + pp.getImprisonedName()); - } -} +package com.untamedears.PrisonPearl; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; + +import com.wolvereness.physicalshop.Shop; +import com.wolvereness.physicalshop.ShopMaterial; +import com.wolvereness.physicalshop.events.ShopInteractEvent; + +class PhysicalShopListener implements Listener { + @SuppressWarnings("WeakerAccess") + final + PrisonPearlStorage pearls; + + public PhysicalShopListener(PrisonPearlPlugin plugin, PrisonPearlStorage pearls) { + this.pearls = pearls; + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(priority=EventPriority.MONITOR) + public void onShopInteract(ShopInteractEvent event) { + if (event.getAction() != Action.LEFT_CLICK_BLOCK) + return; + + Shop shop = event.getShop(); + if (shop.getShopItems() == 0) + return; + + ShopMaterial mat = shop.getMaterial(); + if (mat == null || mat.getMaterial() != Material.ENDER_PEARL || mat.getDurability() == 0) + return; + + PrisonPearl pp = pearls.getByID(mat.getDurability()); + if (pp == null) + return; + + event.getPlayer().sendMessage("The pearl sold by the shop contains " + pp.getImprisonedName()); + } +} diff --git a/src/com/untamedears/PrisonPearl/PrisonPearl.java b/src/com/untamedears/PrisonPearl/PrisonPearl.java index 97d5aac..4aee73a 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearl.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearl.java @@ -1,173 +1,187 @@ -package com.untamedears.PrisonPearl; - -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.BlockState; -import org.bukkit.entity.Entity; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Item; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.Vector; - -public class PrisonPearl { - private short id; - private String imprisonedname; - private Player player; - private Item item; - private Location blocklocation; - - public PrisonPearl(short id, String imprisonedname, Player holderplayer) { - this.id = id; - this.imprisonedname = imprisonedname; - this.player = holderplayer; - } - - public PrisonPearl(short id, String imprisonedname, Location blocklocation) { - this.id = id; - this.imprisonedname = imprisonedname; - this.blocklocation = blocklocation; - } - - public static PrisonPearl makeFromLocation(short id, String imprisonedname, Location loc) { - BlockState bs = loc.getBlock().getState(); - if (bs instanceof InventoryHolder) - return new PrisonPearl(id, imprisonedname, loc); - else - return null; - } - - public short getID() { - return id; - } - - public String getImprisonedName() { - return imprisonedname; - } - - public Player getImprisonedPlayer() { - return Bukkit.getPlayerExact(imprisonedname); - } - - public Player getHolderPlayer() { - return player; - } - - public BlockState getHolderBlockState() { - if (blocklocation != null) - return blocklocation.getBlock().getState(); - else - return null; - } - - public Item getHolderItem() { - return item; - } - - public String getHolderName() { - if (player != null) { - return player.getName(); - } else if (item != null) { - return "nobody"; - } else if (blocklocation != null) { - switch (getHolderBlockState().getType()) { - case CHEST: - return "a chest"; - case FURNACE: - return "a furnace"; - case BREWING_STAND: - return "a brewing stand"; - case DISPENSER: - return "a dispenser"; - default: - System.err.println("PrisonPearl " + id + " is inside an unknown block"); - return "an unknown block"; - } - } else { - System.err.println("PrisonPearl " + id + " has no player, item, nor location"); - return "unknown"; - } - } - - public Location getLocation() { - if (player != null) { - return player.getLocation().add(0, -.5, 0); - } else if (item != null) { - return item.getLocation(); - } else if (blocklocation != null) { - return blocklocation; - } else { - throw new RuntimeException("PrisonPearl " + id + " has no player, item, nor location"); - } - } - - public String describeLocation() { - Location loc = getLocation(); - Vector vec = loc.toVector(); - String str = loc.getWorld().getName() + " " + vec.getBlockX() + " " + vec.getBlockY() + " " + vec.getBlockZ(); - - return "held by " + getHolderName() + " at " + str; - } - - public boolean verifyLocation() { - if (item != null) { - Chunk chunk = item.getLocation().getChunk(); - for (Entity entity : chunk.getEntities()) { - if (entity == item) - return true; - } - - return false; - } else { - Inventory inv; - if (player != null) { - if (!player.isOnline()) - return false; - ItemStack cursoritem = player.getItemOnCursor(); - if (cursoritem.getType() == Material.ENDER_PEARL && cursoritem.getDurability() == id) - return true; - inv = player.getInventory(); - } else if (blocklocation != null) { - BlockState bs = getHolderBlockState(); - if (!(bs instanceof InventoryHolder)) - return false; - inv = ((InventoryHolder)bs).getInventory(); - for (HumanEntity viewer : inv.getViewers()) { - ItemStack cursoritem = viewer.getItemOnCursor(); - if (cursoritem.getType() == Material.ENDER_PEARL && cursoritem.getDurability() == id) - return true; - } - } else { - return false; - } - - for (ItemStack item : inv.all(Material.ENDER_PEARL).values()) { - if (item.getDurability() == id) - return true; - } - return false; - } - } - - public void setHolder(Player player) { - this.player = player; - item = null; - blocklocation = null; - } - - public void setHolder(ItemBlock blockstate) { - player = null; - item = null; - blocklocation = blockstate.getLocation(); - } - - public void setHolder(Item item) { - player = null; - this.item = item; - blocklocation = null; - } -} +package com.untamedears.PrisonPearl; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +public class PrisonPearl { + private final short id; + private final String imprisonedname; + private String motd = ""; + private Player player; + private Item item; + private Location blocklocation; + + public PrisonPearl(short id, String imprisonedname, Player holderplayer) { + this.id = id; + this.imprisonedname = imprisonedname; + this.player = holderplayer; + } + + @SuppressWarnings("WeakerAccess") + public PrisonPearl(short id, String imprisonedname, Location blocklocation) { + this.id = id; + this.imprisonedname = imprisonedname; + this.blocklocation = blocklocation; + } + + public static PrisonPearl makeFromLocation(short id, String imprisonedname, Location loc) { + if (imprisonedname == null || loc == null) + return null; + BlockState bs = loc.getBlock().getState(); + if (bs instanceof InventoryHolder) + return new PrisonPearl(id, imprisonedname, loc); + else + return null; + } + + public short getID() { + return id; + } + + public String getImprisonedName() { + return imprisonedname; + } + + public Player getImprisonedPlayer() { + return Bukkit.getPlayerExact(imprisonedname); + } + + public Player getHolderPlayer() { + return player; + } + + public BlockState getHolderBlockState() { + if (blocklocation != null) + return blocklocation.getBlock().getState(); + else + return null; + } + + public Item getHolderItem() { + return item; + } + + @SuppressWarnings("WeakerAccess") + public String getHolderName() { + if (player != null) { + return player.getName(); + } else if (item != null) { + return "nobody"; + } else if (blocklocation != null) { + switch (getHolderBlockState().getType()) { + case CHEST: + return "a chest"; + case FURNACE: + return "a furnace"; + case BREWING_STAND: + return "a brewing stand"; + case DISPENSER: + return "a dispenser"; + default: + System.err.println("PrisonPearl " + id + " is inside an unknown block"); + return "an unknown block"; + } + } else { + System.err.println("PrisonPearl " + id + " has no player, item, nor location"); + return "unknown"; + } + } + + public Location getLocation() { + if (player != null) { + return player.getLocation().add(0, -.5, 0); + } else if (item != null) { + return item.getLocation(); + } else if (blocklocation != null) { + return blocklocation; + } else { + throw new RuntimeException("PrisonPearl " + id + " has no player, item, nor location"); + } + } + + public String describeLocation() { + Location loc = getLocation(); + Vector vec = loc.toVector(); + String str = loc.getWorld().getName() + " " + vec.getBlockX() + " " + vec.getBlockY() + " " + vec.getBlockZ(); + + return "held by " + getHolderName() + " at " + str; + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public boolean verifyLocation() { + if (item != null) { + Chunk chunk = item.getLocation().getChunk(); + for (Entity entity : chunk.getEntities()) { + if (entity == item) + return true; + } + + return false; + } else { + Inventory inv; + if (player != null) { + if (!player.isOnline()) + return false; + ItemStack cursoritem = player.getItemOnCursor(); + if (cursoritem.getType() == Material.ENDER_PEARL && cursoritem.getDurability() == id) + return true; + inv = player.getInventory(); + } else if (blocklocation != null) { + BlockState bs = getHolderBlockState(); + if (!(bs instanceof InventoryHolder)) + return false; + inv = ((InventoryHolder)bs).getInventory(); + for (HumanEntity viewer : inv.getViewers()) { + ItemStack cursoritem = viewer.getItemOnCursor(); + if (cursoritem.getType() == Material.ENDER_PEARL && cursoritem.getDurability() == id) + return true; + } + } else { + return false; + } + + for (ItemStack item : inv.all(Material.ENDER_PEARL).values()) { + if (item.getDurability() == id) + return true; + } + return false; + } + } + + public void setHolder(Player player) { + this.player = player; + item = null; + blocklocation = null; + } + + public void setHolder(ItemBlock blockstate) { + player = null; + item = null; + blocklocation = blockstate.getLocation(); + } + + public void setHolder(Item item) { + player = null; + this.item = item; + blocklocation = null; + } + + public String getMotd() { + return motd; + } + + public void setMotd(String motd) { + this.motd = motd; + } +} diff --git a/src/com/untamedears/PrisonPearl/PrisonPearlCommands.java b/src/com/untamedears/PrisonPearl/PrisonPearlCommands.java index e191651..209081a 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearlCommands.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearlCommands.java @@ -1,420 +1,610 @@ -package com.untamedears.PrisonPearl; - -import java.util.Map.Entry; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -public class PrisonPearlCommands implements CommandExecutor { - private PrisonPearlPlugin plugin; - private PrisonPearlStorage pearls; - private DamageLogManager damageman; - private PrisonPearlManager pearlman; - private SummonManager summonman; - private BroadcastManager broadcastman; - - public PrisonPearlCommands(PrisonPearlPlugin plugin, DamageLogManager damageman, PrisonPearlStorage pearls, PrisonPearlManager pearlman, SummonManager summonman, BroadcastManager broadcastman) { - this.plugin = plugin; - this.pearls = pearls; - this.damageman = damageman; - this.pearlman = pearlman; - this.summonman = summonman; - this.broadcastman = broadcastman; - } - - @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - if (label.equalsIgnoreCase("pplocate") || label.equalsIgnoreCase("ppl")) { - return locateCmd(sender, args, false); - } else if (label.equalsIgnoreCase("pplocateany")) { - return locateCmd(sender, args, true); - } else if (label.equalsIgnoreCase("ppfree") || label.equalsIgnoreCase("ppf")) { - return freeCmd(sender, args, false); - } else if (label.equalsIgnoreCase("ppfreeany")) { - return freeCmd(sender, args, true); - } else if (label.equalsIgnoreCase("ppsummon") || label.equalsIgnoreCase("pps")) { - return summonCmd(sender, args); - } else if (label.equalsIgnoreCase("ppreturn") || label.equalsIgnoreCase("ppr")) { - return returnCmd(sender, args); - } else if (label.equalsIgnoreCase("ppkill") || label.equalsIgnoreCase("ppk")) { - return killCmd(sender, args); - } else if (label.equalsIgnoreCase("ppsave")) { - return saveCmd(sender, args); - } else if (label.equalsIgnoreCase("ppimprisonany")) { - return imprisonCmd(sender, args); - } else if (label.equalsIgnoreCase("ppbroadcast")) { - return broadcastCmd(sender, args); - } else if (label.equalsIgnoreCase("ppconfirm")) { - return confirmCmd(sender, args); - } else if (label.equalsIgnoreCase("ppsilence")) { - return silenceCmd(sender, args); - } - - return false; - } - - private boolean locateCmd(CommandSender sender, String args[], boolean any) { - String name_is; - String name_possesive; - PrisonPearl pp; - - if (!any) { - if (args.length != 0) - return false; - - if (!(sender instanceof Player)) { - sender.sendMessage("Must use pplocateany at the console"); - return true; - } - - name_is = "You are"; - name_possesive = "Your"; - pp = pearls.getByImprisoned((Player)sender); - } else { - if (args.length != 1) - return false; - - name_is = args[0] + " is"; - name_possesive = args[0] + "'s"; - pp = pearls.getByImprisoned(args[0]); - } - - if (pp != null) { - if (!pp.verifyLocation()) { - System.err.println("PrisonPearl for " + pp.getImprisonedName() + " didn't validate, so is now set free"); - pearlman.freePearl(pp); - } else { - sender.sendMessage(ChatColor.GREEN + name_possesive + " prison pearl is " + pp.describeLocation()); - if (sender instanceof Player && !any) - broadcastman.broadcast((Player)sender, ChatColor.GREEN + pp.getImprisonedName() + ": " + pp.describeLocation()); - } - } else { - sender.sendMessage(name_is + " not imprisoned"); - } - - return true; - } - - private boolean freeCmd(CommandSender sender, String args[], boolean any) { - PrisonPearl pp; - - if (!any) { - if (args.length > 1) - return false; - - if (!(sender instanceof Player)) { - sender.sendMessage("Must use freeany at console"); - return true; - } - - Player player = (Player)sender; - - int slot = getCommandPearlSlot(player, args, 0); - if (slot == -1) - return true; - - pp = pearls.getByItemStack(player.getInventory().getItem(slot)); - player.getInventory().setItem(slot, null); - } else { - if (args.length != 1) - return false; - - pp = pearls.getByImprisoned(args[0]); - - if (pp == null) { - sender.sendMessage(args[0] + " is not imprisoned"); - return true; - } - } - - if (pearlman.freePearl(pp)) { - if (pp.getImprisonedPlayer() != sender) // when freeing yourself, you're already going to get a message - sender.sendMessage("You've freed " + pp.getImprisonedName()); - } else { - sender.sendMessage("You failed to free " + pp.getImprisonedName()); - } - return true; - } - - private boolean imprisonCmd(CommandSender sender, String args[]) { - if (args.length != 1) - return false; - if (!(sender instanceof Player)) { - sender.sendMessage("imprison cannot be used at the console"); - return true; - } - - if (pearlman.imprisonPlayer(args[0], (Player)sender)) { - sender.sendMessage("You imprisoned " + args[0]); - Player player = Bukkit.getPlayerExact(args[0]); - if (player != null) - player.setHealth(0); - } else { - sender.sendMessage("You failed to imprison " + args[0]); - } - return true; - } - - private boolean summonCmd(CommandSender sender, String args[]) { - if (args.length > 2) - return false; - - if (!(sender instanceof Player)) { - sender.sendMessage("Command cannot be used at console"); - return true; - } - Player player = (Player)sender; - - int dist = plugin.getConfig().getInt("summon_damage_radius"); - PrisonPearl pp; - if (args.length == 2) { - try { - dist = Integer.parseInt(args[1]); - pp = getCommandPearl(player, args, 0); - } catch (NumberFormatException e) { - sender.sendMessage("Invalid summon radius '" + args[1] + "'"); - return false; - } - } else if (args.length == 1) { - try { - dist = Integer.parseInt(args[0]); - pp = getCommandPearl(player, args, 1); - } catch (NumberFormatException e) { - pp = getCommandPearl(player, args, 0); - } - } else { - pp = getCommandPearl(player, args, 0); - } - - if (pp == null) - return true; - - if (args.length > 0) { - try { - dist = Integer.parseInt(args[args.length-1]); - } catch (NumberFormatException e) { } - } - - if (pp.getImprisonedPlayer() == null || pp.getImprisonedPlayer().isDead()) { - sender.sendMessage(pp.getImprisonedName() + " cannot be summoned"); - return true; - } else if (pp.getImprisonedPlayer() == player) { - sender.sendMessage("You cannot summon yourself!"); - return true; - } else if (summonman.isSummoned(pp)) { - sender.sendMessage(pp.getImprisonedName() + " is already summoned"); - return true; - } - - if (summonman.summonPearl(pp, player.getLocation(), dist)) - sender.sendMessage("You've summoned " + pp.getImprisonedName()); - else - sender.sendMessage("You failed to summon " + pp.getImprisonedName()); - return true; - } - - private boolean returnCmd(CommandSender sender, String args[]) { - if (args.length > 1) - return false; - - if (!(sender instanceof Player)) { - sender.sendMessage("Command cannot be used at console"); - return true; - } - - Player player = (Player)sender; - PrisonPearl pp = getCommandPearl(player, args, 0); - if (pp == null) - return true; - - if (pp.getImprisonedName().equals(player.getName())) { - sender.sendMessage("You cannot return yourself!"); - return true; - } else if (!summonman.isSummoned(pp)) { - sender.sendMessage(pp.getImprisonedName() + " has not been summoned!"); - return true; - } else if (damageman.hasDamageLog(player)) { - sender.sendMessage(pp.getImprisonedName() + " is in combat and cannot be returned!"); - return true; - } - - if (summonman.returnPearl(pp)) - sender.sendMessage("You've returned " + pp.getImprisonedName()); - else - sender.sendMessage("You failed to return " + pp.getImprisonedName()); - return true; - } - - private boolean killCmd(CommandSender sender, String args[]) { - if (args.length > 1) - return false; - - if (!(sender instanceof Player)) { - sender.sendMessage("Command cannot be used at console"); - return true; - } - - Player player = (Player)sender; - PrisonPearl pp = getCommandPearl(player, args, 0); - if (pp == null) - return true; - - if (!summonman.isSummoned(pp)) { - sender.sendMessage(pp.getImprisonedName() + " has not been summoned!"); - return true; - } - - if (summonman.killPearl(pp)) - sender.sendMessage("You've killed " + pp.getImprisonedName()); - else - sender.sendMessage("You failed to kill " + pp.getImprisonedName()); - return true; - } - - private boolean saveCmd(CommandSender sender, String args[]) { - if (args.length > 0) - return false; - - try { - plugin.saveAll(true); - sender.sendMessage("PrisonPearl data saved!"); - return true; - } catch (RuntimeException e) { - if (!(sender instanceof ConsoleCommandSender)) - sender.sendMessage("PrisonPearl failed to save data! Check server logs!"); - throw e; - } - } - - private boolean broadcastCmd(CommandSender sender, String args[]) { - if (args.length != 1) - return false; - if (!(sender instanceof Player)) { - sender.sendMessage("Command cannot be used at console"); - return true; - } - - Player player = (Player)sender; - Player receiver = Bukkit.getPlayerExact(args[0]); - if (receiver == null) { - sender.sendMessage("No such player " + args[0]); - return true; - } else if (receiver == player) { - sender.sendMessage("You cannot broadcast to yourself!"); - return true; - } else if (!pearls.isImprisoned(player)) { - sender.sendMessage("You are not imprisoned!"); - return true; - } - - if (broadcastman.addBroadcast(player, receiver)) { - sender.sendMessage("You will broadcast pplocate information to " + receiver.getDisplayName()); - receiver.sendMessage("Type /ppconfirm to receive pplocate broadcasts from " + player.getDisplayName()); - } else { - sender.sendMessage("You are already broadcasting to " + receiver.getDisplayName()); - } - - return true; - } - - private boolean confirmCmd(CommandSender sender, String args[]) { - if (args.length > 1) - return false; - if (!(sender instanceof Player)) { - sender.sendMessage("Command cannot be used at console"); - return true; - } - - Player player = (Player)sender; - Player broadcaster; - - if (args.length == 1) { - broadcaster = Bukkit.getPlayerExact(args[0]); - if (broadcaster == null) { - sender.sendMessage("No such player " + args[0]); - return true; - } - } else { - broadcaster = broadcastman.getQuickConfirmPlayer(player); - if (broadcaster == null) { - sender.sendMessage("Nobody has requested to broadcast to you"); - return true; - } - } - - if (broadcastman.confirmBroadcast(broadcaster, player)) { - player.sendMessage("You will now receive broadcasts from " + broadcaster.getDisplayName()); - } else { - player.sendMessage(broadcaster.getDisplayName() + " does not wish to broadcast to you"); - } - return true; - } - - private boolean silenceCmd(CommandSender sender, String args[]) { - if (args.length != 1) - return false; - if (!(sender instanceof Player)) { - sender.sendMessage("Command cannot be used at console"); - return true; - } - - Player player = (Player)sender; - Player broadcaster = Bukkit.getPlayerExact(args[0]); - if (broadcaster == null) { - sender.sendMessage("No such player " + args[0]); - return true; - } - - if (broadcastman.silenceBroadcast(player, broadcaster)) { - player.sendMessage("You will no longer receive broadcasts from " + broadcaster.getDisplayName()); - } else { - player.sendMessage(broadcaster.getDisplayName() + " is not broadcasting to you"); - } - return true; - } - - private PrisonPearl getCommandPearl(Player player, String args[], int pos) { - int slot = getCommandPearlSlot(player, args, pos); - if (slot != -1) - return pearls.getByItemStack(player.getInventory().getItem(slot)); - else - return null; - } - - private int getCommandPearlSlot(Player player, String args[], int pos) { - if (args.length <= pos) { - ItemStack item = player.getItemInHand(); - if (item.getType() != Material.ENDER_PEARL) { - player.sendMessage("You must hold a pearl or supply the player's name to use this command"); - return -1; - } - - if (pearls.getByItemStack(item) == null) { - player.sendMessage("This is an ordinary ender pearl"); - return -1; - } - - return player.getInventory().getHeldItemSlot(); - } else { - PrisonPearl pp = pearls.getByImprisoned(args[pos]); - if (pp != null) { - Inventory inv = player.getInventory(); - for (Entry entry : inv.all(Material.ENDER_PEARL).entrySet()) { - if (entry.getValue().getDurability() == pp.getID()) - return entry.getKey(); - } - } - - player.sendMessage("You don't possess " + args[0] + "'s prison pearl"); - return -1; - } - } -} +package com.untamedears.PrisonPearl; + +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +class PrisonPearlCommands implements CommandExecutor { + private final PrisonPearlPlugin plugin; + private final PrisonPearlStorage pearls; + private final DamageLogManager damageman; + private final PrisonPearlManager pearlman; + private final SummonManager summonman; + private final BroadcastManager broadcastman; + + public PrisonPearlCommands(PrisonPearlPlugin plugin, DamageLogManager damageman, PrisonPearlStorage pearls, PrisonPearlManager pearlman, SummonManager summonman, BroadcastManager broadcastman) { + this.plugin = plugin; + this.pearls = pearls; + this.damageman = damageman; + this.pearlman = pearlman; + this.summonman = summonman; + this.broadcastman = broadcastman; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (label.equalsIgnoreCase("pplocate") || label.equalsIgnoreCase("ppl")) { + return locateCmd(sender, args, false); + } else if (label.equalsIgnoreCase("pplocateany")) { + return locateCmd(sender, args, true); + } else if (label.equalsIgnoreCase("ppfree") || label.equalsIgnoreCase("ppf")) { + return freeCmd(sender, args, false); + } else if (label.equalsIgnoreCase("ppfreeany")) { + return freeCmd(sender, args, true); + } else if (label.equalsIgnoreCase("ppsummon") || label.equalsIgnoreCase("pps")) { + return summonCmd(sender, args); + } else if (label.equalsIgnoreCase("ppreturn") || label.equalsIgnoreCase("ppr")) { + return returnCmd(sender, args); + } else if (label.equalsIgnoreCase("ppkill") || label.equalsIgnoreCase("ppk")) { + return killCmd(sender, args); + } else if (label.equalsIgnoreCase("ppsave")) { + return saveCmd(sender, args); + } else if (label.equalsIgnoreCase("ppimprisonany")) { + return imprisonCmd(sender, args); + } else if (label.equalsIgnoreCase("ppbroadcast")) { + return broadcastCmd(sender, args); + } else if (label.equalsIgnoreCase("ppconfirm")) { + return confirmCmd(sender, args); + } else if (label.equalsIgnoreCase("ppsilence")) { + return silenceCmd(sender, args); + } else if (label.equalsIgnoreCase("pploadalts")) { + return reloadAlts(sender); + } else if (label.equalsIgnoreCase("ppcheckall")) { + return checkAll(sender); + } else if (label.equalsIgnoreCase("ppcheck")) { + return check(sender, args); + } else if (label.equalsIgnoreCase("kill")) { + return kill(); + } else if (label.equalsIgnoreCase("ppsetdist")) { + return setDistCmd(sender, args); + } else if (label.equalsIgnoreCase("ppsetdamage")) { + return setDamageCmd(sender, args); + } else if (label.equalsIgnoreCase("pptogglespeech")) { + return toggleSpeechCmd(sender, args); + } else if (label.equalsIgnoreCase("pptoggledamage")) { + return toggleDamageCmd(sender, args); + } else if (label.equalsIgnoreCase("pptoggleblocks")) { + return toggleBlocksCmd(sender, args); + } else if (label.equalsIgnoreCase("ppsetmotd")) { + return setMotdCmd(sender, args); + } + + return false; + } + + private PrisonPearl setCmd(CommandSender sender, String[] args) { + PrisonPearl pp; + + if (!(sender instanceof Player)) { + sender.sendMessage("ppset cannot be used at the console"); + return null; + } + + String[] anArray = {}; + Player player = (Player)sender; + pp = getCommandPearl(player, anArray, 1); + + if (pp == null){ + return null; + } + + if (args.length > 1) + return null; + + if (pp.getImprisonedPlayer().isDead()) { + sender.sendMessage(pp.getImprisonedName() + " is dead. Bring him back to try again."); + return null; + } else if (pp.getImprisonedPlayer() == player) { + sender.sendMessage("You cannot alter your own pearl!"); + return null; + } else if (!(summonman.isSummoned(pp))) { + sender.sendMessage(pp.getImprisonedName() + " is not summoned."); + return null; + } + + return pp; + } + + @SuppressWarnings("SameReturnValue") + private boolean setDistCmd(CommandSender sender, String args[]) { + + PrisonPearl pp = setCmd(sender, args); + + if (pp == null) { + + return false; + } + + summonman.getSummon(pp.getImprisonedName()).setAllowedDistance(Integer.parseInt(args[0])); + sender.sendMessage(pp.getImprisonedName() + "'s allowed distance set to " + args[0]); + return true; + } + + private boolean setDamageCmd(CommandSender sender, String args[]) { + + PrisonPearl pp = setCmd(sender, args); + + if (pp == null) { + + return false; + } + + summonman.getSummon(pp.getImprisonedName()).setDamageAmount(Integer.parseInt(args[0])); + sender.sendMessage(pp.getImprisonedName() + "'s damage amount set to " + args[0]); + return true; + } + + private boolean toggleSpeechCmd(CommandSender sender, String args[]) { + + PrisonPearl pp = setCmd(sender, args); + + if (pp == null) { + + return false; + } + + boolean speak = summonman.getSummon(pp.getImprisonedName()).isCanSpeak(); + summonman.getSummon(pp.getImprisonedName()).setCanSpeak(!speak); + sender.sendMessage(pp.getImprisonedName() + " ability to speak set to " + !speak); + return true; + } + + private boolean toggleDamageCmd(CommandSender sender, String args[]) { + + PrisonPearl pp = setCmd(sender, args); + + if (pp == null) { + + return false; + } + + boolean damage = summonman.getSummon(pp.getImprisonedName()).isCanDealDamage(); + summonman.getSummon(pp.getImprisonedName()).setCanDealDamage(!damage); + sender.sendMessage(pp.getImprisonedName() + " ability to deal damage set to " + !damage); + return true; + } + + private boolean toggleBlocksCmd(CommandSender sender, String args[]) { + + PrisonPearl pp = setCmd(sender, args); + + if (pp == null) { + + return false; + } + + boolean block = summonman.getSummon(pp.getImprisonedName()).isCanBreakBlocks(); + summonman.getSummon(pp.getImprisonedName()).setCanBreakBlocks(!block); + sender.sendMessage(pp.getImprisonedName() + " ability to break blocks set to " + !block); + return true; + } + + private boolean setMotdCmd(CommandSender sender, String args[]) { + + PrisonPearl pp; + + if (!(sender instanceof Player)) { + sender.sendMessage("ppset cannot be used at the console"); + return true; + } + + String[] anArray = {}; + Player player = (Player)sender; + pp = getCommandPearl(player, anArray, 1); + + if (pp == null) { + + return false; + } + + String s = ""; + for (String arg : args) { + s = s.concat(arg + " "); + } + pp.setMotd(s); + sender.sendMessage(pp.getImprisonedName() + "'s Message of the Day set to " + s); + return true; + } + + private boolean locateCmd(CommandSender sender, String args[], boolean any) { + String name_is; + String name_possesive; + PrisonPearl pp; + + if (!any) { + if (args.length != 0) + return false; + + if (!(sender instanceof Player)) { + sender.sendMessage("Must use pplocateany at the console"); + return true; + } + + name_is = "You are"; + name_possesive = "Your"; + pp = pearls.getByImprisoned((Player)sender); + } else { + if (args.length != 1) + return false; + + name_is = args[0] + " is"; + name_possesive = args[0] + "'s"; + pp = pearls.getByImprisoned(args[0]); + } + + if (pp != null) { + if (!pp.verifyLocation()) { + System.err.println("PrisonPearl for " + pp.getImprisonedName() + " didn't validate, so is now set free"); + pearlman.freePearl(pp); + } else { + sender.sendMessage(ChatColor.GREEN + name_possesive + " prison pearl is " + pp.describeLocation()); + if (sender instanceof Player && !any) + broadcastman.broadcast((Player)sender, ChatColor.GREEN + pp.getImprisonedName() + ": " + pp.describeLocation()); + } + } else { + sender.sendMessage(name_is + " not imprisoned"); + } + + return true; + } + + private boolean freeCmd(CommandSender sender, String args[], boolean any) { + PrisonPearl pp; + + if (!any) { + if (args.length > 1) + return false; + + if (!(sender instanceof Player)) { + sender.sendMessage("Must use freeany at console"); + return true; + } + + Player player = (Player)sender; + + int slot = getCommandPearlSlot(player, args, 0); + if (slot == -1) + return true; + + pp = pearls.getByItemStack(player.getInventory().getItem(slot)); + player.getInventory().setItem(slot, null); + } else { + if (args.length != 1) + return false; + + pp = pearls.getByImprisoned(args[0]); + + if (pp == null) { + sender.sendMessage(args[0] + " is not imprisoned"); + return true; + } + } + + if (pearlman.freePearl(pp)) { + if (pp.getImprisonedPlayer() != sender) // when freeing yourself, you're already going to get a message + sender.sendMessage("You've freed " + pp.getImprisonedName()); + } else { + sender.sendMessage("You failed to free " + pp.getImprisonedName()); + } + return true; + } + + private boolean imprisonCmd(CommandSender sender, String args[]) { + if (args.length != 1) + return false; + if (!(sender instanceof Player)) { + sender.sendMessage("imprison cannot be used at the console"); + return true; + } + + if (pearlman.imprisonPlayer(args[0], (Player)sender)) { + sender.sendMessage("You imprisoned " + args[0]); + Player player = Bukkit.getPlayerExact(args[0]); + if (player != null) + player.setHealth(0); + } else { + sender.sendMessage("You failed to imprison " + args[0]); + } + return true; + } + + private boolean summonCmd(CommandSender sender, String args[]) { + if (args.length > 1) + return false; + + if (!(sender instanceof Player)) { + sender.sendMessage("Command cannot be used at console"); + return true; + } + Player player = (Player)sender; + + PrisonPearl pp; + + if (args.length == 1) { + try { + pp = getCommandPearl(player, args, 0); + } catch (NumberFormatException e) { + pp = getCommandPearl(player, args, 1); + } + } else { + pp = getCommandPearl(player, args, 0); + } + + if (pp == null) + return true; + + //check if the pearled player is combat tagged + if (plugin.isCombatTagged(pp.getImprisonedName())) { + sender.sendMessage(ChatColor.RED+"[PrisonPearl]"+ChatColor.WHITE+" You cannot summon a CombatTagged player."); + return true; + } + + if (pp.getImprisonedPlayer() == null || pp.getImprisonedPlayer().isDead()) { + sender.sendMessage(pp.getImprisonedName() + " cannot be summoned"); + return true; + } else if (pp.getImprisonedPlayer() == player) { + sender.sendMessage("You cannot summon yourself!"); + return true; + } else if (summonman.isSummoned(pp)) { + sender.sendMessage(pp.getImprisonedName() + " is already summoned"); + return true; + } + + if (summonman.summonPearl(pp)) + sender.sendMessage("You've summoned " + pp.getImprisonedName()); + else + sender.sendMessage("You failed to summon " + pp.getImprisonedName()); + return true; + } + + private boolean returnCmd(CommandSender sender, String args[]) { + if (args.length > 1) + return false; + + if (!(sender instanceof Player)) { + sender.sendMessage("Command cannot be used at console"); + return true; + } + + + Player player = (Player)sender; + + PrisonPearl pp = getCommandPearl(player, args, 0); + if (pp == null) + return true; + + //check if the pearled player is combat tagged + if (plugin.isCombatTagged(pp.getImprisonedName())) { + sender.sendMessage(ChatColor.RED+"[PrisonPearl]"+ChatColor.WHITE+" You cannot return a CombatTagged player."); + return true; + } + + if (pp.getImprisonedName().equals(player.getName())) { + sender.sendMessage("You cannot return yourself!"); + return true; + } else if (!summonman.isSummoned(pp)) { + sender.sendMessage(pp.getImprisonedName() + " has not been summoned!"); + return true; + } else if (damageman.hasDamageLog(player)) { + sender.sendMessage(pp.getImprisonedName() + " is in combat and cannot be returned!"); + return true; + } + + if (summonman.returnPearl(pp)) + sender.sendMessage("You've returned " + pp.getImprisonedName()); + else + sender.sendMessage("You failed to return " + pp.getImprisonedName()); + return true; + } + + private boolean killCmd(CommandSender sender, String args[]) { + if (args.length > 1) + return false; + + if (!(sender instanceof Player)) { + sender.sendMessage("Command cannot be used at console"); + return true; + } + + Player player = (Player)sender; + PrisonPearl pp = getCommandPearl(player, args, 0); + if (pp == null) + return true; + + if (!summonman.isSummoned(pp)) { + sender.sendMessage(pp.getImprisonedName() + " has not been summoned!"); + return true; + } + + if (summonman.killPearl(pp)) + sender.sendMessage("You've killed " + pp.getImprisonedName()); + else + sender.sendMessage("You failed to kill " + pp.getImprisonedName()); + return true; + } + + private boolean saveCmd(CommandSender sender, String args[]) { + if (args.length > 0) + return false; + + try { + plugin.saveAll(true); + sender.sendMessage("PrisonPearl data saved!"); + return true; + } catch (RuntimeException e) { + if (!(sender instanceof ConsoleCommandSender)) + sender.sendMessage("PrisonPearl failed to save data! Check server logs!"); + throw e; + } + } + + private boolean broadcastCmd(CommandSender sender, String args[]) { + if (args.length != 1) + return false; + if (!(sender instanceof Player)) { + sender.sendMessage("Command cannot be used at console"); + return true; + } + + Player player = (Player)sender; + Player receiver = Bukkit.getPlayerExact(args[0]); + if (receiver == null) { + sender.sendMessage("No such player " + args[0]); + return true; + } else if (receiver == player) { + sender.sendMessage("You cannot broadcast to yourself!"); + return true; + } else if (!pearls.isImprisoned(player)) { + sender.sendMessage("You are not imprisoned!"); + return true; + } + + if (broadcastman.addBroadcast(player, receiver)) { + sender.sendMessage("You will broadcast pplocate information to " + receiver.getDisplayName()); + receiver.sendMessage("Type /ppconfirm to receive pplocate broadcasts from " + player.getDisplayName()); + } else { + sender.sendMessage("You are already broadcasting to " + receiver.getDisplayName()); + } + + return true; + } + + private boolean confirmCmd(CommandSender sender, String args[]) { + if (args.length > 1) + return false; + if (!(sender instanceof Player)) { + sender.sendMessage("Command cannot be used at console"); + return true; + } + + Player player = (Player)sender; + Player broadcaster; + + if (args.length == 1) { + broadcaster = Bukkit.getPlayerExact(args[0]); + if (broadcaster == null) { + sender.sendMessage("No such player " + args[0]); + return true; + } + } else { + broadcaster = broadcastman.getQuickConfirmPlayer(player); + if (broadcaster == null) { + sender.sendMessage("Nobody has requested to broadcast to you"); + return true; + } + } + + if (broadcastman.confirmBroadcast(broadcaster, player)) { + player.sendMessage("You will now receive broadcasts from " + broadcaster.getDisplayName()); + } else { + player.sendMessage(broadcaster.getDisplayName() + " does not wish to broadcast to you"); + } + return true; + } + + private boolean silenceCmd(CommandSender sender, String args[]) { + if (args.length != 1) + return false; + if (!(sender instanceof Player)) { + sender.sendMessage("Command cannot be used at console"); + return true; + } + + Player player = (Player)sender; + Player broadcaster = Bukkit.getPlayerExact(args[0]); + if (broadcaster == null) { + sender.sendMessage("No such player " + args[0]); + return true; + } + + if (broadcastman.silenceBroadcast(player, broadcaster)) { + player.sendMessage("You will no longer receive broadcasts from " + broadcaster.getDisplayName()); + } else { + player.sendMessage(broadcaster.getDisplayName() + " is not broadcasting to you"); + } + return true; + } + + private PrisonPearl getCommandPearl(Player player, String args[], int pos) { + int slot = getCommandPearlSlot(player, args, pos); + if (slot != -1) + return pearls.getByItemStack(player.getInventory().getItem(slot)); + else + return null; + } + + private int getCommandPearlSlot(Player player, String args[], int pos) { + if (args.length <= pos) { + ItemStack item = player.getItemInHand(); + if (item.getType() != Material.ENDER_PEARL) { + player.sendMessage("You must hold a pearl or supply the player's name to use this command"); + return -1; + } + + if (pearls.getByItemStack(item) == null) { + player.sendMessage("This is an ordinary ender pearl"); + return -1; + } + + return player.getInventory().getHeldItemSlot(); + } else { + PrisonPearl pp = pearls.getByImprisoned(args[pos]); + if (pp != null) { + Inventory inv = player.getInventory(); + for (Entry entry : inv.all(Material.ENDER_PEARL).entrySet()) { + if (entry.getValue().getDurability() == pp.getID()) + return entry.getKey(); + } + } + + player.sendMessage("You don't possess " + args[0] + "'s prison pearl"); + return -1; + } + } + + private boolean reloadAlts(CommandSender sender) { + if (!(sender instanceof Player)) { + plugin.loadAlts(); + plugin.checkBanAllAlts(); + return true; + } + return false; + } + + private boolean checkAll(CommandSender sender) { + if (!(sender instanceof Player)) { + plugin.checkBanAllAlts(); + return true; + } + return false; + } + + private boolean check(CommandSender sender, String[] args) { + if (args.length != 1) + return false; + if (!(sender instanceof Player)) { + boolean isBanned = plugin.isTempBanned(args[0]); + if (isBanned) { + sender.sendMessage(args[0]+" is temp banned for having "+plugin.getImprisonedCount(args[0])+" imprisoned accounts: "+plugin.getImprisonedAltsString(args[0])); + } else { + sender.sendMessage(args[0]+" is not temp banned"); + } + return true; + } + return false; + } + + @SuppressWarnings("SameReturnValue") + private boolean kill() { + return false; + } +} diff --git a/src/com/untamedears/PrisonPearl/PrisonPearlEvent.java b/src/com/untamedears/PrisonPearl/PrisonPearlEvent.java index b6d7665..4bdb3c8 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearlEvent.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearlEvent.java @@ -1,55 +1,55 @@ -package com.untamedears.PrisonPearl; - -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class PrisonPearlEvent extends Event { - public enum Type { NEW, HELD, DROPPED, FREED }; - - private PrisonPearl pp; - private Type type; - private Player imprisoner; - - private boolean cancelled; - - public PrisonPearlEvent(PrisonPearl pp, Type type) { - this.pp = pp; - this.type = type; - } - - public PrisonPearlEvent(PrisonPearl pp, Type type, Player imprisoner) { - this.pp = pp; - this.type = type; - this.imprisoner = imprisoner; - } - - public PrisonPearl getPrisonPearl() { - return pp; - } - - public Type getType() { - return type; - } - - public Player getImprisoner() { - return imprisoner; - } - - public boolean isCancelled() { - return cancelled; - } - - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } - - private static final HandlerList handlers = new HandlerList(); - public HandlerList getHandlers() { - return handlers; - } - public static HandlerList getHandlerList() { - return handlers; - } - -} +package com.untamedears.PrisonPearl; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class PrisonPearlEvent extends Event { + public enum Type { NEW, HELD, DROPPED, FREED } + + private final PrisonPearl pp; + private final Type type; + private Player imprisoner; + + private boolean cancelled; + + public PrisonPearlEvent(PrisonPearl pp, Type type) { + this.pp = pp; + this.type = type; + } + + public PrisonPearlEvent(PrisonPearl pp, Type type, Player imprisoner) { + this.pp = pp; + this.type = type; + this.imprisoner = imprisoner; + } + + public PrisonPearl getPrisonPearl() { + return pp; + } + + public Type getType() { + return type; + } + + public Player getImprisoner() { + return imprisoner; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + private static final HandlerList handlers = new HandlerList(); + public HandlerList getHandlers() { + return handlers; + } + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/src/com/untamedears/PrisonPearl/PrisonPearlManager.java b/src/com/untamedears/PrisonPearl/PrisonPearlManager.java index ae0e156..a0e461b 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearlManager.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearlManager.java @@ -1,344 +1,360 @@ -package com.untamedears.PrisonPearl; - -import java.util.Map.Entry; -import java.util.concurrent.Callable; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.BlockState; -import org.bukkit.block.BrewingStand; -import org.bukkit.block.Chest; -import org.bukkit.block.Dispenser; -import org.bukkit.block.DoubleChest; -import org.bukkit.block.Furnace; -import org.bukkit.configuration.Configuration; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Item; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.entity.EntityCombustEvent; -import org.bukkit.event.entity.ItemDespawnEvent; -import org.bukkit.event.entity.ItemSpawnEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerItemHeldEvent; -import org.bukkit.event.player.PlayerPickupItemEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.world.ChunkUnloadEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.InventoryView; -import org.bukkit.inventory.ItemStack; - -public class PrisonPearlManager implements Listener { - private PrisonPearlPlugin plugin; - private PrisonPearlStorage pearls; - - public PrisonPearlManager(PrisonPearlPlugin plugin, PrisonPearlStorage pearls) { - this.plugin = plugin; - this.pearls = pearls; - - Bukkit.getPluginManager().registerEvents(this, plugin); - } - - public boolean imprisonPlayer(Player imprisoned, Player imprisoner) { - return imprisonPlayer(imprisoned.getName(), imprisoner); - } - - public boolean imprisonPlayer(String imprisonedname, Player imprisoner) { - World respawnworld = Bukkit.getWorld(getConfig().getString("free_world")); - - // set up the imprisoner's inventory - Inventory inv = imprisoner.getInventory(); - ItemStack stack = null; - int stacknum = -1; - - // scan for the smallest stack of normal ender pearls - for (Entry entry : inv.all(Material.ENDER_PEARL).entrySet()) { - ItemStack newstack = entry.getValue(); - int newstacknum = entry.getKey(); - if (newstack.getDurability() == 0) { - if (stack != null) { - // don't keep a stack bigger than the previous one - if (newstack.getAmount() > stack.getAmount()) - continue; - // don't keep an identical sized stack in a higher slot - if (newstack.getAmount() == stack.getAmount() && newstacknum > stacknum) - continue; - } - - stack = newstack; - stacknum = entry.getKey(); - } - } - - int pearlnum; - if (stacknum == -1) { // no pearl (admin command) - pearlnum = inv.firstEmpty(); // give him a new one at the first empty slot - } else if (stack.getAmount() == 1) { // if he's just got one pearl - pearlnum = stacknum; // put the prison pearl there - } else { - pearlnum = inv.firstEmpty(); // otherwise, put the prison pearl in the first empty slot - if (pearlnum > 0) { - stack.setAmount(stack.getAmount()-1); // and reduce his stack of pearls by one - inv.setItem(stacknum, stack); - } else { // no empty slot? - pearlnum = stacknum; // then overwrite his stack of pearls - } - } - - PrisonPearl pp = pearls.newPearl(imprisonedname, imprisoner); // create the prison pearl - if (!prisonPearlEvent(pp, PrisonPearlEvent.Type.NEW, imprisoner)) { // set off an event - pearls.deletePearl(pp); - return false; - } - - inv.setItem(pearlnum, new ItemStack(Material.ENDER_PEARL, 1, pp.getID())); // give it to the imprisoner - - if (getConfig().getBoolean("prison_resetbed")) { - Player imprisoned = Bukkit.getPlayerExact(imprisonedname); - if (imprisoned != null) - imprisoned.setBedSpawnLocation(respawnworld.getSpawnLocation()); // clear out the players bed - } - return true; - } - - public boolean freePlayer(Player player) { - PrisonPearl pp = pearls.getByImprisoned(player); - if (pp == null) - return false; - - return freePearl(pp); - } - - public boolean freePearl(PrisonPearl pp) { - pearls.deletePearl(pp); - if (!prisonPearlEvent(pp, PrisonPearlEvent.Type.FREED)) { // set off an event - pearls.addPearl(pp); - return false; - } - - return true; - } - - // Announce the person in a pearl when a player holds it - @EventHandler(priority=EventPriority.MONITOR) - public void onItemHeldChange(PlayerItemHeldEvent event) { - Inventory inv = event.getPlayer().getInventory(); - ItemStack item = inv.getItem(event.getNewSlot()); - ItemStack newitem = announcePearl(event.getPlayer(), item); - if (newitem != null) - inv.setItem(event.getNewSlot(), newitem); - } - - private ItemStack announcePearl(Player player, ItemStack item) { - if (item == null) - return null; - - if (item.getType() == Material.ENDER_PEARL && item.getDurability() != 0) { - PrisonPearl pp = pearls.getByID(item.getDurability()); - - if (pp != null) { - player.sendMessage(ChatColor.GREEN+"Prison Pearl - " + pp.getImprisonedName()); - } else { - item.setDurability((short)0); - return item; - } - } - - return null; - } - - // Free pearls when right clicked - @EventHandler(priority=EventPriority.LOW) - public void onPlayerInteract(PlayerInteractEvent event) { - PrisonPearl pp = pearls.getByItemStack(event.getItem()); - if (pp == null) - return; - - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - Material m = event.getClickedBlock().getType(); - if (m == Material.CHEST || m == Material.WORKBENCH || m == Material.FURNACE || m == Material.DISPENSER || m == Material.BREWING_STAND) - return; - } else if (event.getAction() != Action.RIGHT_CLICK_AIR) { - return; - } - - Player player = event.getPlayer(); - player.getInventory().setItemInHand(null); - event.setCancelled(true); - - freePearl(pp); - player.sendMessage("You've freed " + pp.getImprisonedName()); - } - - // Free pearls when a player leaves - @EventHandler(priority=EventPriority.MONITOR) - public void onPlayerQuit(PlayerQuitEvent event) { - Inventory inv = event.getPlayer().getInventory(); - for (Entry entry : inv.all(Material.ENDER_PEARL).entrySet()) { - int slot = entry.getKey(); - PrisonPearl pp = pearls.getByItemStack(entry.getValue()); - if (pp == null) - continue; - - if (freePearl(pp)) - inv.setItem(slot, null); - } - } - - // Free the pearl if it despawns - @EventHandler(priority=EventPriority.MONITOR) - public void onItemDespawn(ItemDespawnEvent event) { - PrisonPearl pp = pearls.getByItemStack(event.getEntity().getItemStack()); - if (pp == null) - return; - - freePearl(pp); - } - - // Free the pearl if its on a chunk that unloads - @EventHandler(priority=EventPriority.MONITOR) - public void onChunkUnload(ChunkUnloadEvent event) { - for (Entity e : event.getChunk().getEntities()) { - if (!(e instanceof Item)) - continue; - - final PrisonPearl pp = pearls.getByItemStack(((Item)e).getItemStack()); - if (pp == null) - continue; - - final Entity entity = e; - Bukkit.getScheduler().callSyncMethod(plugin, new Callable() { // doing this in onChunkUnload causes weird things to happen - public Void call() throws Exception { - if (freePearl(pp)) - entity.remove(); - return null; - } - }); - - event.setCancelled(true); - } - } - - // Free the pearl if it combusts in lava/fire - @EventHandler(priority=EventPriority.MONITOR) - public void onEntityCombustEvent(EntityCombustEvent event) { - if (!(event.getEntity() instanceof Item)) - return; - - PrisonPearl pp = pearls.getByItemStack(((Item)event.getEntity()).getItemStack()); - if (pp == null) - return; - - freePearl(pp); - } - - // Track the location of a pearl - // Forbid pearls from being put in storage minecarts - @EventHandler(priority=EventPriority.NORMAL) - public void onInventoryClick(InventoryClickEvent event) { - // announce an prisonpearl if it is clicked - ItemStack newitem = announcePearl((Player)event.getWhoClicked(), event.getCurrentItem()); - if (newitem != null) - event.setCurrentItem(newitem); - - - PrisonPearl pp; - if (!event.isShiftClick()) { - pp = pearls.getByItemStack(event.getCursor()); - } else { - pp = pearls.getByItemStack(event.getCurrentItem()); - } - - if (pp == null) - return; - - InventoryView view = event.getView(); - int rawslot = event.getRawSlot(); - boolean top = view.convertSlot(rawslot) == rawslot; // this means in the top inventory - if (event.isShiftClick()) // for shift clicks, a click in the bottom moves item to the top and vice versa - top = !top; // so flip it - - InventoryHolder holder; - if (top) { - holder = view.getTopInventory().getHolder(); - } else { - holder = view.getBottomInventory().getHolder(); - } - - if (holder instanceof Chest) { - updatePearl(pp, (Chest)holder); - } else if (holder instanceof DoubleChest) { - updatePearl(pp, (Chest)((DoubleChest)holder).getLeftSide()); - } else if (holder instanceof Furnace) { - updatePearl(pp, (Furnace)holder); - } else if (holder instanceof Dispenser) { - updatePearl(pp, (Dispenser)holder); - } else if (holder instanceof BrewingStand) { - updatePearl(pp, (BrewingStand)holder); - } else if (holder instanceof Player) { - updatePearl(pp, (Player)holder); - } else { - event.setCancelled(true); - } - } - - // Track the location of a pearl if it spawns as an item for any reason - @EventHandler(priority=EventPriority.MONITOR) - public void onItemSpawn(ItemSpawnEvent event) { - Item item = event.getEntity(); - PrisonPearl pp = pearls.getByItemStack(item.getItemStack()); - if (pp == null) - return; - - updatePearl(pp, item); - } - - // Track the location of a pearl if a player picks it up - @EventHandler(priority=EventPriority.MONITOR) - public void onPlayerPickupItem(PlayerPickupItemEvent event) { - PrisonPearl pp = pearls.getByItemStack(event.getItem().getItemStack()); - if (pp == null) - return; - - updatePearl(pp, event.getPlayer()); - } - - private void updatePearl(PrisonPearl pp, Item item) { - pp.setHolder(item); - pearls.markDirty(); - Bukkit.getPluginManager().callEvent(new PrisonPearlEvent(pp, PrisonPearlEvent.Type.DROPPED)); - } - - private void updatePearl(PrisonPearl pp, Player player) { - pp.setHolder(player); - pearls.markDirty(); - Bukkit.getPluginManager().callEvent(new PrisonPearlEvent(pp, PrisonPearlEvent.Type.HELD)); - } - - private void updatePearl(PrisonPearl pp, ItemBlock block) { - pp.setHolder(block); - pearls.markDirty(); - Bukkit.getPluginManager().callEvent(new PrisonPearlEvent(pp, PrisonPearlEvent.Type.HELD)); - } - - private boolean prisonPearlEvent(PrisonPearl pp, PrisonPearlEvent.Type type) { - return prisonPearlEvent(pp, type, null); - } - - private boolean prisonPearlEvent(PrisonPearl pp, PrisonPearlEvent.Type type, Player imprisoner) { - PrisonPearlEvent event = new PrisonPearlEvent(pp, type, imprisoner); - Bukkit.getPluginManager().callEvent(event); - return !event.isCancelled(); - } - - private Configuration getConfig() { - return plugin.getConfig(); - } -} +package com.untamedears.PrisonPearl; + +import java.util.Map.Entry; +import java.util.concurrent.Callable; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.BlockState; +import org.bukkit.block.BrewingStand; +import org.bukkit.block.Chest; +import org.bukkit.block.Dispenser; +import org.bukkit.block.DoubleChest; +import org.bukkit.block.Furnace; +import org.bukkit.configuration.Configuration; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.ItemDespawnEvent; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +class PrisonPearlManager implements Listener { + private final PrisonPearlPlugin plugin; + private final PrisonPearlStorage pearls; + + public PrisonPearlManager(PrisonPearlPlugin plugin, PrisonPearlStorage pearls) { + this.plugin = plugin; + this.pearls = pearls; + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + public boolean imprisonPlayer(Player imprisoned, Player imprisoner) { + return imprisonPlayer(imprisoned.getName(), imprisoner); + } + + /** + * @param imprisonedname + * @param imprisoner + * @return + */ + /** + * @param imprisonedname + * @param imprisoner + * @return + */ + public boolean imprisonPlayer(String imprisonedname, Player imprisoner) { + World respawnworld = Bukkit.getWorld(getConfig().getString("free_world")); + + // set up the imprisoner's inventory + Inventory inv = imprisoner.getInventory(); + ItemStack stack = null; + int stacknum = -1; + + // scan for the smallest stack of normal ender pearls + for (Entry entry : inv.all(Material.ENDER_PEARL).entrySet()) { + ItemStack newstack = entry.getValue(); + int newstacknum = entry.getKey(); + if (newstack.getDurability() == 0) { + if (stack != null) { + // don't keep a stack bigger than the previous one + if (newstack.getAmount() > stack.getAmount()) + continue; + // don't keep an identical sized stack in a higher slot + if (newstack.getAmount() == stack.getAmount() && newstacknum > stacknum) + continue; + } + + stack = newstack; + stacknum = entry.getKey(); + } + } + + int pearlnum; + ItemStack dropStack = null; + if (stacknum == -1) { // no pearl (admin command) + pearlnum = inv.firstEmpty(); // give him a new one at the first empty slot + } else if (stack.getAmount() == 1) { // if he's just got one pearl + pearlnum = stacknum; // put the prison pearl there + } else { + pearlnum = inv.firstEmpty(); // otherwise, put the prison pearl in the first empty slot + if (pearlnum > 0) { + stack.setAmount(stack.getAmount()-1); // and reduce his stack of pearls by one + inv.setItem(stacknum, stack); + } else { // no empty slot? + dropStack = new ItemStack(Material.ENDER_PEARL, stack.getAmount()-1); + pearlnum = stacknum; // then overwrite his stack of pearls + } + } + + //drop pearls that otherwise would be deleted + if (dropStack != null) { + imprisoner.getWorld().dropItem(imprisoner.getLocation(), dropStack); + Bukkit.getLogger().info(imprisoner.getLocation()+", "+dropStack.getAmount()); + } + + PrisonPearl pp = pearls.newPearl(imprisonedname, imprisoner); // create the prison pearl + if (!prisonPearlEvent(pp, PrisonPearlEvent.Type.NEW, imprisoner)) { // set off an event + pearls.deletePearl(pp); + return false; + } + + inv.setItem(pearlnum, new ItemStack(Material.ENDER_PEARL, 1, pp.getID())); // give it to the imprisoner + + if (getConfig().getBoolean("prison_resetbed")) { + Player imprisoned = Bukkit.getPlayerExact(imprisonedname); + if (imprisoned != null) + imprisoned.setBedSpawnLocation(respawnworld.getSpawnLocation()); // clear out the players bed + } + return true; + } + + public boolean freePlayer(Player player) { + PrisonPearl pp = pearls.getByImprisoned(player); + return pp != null && freePearl(pp); + + } + + public boolean freePearl(PrisonPearl pp) { + pearls.deletePearl(pp); + if (!prisonPearlEvent(pp, PrisonPearlEvent.Type.FREED)) { // set off an event + pearls.addPearl(pp); + return false; + } + + return true; + } + + // Announce the person in a pearl when a player holds it + @EventHandler(priority=EventPriority.MONITOR) + public void onItemHeldChange(PlayerItemHeldEvent event) { + Inventory inv = event.getPlayer().getInventory(); + ItemStack item = inv.getItem(event.getNewSlot()); + ItemStack newitem = announcePearl(event.getPlayer(), item); + if (newitem != null) + inv.setItem(event.getNewSlot(), newitem); + } + + private ItemStack announcePearl(Player player, ItemStack item) { + if (item == null) + return null; + + if (item.getType() == Material.ENDER_PEARL && item.getDurability() != 0) { + PrisonPearl pp = pearls.getByID(item.getDurability()); + + if (pp != null) { + player.sendMessage(ChatColor.GREEN+"Prison Pearl - " + pp.getImprisonedName()); + } else { + item.setDurability((short)0); + return item; + } + } + + return null; + } + + // Free pearls when right clicked + @EventHandler(priority=EventPriority.LOW) + public void onPlayerInteract(PlayerInteractEvent event) { + PrisonPearl pp = pearls.getByItemStack(event.getItem()); + if (pp == null) + return; + + if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + Material m = event.getClickedBlock().getType(); + if (m == Material.CHEST || m == Material.WORKBENCH || m == Material.FURNACE || m == Material.DISPENSER || m == Material.BREWING_STAND) + return; + } else if (event.getAction() != Action.RIGHT_CLICK_AIR) { + return; + } + + Player player = event.getPlayer(); + player.getInventory().setItemInHand(null); + event.setCancelled(true); + + freePearl(pp); + player.sendMessage("You've freed " + pp.getImprisonedName()); + } + + // Free pearls when a player leaves + @EventHandler(priority=EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + Inventory inv = event.getPlayer().getInventory(); + for (Entry entry : inv.all(Material.ENDER_PEARL).entrySet()) { + int slot = entry.getKey(); + PrisonPearl pp = pearls.getByItemStack(entry.getValue()); + if (pp == null) + continue; + + if (freePearl(pp)) + inv.setItem(slot, null); + } + } + + // Free the pearl if it despawns + @EventHandler(priority=EventPriority.MONITOR) + public void onItemDespawn(ItemDespawnEvent event) { + PrisonPearl pp = pearls.getByItemStack(event.getEntity().getItemStack()); + if (pp == null) + return; + + freePearl(pp); + } + + // Free the pearl if its on a chunk that unloads + @EventHandler(priority=EventPriority.MONITOR) + public void onChunkUnload(ChunkUnloadEvent event) { + for (Entity e : event.getChunk().getEntities()) { + if (!(e instanceof Item)) + continue; + + final PrisonPearl pp = pearls.getByItemStack(((Item)e).getItemStack()); + if (pp == null) + continue; + + final Entity entity = e; + Bukkit.getScheduler().callSyncMethod(plugin, new Callable() { // doing this in onChunkUnload causes weird things to happen + public Void call() throws Exception { + if (freePearl(pp)) + entity.remove(); + return null; + } + }); + + event.setCancelled(true); + } + } + + // Free the pearl if it combusts in lava/fire + @EventHandler(priority=EventPriority.MONITOR) + public void onEntityCombustEvent(EntityCombustEvent event) { + if (!(event.getEntity() instanceof Item)) + return; + + PrisonPearl pp = pearls.getByItemStack(((Item)event.getEntity()).getItemStack()); + if (pp == null) + return; + + freePearl(pp); + } + + // Track the location of a pearl + // Forbid pearls from being put in storage minecarts + @EventHandler(priority=EventPriority.NORMAL) + public void onInventoryClick(InventoryClickEvent event) { + // announce an prisonpearl if it is clicked + ItemStack newitem = announcePearl((Player)event.getWhoClicked(), event.getCurrentItem()); + if (newitem != null) + event.setCurrentItem(newitem); + + + PrisonPearl pp; + if (!event.isShiftClick()) { + pp = pearls.getByItemStack(event.getCursor()); + } else { + pp = pearls.getByItemStack(event.getCurrentItem()); + } + + if (pp == null) + return; + + InventoryView view = event.getView(); + int rawslot = event.getRawSlot(); + boolean top = view.convertSlot(rawslot) == rawslot; // this means in the top inventory + if (event.isShiftClick()) // for shift clicks, a click in the bottom moves item to the top and vice versa + top = !top; // so flip it + + InventoryHolder holder; + if (top) { + holder = view.getTopInventory().getHolder(); + } else { + holder = view.getBottomInventory().getHolder(); + } + + if (holder instanceof Chest) { + updatePearl(pp, (Chest)holder); + } else if (holder instanceof DoubleChest) { + updatePearl(pp, (Chest)((DoubleChest)holder).getLeftSide()); + } else if (holder instanceof Furnace) { + updatePearl(pp, (Furnace)holder); + } else if (holder instanceof Dispenser) { + updatePearl(pp, (Dispenser)holder); + } else if (holder instanceof BrewingStand) { + updatePearl(pp, (BrewingStand)holder); + } else if (holder instanceof Player) { + updatePearl(pp, (Player)holder); + } else { + event.setCancelled(true); + } + } + + // Track the location of a pearl if it spawns as an item for any reason + @EventHandler(priority=EventPriority.MONITOR) + public void onItemSpawn(ItemSpawnEvent event) { + Item item = event.getEntity(); + PrisonPearl pp = pearls.getByItemStack(item.getItemStack()); + if (pp == null) + return; + + updatePearl(pp, item); + } + + // Track the location of a pearl if a player picks it up + @EventHandler(priority=EventPriority.MONITOR) + public void onPlayerPickupItem(PlayerPickupItemEvent event) { + PrisonPearl pp = pearls.getByItemStack(event.getItem().getItemStack()); + if (pp == null) + return; + + updatePearl(pp, event.getPlayer()); + } + + private void updatePearl(PrisonPearl pp, Item item) { + pp.setHolder(item); + pearls.markDirty(); + Bukkit.getPluginManager().callEvent(new PrisonPearlEvent(pp, PrisonPearlEvent.Type.DROPPED)); + } + + private void updatePearl(PrisonPearl pp, Player player) { + pp.setHolder(player); + pearls.markDirty(); + Bukkit.getPluginManager().callEvent(new PrisonPearlEvent(pp, PrisonPearlEvent.Type.HELD)); + } + + private void updatePearl(PrisonPearl pp, ItemBlock block) { + pp.setHolder(block); + pearls.markDirty(); + Bukkit.getPluginManager().callEvent(new PrisonPearlEvent(pp, PrisonPearlEvent.Type.HELD)); + } + + private boolean prisonPearlEvent(PrisonPearl pp, PrisonPearlEvent.Type type) { + return prisonPearlEvent(pp, type, null); + } + + private boolean prisonPearlEvent(PrisonPearl pp, PrisonPearlEvent.Type type, Player imprisoner) { + PrisonPearlEvent event = new PrisonPearlEvent(pp, type, imprisoner); + Bukkit.getPluginManager().callEvent(event); + return !event.isCancelled(); + } + + private Configuration getConfig() { + return plugin.getConfig(); + } +} diff --git a/src/com/untamedears/PrisonPearl/PrisonPearlPlugin.java b/src/com/untamedears/PrisonPearl/PrisonPearlPlugin.java index 3a8f50a..d0316d4 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearlPlugin.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearlPlugin.java @@ -1,446 +1,696 @@ -package com.untamedears.PrisonPearl; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Random; -import java.util.concurrent.Callable; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerPortalEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.PlayerRespawnEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.permissions.PermissionAttachment; -import org.bukkit.plugin.java.JavaPlugin; - -public class PrisonPearlPlugin extends JavaPlugin implements Listener { - private PrisonPearlStorage pearls; - private DamageLogManager damageman; - private PrisonPearlManager pearlman; - private SummonManager summonman; - private PrisonPortaledPlayerManager portalman; - private BroadcastManager broadcastman; - - private Map attachments; - - public void onEnable() { - getConfig().options().copyDefaults(true); - saveConfig(); - - pearls = new PrisonPearlStorage(); - load(pearls, getPrisonPearlsFile()); - - damageman = new DamageLogManager(this); - pearlman = new PrisonPearlManager(this, pearls); - summonman = new SummonManager(this, pearls); - load(summonman, getSummonFile()); - portalman = new PrisonPortaledPlayerManager(this, pearls); - load(portalman, getPortaledPlayersFile()); - broadcastman = new BroadcastManager(); - if (Bukkit.getPluginManager().isPluginEnabled("PhysicalShop")) - new PhysicalShopListener(this, pearls); - - Bukkit.getPluginManager().registerEvents(this, this); - Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() { - public void run() { - saveAll(false); - } - }, 0, getConfig().getLong("save_ticks")); - - PrisonPearlCommands commands = new PrisonPearlCommands(this, damageman, pearls, pearlman, summonman, broadcastman); - for (String command : getDescription().getCommands().keySet()) { - if (command.equals("ppkill") && !getConfig().getBoolean("ppkill_enabled")) - continue; - - getCommand(command).setExecutor(commands); - } - - // shamelessly swiped from bookworm, not sure why there isn't a Bukkit API for this - // this causes items to be stacked by their durability value - try { - Method method = net.minecraft.server.Item.class.getDeclaredMethod("a", boolean.class); - if (method.getReturnType() == net.minecraft.server.Item.class) { - method.setAccessible(true); - method.invoke(net.minecraft.server.Item.ENDER_PEARL, true); - } - } catch (Exception e) { - e.printStackTrace(); - } - - attachments = new HashMap(); - for (Player player : Bukkit.getOnlinePlayers()) - updateAttachment(player); - } - - public void onDisable() { - saveAll(true); - - for (PermissionAttachment attachment : attachments.values()) - attachment.remove(); - } - - public void saveAll(boolean force) { - if (force || pearls.isDirty()) - save(pearls, getPrisonPearlsFile()); - if (force || summonman.isDirty()) - save(summonman, getSummonFile()); - if (force || portalman.isDirty()) - save(portalman, getPortaledPlayersFile()); - } - - private static void load(SaveLoad obj, File file) { - try { - obj.load(file); - } catch (FileNotFoundException e) { - System.out.println(file.getName() + " not exist, creating."); - - try { - obj.save(file); - } catch (IOException e2) { - throw new RuntimeException("Failed to create " + file.getAbsolutePath(), e2); - } - } catch (IOException e) { - throw new RuntimeException("Failed to load prison pearls from " + file.getAbsolutePath(), e); - } - } - - private static void save(SaveLoad obj, File file) { - try { - File newfile = new File(file.getAbsolutePath() + ".new"); - File bakfile = new File(file.getAbsolutePath() + ".bak"); - - obj.save(newfile); - if (file.exists() && !file.renameTo(bakfile)) - throw new IOException("Failed to rename " + file.getAbsolutePath() + " to " + bakfile.getAbsolutePath()); - if (!newfile.renameTo(file)) - throw new IOException("Failed to rename " + newfile.getAbsolutePath() + " to " + file.getAbsolutePath()); - } catch (IOException e) { - throw new RuntimeException("Failed to save prison pearls to " + file.getAbsolutePath(), e); - } - } - - private File getPrisonPearlsFile() { - return new File(getDataFolder(), "prisonpearls.txt"); - } - - private File getSummonFile() { - return new File(getDataFolder(), "summons.txt"); - } - - private File getPortaledPlayersFile() { - return new File(getDataFolder(), "portaledplayers.txt"); - } - - // Free player if he was free'd while offline - // otherwise, correct his spawn location if necessary - @EventHandler(priority=EventPriority.HIGHEST) - public void onPlayerJoin(PlayerJoinEvent event) { - final Player player = event.getPlayer(); - updateAttachment(player); - - if (player.isDead()) - return; - - Location loc = player.getLocation(); - Location newloc = getRespawnLocation(player, loc); - if (newloc != null) { - if (loc.getWorld() == getPrisonWorld() && (newloc.getWorld() != loc.getWorld() || newloc == RESPAWN_PLAYER)) - player.sendMessage("While away, you were freed!"); // he was freed offline - delayedTp(player, newloc); - } else { - prisonMotd(player); - } - } - - // don't let people escape through the end portal - @EventHandler(priority=EventPriority.HIGHEST) - public void onPlayerPortalEvent(PlayerPortalEvent event) { - Player player = event.getPlayer(); - - if (pearls.isImprisoned(player) && !summonman.isSummoned(player)) { // if in prison but not imprisoned - if (event.getTo().getWorld() != getPrisonWorld()) { - prisonMotd(player); - delayedTp(player, getPrisonSpawnLocation()); - } - } - } - - // remove permission attachments - @EventHandler(priority=EventPriority.MONITOR) - public void onPlayerQuit(PlayerQuitEvent event) { - PermissionAttachment attachment = attachments.remove(event.getPlayer().getName()); - if (attachment != null) - attachment.remove(); - } - - // adjust spawnpoint if necessary - @EventHandler(priority=EventPriority.HIGHEST) - public void onPlayerRespawn(PlayerRespawnEvent event) { - prisonMotd(event.getPlayer()); - Location newloc = getRespawnLocation(event.getPlayer(), event.getRespawnLocation()); - if (newloc != null && newloc != RESPAWN_PLAYER) - event.setRespawnLocation(newloc); - } - - // called when a player joins or spawns - private void prisonMotd(Player player) { - if (pearls.isImprisoned(player) && !summonman.isSummoned(player)) { // if player is imprisoned - for (String line : getConfig().getStringList("prison_motd")) // give him prison_motd - player.sendMessage(line); - } - } - - private static Location RESPAWN_PLAYER = new Location(null, 0, 0, 0); - - // gets where the player should be respawned at - // returns null if the curloc is an acceptable respawn location - private Location getRespawnLocation(Player player, Location curloc) { - if (pearls.isImprisoned(player)) { // if player is imprisoned - if (summonman.isSummoned(player)) // if summoned - return null; // don't modify location - if (curloc.getWorld() != getPrisonWorld()) // but not in prison world - return getPrisonSpawnLocation(); // should bre respawned in prison - } else if (curloc.getWorld() == getPrisonWorld() && !portalman.isPlayerPortaledToPrison(player)) { // not imprisoned, but spawning in prison? - if (player.getBedSpawnLocation() != null) // if he's got a bed - return player.getBedSpawnLocation(); // spawn him there - else if (getConfig().getBoolean("free_respawn")) // if we should respawn instead of tp to spawn - return RESPAWN_PLAYER; // kill the player - else - return getFreeWorld().getSpawnLocation(); // otherwise, respawn him at the spawn of the free world - } - - return null; // don't modify respawn location - } - - // Imprison people upon death - @EventHandler(priority=EventPriority.HIGHEST) - public void onEntityDeath(EntityDeathEvent event) { - if (!(event.getEntity() instanceof Player)) - return; - - Player player = (Player)event.getEntity(); - - PrisonPearl pp = pearls.getByImprisoned(player); // find out if the player is imprisoned - if (pp != null) { // if imprisoned - if (!getConfig().getBoolean("prison_stealing") || player.getLocation().getWorld() == getPrisonWorld()) // bail if prisoner stealing isn't allowed, or if the player is in prison (can't steal prisoners from prison ever) - return; - } - - for (Player damager : damageman.getDamagers(player)) { // check to see if anyone can imprison him - if (pp != null && pp.getHolderPlayer() == damager) // if this damager has already imprisoned this person - break; // don't be confusing and re-imprison him, just let him die - - int firstpearl = Integer.MAX_VALUE; // find the first regular enderpearl in their inventory - for (Entry entry : damager.getInventory().all(Material.ENDER_PEARL).entrySet()) { - if (entry.getValue().getDurability() == 0) - firstpearl = Math.min(entry.getKey(), firstpearl); - } - - if (firstpearl == Integer.MAX_VALUE) // no pearl - continue; // no imprisonment - - if (getConfig().getBoolean("prison_musthotbar") && firstpearl > 9) // bail if it must be in the hotbar - continue; - - if (pearlman.imprisonPlayer(player, damager)) // otherwise, try to imprison - break; - } - } - - // Announce prison pearl events - // Teleport players when freed - @EventHandler(priority=EventPriority.MONITOR) - public void onPrisonPearlEvent(PrisonPearlEvent event) { - if (event.isCancelled()) - return; - - PrisonPearl pp = event.getPrisonPearl(); - Player player = pp.getImprisonedPlayer(); - if (player == null) - return; - - if (event.getType() == PrisonPearlEvent.Type.NEW) { - updateAttachment(player); - - Player imprisoner = event.getImprisoner(); - imprisoner.sendMessage(ChatColor.GREEN+"You've bound " + player.getDisplayName() + ChatColor.GREEN+" to a prison pearl!"); - player.sendMessage(ChatColor.RED+"You've been bound to a prison pearl owned by " + imprisoner.getDisplayName()); - } else if (event.getType() == PrisonPearlEvent.Type.DROPPED || event.getType() == PrisonPearlEvent.Type.HELD) { - String loc = pp.describeLocation(); - player.sendMessage(ChatColor.GREEN + "Your prison pearl is " + loc); - broadcastman.broadcast(player, ChatColor.GREEN + player.getName() + ": " + loc); - } else if (event.getType() == PrisonPearlEvent.Type.FREED) { - updateAttachment(player); - - if (!player.isDead() && player.getLocation().getWorld() == getPrisonWorld()) { // if the player isn't dead and is in prison world - Location loc = null; - if (getConfig().getBoolean("free_tppearl")) // if we tp to pearl on players being freed - loc = fuzzLocation(pp.getLocation()); // get the location of the pearl - if (loc == null) // if we don't have a location yet - loc = getRespawnLocation(player, player.getLocation()); // get the respawn location for the player - - if (loc == RESPAWN_PLAYER) { // if we're supposed to respawn the player - player.setHealth(0); // kill him - } else { - player.teleport(loc); // otherwise teleport - } - } - - player.sendMessage("You've been freed!"); - broadcastman.broadcast(player, player.getDisplayName() + " was freed!"); - } - } - - // Announce summon events - // Teleport player when summoned or returned - @EventHandler(priority=EventPriority.MONITOR) - public void onSummonEvent(SummonEvent event) { - if (event.isCancelled()) - return; - - PrisonPearl pp = event.getPrisonPearl(); - Player player = pp.getImprisonedPlayer(); - if (player == null) - return; - - switch (event.getType()) { - case SUMMONED: - player.sendMessage(ChatColor.RED+"You've been summoned to your prison pearl!"); - player.teleport(fuzzLocation(event.getLocation())); - break; - - case RETURNED: - player.sendMessage(ChatColor.RED+"You've been returned to your prison"); - player.teleport(event.getLocation()); - break; - - case KILLED: - player.sendMessage(ChatColor.RED+"You've been struck down by your pearl!"); - break; - } - } - - - private void updateAttachment(Player player) { - PermissionAttachment attachment = attachments.get(player.getName()); - if (attachment == null) { - attachment = player.addAttachment(this); - attachments.put(player.getName(), attachment); - } - - if (pearls.isImprisoned(player)) { - for (String grant : getConfig().getStringList("prison_grant_perms")) - attachment.setPermission(grant, true); - for (String deny : getConfig().getStringList("prison_deny_perms")) - attachment.setPermission(deny, false); - } else { - for (String grant : getConfig().getStringList("prison_grant_perms")) - attachment.unsetPermission(grant); - for (String deny : getConfig().getStringList("prison_deny_perms")) - attachment.unsetPermission(deny); - } - - player.recalculatePermissions(); - } - - - private World getFreeWorld() { - return Bukkit.getWorld(getConfig().getString("free_world")); - } - - private World getPrisonWorld() { - return Bukkit.getWorld(getConfig().getString("prison_world")); - } - - // hill climbing algorithm which attempts to randomly spawn prisoners while actively avoiding pits - // the obsidian pillars, or lava. - private Location getPrisonSpawnLocation() { - Random rand = new Random(); - Location loc = getPrisonWorld().getSpawnLocation(); // start at spawn - for (int i=0; i<30; i++) { // for up to 30 iterations - if (loc.getY() > 40 && loc.getY() < 70 && i > 5 && !isObstructed(loc)) // if the current candidate looks reasonable and we've iterated at least 5 times - return loc; // we're done - - Location newloc = loc.clone().add(rand.nextGaussian()*(2*i), 0, rand.nextGaussian()*(2*i)); // pick a new location near the current one - newloc = moveToGround(newloc); - if (newloc == null) - continue; - - if (newloc.getY() > loc.getY()+(int)(rand.nextGaussian()*3) || loc.getY() > 70) // if its better in a fuzzy sense, or if the current location is too high - loc = newloc; // it becomes the new current location - } - - return loc; - } - - private Location moveToGround(Location loc) { - Location ground = new Location(loc.getWorld(), loc.getX(), 100, loc.getZ()); - while (ground.getBlockY() >= 1) { - if (!ground.getBlock().isEmpty()) - return ground; - ground.add(0, -1, 0); - } - return null; - } - - private boolean isObstructed(Location loc) { - Location ground = new Location(loc.getWorld(), loc.getX(), 100, loc.getZ()); - while (ground.getBlockY() >= 1) { - if (!ground.getBlock().isEmpty()) - break; - - ground.add(0, -1, 0); - } - - for (int x=-2; x<=2; x++) { - for (int y=-2; y<=2; y++) { - for (int z=-2; z<=2; z++) { - Location l = ground.clone().add(x, y, z); - Material type = l.getBlock().getType(); - if (type == Material.LAVA || type == Material.STATIONARY_LAVA || type == Material.ENDER_PORTAL || type == Material.BEDROCK) - return true; - } - } - } - - return false; - } - - private Location fuzzLocation(Location loc) { - if (loc == null) - return null; - - double rad = Math.random()*Math.PI*2; - Location newloc = loc.clone(); - newloc.add(1.2*Math.cos(rad), 1.2*Math.sin(rad), 0); - return newloc; - } - - private void delayedTp(final Player player, final Location loc) { - if (loc == RESPAWN_PLAYER) { - player.setHealth(0); - } else { - Bukkit.getScheduler().callSyncMethod(this, new Callable() { - public Void call() { - player.teleport(loc); - return null; - } - }); - } - } -} +package com.untamedears.PrisonPearl; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; +import java.util.concurrent.Callable; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.*; +import org.bukkit.inventory.ItemStack; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.plugin.java.JavaPlugin; + +public class PrisonPearlPlugin extends JavaPlugin implements Listener { + private PrisonPearlStorage pearls; + private DamageLogManager damageman; + private PrisonPearlManager pearlman; + private SummonManager summonman; + private PrisonPortaledPlayerManager portalman; + private BroadcastManager broadcastman; + private AltsList altsList; + private static Logger log; + private static final Integer maxImprisonedAlts = 2; + //private static long loginDelay = 10*60*1000; + private static final String kickMessage = "You have too many imprisoned alts! If you think this is an error, please message the mods on /r/civcraft"; + //private static String delayMessage = "You cannot switch alt accounts that quickly, please wait "; + private HashMap lastLoggout; + private HashMap banned; + + private CombatTagManager combatTagManager; + + private Map attachments; + + public void onEnable() { + getConfig().options().copyDefaults(true); + saveConfig(); + + log = this.getLogger(); + + //lastLoggout = new HashMap(); + //wasKicked = new HashMap(); + banned = new HashMap(); + + pearls = new PrisonPearlStorage(); + load(pearls, getPrisonPearlsFile()); + + damageman = new DamageLogManager(this); + pearlman = new PrisonPearlManager(this, pearls); + summonman = new SummonManager(this, pearls); + load(summonman, getSummonFile()); + portalman = new PrisonPortaledPlayerManager(this, pearls); + load(portalman, getPortaledPlayersFile()); + broadcastman = new BroadcastManager(); + combatTagManager = new CombatTagManager(this.getServer(), log); + + loadAlts(); + checkBanAllAlts(); + + if (Bukkit.getPluginManager().isPluginEnabled("PhysicalShop")) + new PhysicalShopListener(this, pearls); + + Bukkit.getPluginManager().registerEvents(this, this); + Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() { + public void run() { + saveAll(false); + } + }, 0, getConfig().getLong("save_ticks")); + + PrisonPearlCommands commands = new PrisonPearlCommands(this, damageman, pearls, pearlman, summonman, broadcastman); + for (String command : getDescription().getCommands().keySet()) { + if (command.equals("ppkill") && !getConfig().getBoolean("ppkill_enabled")) + continue; + + getCommand(command).setExecutor(commands); + } + + // shamelessly swiped from bookworm, not sure why there isn't a Bukkit API for this + // this causes items to be stacked by their durability value + try { + Method method = net.minecraft.server.Item.class.getDeclaredMethod("a", boolean.class); + if (method.getReturnType() == net.minecraft.server.Item.class) { + method.setAccessible(true); + method.invoke(net.minecraft.server.Item.ENDER_PEARL, true); + } + } catch (Exception e) { + e.printStackTrace(); + } + + attachments = new HashMap(); + for (Player player : Bukkit.getOnlinePlayers()) + updateAttachment(player); + } + + public void onDisable() { + saveAll(true); + unBanAll(); + + for (PermissionAttachment attachment : attachments.values()) + attachment.remove(); + } + + public void saveAll(boolean force) { + if (force || pearls.isDirty()) + save(pearls, getPrisonPearlsFile()); + if (force || summonman.isDirty()) + save(summonman, getSummonFile()); + if (force || portalman.isDirty()) + save(portalman, getPortaledPlayersFile()); + } + + private static void load(SaveLoad obj, File file) { + try { + obj.load(file); + } catch (FileNotFoundException e) { + System.out.println(file.getName() + " not exist, creating."); + + try { + obj.save(file); + } catch (IOException e2) { + throw new RuntimeException("Failed to create " + file.getAbsolutePath(), e2); + } + } catch (IOException e) { + throw new RuntimeException("Failed to load prison pearls from " + file.getAbsolutePath(), e); + } + } + + private static void save(SaveLoad obj, File file) { + try { + File newfile = new File(file.getAbsolutePath() + ".new"); + File bakfile = new File(file.getAbsolutePath() + ".bak"); + + obj.save(newfile); + + if (bakfile.exists()) { + //noinspection ResultOfMethodCallIgnored + bakfile.delete(); + } + + if (file.exists() && !file.renameTo(bakfile)) + throw new IOException("Failed to rename " + file.getAbsolutePath() + " to " + bakfile.getAbsolutePath()); + if (!newfile.renameTo(file)) + throw new IOException("Failed to rename " + newfile.getAbsolutePath() + " to " + file.getAbsolutePath()); + } catch (IOException e) { + throw new RuntimeException("Failed to save prison pearls to " + file.getAbsolutePath(), e); + } + } + + private File getPrisonPearlsFile() { + return new File(getDataFolder(), "prisonpearls.txt"); + } + + private File getSummonFile() { + return new File(getDataFolder(), "summons.txt"); + } + + private File getPortaledPlayersFile() { + return new File(getDataFolder(), "portaledplayers.txt"); + } + + + private File getAltsListFile() { + return new File(getDataFolder(), "alts.txt"); + } + + + // Free player if he was free'd while offline + // otherwise, correct his spawn location if necessary + @EventHandler(priority=EventPriority.HIGHEST) + public void onPlayerJoin(PlayerJoinEvent event) { + final Player player = event.getPlayer(); + updateAttachment(player); + checkBan(player.getName()); + + if (player.isDead()) + return; + + Location loc = player.getLocation(); + Location newloc = getRespawnLocation(player, loc); + if (newloc != null) { + if (loc.getWorld() == getPrisonWorld() && (newloc.getWorld() != loc.getWorld() || newloc == RESPAWN_PLAYER)) + player.sendMessage("While away, you were freed!"); // he was freed offline + delayedTp(player, newloc); + } else { + prisonMotd(player); + } + } + + // don't let people escape through the end portal + @EventHandler(priority=EventPriority.HIGHEST) + public void onPlayerPortalEvent(PlayerPortalEvent event) { + Player player = event.getPlayer(); + + if (pearls.isImprisoned(player) && !summonman.isSummoned(player)) { // if in prison but not imprisoned + if (event.getTo().getWorld() != getPrisonWorld()) { + prisonMotd(player); + delayedTp(player, getPrisonSpawnLocation()); + } + } + } + + // remove permission attachments and record the time players log out + @EventHandler(priority=EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + PermissionAttachment attachment = attachments.remove(event.getPlayer().getName()); + if (attachment != null) + attachment.remove(); + } + + // adjust spawnpoint if necessary + @EventHandler(priority=EventPriority.HIGHEST) + public void onPlayerRespawn(PlayerRespawnEvent event) { + prisonMotd(event.getPlayer()); + Location newloc = getRespawnLocation(event.getPlayer(), event.getRespawnLocation()); + if (newloc != null && newloc != RESPAWN_PLAYER) + event.setRespawnLocation(newloc); + } + + // called when a player joins or spawns + private void prisonMotd(Player player) { + if (pearls.isImprisoned(player) && !summonman.isSummoned(player)) { // if player is imprisoned + for (String line : getConfig().getStringList("prison_motd")) // give him prison_motd + player.sendMessage(line); + player.sendMessage(pearls.getByImprisoned(player).getMotd()); + } + } + + private static final Location RESPAWN_PLAYER = new Location(null, 0, 0, 0); + + // gets where the player should be respawned at + // returns null if the curloc is an acceptable respawn location + private Location getRespawnLocation(Player player, Location curloc) { + if (pearls.isImprisoned(player)) { // if player is imprisoned + if (summonman.isSummoned(player)) // if summoned + return null; // don't modify location + if (curloc.getWorld() != getPrisonWorld()) // but not in prison world + return getPrisonSpawnLocation(); // should bre respawned in prison + } else if (curloc.getWorld() == getPrisonWorld() && !portalman.isPlayerPortaledToPrison(player)) { // not imprisoned, but spawning in prison? + if (player.getBedSpawnLocation() != null) // if he's got a bed + return player.getBedSpawnLocation(); // spawn him there + else if (getConfig().getBoolean("free_respawn")) // if we should respawn instead of tp to spawn + return RESPAWN_PLAYER; // kill the player + else + return getFreeWorld().getSpawnLocation(); // otherwise, respawn him at the spawn of the free world + } + + return null; // don't modify respawn location + } + + // Imprison people upon death + @EventHandler(priority=EventPriority.HIGHEST) + public void onEntityDeath(EntityDeathEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player)event.getEntity(); + String playerName = player.getName(); + + if (combatTagManager.isCombatTagNPC(event.getEntity())) { + String npcName = player.getName(); + String realName = combatTagManager.getNPCPlayerName(player); + log.info("NPC: "+npcName+", Player: "+playerName); + if (!realName.equals("")) { + playerName = realName; + } + } + + PrisonPearl pp = pearls.getByImprisoned(playerName); // find out if the player is imprisoned + if (pp != null) { // if imprisoned + if (!getConfig().getBoolean("prison_stealing") || player.getLocation().getWorld() == getPrisonWorld()) {// bail if prisoner stealing isn't allowed, or if the player is in prison (can't steal prisoners from prison ever) + // reveal location of pearl to damaging players if pearl stealing is disabled + for (Player damager : damageman.getDamagers(player)) { + damager.sendMessage(ChatColor.GREEN+"[PrisonPearl] "+pp.getImprisonedName()+" cannot be pearled here because they are already "+pp.describeLocation()); + } + return; + } + } + + for (Player damager : damageman.getDamagers(player)) { // check to see if anyone can imprison him + if (pp != null && pp.getHolderPlayer() == damager) // if this damager has already imprisoned this person + break; // don't be confusing and re-imprison him, just let him die + + int firstpearl = Integer.MAX_VALUE; // find the first regular enderpearl in their inventory + for (Entry entry : damager.getInventory().all(Material.ENDER_PEARL).entrySet()) { + if (entry.getValue().getDurability() == 0) + firstpearl = Math.min(entry.getKey(), firstpearl); + } + + if (firstpearl == Integer.MAX_VALUE) // no pearl + continue; // no imprisonment + + if (getConfig().getBoolean("prison_musthotbar") && firstpearl > 9) // bail if it must be in the hotbar + continue; + + if (pearlman.imprisonPlayer(player, damager)) // otherwise, try to imprison + break; + } + } + + // Announce prison pearl events + // Teleport players when freed + @EventHandler(priority=EventPriority.MONITOR) + public void onPrisonPearlEvent(PrisonPearlEvent event) { + if (event.isCancelled()) + return; + + PrisonPearl pp = event.getPrisonPearl(); + Player player = pp.getImprisonedPlayer(); + if (player == null) + return; + + if (event.getType() == PrisonPearlEvent.Type.NEW) { + updateAttachment(player); + + Player imprisoner = event.getImprisoner(); + imprisoner.sendMessage(ChatColor.GREEN+"You've bound " + player.getDisplayName() + ChatColor.GREEN+" to a prison pearl!"); + player.sendMessage(ChatColor.RED+"You've been bound to a prison pearl owned by " + imprisoner.getDisplayName()); + + String[] alts = altsList.getAltsArray(player.getName()); + checkBans(alts); + + } else if (event.getType() == PrisonPearlEvent.Type.DROPPED || event.getType() == PrisonPearlEvent.Type.HELD) { + String loc = pp.describeLocation(); + player.sendMessage(ChatColor.GREEN + "Your prison pearl is " + loc); + broadcastman.broadcast(player, ChatColor.GREEN + player.getName() + ": " + loc); + } else if (event.getType() == PrisonPearlEvent.Type.FREED) { + updateAttachment(player); + + if (!player.isDead() && player.getLocation().getWorld() == getPrisonWorld()) { // if the player isn't dead and is in prison world + Location loc = null; + if (getConfig().getBoolean("free_tppearl")) // if we tp to pearl on players being freed + loc = fuzzLocation(pp.getLocation()); // get the location of the pearl + if (loc == null) // if we don't have a location yet + loc = getRespawnLocation(player, player.getLocation()); // get the respawn location for the player + + if (loc == RESPAWN_PLAYER) { // if we're supposed to respawn the player + player.setHealth(0); // kill him + } else { + player.teleport(loc); // otherwise teleport + } + } + String[] alts = altsList.getAltsArray(player.getName()); + checkBans(alts); + + player.sendMessage("You've been freed!"); + broadcastman.broadcast(player, player.getDisplayName() + " was freed!"); + } + } + + // Announce summon events + // Teleport player when summoned or returned + @EventHandler(priority=EventPriority.MONITOR) + public void onSummonEvent(SummonEvent event) { + if (event.isCancelled()) + return; + + PrisonPearl pp = event.getPrisonPearl(); + Player player = pp.getImprisonedPlayer(); + if (player == null) + return; + + switch (event.getType()) { + case SUMMONED: + player.sendMessage(ChatColor.RED+"You've been summoned to your prison pearl!"); + player.teleport(fuzzLocation(event.getLocation())); + break; + + case RETURNED: + player.sendMessage(ChatColor.RED+"You've been returned to your prison"); + player.teleport(event.getLocation()); + break; + + case KILLED: + player.sendMessage(ChatColor.RED+"You've been struck down by your pearl!"); + break; + } + } + + private void updateAttachment(Player player) { + PermissionAttachment attachment = attachments.get(player.getName()); + if (attachment == null) { + attachment = player.addAttachment(this); + attachments.put(player.getName(), attachment); + } + + if (pearls.isImprisoned(player)) { + for (String grant : getConfig().getStringList("prison_grant_perms")) + attachment.setPermission(grant, true); + for (String deny : getConfig().getStringList("prison_deny_perms")) + attachment.setPermission(deny, false); + } else { + for (String grant : getConfig().getStringList("prison_grant_perms")) + attachment.unsetPermission(grant); + for (String deny : getConfig().getStringList("prison_deny_perms")) + attachment.unsetPermission(deny); + } + + player.recalculatePermissions(); + } + + + private World getFreeWorld() { + return Bukkit.getWorld(getConfig().getString("free_world")); + } + + private World getPrisonWorld() { + return Bukkit.getWorld(getConfig().getString("prison_world")); + } + + // hill climbing algorithm which attempts to randomly spawn prisoners while actively avoiding pits + // the obsidian pillars, or lava. + private Location getPrisonSpawnLocation() { + Random rand = new Random(); + Location loc = getPrisonWorld().getSpawnLocation(); // start at spawn + for (int i=0; i<30; i++) { // for up to 30 iterations + if (loc.getY() > 40 && loc.getY() < 70 && i > 5 && !isObstructed(loc)) // if the current candidate looks reasonable and we've iterated at least 5 times + return loc; // we're done + + Location newloc = loc.clone().add(rand.nextGaussian()*(2*i), 0, rand.nextGaussian()*(2*i)); // pick a new location near the current one + newloc = moveToGround(newloc); + if (newloc == null) + continue; + + if (newloc.getY() > loc.getY()+(int)(rand.nextGaussian()*3) || loc.getY() > 70) // if its better in a fuzzy sense, or if the current location is too high + loc = newloc; // it becomes the new current location + } + + return loc; + } + + private Location moveToGround(Location loc) { + Location ground = new Location(loc.getWorld(), loc.getX(), 100, loc.getZ()); + while (ground.getBlockY() >= 1) { + if (!ground.getBlock().isEmpty()) + return ground; + ground.add(0, -1, 0); + } + return null; + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + private boolean isObstructed(Location loc) { + Location ground = new Location(loc.getWorld(), loc.getX(), 100, loc.getZ()); + while (ground.getBlockY() >= 1) { + if (!ground.getBlock().isEmpty()) + break; + + ground.add(0, -1, 0); + } + + for (int x=-2; x<=2; x++) { + for (int y=-2; y<=2; y++) { + for (int z=-2; z<=2; z++) { + Location l = ground.clone().add(x, y, z); + Material type = l.getBlock().getType(); + if (type == Material.LAVA || type == Material.STATIONARY_LAVA || type == Material.ENDER_PORTAL || type == Material.BEDROCK) + return true; + } + } + } + + return false; + } + + private Location fuzzLocation(Location loc) { + if (loc == null) + return null; + + double rad = Math.random()*Math.PI*2; + Location newloc = loc.clone(); + newloc.add(1.2*Math.cos(rad), 1.2*Math.sin(rad), 0); + return newloc; + } + + private void delayedTp(final Player player, final Location loc) { + if (loc == RESPAWN_PLAYER) { + player.setHealth(0); + } else { + Bukkit.getScheduler().callSyncMethod(this, new Callable() { + public Void call() { + player.teleport(loc); + return null; + } + }); + } + } + +@SuppressWarnings("SameReturnValue") +@EventHandler(priority=EventPriority.NORMAL) + private boolean onPlayerChatEvent(AsyncPlayerChatEvent event) { + if (summonman.isSummoned(event.getPlayer()) && !summonman.getSummon(event.getPlayer()).isCanSpeak()) { + event.setCancelled(true); + } + + return true; + } + + @EventHandler(priority=EventPriority.NORMAL) + public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + + if (!(event.getDamager() instanceof Player)) { + return; + } + + Player player = (Player)event.getDamager(); + + if(summonman.isSummoned(player) && !summonman.getSummon(player).isCanDealDamage()) { + event.setCancelled(true); + } + } + + @EventHandler(priority=EventPriority.NORMAL) + public void onBlockBreakEvent(BlockBreakEvent event) { + + Player player = event.getPlayer(); + + if(summonman.isSummoned(player) && !summonman.getSummon(player).isCanBreakBlocks()) { + event.setCancelled(true); + } + } + + public boolean isCombatTagged(String playerName) { + if (combatTagManager != null) { + return combatTagManager.isCombatTagged(playerName); + } + return false; + } + + public void loadAlts() { + if (altsList == null) { + altsList = new AltsList(); + } + altsList.load(getAltsListFile()); + } + + public void checkBanAllAlts() { + if (altsList != null) { + Integer bannedCount = 0, unbannedCount = 0, total = 0, result; + for (String name : altsList.getAllNames()) { + //log.info("checking "+name); + result = checkBan(name); + total++; + if (result == 2) { + bannedCount++; + } else if (result == 1) { + unbannedCount++; + } + } + log.info("checked "+total+" accounts, banned "+bannedCount+" accounts, unbanned "+unbannedCount+" accounts"); + } + } + + void unBanAll() { + Server s = this.getServer(); + String name; + for (String s1 : banned.keySet()) { + name = s1; + if (banned.get(name)) { + s.getOfflinePlayer(name).setBanned(false); + log.info("unbanning " + name); + } + } + } + + //gets the most recent time an alt account has logged out (returns 0 if there are none recorded) + private Long getMostRecentAltLogout(String[] alts) { + Long time = (long) 0; + Long temp; + for (String alt : alts) { + if (lastLoggout.containsKey(alt)) { + temp = lastLoggout.get(alt); + if (temp > time) { + time = temp; + } + } + } + return time; + } + + private int checkBan(String name) { + //log.info("checking "+name); + String[] alts = altsList.getAltsArray(name); + Integer pearledCount = pearls.getImprisonedCount(alts); + String[] imprisonedNames = pearls.getImprisonedNames(alts); + String names = ""; + for (int i = 0; i < imprisonedNames.length; i++) { + names = names + imprisonedNames[i]; + if (i < imprisonedNames.length-1) { + names = names + ", "; + } + } + if (pearledCount > maxImprisonedAlts && pearls.isImprisoned(name)) { + int count = 0; + for (String imprisonedName : imprisonedNames) { + if (imprisonedName.compareTo(name) < 0) { + count++; + } + if (count >= maxImprisonedAlts) { + banAndKick(name, pearledCount, names); + return 2; + } + } + } else if (pearledCount.equals(maxImprisonedAlts) || (pearledCount > maxImprisonedAlts && !pearls.isImprisoned(name))) { + banAndKick(name,pearledCount,names); + return 2; + } else if (banned.containsKey(name) && banned.get(name)) { + this.getServer().getOfflinePlayer(name).setBanned(false); + banned.put(name, false); + return 1; + } + return 0; + } + + private void banAndKick(String name, int pearledCount, String names) { + this.getServer().getOfflinePlayer(name).setBanned(true); + Player p = this.getServer().getPlayer(name); + if (p != null) { + p.kickPlayer(kickMessage); + } + banned.put(name, true); + log.info("banning "+name+" for having "+pearledCount+" imprisoned alts: "+names); + } + + private void checkBans(String[] names) { + Integer pearledCount; + String[] imprisonedNames; + String[] alts; + for (String name : names) { + log.info("checking " + name); + alts = altsList.getAltsArray(name); + imprisonedNames = pearls.getImprisonedNames(alts); + String iNames = ""; + for (int j = 0; j < imprisonedNames.length; j++) { + iNames = iNames + imprisonedNames[j]; + if (j < imprisonedNames.length - 1) { + iNames = iNames + ", "; + } + } + pearledCount = pearls.getImprisonedCount(alts); + if (pearledCount >= maxImprisonedAlts) { + this.getServer().getOfflinePlayer(name).setBanned(true); + Player p = this.getServer().getPlayer(name); + if (p != null) { + p.kickPlayer(kickMessage); + } + banned.put(name, true); + log.info("banning " + name + ", for having " + pearledCount + " imprisoned alts: " + iNames); + } else if (banned.containsKey(name) && banned.get(name).equals(Boolean.TRUE)) { + this.getServer().getOfflinePlayer(name).setBanned(false); + banned.put(name, false); + log.info("unbanning " + name + ", no longer has too many imprisoned alts."); + } + } + } + + public boolean isTempBanned(String name) { + if (banned.containsKey(name)) { + return banned.get(name); + } + return false; + } + + public int getImprisonedCount(String name) { + return pearls.getImprisonedCount(altsList.getAltsArray(name)); + } + + public String getImprisonedAltsString(String name) { + String result = ""; + String[] alts = pearls.getImprisonedNames(altsList.getAltsArray(name)); + for (int i = 0; i < alts.length; i++) { + result = result + "alts[i]"; + if (i < alts.length - 1) { + result = result + ", "; + } + } + return result; + } +} diff --git a/src/com/untamedears/PrisonPearl/PrisonPearlStorage.java b/src/com/untamedears/PrisonPearl/PrisonPearlStorage.java index dea50e6..e0a4c3c 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearlStorage.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearlStorage.java @@ -1,139 +1,186 @@ -package com.untamedears.PrisonPearl; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.util.HashMap; -import java.util.Map; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -public class PrisonPearlStorage implements SaveLoad { - private Map pearls_byid; - private Map pearls_byimprisoned; - private short nextid; - - private boolean dirty; - - public PrisonPearlStorage() { - pearls_byid = new HashMap(); - pearls_byimprisoned = new HashMap(); - nextid = 1; - } - - public boolean isDirty() { - return dirty; - } - - public void markDirty() { - dirty = true; - } - - public void load(File file) throws IOException { - FileInputStream fis = new FileInputStream(file); - BufferedReader br = new BufferedReader(new InputStreamReader(fis)); - - nextid = Short.parseShort(br.readLine()); - - String line; - while ((line = br.readLine()) != null) { - String parts[] = line.split(" "); - short id = Short.parseShort(parts[0]); - String imprisoned = parts[1]; - Location loc = new Location(Bukkit.getWorld(parts[2]), Integer.parseInt(parts[3]), Integer.parseInt(parts[4]), Integer.parseInt(parts[5])); - PrisonPearl pp = PrisonPearl.makeFromLocation(id, imprisoned, loc); - if (pp == null) { - System.err.println("PrisonPearl for " + imprisoned + " didn't validate, so is now set free. Chunks and/or prisonpearls.txt are corrupt"); - continue; - } - - addPearl(pp); - } - - fis.close(); - - dirty = false; - } - - public void save(File file) throws IOException { - FileOutputStream fos = new FileOutputStream(file); - BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fos)); - - br.write(nextid + "\n"); - - for (PrisonPearl pp : pearls_byid.values()) { - if (pp.getHolderBlockState() == null) - continue; - - Location loc = pp.getLocation(); - br.append(pp.getID() + " " + pp.getImprisonedName() + " " + loc.getWorld().getName() + " " + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ() + "\n"); - } - - br.flush(); - fos.close(); - - dirty = false; - } - - public PrisonPearl newPearl(Player imprisoned, Player imprisoner) { - return newPearl(imprisoned.getName(), imprisoner); - } - - public PrisonPearl newPearl(String imprisonedname, Player imprisoner) { - PrisonPearl pp = new PrisonPearl(nextid++, imprisonedname, imprisoner); - addPearl(pp); - return pp; - } - - public void deletePearl(PrisonPearl pp) { - pearls_byid.remove(pp.getID()); - pearls_byimprisoned.remove(pp.getImprisonedName()); - dirty = true; - } - - public void addPearl(PrisonPearl pp) { - PrisonPearl old = pearls_byimprisoned.get(pp.getImprisonedName()); - if (old != null) - pearls_byid.remove(old.getID()); - - pearls_byid.put(pp.getID(), pp); - pearls_byimprisoned.put(pp.getImprisonedName(), pp); - dirty = true; - } - - public PrisonPearl getByID(short id) { - return pearls_byid.get(id); - } - - public PrisonPearl getByItemStack(ItemStack item) { - if (item == null || item.getType() != Material.ENDER_PEARL || item.getDurability() == 0) - return null; - else - return pearls_byid.get(item.getDurability()); - } - - public PrisonPearl getByImprisoned(String name) { - return pearls_byimprisoned.get(name); - } - - public PrisonPearl getByImprisoned(Player player) { - return pearls_byimprisoned.get(player.getName()); - } - - boolean isImprisoned(String name) { - return pearls_byimprisoned.containsKey(name); - } - - boolean isImprisoned(Player player) { - return pearls_byimprisoned.containsKey(player.getName()); - } -} +package com.untamedears.PrisonPearl; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class PrisonPearlStorage implements SaveLoad { + private final Map pearls_byid; + private final Map pearls_byimprisoned; + private short nextid; + + private boolean dirty; + + public PrisonPearlStorage() { + pearls_byid = new HashMap(); + pearls_byimprisoned = new HashMap(); + nextid = 1; + } + + public boolean isDirty() { + return dirty; + } + + public void markDirty() { + dirty = true; + } + + public void load(File file) throws IOException { + FileInputStream fis = new FileInputStream(file); + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + + nextid = Short.parseShort(br.readLine()); + + String line; + while ((line = br.readLine()) != null) { + String parts[] = line.split(" "); + short id = Short.parseShort(parts[0]); + String imprisoned = parts[1]; + Location loc = new Location(Bukkit.getWorld(parts[2]), Integer.parseInt(parts[3]), Integer.parseInt(parts[4]), Integer.parseInt(parts[5])); + PrisonPearl pp = PrisonPearl.makeFromLocation(id, imprisoned, loc); + if (parts.length != 6) { + String motd = ""; + for (int i = 6; i < parts.length; i++) { + motd = motd.concat(parts[i] + " "); + } + pp.setMotd(motd); + } + if (pp == null) { + System.err.println("PrisonPearl for " + imprisoned + " didn't validate, so is now set free. Chunks and/or prisonpearls.txt are corrupt"); + continue; + } + + addPearl(pp); + } + + fis.close(); + + dirty = false; + } + + public void save(File file) throws IOException { + FileOutputStream fos = new FileOutputStream(file); + BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fos)); + + br.write(nextid + "\n"); + + for (PrisonPearl pp : pearls_byid.values()) { + if (pp.getHolderBlockState() == null) + continue; + + Location loc = pp.getLocation(); + br.append(String.valueOf(pp.getID())); + br.append(" "); + br.append(pp.getImprisonedName()); + br.append(" "); + br.append(loc.getWorld().getName()); + br.append(" "); + br.append(String.valueOf(loc.getBlockX())); + br.append(" "); + br.append(String.valueOf(loc.getBlockY())); + br.append(" "); + br.append(String.valueOf(loc.getBlockZ())); + br.append(" "); + br.append(pp.getMotd()); + br.append("\n"); + } + + br.flush(); + fos.close(); + + dirty = false; + } + + public PrisonPearl newPearl(Player imprisoned, Player imprisoner) { + return newPearl(imprisoned.getName(), imprisoner); + } + + public PrisonPearl newPearl(String imprisonedname, Player imprisoner) { + PrisonPearl pp = new PrisonPearl(nextid++, imprisonedname, imprisoner); + addPearl(pp); + return pp; + } + + public void deletePearl(PrisonPearl pp) { + pearls_byid.remove(pp.getID()); + pearls_byimprisoned.remove(pp.getImprisonedName()); + dirty = true; + } + + public void addPearl(PrisonPearl pp) { + PrisonPearl old = pearls_byimprisoned.get(pp.getImprisonedName()); + if (old != null) + pearls_byid.remove(old.getID()); + + pearls_byid.put(pp.getID(), pp); + pearls_byimprisoned.put(pp.getImprisonedName(), pp); + dirty = true; + } + + public PrisonPearl getByID(short id) { + return pearls_byid.get(id); + } + + public PrisonPearl getByItemStack(ItemStack item) { + if (item == null || item.getType() != Material.ENDER_PEARL || item.getDurability() == 0) + return null; + else + return pearls_byid.get(item.getDurability()); + } + + public PrisonPearl getByImprisoned(String name) { + return pearls_byimprisoned.get(name); + } + + public PrisonPearl getByImprisoned(Player player) { + return pearls_byimprisoned.get(player.getName()); + } + + boolean isImprisoned(String name) { + return pearls_byimprisoned.containsKey(name); + } + + boolean isImprisoned(Player player) { + return pearls_byimprisoned.containsKey(player.getName()); + } + + public Integer getImprisonedCount(String[] names) { + Integer count = 0; + for (String name : names) { + if (pearls_byimprisoned.containsKey(name)) { + count++; + } + } + return count; + } + + public String[] getImprisonedNames(String[] names) { + List iNames = new ArrayList(); + for (String name : names) { + if (pearls_byimprisoned.containsKey(name)) { + iNames.add(name); + } + } + int count = iNames.size(); + String[] results = new String[count]; + for (int i = 0; i < count; i++) { + results[i] = iNames.get(i); + } + return results; + } +} diff --git a/src/com/untamedears/PrisonPearl/PrisonPortaledPlayerManager.java b/src/com/untamedears/PrisonPearl/PrisonPortaledPlayerManager.java index 01392ef..02e34e5 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPortaledPlayerManager.java +++ b/src/com/untamedears/PrisonPearl/PrisonPortaledPlayerManager.java @@ -1,113 +1,115 @@ -package com.untamedears.PrisonPearl; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.util.HashSet; -import java.util.Set; - -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerPortalEvent; -import org.bukkit.event.player.PlayerRespawnEvent; - -public class PrisonPortaledPlayerManager implements Listener, SaveLoad { - private PrisonPearlPlugin plugin; - private PrisonPearlStorage pearls; - - private Set portaled_players; - private boolean dirty; - - public PrisonPortaledPlayerManager(PrisonPearlPlugin plugin, PrisonPearlStorage pearls) { - this.plugin = plugin; - this.pearls = pearls; - - portaled_players = new HashSet(); - - Bukkit.getPluginManager().registerEvents(this, plugin); - } - - public boolean isDirty() { - return dirty; - } - - public void load(File file) throws NumberFormatException, IOException { - FileInputStream fis = new FileInputStream(file); - BufferedReader br = new BufferedReader(new InputStreamReader(fis)); - - String name; - while ((name = br.readLine()) != null) { - portaled_players.add(name); - } - - fis.close(); - dirty = false; - } - - public void save(File file) throws IOException { - FileOutputStream fos = new FileOutputStream(file); - BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fos)); - - for (String name : portaled_players) { - br.append(name + "\n"); - } - - br.flush(); - fos.close(); - dirty = false; - } - - public boolean isPlayerPortaledToPrison(Player player) { - return isPlayerPortaledToPrison(player.getName()); - } - - public boolean isPlayerPortaledToPrison(String playername) { - return portaled_players.contains(playername); - } - - @EventHandler(priority=EventPriority.MONITOR) - public void onPlayerRespawn(PlayerRespawnEvent event) { - Player player = event.getPlayer(); - if (pearls.isImprisoned(player.getName())) - return; - - if (event.getRespawnLocation().getWorld() != getPrisonWorld()) { - portaled_players.remove(player.getName()); - dirty = true; - } - } - - @EventHandler(priority=EventPriority.MONITOR) - public void onPlayerPortalEvent(PlayerPortalEvent event) { - Player player = event.getPlayer(); - if (pearls.isImprisoned(player.getName())) - return; - - if (event.getTo().getWorld() == getPrisonWorld()) - portaled_players.add(player.getName()); - else - portaled_players.remove(player.getName()); - dirty = true; - } - - @EventHandler(priority=EventPriority.MONITOR) - public void onPrisonPearlEvent(PrisonPearlEvent event) { - if (event.getType() == PrisonPearlEvent.Type.NEW) { - portaled_players.remove(event.getPrisonPearl().getImprisonedName()); - dirty = true; - } - } - - private World getPrisonWorld() { - return Bukkit.getWorld(plugin.getConfig().getString("prison_world")); - } -} +package com.untamedears.PrisonPearl; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerPortalEvent; +import org.bukkit.event.player.PlayerRespawnEvent; + +public class PrisonPortaledPlayerManager implements Listener, SaveLoad { + private final PrisonPearlPlugin plugin; + private final PrisonPearlStorage pearls; + + private final Set portaled_players; + private boolean dirty; + + public PrisonPortaledPlayerManager(PrisonPearlPlugin plugin, PrisonPearlStorage pearls) { + this.plugin = plugin; + this.pearls = pearls; + + portaled_players = new HashSet(); + + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + public boolean isDirty() { + return dirty; + } + + public void load(File file) throws NumberFormatException, IOException { + FileInputStream fis = new FileInputStream(file); + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + + String name; + while ((name = br.readLine()) != null) { + portaled_players.add(name); + } + + fis.close(); + dirty = false; + } + + public void save(File file) throws IOException { + FileOutputStream fos = new FileOutputStream(file); + BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fos)); + + for (String name : portaled_players) { + br.append(name).append("\n"); + } + + br.flush(); + fos.close(); + dirty = false; + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public boolean isPlayerPortaledToPrison(Player player) { + return isPlayerPortaledToPrison(player.getName()); + } + + @SuppressWarnings("WeakerAccess") + public boolean isPlayerPortaledToPrison(String playername) { + return portaled_players.contains(playername); + } + + @EventHandler(priority=EventPriority.MONITOR) + public void onPlayerRespawn(PlayerRespawnEvent event) { + Player player = event.getPlayer(); + if (pearls.isImprisoned(player.getName())) + return; + + if (event.getRespawnLocation().getWorld() != getPrisonWorld()) { + portaled_players.remove(player.getName()); + dirty = true; + } + } + + @EventHandler(priority=EventPriority.MONITOR) + public void onPlayerPortalEvent(PlayerPortalEvent event) { + Player player = event.getPlayer(); + if (pearls.isImprisoned(player.getName())) + return; + + if (event.getTo().getWorld() == getPrisonWorld()) + portaled_players.add(player.getName()); + else + portaled_players.remove(player.getName()); + dirty = true; + } + + @EventHandler(priority=EventPriority.MONITOR) + public void onPrisonPearlEvent(PrisonPearlEvent event) { + if (event.getType() == PrisonPearlEvent.Type.NEW) { + portaled_players.remove(event.getPrisonPearl().getImprisonedName()); + dirty = true; + } + } + + private World getPrisonWorld() { + return Bukkit.getWorld(plugin.getConfig().getString("prison_world")); + } +} diff --git a/src/com/untamedears/PrisonPearl/SaveLoad.java b/src/com/untamedears/PrisonPearl/SaveLoad.java index e3e5115..7264c6e 100644 --- a/src/com/untamedears/PrisonPearl/SaveLoad.java +++ b/src/com/untamedears/PrisonPearl/SaveLoad.java @@ -1,11 +1,11 @@ -package com.untamedears.PrisonPearl; - -import java.io.File; -import java.io.IOException; - -public interface SaveLoad { - public void save(File file) throws IOException; - public void load(File file) throws IOException; - - public boolean isDirty(); -} +package com.untamedears.PrisonPearl; + +import java.io.File; +import java.io.IOException; + +public interface SaveLoad { + public void save(File file) throws IOException; + public void load(File file) throws IOException; + + // --Commented out by Inspection (9/8/12 5:38 PM):public boolean isDirty(); +} diff --git a/src/com/untamedears/PrisonPearl/Summon.java b/src/com/untamedears/PrisonPearl/Summon.java index 29674ac..20036ab 100644 --- a/src/com/untamedears/PrisonPearl/Summon.java +++ b/src/com/untamedears/PrisonPearl/Summon.java @@ -1,37 +1,77 @@ -package com.untamedears.PrisonPearl; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.entity.Player; - -public class Summon { - private String summonedname; - private Location returnloc; - private int alloweddistance; - - public Summon(String summonedname, Location returnloc, int alloweddistance) { - this.summonedname = summonedname; - this.returnloc = returnloc; - this.alloweddistance = alloweddistance; - } - - public String getSummonedName() { - return summonedname; - } - - public Player getSummonedPlayer() { - return Bukkit.getPlayerExact(summonedname); - } - - public Location getReturnLocation() { - return returnloc; - } - - public int getAllowedDistance() { - return alloweddistance; - } - - public void setAllowedDistance(int alloweddistance) { - this.alloweddistance = alloweddistance; - } -} +package com.untamedears.PrisonPearl; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public class Summon { + private final String summonedname; + private final Location returnloc; + private int alloweddistance; + private int damageamount; + private boolean canSpeak; + private boolean canDealDamage; + private boolean canBreakBlocks; + + public Summon(String summonedname, Location returnloc, int alloweddistance, int damageamount, boolean canSpeak, boolean canDealDamage, boolean canBreakBlocks) { + this.summonedname = summonedname; + this.returnloc = returnloc; + this.alloweddistance = alloweddistance; + this.damageamount = damageamount; + this.canSpeak = canSpeak; + this.canDealDamage = canDealDamage; + this.canBreakBlocks = canBreakBlocks; + } + + public String getSummonedName() { + return summonedname; + } + + public Player getSummonedPlayer() { + return Bukkit.getPlayerExact(summonedname); + } + + public Location getReturnLocation() { + return returnloc; + } + + public int getAllowedDistance() { + return alloweddistance; + } + + public void setAllowedDistance(int alloweddistance) { + this.alloweddistance = alloweddistance; + } + + public int getDamageAmount() { + return damageamount; + } + + public void setDamageAmount(int damageamount) { + this.damageamount = damageamount; + } + + public boolean isCanSpeak() { + return canSpeak; + } + + public void setCanSpeak(boolean canSpeak) { + this.canSpeak = canSpeak; + } + + public boolean isCanDealDamage() { + return canDealDamage; + } + + public void setCanDealDamage(boolean canDealDamage) { + this.canDealDamage = canDealDamage; + } + + public boolean isCanBreakBlocks() { + return canBreakBlocks; + } + + public void setCanBreakBlocks(boolean canBreakBlocks) { + this.canBreakBlocks = canBreakBlocks; + } +} diff --git a/src/com/untamedears/PrisonPearl/SummonEvent.java b/src/com/untamedears/PrisonPearl/SummonEvent.java index ef6dc75..2ff6763 100644 --- a/src/com/untamedears/PrisonPearl/SummonEvent.java +++ b/src/com/untamedears/PrisonPearl/SummonEvent.java @@ -1,54 +1,54 @@ -package com.untamedears.PrisonPearl; - -import org.bukkit.Location; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class SummonEvent extends Event { - public enum Type { SUMMONED, RETURNED, KILLED, DIED }; - - private PrisonPearl pp; - private Type type; - private Location location; - - private boolean cancelled; - - public SummonEvent(PrisonPearl pp, Type type) { - this.pp = pp; - this.type = type; - } - - public SummonEvent(PrisonPearl pp, Type type, Location location) { - this.pp = pp; - this.type = type; - this.location = location; - } - - public PrisonPearl getPrisonPearl() { - return pp; - } - - public Type getType() { - return type; - } - - public Location getLocation() { - return location; - } - - public boolean isCancelled() { - return cancelled; - } - - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } - - private static final HandlerList handlers = new HandlerList(); - public HandlerList getHandlers() { - return handlers; - } - public static HandlerList getHandlerList() { - return handlers; - } -} +package com.untamedears.PrisonPearl; + +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class SummonEvent extends Event { + public enum Type { SUMMONED, RETURNED, KILLED, DIED } + + private final PrisonPearl pp; + private final Type type; + private Location location; + + private boolean cancelled; + + public SummonEvent(PrisonPearl pp, Type type) { + this.pp = pp; + this.type = type; + } + + public SummonEvent(PrisonPearl pp, Type type, Location location) { + this.pp = pp; + this.type = type; + this.location = location; + } + + public PrisonPearl getPrisonPearl() { + return pp; + } + + public Type getType() { + return type; + } + + public Location getLocation() { + return location; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + private static final HandlerList handlers = new HandlerList(); + public HandlerList getHandlers() { + return handlers; + } + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/untamedears/PrisonPearl/SummonManager.java b/src/com/untamedears/PrisonPearl/SummonManager.java index f03486e..26fe202 100644 --- a/src/com/untamedears/PrisonPearl/SummonManager.java +++ b/src/com/untamedears/PrisonPearl/SummonManager.java @@ -1,211 +1,219 @@ -package com.untamedears.PrisonPearl; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDeathEvent; - -public class SummonManager implements Listener, SaveLoad { - private PrisonPearlPlugin plugin; - private PrisonPearlStorage pearls; - - private Map summons; - private boolean dirty; - - public SummonManager(PrisonPearlPlugin plugin, PrisonPearlStorage pearls) { - this.plugin = plugin; - this.pearls = pearls; - - summons = new HashMap(); - - Bukkit.getPluginManager().registerEvents(this, plugin); - Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() { - public void run() { - inflictSummonDamage(); - } - }, 0, plugin.getConfig().getInt("summon_damage_ticks")); - } - - public boolean isDirty() { - return dirty; - } - - public void load(File file) throws NumberFormatException, IOException { - FileInputStream fis = new FileInputStream(file); - BufferedReader br = new BufferedReader(new InputStreamReader(fis)); - - String line; - while ((line = br.readLine()) != null) { - String[] parts = line.split(" "); - String name = parts[0]; - Location loc = new Location(Bukkit.getWorld(parts[1]), Integer.parseInt(parts[2]), Integer.parseInt(parts[3]), Integer.parseInt(parts[4])); - int dist = parts.length == 6 ? Integer.parseInt(parts[5]) : 20; - - if (!pearls.isImprisoned(name)) - continue; - - summons.put(name, new Summon(name, loc, dist)); - } - - fis.close(); - dirty = false; - } - - public void save(File file) throws IOException { - FileOutputStream fos = new FileOutputStream(file); - BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fos)); - - for (Entry entry : summons.entrySet()) { - Summon summon = entry.getValue(); - Location loc = summon.getReturnLocation(); - br.append(summon.getSummonedName() + " " + loc.getWorld().getName() + " " + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ() + " " + summon.getAllowedDistance() + "\n"); - } - - br.flush(); - fos.close(); - dirty = false; - } - - private void inflictSummonDamage() { - Iterator> i = summons.entrySet().iterator(); - while (i.hasNext()) { - Summon summon = i.next().getValue(); - PrisonPearl pp = pearls.getByImprisoned(summon.getSummonedName()); - if (pp == null) { - System.err.println("Somehow " + summon.getSummonedName() + " was summoned but isn't imprisoned"); - i.remove(); - dirty = true; - continue; - } - - Player player = pp.getImprisonedPlayer(); - if (player == null) - continue; - - Location pploc = pp.getLocation(); - Location playerloc = player.getLocation(); - - if (pploc.getWorld() != playerloc.getWorld() || pploc.distance(playerloc) > summon.getAllowedDistance()) - player.damage(plugin.getConfig().getInt("summon_damage_amt")); - } - } - - public boolean summonPearl(PrisonPearl pp, Location loc, int dist) { - Player player = pp.getImprisonedPlayer(); - if (player == null || player.isDead()) - return false; - - if (summons.containsKey(player.getName())) - return false; - - Summon summon = new Summon(player.getName(), player.getLocation().add(0, -.5, 0), dist); - summons.put(summon.getSummonedName(), summon); - - if (!summonEvent(pp, SummonEvent.Type.SUMMONED, pp.getLocation())) { - summons.remove(player.getName()); - return false; - } - - dirty = true; - return true; - } - - public boolean returnPearl(PrisonPearl pp) { - Summon summon = summons.remove(pp.getImprisonedName()); - if (summon == null) - return false; - - if (!summonEvent(pp, SummonEvent.Type.RETURNED, summon.getReturnLocation())) { - summons.put(pp.getImprisonedName(), summon); - return false; - } - - dirty = true; - return true; - } - - public boolean killPearl(PrisonPearl pp) { - Summon summon = summons.remove(pp.getImprisonedName()); - if (summon == null) - return false; - - if (!summonEvent(pp, SummonEvent.Type.KILLED, summon.getReturnLocation())) { - summons.put(pp.getImprisonedName(), summon); - return false; - } - - pp.getImprisonedPlayer().setHealth(0); - dirty = true; - return true; - } - - public boolean isSummoned(Player player) { - return summons.containsKey(player.getName()); - } - - public boolean isSummoned(PrisonPearl pp) { - return summons.containsKey(pp.getImprisonedName()); - } - - public Summon getSummon(Player player) { - return summons.get(player.getName()); - } - - public Summon getSummon(String name) { - return summons.get(name); - } - - @EventHandler(priority=EventPriority.HIGHEST) - public void onEntityDeath(EntityDeathEvent event) { - if (!(event.getEntity() instanceof Player)) - return; - - Player player = (Player)event.getEntity(); - Summon summon = summons.remove(player.getName()); - if (summon == null) - return; - dirty = true; - - PrisonPearl pp = pearls.getByImprisoned(player); - if (pp == null) - return; - - summonEvent(pp, SummonEvent.Type.DIED); - } - - @EventHandler(priority=EventPriority.MONITOR) - public void onPrisonPearlEvent(PrisonPearlEvent event) { - if (event.getType() == PrisonPearlEvent.Type.FREED) { - summons.remove(event.getPrisonPearl().getImprisonedName()); - dirty = true; - } - } - - private boolean summonEvent(PrisonPearl pp, SummonEvent.Type type) { - SummonEvent event = new SummonEvent(pp, type); - Bukkit.getPluginManager().callEvent(event); - return !event.isCancelled(); - } - - private boolean summonEvent(PrisonPearl pp, SummonEvent.Type type, Location loc) { - SummonEvent event = new SummonEvent(pp, type, loc); - Bukkit.getPluginManager().callEvent(event); - return !event.isCancelled(); - } -} +package com.untamedears.PrisonPearl; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; + +public class SummonManager implements Listener, SaveLoad { + private final PrisonPearlPlugin plugin; + private final PrisonPearlStorage pearls; + + private final Map summons; + private boolean dirty; + + public SummonManager(PrisonPearlPlugin plugin, PrisonPearlStorage pearls) { + this.plugin = plugin; + this.pearls = pearls; + + summons = new HashMap(); + + Bukkit.getPluginManager().registerEvents(this, plugin); + Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() { + public void run() { + inflictSummonDamage(); + } + }, 0, plugin.getConfig().getInt("summon_damage_ticks")); + } + + public boolean isDirty() { + return dirty; + } + + public void load(File file) throws NumberFormatException, IOException { + FileInputStream fis = new FileInputStream(file); + BufferedReader br = new BufferedReader(new InputStreamReader(fis)); + + String line; + while ((line = br.readLine()) != null) { + String[] parts = line.split(" "); + String name = parts[0]; + Location loc = new Location(Bukkit.getWorld(parts[1]), Integer.parseInt(parts[2]), Integer.parseInt(parts[3]), Integer.parseInt(parts[4])); + int dist = parts.length >= 6 ? Integer.parseInt(parts[5]) : plugin.getConfig().getInt("summon_damage_radius"); + int damage = parts.length >= 7 ? Integer.parseInt(parts[6]) : plugin.getConfig().getInt("summon_damage_amt"); + boolean canSpeak = parts.length >= 8 ? Boolean.parseBoolean(parts[7]) : true; + boolean canDamage = parts.length >= 9 ? Boolean.parseBoolean(parts[8]) : true; + boolean canBreak = parts.length == 10 ? Boolean.parseBoolean(parts[9]) : true; + System.out.println(name + " " + loc + " " + dist + " " + damage + " " + canSpeak + " " + canDamage + " " + canBreak); + + + if (!pearls.isImprisoned(name)) + continue; + + summons.put(name, new Summon(name, loc, dist, damage, canSpeak, canDamage, canBreak)); + } + + fis.close(); + dirty = false; + } + + public void save(File file) throws IOException { + FileOutputStream fos = new FileOutputStream(file); + BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fos)); + + for (Entry entry : summons.entrySet()) { + Summon summon = entry.getValue(); + Location loc = summon.getReturnLocation(); + br.append(summon.getSummonedName()).append(" ").append(loc.getWorld().getName()).append(" ").append(String.valueOf(loc.getBlockX())).append(" ").append(String.valueOf(loc.getBlockY())).append(" ").append(String.valueOf(loc.getBlockZ())).append(" ").append(String.valueOf(summon.getAllowedDistance())).append(" ").append(String.valueOf(summon.getDamageAmount())).append(" ").append(String.valueOf(summon.isCanSpeak())).append(" ").append(String.valueOf(summon.isCanDealDamage())).append(" ").append(String.valueOf(summon.isCanBreakBlocks())).append("\n"); + } + + br.flush(); + fos.close(); + dirty = false; + } + + private void inflictSummonDamage() { + Iterator> i = summons.entrySet().iterator(); + while (i.hasNext()) { + Summon summon = i.next().getValue(); + PrisonPearl pp = pearls.getByImprisoned(summon.getSummonedName()); + if (pp == null) { + System.err.println("Somehow " + summon.getSummonedName() + " was summoned but isn't imprisoned"); + i.remove(); + dirty = true; + continue; + } + + Player player = pp.getImprisonedPlayer(); + if (player == null) + continue; + + Location pploc = pp.getLocation(); + Location playerloc = player.getLocation(); + + if (pploc.getWorld() != playerloc.getWorld() || pploc.distance(playerloc) > summon.getAllowedDistance()) + player.damage(summon.getDamageAmount()); + } + } + + public boolean summonPearl(PrisonPearl pp) { + Player player = pp.getImprisonedPlayer(); + if (player == null || player.isDead()) + return false; + + if (summons.containsKey(player.getName())) + return false; + + Summon summon = new Summon(player.getName(), player.getLocation().add(0, -.5, 0), plugin.getConfig().getInt("summon_damage_radius"), plugin.getConfig().getInt("summon_damage_amt"), true, true, true); + summons.put(summon.getSummonedName(), summon); + + if (!summonEvent(pp, SummonEvent.Type.SUMMONED, pp.getLocation())) { + summons.remove(player.getName()); + return false; + } + + dirty = true; + return true; + } + + public boolean returnPearl(PrisonPearl pp) { + Summon summon = summons.remove(pp.getImprisonedName()); + if (summon == null) + return false; + + if (!summonEvent(pp, SummonEvent.Type.RETURNED, summon.getReturnLocation())) { + summons.put(pp.getImprisonedName(), summon); + return false; + } + + dirty = true; + return true; + } + + public boolean killPearl(PrisonPearl pp) { + Summon summon = summons.remove(pp.getImprisonedName()); + if (summon == null) + return false; + + if (!summonEvent(pp, SummonEvent.Type.KILLED, summon.getReturnLocation())) { + summons.put(pp.getImprisonedName(), summon); + return false; + } + + pp.getImprisonedPlayer().setHealth(0); + dirty = true; + return true; + } + + public boolean isSummoned(Player player) { + return summons.containsKey(player.getName()); + } + + public boolean isSummoned(PrisonPearl pp) { + return summons.containsKey(pp.getImprisonedName()); + } + + public Summon getSummon(Player player) { + return summons.get(player.getName()); + } + + public Summon getSummon(String name) { + return summons.get(name); + } + + @EventHandler(priority=EventPriority.HIGHEST) + public void onEntityDeath(EntityDeathEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + + Player player = (Player)event.getEntity(); + Summon summon = summons.remove(player.getName()); + if (summon == null) + return; + dirty = true; + + PrisonPearl pp = pearls.getByImprisoned(player); + if (pp == null) + return; + + summonEvent(pp, SummonEvent.Type.DIED); + } + + @EventHandler(priority=EventPriority.MONITOR) + public void onPrisonPearlEvent(PrisonPearlEvent event) { + if (event.getType() == PrisonPearlEvent.Type.FREED) { + summons.remove(event.getPrisonPearl().getImprisonedName()); + dirty = true; + } + } + + @SuppressWarnings({"UnusedReturnValue", "SameParameterValue"}) + private boolean summonEvent(PrisonPearl pp, @SuppressWarnings("SameParameterValue") SummonEvent.Type type) { + SummonEvent event = new SummonEvent(pp, type); + Bukkit.getPluginManager().callEvent(event); + return !event.isCancelled(); + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + private boolean summonEvent(PrisonPearl pp, SummonEvent.Type type, Location loc) { + SummonEvent event = new SummonEvent(pp, type, loc); + Bukkit.getPluginManager().callEvent(event); + return !event.isCancelled(); + } +}