diff --git a/plugin.yml b/plugin.yml index f772bdc..4978a84 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,14 +1,18 @@ name: PrisonPearl main: com.untamedears.PrisonPearl.PrisonPearlPlugin -version: 1.3 -soft-depend: [PhysicalShop] +version: 1.5.1 +soft-depend: [PhysicalShop, CombatTag] commands: pplocate: description: Locates your prison pearl usage: / aliases: ppl - + + ppfeed: + description: Feeds prison pearls + usage: / + pplocateany: description: Locates any prison pearl in the world usage: / player @@ -66,7 +70,35 @@ commands: 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 @@ -89,4 +121,4 @@ permissions: prisonpearl.save: description: Allows user to use ppsave command - \ No newline at end of file + diff --git a/src/com/untamedears/PrisonPearl/PrisonPearlCommands.java b/src/com/untamedears/PrisonPearl/PrisonPearlCommands.java index e191651..80a23aa 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearlCommands.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearlCommands.java @@ -13,13 +13,13 @@ 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; +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; @@ -56,12 +56,194 @@ public boolean onCommand(CommandSender sender, Command cmd, String label, String 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); + } else if (label.equalsIgnoreCase("ppfeed")) { + return feedCmd(sender, args, false); + } else if (label.equalsIgnoreCase("pprestore")) { + return restoreCmd(sender, args, false); + } return false; } - private boolean locateCmd(CommandSender sender, String args[], boolean any) { + private boolean restoreCmd(CommandSender sender, String args[], boolean any){ + if ((sender instanceof Player)) { + sender.sendMessage("Must use [[restore at the console"); + return true; + } + if (!args[0].isEmpty()){ + sender.sendMessage("Restoring from " + args[0]); + sender.sendMessage(pearls.restorePearls(pearlman, args[0])); + }else{ + sender.sendMessage("Restoring from most recent record..."); + sender.sendMessage(pearls.restorePearls(pearlman, null)); + } + return true; + } + + private boolean feedCmd(CommandSender sender, String args[], boolean any) { + if ((sender instanceof Player)) { + sender.sendMessage("Must use ppfeed at the console"); + return true; + } + sender.sendMessage("Feeding all pearls: " + pearls.getPearlCount()); + sender.sendMessage(pearls.feedPearls(pearlman)); + return true; + } + + 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; @@ -164,7 +346,7 @@ private boolean imprisonCmd(CommandSender sender, String args[]) { } private boolean summonCmd(CommandSender sender, String args[]) { - if (args.length > 2) + if (args.length > 1) return false; if (!(sender instanceof Player)) { @@ -173,22 +355,13 @@ private boolean summonCmd(CommandSender sender, String args[]) { } Player player = (Player)sender; - int dist = plugin.getConfig().getInt("summon_damage_radius"); PrisonPearl pp; - if (args.length == 2) { + + if (args.length == 1) { 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); + pp = getCommandPearl(player, args, 1); } } else { pp = getCommandPearl(player, args, 0); @@ -196,11 +369,11 @@ private boolean summonCmd(CommandSender sender, String args[]) { if (pp == null) return true; - - if (args.length > 0) { - try { - dist = Integer.parseInt(args[args.length-1]); - } catch (NumberFormatException e) { } + + //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()) { @@ -214,7 +387,7 @@ private boolean summonCmd(CommandSender sender, String args[]) { return true; } - if (summonman.summonPearl(pp, player.getLocation(), dist)) + if (summonman.summonPearl(pp)) sender.sendMessage("You've summoned " + pp.getImprisonedName()); else sender.sendMessage("You failed to summon " + pp.getImprisonedName()); @@ -230,11 +403,19 @@ private boolean returnCmd(CommandSender sender, String args[]) { 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; @@ -417,4 +598,41 @@ private int getCommandPearlSlot(Player player, String args[], int pos) { 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/PrisonPearlPlugin.java b/src/com/untamedears/PrisonPearl/PrisonPearlPlugin.java index 3a8f50a..2b5cf44 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearlPlugin.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearlPlugin.java @@ -5,25 +5,28 @@ 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 java.lang.Thread; 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.PlayerJoinEvent; -import org.bukkit.event.player.PlayerPortalEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.*; import org.bukkit.inventory.ItemStack; import org.bukkit.permissions.PermissionAttachment; import org.bukkit.plugin.java.JavaPlugin; @@ -35,13 +38,31 @@ public class PrisonPearlPlugin extends JavaPlugin implements Listener { 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; + private final boolean startupFeed = true; //ADDED SO ONE CAN DISABLE STARTUP FEED + 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()); @@ -52,6 +73,12 @@ public void onEnable() { 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); @@ -73,10 +100,10 @@ public void run() { // 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 method = net.minecraft.server.v1_4_6.Item.class.getDeclaredMethod("a", boolean.class); + if (method.getReturnType() == net.minecraft.server.v1_4_6.Item.class) { method.setAccessible(true); - method.invoke(net.minecraft.server.Item.ENDER_PEARL, true); + method.invoke(net.minecraft.server.v1_4_6.Item.ENDER_PEARL, true); } } catch (Exception e) { e.printStackTrace(); @@ -85,10 +112,21 @@ public void run() { attachments = new HashMap(); for (Player player : Bukkit.getOnlinePlayers()) updateAttachment(player); + + if (startupFeed){ + //try{ + //Thread.sleep(1000 * 60); + pearls.feedPearls(pearlman); + //} + //catch(Exception e){ + //System.out.println("A straight foolish error has occurred while loading PrisonPearl."); + //} + } } public void onDisable() { saveAll(true); + unBanAll(); for (PermissionAttachment attachment : attachments.values()) attachment.remove(); @@ -112,7 +150,7 @@ private static void load(SaveLoad obj, File file) { try { obj.save(file); } catch (IOException e2) { - throw new RuntimeException("Failed to create " + file.getAbsolutePath(), 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); @@ -125,6 +163,12 @@ private static void save(SaveLoad obj, File file) { 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)) @@ -146,12 +190,19 @@ 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; @@ -180,7 +231,7 @@ public void onPlayerPortalEvent(PlayerPortalEvent event) { } } - // remove permission attachments + // 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()); @@ -202,10 +253,11 @@ 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 Location RESPAWN_PLAYER = new Location(null, 0, 0, 0); + 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 @@ -234,11 +286,26 @@ public void onEntityDeath(EntityDeathEvent event) { return; Player player = (Player)event.getEntity(); + String playerName = player.getName(); - PrisonPearl pp = pearls.getByImprisoned(player); // find out if the player is imprisoned + 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) + 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 @@ -280,6 +347,10 @@ public void onPrisonPearlEvent(PrisonPearlEvent event) { 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); @@ -300,6 +371,8 @@ public void onPrisonPearlEvent(PrisonPearlEvent event) { 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!"); @@ -334,7 +407,6 @@ public void onSummonEvent(SummonEvent event) { break; } } - private void updateAttachment(Player player) { PermissionAttachment attachment = attachments.get(player.getName()); @@ -398,7 +470,8 @@ private Location moveToGround(Location loc) { return null; } - private boolean isObstructed(Location loc) { + @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()) @@ -443,4 +516,195 @@ public Void call() { }); } } + +@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..a53c867 100644 --- a/src/com/untamedears/PrisonPearl/PrisonPearlStorage.java +++ b/src/com/untamedears/PrisonPearl/PrisonPearlStorage.java @@ -8,7 +8,10 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.util.ArrayList; import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.List; import java.util.Map; import org.bukkit.Bukkit; @@ -16,10 +19,19 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.BrewingStand; +import org.bukkit.block.Chest; +import org.bukkit.block.Dispenser; +import org.bukkit.block.Furnace; +import org.bukkit.inventory.DoubleChestInventory; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; public class PrisonPearlStorage implements SaveLoad { - private Map pearls_byid; - private Map pearls_byimprisoned; + private final Map pearls_byid; + private final Map pearls_byimprisoned; private short nextid; private boolean dirty; @@ -50,7 +62,14 @@ public void load(File file) throws IOException { 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); + 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; @@ -75,8 +94,21 @@ public void save(File file) throws IOException { continue; Location loc = pp.getLocation(); - br.append(pp.getID() + " " + pp.getImprisonedName() + " " + loc.getWorld().getName() + " " + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ() + "\n"); - } + 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(); @@ -129,6 +161,10 @@ public PrisonPearl getByImprisoned(Player player) { return pearls_byimprisoned.get(player.getName()); } + public Integer getPearlCount(){ + return pearls_byimprisoned.size(); + } + boolean isImprisoned(String name) { return pearls_byimprisoned.containsKey(name); } @@ -136,4 +172,126 @@ boolean isImprisoned(String 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; + } + + public String feedPearls(PrisonPearlManager pearlman){ + String message = ""; + String log = ""; + ConcurrentHashMap map = new ConcurrentHashMap(pearls_byid); + + int pearlsfed = 0; + int coalfed = 0; + int freedpearls = 0; + for (PrisonPearl pp : map.values()) { + + BlockState inherentViolence = pp.getHolderBlockState(); + Material mat = inherentViolence.getType(); + + Inventory inv[] = new Inventory[2]; + inv[0] = inv[1] = null; + if (inherentViolence == null) + { + continue; + } + else + { + switch(mat) + { + case FURNACE: + inv[0] = ((Furnace)inherentViolence).getInventory(); + break; + case DISPENSER: + inv[0] = ((Dispenser)inherentViolence).getInventory(); + break; + case BREWING_STAND: + inv[0] = ((BrewingStand)inherentViolence).getInventory(); + break; + default: + if (mat == Material.CHEST || mat == Material.LOCKED_CHEST){ + Chest c = ((Chest)inherentViolence); + DoubleChestInventory dblInv = null; + try{ + dblInv = (DoubleChestInventory)c.getInventory(); + inv[0] = dblInv.getLeftSide(); + inv[1] = dblInv.getRightSide(); + } + catch(Exception e){ + inv[0] = (Inventory)c.getInventory(); + } + }else{ + pearlman.freePearl(pp); + log+="\n freed:"+pp.getImprisonedName()+",reason:"+"badcontainer"; + freedpearls++; + } + break; + } + } + + message = message + "Pearl #" + pp.getID() + ",Name: " + pp.getImprisonedName() + " in a " + pp.getHolderBlockState().getType(); + int requirementSize = 8; + ItemStack requirement = new ItemStack(Material.COAL, requirementSize); + if(inv[0].containsAtLeast(requirement,requirementSize)) + { + message = message + "\n Chest contains enough purestrain coal."; + inv[0].removeItem(requirement); + pearlsfed++; + coalfed += requirementSize; + log+="\n fed:" + pp.getImprisonedName() + ",location:"+ pp.describeLocation(); + } + else if(inv[1] != null && inv[1].containsAtLeast(requirement,requirementSize)){ + message = message + "\n Chest contains enough purestrain coal."; + inv[1].removeItem(requirement); + pearlsfed++; + coalfed += requirementSize; + log+="\n fed:" + pp.getImprisonedName() + ",location:"+ pp.describeLocation(); + } + else { + message = message + "\n Chest does not contain enough purestrain coal."; + pearlman.freePearl(pp); + log+="\n freed:"+pp.getImprisonedName()+",reason:"+"nocoal"+",location:"+pp.describeLocation(); + freedpearls++; + } + } + message = message + "\n Feeding Complete. " + pearlsfed + " were fed " + coalfed + " coal. " + freedpearls + " players were freed."; + return message; + } + + public String restorePearls(PrisonPearlManager pearlman, String config){ + //Read pearl config + + //For each entry + + //Create pearl for player + + //Place in chest + + //Check imprisonment status + + //Report restoration + return ""; + } }