diff --git a/src/main/java/com/gamingmesh/jobs/Jobs.java b/src/main/java/com/gamingmesh/jobs/Jobs.java index de39827f..46304bd0 100644 --- a/src/main/java/com/gamingmesh/jobs/Jobs.java +++ b/src/main/java/com/gamingmesh/jobs/Jobs.java @@ -572,7 +572,7 @@ public final class Jobs extends JavaPlugin { getPlayerManager().addPlayerToCache(jPlayer); } if (!getPlayerManager().getPlayersCache().isEmpty()) - consoleMsg("&e[Jobs] Preloaded " + getPlayerManager().getPlayersCache().size() + " players data in " + ((int) ((System.currentTimeMillis() - time) / 1000.0D * 100.0D) / 100.0D)); + consoleMsg("&e[Jobs] Preloaded &6" + getPlayerManager().getPlayersCache().size() + " &eplayers data in &6" + ((int) ((System.currentTimeMillis() - time) / 1000.0D * 100.0D) / 100.0D)); } public static void convertDatabase() { diff --git a/src/main/java/com/gamingmesh/jobs/PlayerManager.java b/src/main/java/com/gamingmesh/jobs/PlayerManager.java index f36765c4..1eb6f253 100644 --- a/src/main/java/com/gamingmesh/jobs/PlayerManager.java +++ b/src/main/java/com/gamingmesh/jobs/PlayerManager.java @@ -64,6 +64,7 @@ import com.gamingmesh.jobs.stuff.Util; import net.Zrips.CMILib.ActionBar.CMIActionBar; import net.Zrips.CMILib.Items.CMIItemStack; import net.Zrips.CMILib.Logs.CMIDebug; +import net.Zrips.CMILib.Messages.CMIMessages; import net.Zrips.CMILib.NBT.CMINBT; import net.Zrips.CMILib.Version.Version; @@ -121,6 +122,27 @@ public class PlayerManager { } public void addPlayerToMap(PlayerInfo info) { + + // Checking duplicated UUID's which usually is a cause of previous bugs + if (playerUUIDMap.containsKey(info.getUuid()) && playerUUIDMap.get(info.getUuid()).getID() != info.getID()) { + int id = playerUUIDMap.get(info.getUuid()).getID(); + CMIMessages.consoleMessage("&7Duplicate! &5" + info.getName() + " &7same UUID for 2 entries in dabase. Please remove of one them from users table id1: &2" + id + " &7id2: &2" + info.getID()); + + if (id < info.getID()) { + return; + } + } + + // Checking duplicated names which usually is a cause of previous bugs + if (playerNameMap.containsKey(info.getName().toLowerCase()) && playerNameMap.get(info.getName().toLowerCase()).getID() != info.getID()) { + int id = playerNameMap.get(info.getName().toLowerCase()).getID(); + CMIMessages.consoleMessage("&7Name Duplicate! &5" + info.getName() + " &7same UUID for 2 entries in dabase. Please remove of one them from users table id1: &2" + id + " &7id2: &2" + info + .getID()); + if (id < info.getID()) { + return; + } + } + playerUUIDMap.put(info.getUuid(), info); playerIdMap.put(info.getID(), info); playerNameMap.put(info.getName().toLowerCase(), info); @@ -388,7 +410,6 @@ public class PlayerManager { */ public JobsPlayer getJobsPlayer(String playerName) { playerName = playerName.toLowerCase(); - JobsPlayer jPlayer = players.get(playerName); return jPlayer != null ? jPlayer : playersCache.get(playerName); } @@ -419,13 +440,22 @@ public class PlayerManager { for (JobsDAOData jobdata : jobs) { Job job = Jobs.getJob(jobdata.getJobName()); if (job != null) { + + // Fixing issue with doubled jobs. Picking bigger job by level or exp + JobProgression oldProg = jPlayer.getJobProgression(job); + if (oldProg != null && (oldProg.getLevel() > jobdata.getLevel() || oldProg.getLevel() == jobdata.getLevel() && oldProg.getExperience() > jobdata.getExperience())) { + Jobs.getDBManager().getDB().removeSpecificJob(jPlayer, jobdata.getJobName(), jobdata.getLevel()); + CMIMessages.consoleMessage("Cleaned up duplicated jobs record for " + jPlayer.getName() + " Job:" + jobdata.getJobName() + " Level:" + jobdata.getLevel()); + continue; + } + jPlayer.progression.add(new JobProgression(job, jPlayer, jobdata.getLevel(), jobdata.getExperience())); jPlayer.reloadMaxExperience(); jPlayer.reloadLimits(); } } } - + if (points != null) jPlayer.setPoints(points); 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 943fd910..9291e82e 100644 --- a/src/main/java/com/gamingmesh/jobs/commands/list/convert.java +++ b/src/main/java/com/gamingmesh/jobs/commands/list/convert.java @@ -1,7 +1,5 @@ package com.gamingmesh.jobs.commands.list; -import java.util.concurrent.CompletableFuture; - import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -23,20 +21,17 @@ public class convert implements Cmd { return true; } - CompletableFuture.supplyAsync(() -> { - Jobs.convertDatabase(); - return true; - }).thenAccept(e -> { - String from = "MySQL"; - String to = "SQLite"; + Jobs.convertDatabase(); - if (Jobs.getDBManager().getDbType() != DataBaseType.SqLite) { - from = "SQLite"; - to = "MySQL"; - } + String from = "MySQL"; + String to = "SQLite"; - Jobs.consoleMsg("&eData base was converted from &2" + from + " &eto &2" + to + "&e!"); - }); + if (Jobs.getDBManager().getDbType() != DataBaseType.SqLite) { + from = "SQLite"; + to = "MySQL"; + } + + Jobs.consoleMsg("&eData base was converted from &2" + from + " &eto &2" + to + "&e!"); return true; } diff --git a/src/main/java/com/gamingmesh/jobs/dao/JobsDAO.java b/src/main/java/com/gamingmesh/jobs/dao/JobsDAO.java index 9066fbeb..efe5d6e3 100644 --- a/src/main/java/com/gamingmesh/jobs/dao/JobsDAO.java +++ b/src/main/java/com/gamingmesh/jobs/dao/JobsDAO.java @@ -634,6 +634,7 @@ public abstract class JobsDAO { res = prest.executeQuery(); while (res.next()) { int id = res.getInt(JobsTableFields.userid.getCollumn()); + List ls = map.get(id); if (ls == null) ls = new ArrayList<>(); @@ -644,13 +645,13 @@ public abstract class JobsDAO { converted = false; } else { // This should be removed when we switch over to id only method - if (converted) - if (res.getString(JobsTableFields.job.getCollumn()) == null || res.getString(JobsTableFields.job.getCollumn()).isEmpty()) - converted = false; + if (converted && res.getString(JobsTableFields.job.getCollumn()) == null || res.getString(JobsTableFields.job.getCollumn()).isEmpty()) + converted = false; Job job = Jobs.getJob(jobId); - if (job != null) + if (job != null) { ls.add(new JobsDAOData(job.getName(), res.getInt(JobsTableFields.level.getCollumn()), res.getDouble(JobsTableFields.experience.getCollumn()))); + } } map.put(id, ls); @@ -1588,6 +1589,33 @@ public abstract class JobsDAO { return done; } + /** + * Quit a job (delete player-job entry from storage) + * @param player - player that wishes to quit the job + * @param job - job that the player wishes to quit + */ + public synchronized boolean removeSpecificJob(JobsPlayer jPlayer, String jobName, int level) { + JobsConnection conn = getConnection(); + if (conn == null) + return false; + PreparedStatement prest = null; + boolean done = true; + try { + prest = conn.prepareStatement("DELETE FROM `" + getJobsTableName() + "` WHERE `" + JobsTableFields.userid.getCollumn() + "` = ? AND `" + JobsTableFields.job.getCollumn() + + "` = ? AND `" + JobsTableFields.level.getCollumn() + "` = ?;"); + prest.setInt(1, jPlayer.getUserId()); + prest.setString(2, jobName); + prest.setInt(3, level); + prest.execute(); + } catch (SQLException e) { + e.printStackTrace(); + done = false; + } finally { + close(prest); + } + return done; + } + /** * Record job to archive * @param player - player that wishes to quit the job @@ -1857,7 +1885,7 @@ public abstract class JobsDAO { try { prest = conn.prepareStatement("UPDATE `" + getJobsTableName() + "` SET `" + JobsTableFields.level.getCollumn() + "` = ?, `" + JobsTableFields.experience.getCollumn() + "` = ? WHERE `" + JobsTableFields.userid.getCollumn() + "` = ? AND `" + JobsTableFields.jobid.getCollumn() + "` = ? " - + "OR `" + JobsTableFields.userid.getCollumn() + "` = ? AND `" + JobsTableFields.jobid.getCollumn() + "` = ?;"); + + "OR `" + JobsTableFields.userid.getCollumn() + "` = ? AND `" + JobsTableFields.jobid.getCollumn() + "` = ?;"); for (JobProgression progression : player.getJobProgression()) { prest.setInt(1, progression.getLevel()); prest.setDouble(2, progression.getExperience()); diff --git a/src/main/java/com/gamingmesh/jobs/listeners/JobsListener.java b/src/main/java/com/gamingmesh/jobs/listeners/JobsListener.java index f2ef2c47..02a841d8 100644 --- a/src/main/java/com/gamingmesh/jobs/listeners/JobsListener.java +++ b/src/main/java/com/gamingmesh/jobs/listeners/JobsListener.java @@ -110,7 +110,7 @@ public class JobsListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockFromToEvent(BlockFromToEvent event) { - + if (!Jobs.getGCManager().useBlockProtection) return; if (!Jobs.getGCManager().ignoreOreGenerators) @@ -119,7 +119,7 @@ public class JobsListener implements Listener { return; Jobs.getBpManager().remove(event.getToBlock()); } - + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(PlayerJoinEvent event) { if (Jobs.getGCManager().isShowNewVersion() && event.getPlayer().hasPermission("jobs.versioncheck")) @@ -163,8 +163,7 @@ public class JobsListener implements Listener { if (!Jobs.getGCManager().MultiServerCompatability()) Jobs.getPlayerManager().playerJoin(event.getPlayer()); else { - plugin.getServer().getScheduler().runTaskLater(plugin, () -> - Jobs.getPlayerManager().playerJoin(event.getPlayer()), 10L); + plugin.getServer().getScheduler().runTaskLater(plugin, () -> Jobs.getPlayerManager().playerJoin(event.getPlayer()), 10L); } } @@ -182,10 +181,7 @@ public class JobsListener implements Listener { @EventHandler(priority = EventPriority.MONITOR) public void onPlayerQuit(PlayerQuitEvent event) { - java.util.concurrent.CompletableFuture.supplyAsync(() -> { - Jobs.getPlayerManager().playerQuit(event.getPlayer()); - return true; - }); + Jobs.getPlayerManager().playerQuit(event.getPlayer()); } @EventHandler(priority = EventPriority.MONITOR) @@ -221,7 +217,7 @@ public class JobsListener implements Listener { } player.performCommand("jobs " + command + " " + CMIChatColor.stripColor(plugin.getComplement().getLine(sign, 2)) - + " " + CMIChatColor.stripColor(plugin.getComplement() + + " " + CMIChatColor.stripColor(plugin.getComplement() .getLine(sign, 3)).replace(" ", "")); // Replace trailing spaces at 3rd line to parse command }