diff --git a/src/main/java/com/gamingmesh/jobs/commands/list/convert.java b/src/main/java/com/gamingmesh/jobs/commands/list/convert.java index 8830bcad..996fe798 100644 --- a/src/main/java/com/gamingmesh/jobs/commands/list/convert.java +++ b/src/main/java/com/gamingmesh/jobs/commands/list/convert.java @@ -52,7 +52,7 @@ public class convert implements Cmd { Jobs.getPlayerManager().clearMaps(); Jobs.getPlayerManager().clearCache(); - Jobs.getJobsDAO().saveExplore(false); + Jobs.getJobsDAO().saveExplore(); Jobs.getJobsDAO().saveBlockProtection(); Jobs.loadAllPlayersData(); } catch (SQLException e) { diff --git a/src/main/java/com/gamingmesh/jobs/commands/list/explored.java b/src/main/java/com/gamingmesh/jobs/commands/list/explored.java new file mode 100644 index 00000000..789e6aa7 --- /dev/null +++ b/src/main/java/com/gamingmesh/jobs/commands/list/explored.java @@ -0,0 +1,54 @@ +package com.gamingmesh.jobs.commands.list; + +import java.util.HashMap; + +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.commands.Cmd; +import com.gamingmesh.jobs.commands.JobCommand; +import com.gamingmesh.jobs.container.ExploreChunk; +import com.gamingmesh.jobs.container.ExploreRegion; +import com.gamingmesh.jobs.stuff.ChatColor; + +public class explored implements Cmd { + + @Override + @JobCommand(1600) + public boolean perform(Jobs plugin, CommandSender sender, String[] args) { + + if (!(sender instanceof Player)) + return false; + + Player player = (Player) sender; + + World world = player.getWorld(); + + HashMap worlds = Jobs.getExplore().getWorlds(); + + if (!worlds.containsKey(world.getName())) { + sender.sendMessage(ChatColor.GREEN + Jobs.getLanguage().getMessage("command.explored.error.noexplore")); + return false; + } + + ExploreRegion regions = worlds.get(world.getName()); + + ExploreChunk chunk = regions.getChunk(player.getLocation().getChunk()); + + if (chunk == null) { + sender.sendMessage(ChatColor.GREEN + Jobs.getLanguage().getMessage("command.explored.error.noexplore")); + return false; + } + + int i = 0; + for (String one : chunk.getPlayers()) { + i++; + sender.sendMessage(ChatColor.GREEN + Jobs.getLanguage().getMessage("command.explored.list", "%place%", i, "%playername%", one)); + } + sender.sendMessage(ChatColor.GREEN + Jobs.getLanguage().getMessage("general.info.separator")); + + return true; + } +} diff --git a/src/main/java/com/gamingmesh/jobs/config/ExploreManager.java b/src/main/java/com/gamingmesh/jobs/config/ExploreManager.java index ca090867..c1419c35 100644 --- a/src/main/java/com/gamingmesh/jobs/config/ExploreManager.java +++ b/src/main/java/com/gamingmesh/jobs/config/ExploreManager.java @@ -1,7 +1,12 @@ package com.gamingmesh.jobs.config; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map.Entry; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -12,6 +17,7 @@ import com.gamingmesh.jobs.Jobs; import com.gamingmesh.jobs.container.ExploreChunk; import com.gamingmesh.jobs.container.ExploreRegion; import com.gamingmesh.jobs.container.ExploreRespond; +import com.gamingmesh.jobs.dao.JobsDAO.ExploreDataTableFields; import com.gamingmesh.jobs.stuff.Debug; public class ExploreManager { @@ -59,39 +65,84 @@ public class ExploreManager { return i; } - public ExploreRespond ChunkRespond(Player player, Chunk chunk, boolean isNew) { - return ChunkRespond(player.getName(), chunk.getWorld().getName(), chunk.getX(), chunk.getZ(), isNew); + public ExploreRespond ChunkRespond(Player player, Chunk chunk) { + return ChunkRespond(player.getName(), chunk.getWorld().getName(), chunk.getX(), chunk.getZ()); } - public ExploreRespond ChunkRespond(String player, String worldName, int x, int z, boolean isNew) { + public ExploreRespond ChunkRespond(String player, String world, int x, int z) { - int ChunkX = x; - int ChunkZ = z; +// int ChunkX = x; +// int ChunkZ = z; - int RegionX = (int) Math.floor(ChunkX / 32D); - int RegionZ = (int) Math.floor(ChunkZ / 32D); +// int RegionX = (int) Math.floor(ChunkX / 32D); +// int RegionZ = (int) Math.floor(ChunkZ / 32D); - if (!worlds.containsKey(worldName)) { - ExploreChunk eChunk = new ExploreChunk(player, ChunkX, ChunkZ); - if (!isNew) - eChunk.setOldChunk(); - ExploreRegion eRegion = new ExploreRegion(RegionX, RegionZ); - eRegion.addChunk(eChunk); - worlds.put(worldName, eRegion); - return new ExploreRespond(eChunk.getCount(), true); + ExploreRegion eRegions = worlds.get(world); + if (eRegions == null) { + int RegionX = (int) Math.floor(x / 32D); + int RegionZ = (int) Math.floor(z / 32D); + eRegions = new ExploreRegion(RegionX, RegionZ); } - ExploreRegion eRegion = worlds.get(worldName); - ExploreChunk eChunk = eRegion.getChunk(ChunkX + ":" + ChunkZ); + ExploreChunk chunk = eRegions.getChunk(x, z); + if (chunk == null) + chunk = new ExploreChunk(x, z); - if (eChunk == null) { - eChunk = new ExploreChunk(player, ChunkX, ChunkZ); - if (!isNew) - eChunk.setOldChunk(); - eRegion.addChunk(eChunk); - return new ExploreRespond(eChunk.getCount(), true); + eRegions.addChunk(chunk); + worlds.put(world, eRegions); + + return chunk.addPlayer(player); + +// if (!worlds.containsKey(worldName)) { +// ExploreChunk eChunk = new ExploreChunk(player, ChunkX, ChunkZ); +// if (!isNew) +// eChunk.setOldChunk(); +// ExploreRegion eRegion = new ExploreRegion(RegionX, RegionZ); +// eRegion.addChunk(eChunk); +// worlds.put(worldName, eRegion); +// Debug.D("new chunk " + eChunk.isNew()); +// return new ExploreRespond(eChunk.getCount(), true); +// } +// ExploreRegion eRegion = worlds.get(worldName); +// ExploreChunk eChunk = eRegion.getChunk(ChunkX + ":" + ChunkZ); +// +// if (eChunk == null) { +// eChunk = new ExploreChunk(player, ChunkX, ChunkZ); +// if (!isNew) +// eChunk.setOldChunk(); +// eRegion.addChunk(eChunk); +// Debug.D("new chunk " + eChunk.isNew()); +// return new ExploreRespond(eChunk.getCount(), true); +// } +// eChunk.setOldChunk(); +// return eChunk.addPlayer(player); + } + + public void load(ResultSet res) { + try { + String world = res.getString(ExploreDataTableFields.worldname.getCollumn()); + int x = res.getInt(ExploreDataTableFields.chunkX.getCollumn()); + int z = res.getInt(ExploreDataTableFields.chunkZ.getCollumn()); + String names = res.getString(ExploreDataTableFields.playerNames.getCollumn()); + int id = res.getInt("id"); + + ExploreRegion eRegions = worlds.get(world); + if (eRegions == null) { + int RegionX = (int) Math.floor(x / 32D); + int RegionZ = (int) Math.floor(z / 32D); + eRegions = new ExploreRegion(RegionX, RegionZ); + } + ExploreChunk chunk = eRegions.getChunk(x, z); + if (chunk == null) + chunk = new ExploreChunk(x, z); + chunk.deserializeNames(names); + chunk.setDbId(id); + + eRegions.addChunk(chunk); + worlds.put(world, eRegions); + + } catch (SQLException e) { + e.printStackTrace(); } - eChunk.setOldChunk(); - return eChunk.addPlayer(player); } // // public void addChunk(String player, String worldName, int x, int z) { diff --git a/src/main/java/com/gamingmesh/jobs/config/LanguageManager.java b/src/main/java/com/gamingmesh/jobs/config/LanguageManager.java index 9a7df3ce..d100bacb 100644 --- a/src/main/java/com/gamingmesh/jobs/config/LanguageManager.java +++ b/src/main/java/com/gamingmesh/jobs/config/LanguageManager.java @@ -390,6 +390,10 @@ public class LanguageManager { c.get("command.leaveall.help.info", "Leave all your jobs."); c.get("command.leaveall.error.nojobs", "You do not have any jobs to leave!"); c.get("command.leaveall.success", "You have left all your jobs."); + + c.get("command.explored.help.info", "Check who visited this chunk"); + c.get("command.explored.error.noexplore", "No one visited this chunk"); + c.get("command.explored.list", "&e%place%. %playername%"); c.get("command.browse.help.info", "List the jobs available to you."); c.get("command.browse.error.nojobs", "There are no jobs you can join."); diff --git a/src/main/java/com/gamingmesh/jobs/container/ExploreChunk.java b/src/main/java/com/gamingmesh/jobs/container/ExploreChunk.java index 8265c03d..21ebf62c 100644 --- a/src/main/java/com/gamingmesh/jobs/container/ExploreChunk.java +++ b/src/main/java/com/gamingmesh/jobs/container/ExploreChunk.java @@ -1,16 +1,19 @@ package com.gamingmesh.jobs.container; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.stuff.Debug; public class ExploreChunk { int x; int z; Set playerNames = new HashSet(); - boolean isNewChunk = true; + private Integer dbId = null; + private boolean updated = false; public ExploreChunk(String playerName, int x, int z) { this.x = x; @@ -18,15 +21,21 @@ public class ExploreChunk { this.playerNames.add(playerName); } + public ExploreChunk(int x, int z) { + this.x = x; + this.z = z; + } + public ExploreRespond addPlayer(String playerName) { - boolean newChunk = false; + boolean newChunkForPlayer = false; if (!playerNames.contains(playerName)) { - playerNames.add(playerName); - newChunk = true; + if (playerNames.size() < Jobs.getExplore().getPlayerAmount()) { + playerNames.add(playerName); + updated = true; + } + newChunkForPlayer = true; } - if (playerNames.size() > Jobs.getExplore().getPlayerAmount()) - playerNames.remove(0); - return new ExploreRespond(playerNames.size(), newChunk); + return new ExploreRespond(newChunkForPlayer ? playerNames.size() : playerNames.size() + 1, newChunkForPlayer); } public boolean isAlreadyVisited(String playerName) { @@ -44,16 +53,41 @@ public class ExploreChunk { public int getZ() { return this.z; } - + public Set getPlayers() { return this.playerNames; } - - public boolean isNew() { - return this.isNewChunk; + + public String serializeNames() { + String s = ""; + for (String one : this.playerNames) { + if (!s.isEmpty()) + s += ";"; + s += one; + } + return s; } - - public void setOldChunk() { - isNewChunk = false; + + public void deserializeNames(String names) { + if (names.contains(";")) + playerNames.addAll(Arrays.asList(names.split(";"))); + else + playerNames.add(names); + } + + public Integer getDbId() { + return dbId; + } + + public void setDbId(Integer dbId) { + this.dbId = dbId; + } + + public boolean isUpdated() { + return updated; + } + + public void setUpdated(boolean updated) { + this.updated = updated; } } diff --git a/src/main/java/com/gamingmesh/jobs/container/ExploreRegion.java b/src/main/java/com/gamingmesh/jobs/container/ExploreRegion.java index a653356f..4c49ba39 100644 --- a/src/main/java/com/gamingmesh/jobs/container/ExploreRegion.java +++ b/src/main/java/com/gamingmesh/jobs/container/ExploreRegion.java @@ -2,6 +2,8 @@ package com.gamingmesh.jobs.container; import java.util.HashMap; +import org.bukkit.Chunk; + public class ExploreRegion { int x; @@ -21,6 +23,14 @@ public class ExploreRegion { return chunks; } + public ExploreChunk getChunk(int x, int z) { + return getChunk(x + ":" + z); + } + + public ExploreChunk getChunk(Chunk chunk) { + return getChunk(chunk.getX() + ":" + chunk.getZ()); + } + public ExploreChunk getChunk(String cord) { return chunks.get(cord); } diff --git a/src/main/java/com/gamingmesh/jobs/dao/JobsDAO.java b/src/main/java/com/gamingmesh/jobs/dao/JobsDAO.java index 11e6be7b..5fcd2e49 100644 --- a/src/main/java/com/gamingmesh/jobs/dao/JobsDAO.java +++ b/src/main/java/com/gamingmesh/jobs/dao/JobsDAO.java @@ -267,16 +267,16 @@ public abstract class JobsDAO { } } - public enum ExploreTableFields implements JobsTableInterface { + public enum ExploreDataTableFields implements JobsTableInterface { worldname("varchar(64)", TablesFieldsType.varchar), chunkX("int", TablesFieldsType.number), chunkZ("int", TablesFieldsType.number), - playerName("text", TablesFieldsType.text); + playerNames("text", TablesFieldsType.text); private String type; private TablesFieldsType fieldType; - ExploreTableFields(String type, TablesFieldsType fieldType) { + ExploreDataTableFields(String type, TablesFieldsType fieldType) { this.type = type; this.fieldType = fieldType; } @@ -316,9 +316,9 @@ public abstract class JobsDAO { LogTable("log", "CREATE TABLE IF NOT EXISTS `[tableName]` (`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY[fields]);", "CREATE TABLE IF NOT EXISTS `[tableName]` (`id` INTEGER PRIMARY KEY AUTOINCREMENT[fields]);", LogTableFields.class), - ExploreTable("explore", + ExploreDataTable("exploreData", "CREATE TABLE IF NOT EXISTS `[tableName]` (`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY[fields]);", - "CREATE TABLE IF NOT EXISTS `[tableName]` (`id` INTEGER PRIMARY KEY AUTOINCREMENT[fields]);", ExploreTableFields.class), + "CREATE TABLE IF NOT EXISTS `[tableName]` (`id` INTEGER PRIMARY KEY AUTOINCREMENT[fields]);", ExploreDataTableFields.class), PointsTable("points", "CREATE TABLE IF NOT EXISTS `[tableName]` (`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY[fields]);", "CREATE TABLE IF NOT EXISTS `[tableName]` (`id` INTEGER PRIMARY KEY AUTOINCREMENT[fields]);", PointsTableFields.class); @@ -1791,11 +1791,13 @@ public abstract class JobsDAO { * Save player-explore information * @param jobexplore - the information getting saved */ + public void saveExplore() { - saveExplore(true); + insertExplore(); + updateExplore(); } - public void saveExplore(boolean ignoreOld) { + public void insertExplore() { if (!Jobs.getExplore().isExploreEnabled()) return; @@ -1805,7 +1807,7 @@ public abstract class JobsDAO { PreparedStatement prest2 = null; try { - prest2 = conn.prepareStatement("INSERT INTO `" + prefix + "explore` (`worldname`, `chunkX`, `chunkZ`, `playerName`) VALUES (?, ?, ?, ?);"); + prest2 = conn.prepareStatement("INSERT INTO `" + prefix + "exploreData` (`worldname`, `chunkX`, `chunkZ`, `playerNames`) VALUES (?, ?, ?, ?);"); conn.setAutoCommit(false); int i = 0; @@ -1813,16 +1815,14 @@ public abstract class JobsDAO { for (Entry worlds : temp.entrySet()) { for (Entry oneChunk : worlds.getValue().getChunks().entrySet()) { - if (!oneChunk.getValue().isNew() && ignoreOld) + if (oneChunk.getValue().getDbId() != null) continue; - for (String oneuser : oneChunk.getValue().getPlayers()) { - prest2.setString(1, worlds.getKey()); - prest2.setInt(2, oneChunk.getValue().getX()); - prest2.setInt(3, oneChunk.getValue().getZ()); - prest2.setString(4, oneuser); - prest2.addBatch(); - i++; - } + prest2.setString(1, worlds.getKey()); + prest2.setInt(2, oneChunk.getValue().getX()); + prest2.setInt(3, oneChunk.getValue().getZ()); + prest2.setString(4, oneChunk.getValue().serializeNames()); + prest2.addBatch(); + i++; } } prest2.executeBatch(); @@ -1841,6 +1841,50 @@ public abstract class JobsDAO { } } + public void updateExplore() { + if (!Jobs.getExplore().isExploreEnabled()) + return; + + JobsConnection conn = getConnection(); + if (conn == null) + return; + PreparedStatement prest = null; + try { + conn.setAutoCommit(false); + prest = conn.prepareStatement("UPDATE `" + prefix + "exploreData` SET `playerNames` = ? WHERE `id` = ?;"); + + int i = 0; + + HashMap temp = new HashMap(Jobs.getExplore().getWorlds()); + + for (Entry worlds : temp.entrySet()) { + for (Entry oneChunk : worlds.getValue().getChunks().entrySet()) { + if (oneChunk.getValue().getDbId() == null) + continue; + if (!oneChunk.getValue().isUpdated()) + continue; + prest.setString(1, oneChunk.getValue().serializeNames()); + prest.setInt(2, oneChunk.getValue().getDbId()); + prest.addBatch(); + i++; + } + } + prest.executeBatch(); + conn.commit(); + conn.setAutoCommit(true); + + if (i > 0) { + String message = ChatColor.translateAlternateColorCodes('&', "&e[Jobs] Updated " + i + " explorer entries."); + ConsoleCommandSender console = Bukkit.getServer().getConsoleSender(); + console.sendMessage(message); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + close(prest); + } + } + /** * Save player-explore information * @param jobexplore - the information getting saved @@ -1852,13 +1896,40 @@ public abstract class JobsDAO { JobsConnection conn = getConnection(); if (conn == null) return; + + if (this.isTable(prefix + "explore")) { + PreparedStatement prest = null; + ResultSet res = null; + try { + prest = conn.prepareStatement("SELECT * FROM `" + prefix + "explore`;"); + res = prest.executeQuery(); + while (res.next()) { + Jobs.getExplore().ChunkRespond(res.getString("playerName"), res.getString("worldname"), res.getInt("chunkX"), res.getInt("chunkZ")); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + close(res); + close(prest); + } + Statement stmt = null; + try { + stmt = conn.createStatement(); + stmt.executeUpdate("DROP TABLE `" + prefix + "explore`;"); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + close(stmt); + } + } + PreparedStatement prest = null; ResultSet res = null; try { - prest = conn.prepareStatement("SELECT * FROM `" + prefix + "explore`;"); + prest = conn.prepareStatement("SELECT * FROM `" + prefix + "exploreData`;"); res = prest.executeQuery(); while (res.next()) { - Jobs.getExplore().ChunkRespond(res.getString("playerName"), res.getString("worldname"), res.getInt("chunkX"), res.getInt("chunkZ"), false); + Jobs.getExplore().load(res); } } catch (SQLException e) { e.printStackTrace(); @@ -1866,6 +1937,7 @@ public abstract class JobsDAO { close(res); close(prest); } + } /** diff --git a/src/main/java/com/gamingmesh/jobs/listeners/JobsPaymentListener.java b/src/main/java/com/gamingmesh/jobs/listeners/JobsPaymentListener.java index 70064b8d..22f047a6 100644 --- a/src/main/java/com/gamingmesh/jobs/listeners/JobsPaymentListener.java +++ b/src/main/java/com/gamingmesh/jobs/listeners/JobsPaymentListener.java @@ -1335,7 +1335,7 @@ public class JobsPaymentListener implements Listener { if (!Jobs.getGCManager().payExploringWhenFlying() && player.isFlying()) return; - ExploreRespond respond = Jobs.getExplore().ChunkRespond(event.getPlayer(), event.getNewChunk(), true); + ExploreRespond respond = Jobs.getExplore().ChunkRespond(event.getPlayer(), event.getNewChunk()); if (!respond.isNewChunk()) return;