diff --git a/Plan/.idea/libraries/Maven__com_djrapitops_abstract_plugin_framework_2_0_1.xml b/Plan/.idea/libraries/Maven__com_djrapitops_abstract_plugin_framework_2_0_1.xml index 554d77a3e..826d210d1 100644 --- a/Plan/.idea/libraries/Maven__com_djrapitops_abstract_plugin_framework_2_0_1.xml +++ b/Plan/.idea/libraries/Maven__com_djrapitops_abstract_plugin_framework_2_0_1.xml @@ -2,9 +2,12 @@ - - - + + + + + + \ No newline at end of file diff --git a/Plan/.idea/sonarIssues.xml b/Plan/.idea/sonarIssues.xml new file mode 100644 index 000000000..d057f2bd2 --- /dev/null +++ b/Plan/.idea/sonarIssues.xml @@ -0,0 +1,184 @@ + + + + + + \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/UserData.java b/Plan/src/main/java/com/djrapitops/plan/data/UserData.java index e7b70e383..4cea741e5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/UserData.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/UserData.java @@ -4,6 +4,8 @@ import com.djrapitops.plugin.utilities.Verify; import com.djrapitops.plugin.utilities.player.IOfflinePlayer; import com.djrapitops.plugin.utilities.player.IPlayer; import main.java.com.djrapitops.plan.Log; +import main.java.com.djrapitops.plan.data.time.GMTimes; +import main.java.com.djrapitops.plan.data.time.WorldTimes; import java.net.InetAddress; import java.util.*; @@ -16,71 +18,75 @@ import java.util.stream.Collectors; */ public class UserData { - private final List sessions; private int accessing; private boolean clearAfterSave; + private UUID uuid; - private Set ips; + private String name; private Set nicknames; private String lastNick; - private long registered; - private long lastPlayed; - private long playTime; + private String geolocation; + private Set ips; + private int loginTimes; private int timesKicked; - private long lastGmSwapTime; - private String lastGamemode; - private Map gmTimes; + private boolean isOp; private boolean isBanned; - private String geolocation; + private boolean isOnline; + private int mobKills; private List playerKills; private int deaths; - private String name; - private boolean isOnline; - private SessionData currentSession; + + private long registered; + private long lastPlayed; + private long playTime; + + private GMTimes gmTimes; + private WorldTimes worldTimes; + + private final List sessions; /** * Creates a new UserData object with given values and default values. *

* Some variables are left uninitialized: isBanned, lastPlayed, playTime, - * loginTimes, timesKicked, lastGmSwapTime, mobKills, deaths and - * currentSession. + * loginTimes, timesKicked, lastGmSwapTime, mobKills, deaths, lastWorldSwapTime, lastWorld *

* These variables need to be set with setters. *

* All Collections are left empty: locations, nicknames, ips, sessions, * playerKills. Because nicknames is empty, lastNick is an empty string. *

- * gmTimes HashMap will contain 4 '0L' values: SURVIVAL, CREATIVE, + * gmTimes Map will contain 4 '0L' values: SURVIVAL, CREATIVE, * ADVENTURE, SPECTATOR + * worldTimes Map is left empty. * * @param uuid UUID of the player * @param reg Epoch millisecond the player registered. * @param op Is the player op? (true/false) - * @param lastGM last GameMode the player was seen in. * @param name Name of the player. * @param online Is the player online? */ - public UserData(UUID uuid, long reg, boolean op, String lastGM, String name, boolean online) { + public UserData(UUID uuid, long reg, boolean op, String gm, String name, boolean online) { accessing = 0; + + this.gmTimes = new GMTimes(gm); + this.worldTimes = new WorldTimes(); + this.uuid = uuid; - registered = reg; - isOp = op; + this.name = name; + lastNick = ""; nicknames = new HashSet<>(); ips = new HashSet<>(); - gmTimes = new HashMap<>(); - String[] gms = new String[]{"SURVIVAL", "CREATIVE", "ADVENTURE", "SPECTATOR"}; - for (String gm : gms) { - gmTimes.put(gm, 0L); - } - lastGamemode = lastGM; geolocation = "Not Known"; - this.name = name; + + isOp = op; isOnline = online; + registered = reg; + sessions = new ArrayList<>(); - lastNick = ""; playerKills = new ArrayList<>(); } @@ -160,10 +166,8 @@ public class UserData { this.playTime = data.getPlayTime(); this.loginTimes = data.getLoginTimes(); this.timesKicked = data.getTimesKicked(); - this.lastGmSwapTime = data.getLastGmSwapTime(); - this.lastGamemode = data.getLastGamemode(); - this.gmTimes = new HashMap<>(); - gmTimes.putAll(data.getGmTimes()); + this.gmTimes = data.getGmTimes(); + this.worldTimes = data.getWorldTimes(); this.isOp = data.isOp(); this.isBanned = data.isBanned(); this.geolocation = data.getGeolocation(); @@ -179,12 +183,22 @@ public class UserData { @Override public String toString() { try { - return "{" + "accessing:" + accessing + "|uuid:" + uuid + "|ips:" + ips + "|nicknames:" + nicknames + "|lastNick:" + lastNick + "|registered:" + registered + "|lastPlayed:" + lastPlayed + "|playTime:" + playTime + "|loginTimes:" + loginTimes + "|timesKicked:" + timesKicked + "|lastGmSwapTime:" + lastGmSwapTime + "|lastGamemode:" + lastGamemode + "|gmTimes:" + gmTimes + "|isOp:" + isOp + "|isBanned:" + isBanned + "|geolocation:" + geolocation + "|mobKills:" + mobKills + "|playerKills:" + playerKills + "|deaths:" + deaths + "|name:" + name + "|isOnline:" + isOnline + "|currentSession:" + currentSession + "|sessions:" + sessions + '}'; + return "{" + "accessing:" + accessing + "|uuid:" + uuid + "|ips:" + ips + "|nicknames:" + nicknames + "|lastNick:" + lastNick + "|registered:" + registered + "|lastPlayed:" + lastPlayed + "|playTime:" + playTime + "|loginTimes:" + loginTimes + "|timesKicked:" + timesKicked + "|gm:" + gmTimes + "|world:" + worldTimes + "|isOp:" + isOp + "|isBanned:" + isBanned + "|geolocation:" + geolocation + "|mobKills:" + mobKills + "|playerKills:" + playerKills + "|deaths:" + deaths + "|name:" + name + "|isOnline:" + isOnline + "|sessions:" + sessions + '}'; } catch (Exception e) { return "UserData: Error on toString:" + e; } } + @Deprecated + public String getLastGamemode() { + return gmTimes.getState(); + } + + @Deprecated + public long getLastGmSwapTime() { + return gmTimes.getLastStateChange(); + } + /** * Adds an to the ips Set if it is not null or the set doesn't contain it. * @@ -242,37 +256,6 @@ public class UserData { nicknames.addAll(addNicks.stream().filter(nick -> !Verify.isEmpty(nick)).collect(Collectors.toList())); } - /** - * Set a specific GameMode's millisecond value. - * - * @param gm Name of Gamemode. - * @param time Milliseconds spent in the gamemode. - */ - public void setGMTime(String gm, long time) { - if (!Verify.notNull(gmTimes)) { - gmTimes = new HashMap<>(); - } - if (Verify.notNull(gm)) { - gmTimes.put(gm, time); - } - } - - /** - * Set every GameMode's millisecond value. - * - * @param survivalTime ms spent in SURVIVAL - * @param creativeTime ms spent in CREATIVE - * @param adventureTime ms spent in ADVENTURE - * @param spectatorTime ms spent in SPECTATOR - */ - public void setAllGMTimes(long survivalTime, long creativeTime, long adventureTime, long spectatorTime) { - gmTimes.clear(); - gmTimes.put("SURVIVAL", survivalTime); - gmTimes.put("CREATIVE", creativeTime); - gmTimes.put("ADVENTURE", adventureTime); - gmTimes.put("SPECTATOR", spectatorTime); - } - /** * Adds a new SessionData to the sessions list. *

@@ -301,28 +284,6 @@ public class UserData { this.sessions.addAll(filteredSessions); } - /** - * Gets the current session. - *

- * Currently unused. - * - * @return SessionData object with a recent start. - */ - public SessionData getCurrentSession() { - return currentSession; - } - - /** - * Sets the current session. - *

- * Currently unused. - * - * @param session SessionData object, no restrictions. - */ - public void setCurrentSession(SessionData session) { - currentSession = session; - } - /** * Changes the value of isBanned. * @@ -522,66 +483,31 @@ public class UserData { } /** - * Get the GMTimes Map. + * Get the GMTimes object. * - * @return a GameMode map with 4 keys: SURVIVAL, CREATIVE, ADVENTURE, - * SPECTATOR. + * @return TimeKeeper object with possible keys of SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR */ - public Map getGmTimes() { - if (gmTimes == null) { - gmTimes = new HashMap<>(); - } + public GMTimes getGmTimes() { return gmTimes; } /** - * Set the GM Times map containing playtime in each gamemode. + * Set the GM Times object containing playtime in each gamemode. * - * @param gmTimes Map containing SURVIVAL, CREATIVE, ADVENTURE and SPECTATOR - * (After 1.8) keys. + * @param gmTimes GM Times object */ - public void setGmTimes(Map gmTimes) { + public void setGmTimes(GMTimes gmTimes) { if (Verify.notNull(gmTimes)) { this.gmTimes = gmTimes; } } - /** - * Get the last time a Gamemode time was updated. - * - * @return Epoch millisecond of last GM Time update. - */ - public long getLastGmSwapTime() { - return lastGmSwapTime; - } - - /** - * Set the last time a Gamemode time was updated. - * - * @param lastGmSwapTime Epoch millisecond a gm time was updated. - */ - public void setLastGmSwapTime(long lastGmSwapTime) { - this.lastGmSwapTime = lastGmSwapTime; - } - - /** - * Get the last Gamemode that the user was seen in. - *

- * When player changes to SURVIVAL this is set to SURVIVAL. - * - * @return Gamemode. - */ - public String getLastGamemode() { - return lastGamemode; - } - - /** - * Set the last gamemode the user was seen in. - * - * @param lastGamemode gamemode. - */ - public void setLastGamemode(String lastGamemode) { - this.lastGamemode = lastGamemode; + public void setGmTimes(Map times) { + if (Verify.notNull(times)) { + for (Map.Entry entry : times.entrySet()) { + gmTimes.setTime(entry.getKey(), entry.getValue()); + } + } } /** @@ -752,6 +678,15 @@ public class UserData { this.lastNick = lastNick; } + + public WorldTimes getWorldTimes() { + return worldTimes; + } + + public void setWorldTimes(WorldTimes worldTimes) { + this.worldTimes = worldTimes; + } + /** * Check whether or not the object should be cleared from cache after it has * been saved. @@ -794,9 +729,8 @@ public class UserData { result = 31 * result + (int) (playTime ^ (playTime >>> 32)); result = 31 * result + loginTimes; result = 31 * result + timesKicked; - result = 31 * result + (int) (lastGmSwapTime ^ (lastGmSwapTime >>> 32)); - result = 31 * result + lastGamemode.hashCode(); result = 31 * result + gmTimes.hashCode(); + result = 31 * result + worldTimes.hashCode(); result = 31 * result + (isOp ? 1 : 0); result = 31 * result + (isBanned ? 1 : 0); result = 31 * result + geolocation.hashCode(); @@ -826,7 +760,6 @@ public class UserData { && this.playTime == other.playTime && this.loginTimes == other.loginTimes && this.timesKicked == other.timesKicked - && this.lastGmSwapTime == other.lastGmSwapTime && this.mobKills == other.mobKills && this.deaths == other.deaths && Objects.equals(this.lastNick, other.lastNick) @@ -834,8 +767,8 @@ public class UserData { && Objects.equals(this.uuid, other.uuid) && Objects.equals(this.ips, other.ips) && Objects.equals(this.nicknames, other.nicknames) - && Objects.equals(this.lastGamemode, other.lastGamemode) && Objects.equals(this.gmTimes, other.gmTimes) + && Objects.equals(this.worldTimes, other.worldTimes) && Objects.equals(this.playerKills, other.playerKills) && Objects.equals(this.sessions, other.sessions); } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/handling/GamemodeHandling.java b/Plan/src/main/java/com/djrapitops/plan/data/handling/GamemodeHandling.java index ccdc241c4..84b6047f7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/handling/GamemodeHandling.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/handling/GamemodeHandling.java @@ -2,8 +2,7 @@ package main.java.com.djrapitops.plan.data.handling; import com.djrapitops.plugin.utilities.player.Gamemode; import main.java.com.djrapitops.plan.data.UserData; - -import java.util.Map; +import main.java.com.djrapitops.plan.data.time.GMTimes; /** * Class containing static methods for processing information contained in a @@ -27,20 +26,13 @@ public class GamemodeHandling { return; } final String newGamemode = newGM.name(); - String lastGamemode = data.getLastGamemode(); - if (lastGamemode == null) { - data.setLastGamemode(newGamemode); - } - lastGamemode = data.getLastGamemode(); - Map times = data.getGmTimes(); - long currentGMTime = times.getOrDefault(lastGamemode, 0L); - data.setPlayTime(data.getPlayTime() + (time - data.getLastPlayed())); + long diff = time - data.getLastPlayed(); + long playTime = data.getPlayTime() + diff; + data.setPlayTime(playTime); data.setLastPlayed(time); - long lastSwap = data.getLastGmSwapTime(); - long playtime = data.getPlayTime(); - data.setGMTime(lastGamemode, currentGMTime + (playtime - lastSwap)); - data.setLastGmSwapTime(playtime); - data.setLastGamemode(newGamemode); + + GMTimes gmTimes = data.getGmTimes(); + gmTimes.changeState(newGamemode, playTime); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/time/GMTimes.java b/Plan/src/main/java/com/djrapitops/plan/data/time/GMTimes.java new file mode 100644 index 000000000..f5e5cf38e --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/time/GMTimes.java @@ -0,0 +1,73 @@ +package main.java.com.djrapitops.plan.data.time; + +import com.djrapitops.plugin.utilities.Verify; +import main.java.com.djrapitops.plan.database.tables.GMTimesTable; + +import java.util.Map; + +/** + * TimeKeeper class that tracks the time spent in each GameMode based on Playtime. + * + * @author Rsl1122 + * @since 3.6.0 + */ +public class GMTimes extends TimeKeeper { + + public GMTimes(Map times, String lastState, long lastStateChange) { + super(times, lastState, lastStateChange); + } + + public GMTimes(String lastState, long lastStateChange) { + super(lastState, lastStateChange); + } + + public GMTimes(String lastState) { + super(lastState); + } + + public GMTimes(Map times) { + super(times); + } + + public GMTimes() { + super(); + } + + /** + * Sets times for all 4 gamemodes. + *

+ * Give 1 - 4 parameters. + * times starts from Survival, ends in Spectator. + *

+ * Given too few parameters (Under 4, rest are set as 0L) + * Extra parameters are ignored (Over 4) + * + * @param times 1-4 time parameters. + * @throws IllegalArgumentException If any parameter is null. + */ + public void setAllGMTimes(long... times) throws IllegalArgumentException { + Verify.nullCheck(times); + String[] gms = GMTimesTable.getGMKeyArray(); + int size = times.length; + for (int i = 0; i < 4; i++) { + if (i >= size) { + setTime(gms[i], 0L); + } else { + setTime(gms[i], times[i]); + } + } + } + + public void resetTimes(long playtime) { + resetState("SURVIVAL", playtime); + resetState("CREATIVE"); + resetState("ADVENTURE"); + resetState("SPECTATOR"); + } + + @Override + public String getState() { + String state = super.getState(); + return state != null ? state : "SURVIVAL"; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java b/Plan/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java new file mode 100644 index 000000000..b17c28c41 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java @@ -0,0 +1,162 @@ +package main.java.com.djrapitops.plan.data.time; + +import com.djrapitops.plugin.utilities.Verify; + +import java.util.HashMap; +import java.util.Map; + +/** + * Abstract class for keeping track of time spent in each state. + */ +public abstract class TimeKeeper { + /** + * Keeps time of states. + */ + protected Map times; + /** + * Last State seen in + */ + protected String state; + /** + * Relates to Playtime Milliseconds. + */ + protected long lastStateChange; + + public TimeKeeper(Map times, String lastState, long lastStateChange) { + this.times = times; + this.state = lastState; + this.lastStateChange = lastStateChange; + } + + public TimeKeeper(String lastState, long lastStateChange) { + this(new HashMap<>(), lastState, lastStateChange); + } + + public TimeKeeper(String lastState) { + this(new HashMap<>(), lastState, 0L); + } + + public TimeKeeper(Map times) { + this(times, null, 0); + } + + public TimeKeeper() { + this(new HashMap<>()); + } + + public void setTime(String state, long time) throws IllegalArgumentException { + times.put(Verify.nullCheck(state), time); + } + + public void renameState(String state, String renameTo) { + Verify.nullCheck(state, renameTo); + Long time = times.get(state); + if (time != null) { + times.put(renameTo, time); + times.remove(state); + if (state.equals(this.state)) { + this.state = renameTo; + } + } + } + + /** + * Adds time to the last state while updating the status of other parameters. + * + * @param newState New State seen in. + * @param playTime Current Playtime. + * @throws IllegalArgumentException If new state is null. + * @throws IllegalStateException If lastStateChange time is higher than playtime. + */ + public void changeState(String newState, long playTime) throws IllegalArgumentException, IllegalStateException { + Verify.nullCheck(newState); + if (playTime < lastStateChange) { + throw new IllegalStateException("Given Playtime is lower than last status change time: " + playTime + " / " + lastStateChange); + } + if (state == null) { + state = newState; + } + Long currentTime = times.get(state); + if (currentTime == null) { + currentTime = 0L; + } + long diff = playTime - lastStateChange; + times.put(state, currentTime + diff); + state = newState; + lastStateChange = playTime; + } + + protected void resetState(String state) { + times.remove(Verify.nullCheck(state)); + } + + protected void resetState(String state, long time) { + if (time > 0) { + times.put(Verify.nullCheck(state), time); + lastStateChange = time; + this.state = state; + } else { + resetState(state); + } + } + + public long getTime(String state) { + Long time = times.get(state); + return time != null ? time : 0L; + } + + public long getTotal() { + return times.values().stream().mapToLong(i -> i).sum(); + } + + public void setTimes(Map times) { + this.times = times; + } + + public Map getTimes() { + return times; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TimeKeeper that = (TimeKeeper) o; + + if (lastStateChange != that.lastStateChange) return false; + if (times != null ? !times.equals(that.times) : that.times != null) return false; + return state != null ? state.equals(that.state) : that.state == null; + } + + @Override + public int hashCode() { + int result = times != null ? times.hashCode() : 0; + result = 31 * result + (state != null ? state.hashCode() : 0); + result = 31 * result + (int) (lastStateChange ^ (lastStateChange >>> 32)); + return result; + } + + public void setState(String state) { + this.state = state; + } + + public void setLastStateChange(long lastStateChange) { + this.lastStateChange = lastStateChange; + } + + public String getState() { + return state; + } + + public long getLastStateChange() { + return lastStateChange; + } + + @Override + public String toString() { + return "times:" + times + + ",state:" + state + + ",lastStateChange:" + lastStateChange; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java b/Plan/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java new file mode 100644 index 000000000..7ee4e79b4 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java @@ -0,0 +1,43 @@ +package main.java.com.djrapitops.plan.data.time; + +import java.util.Map; + +/** + * TimeKeeper class that tracks the time spent in each World based on Playtime. + * + * @author Rsl1122 + * @since 3.6.0 + */ +public class WorldTimes extends TimeKeeper { + + public WorldTimes(Map times, String lastState, long lastStateChange) { + super(times, lastState, lastStateChange); + } + + public WorldTimes(String lastState, long lastStateChange) { + super(lastState, lastStateChange); + } + + public WorldTimes(String lastState) { + super(lastState); + } + + public WorldTimes(Map times, long lastStateChange) { + super(times, null, lastStateChange); + } + + public WorldTimes(Map times) { + super(times); + } + + public WorldTimes() { + super(); + } + + @Override + public String getState() { + String state = super.getState(); + return state != null ? state : "Unknown"; + } + +} diff --git a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java index f68622e8c..f122181e9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java @@ -7,6 +7,7 @@ import main.java.com.djrapitops.plan.data.KillData; import main.java.com.djrapitops.plan.data.SessionData; import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor; +import main.java.com.djrapitops.plan.data.time.WorldTimes; import main.java.com.djrapitops.plan.database.Database; import main.java.com.djrapitops.plan.database.tables.*; import main.java.com.djrapitops.plan.utilities.Benchmark; @@ -289,7 +290,15 @@ public abstract class SQLDB extends Database { return false; } int userId = usersTable.getUserId(uuid); - return userId != -1 && locationsTable.removeUserLocations(userId) && ipsTable.removeUserIps(userId) && nicknamesTable.removeUserNicknames(userId) && gmTimesTable.removeUserGMTimes(userId) && sessionsTable.removeUserSessions(userId) && killsTable.removeUserKillsAndVictims(userId) && usersTable.removeUser(uuid); + return userId != -1 + && locationsTable.removeUserLocations(userId) + && ipsTable.removeUserIps(userId) + && nicknamesTable.removeUserNicknames(userId) + && gmTimesTable.removeUserGMTimes(userId) + && sessionsTable.removeUserSessions(userId) + && killsTable.removeUserKillsAndVictims(userId) + && worldTimesTable.removeUserWorldTimes(userId) + && usersTable.removeUser(uuid); } finally { Benchmark.stop("Database: Remove Account"); setAvailable(); @@ -329,8 +338,11 @@ public abstract class SQLDB extends Database { List ips = ipsTable.getIPAddresses(userId); data.addIpAddresses(ips); - Map times = gmTimesTable.getGMTimes(userId); - data.setGmTimes(times); + Map gmTimes = gmTimesTable.getGMTimes(userId); + data.getGmTimes().setTimes(gmTimes); + Map worldTimes = worldTimesTable.getWorldTimes(userId); + data.getWorldTimes().setTimes(worldTimes); + List sessions = sessionsTable.getSessionData(userId); data.addSessions(sessions); data.setPlayerKills(killsTable.getPlayerKills(userId)); @@ -372,6 +384,7 @@ public abstract class SQLDB extends Database { Map> playerKills = killsTable.getPlayerKills(ids, idUuidRel); Map> sessionData = sessionsTable.getSessionData(ids); Map> gmTimes = gmTimesTable.getGMTimes(ids); + Map> worldTimes = worldTimesTable.getWorldTimes(ids); Log.debug("Sizes: UUID:" + uuids.size() + " DATA:" + data.size() + " ID:" + userIds.size() + " N:" + nicknames.size() + " I:" + ipList.size() + " K:" + playerKills.size() + " S:" + sessionData.size()); for (UserData uData : data) { @@ -381,7 +394,8 @@ public abstract class SQLDB extends Database { uData.addNicknames(nicknames.get(id)); uData.addSessions(sessionData.get(id)); uData.setPlayerKills(playerKills.get(id)); - uData.setGmTimes(gmTimes.get(id)); + uData.getGmTimes().setTimes(gmTimes.get(id)); + uData.getWorldTimes().setTimes(worldTimes.get(id)); } Benchmark.stop("Database: Get UserData for " + uuidsCol.size()); @@ -402,6 +416,7 @@ public abstract class SQLDB extends Database { } setStatus("Save userdata (multiple) for " + data.size()); usersTable.saveUserDataInformationBatch(data); + // Transform to map Map userDatas = data.stream().collect(Collectors.toMap(UserData::getUuid, Function.identity())); // Get UserIDs @@ -414,7 +429,15 @@ public abstract class SQLDB extends Database { Map uuids = userIds.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); Map> sessions = new HashMap<>(); Map> gmTimes = new HashMap<>(); + Map> worldTimes = new HashMap<>(); // Put to dataset + List worldNames = data.stream() + .map(UserData::getWorldTimes) + .map(WorldTimes::getTimes) + .map(Map::keySet) + .flatMap(keySet -> keySet.stream()) + .distinct() + .collect(Collectors.toList()); for (Map.Entry entrySet : userDatas.entrySet()) { UUID uuid = entrySet.getKey(); UserData uData = entrySet.getValue(); @@ -431,7 +454,8 @@ public abstract class SQLDB extends Database { ips.put(id, new HashSet<>(uData.getIps())); kills.put(id, new ArrayList<>(uData.getPlayerKills())); sessions.put(id, new ArrayList<>(uData.getSessions())); - gmTimes.put(id, uData.getGmTimes()); + gmTimes.put(id, new HashMap<>(uData.getGmTimes().getTimes())); + worldTimes.put(id, new HashMap<>(uData.getWorldTimes().getTimes())); } // Save nicknamesTable.saveNickLists(nicknames, lastNicks); @@ -439,6 +463,8 @@ public abstract class SQLDB extends Database { killsTable.savePlayerKills(kills, uuids); sessionsTable.saveSessionData(sessions); gmTimesTable.saveGMTimes(gmTimes); + worldTable.saveWorlds(worldNames); + worldTimesTable.saveWorldTimes(worldTimes); userDatas.values().stream() .filter(Objects::nonNull) .filter(UserData::isAccessed) @@ -470,7 +496,9 @@ public abstract class SQLDB extends Database { nicknamesTable.saveNickList(userId, new HashSet<>(data.getNicknames()), data.getLastNick()); ipsTable.saveIPList(userId, new HashSet<>(data.getIps())); killsTable.savePlayerKills(userId, new ArrayList<>(data.getPlayerKills())); - gmTimesTable.saveGMTimes(userId, data.getGmTimes()); + gmTimesTable.saveGMTimes(userId, data.getGmTimes().getTimes()); + worldTable.saveWorlds(new HashSet<>(data.getWorldTimes().getTimes().keySet())); + worldTimesTable.saveWorldTimes(userId, data.getWorldTimes().getTimes()); data.stopAccessing(); setAvailable(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/CommandUseTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/CommandUseTable.java index 87be9afca..a9261f919 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/CommandUseTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/CommandUseTable.java @@ -93,12 +93,12 @@ public class CommandUseTable extends Table { Map updateData = new HashMap<>(data); updateData.keySet().removeAll(newData.keySet()); - for (Map.Entry entrySet : saved.entrySet()) { - String cmd = entrySet.getKey(); + for (Map.Entry savedEntry : saved.entrySet()) { + String cmd = savedEntry.getKey(); // IMPORTANT - not using saved as value Integer toSave = updateData.get(cmd); - if (toSave != null && toSave <= entrySet.getValue()) { + if (toSave != null && toSave <= savedEntry.getValue()) { updateData.remove(cmd); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/GMTimesTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/GMTimesTable.java index 45ed051bc..c75481364 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/GMTimesTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/GMTimesTable.java @@ -1,5 +1,6 @@ package main.java.com.djrapitops.plan.database.tables; +import com.djrapitops.plugin.utilities.Verify; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.database.databases.SQLDB; import main.java.com.djrapitops.plan.utilities.Benchmark; @@ -137,7 +138,7 @@ public class GMTimesTable extends Table { * @throws SQLException */ public void saveGMTimes(int userId, Map gamemodeTimes) throws SQLException { - if (gamemodeTimes == null || gamemodeTimes.isEmpty()) { + if (Verify.isEmpty(gamemodeTimes)) { return; } PreparedStatement statement = null; @@ -191,7 +192,7 @@ public class GMTimesTable extends Table { } public void saveGMTimes(Map> gamemodeTimes) throws SQLException { - if (gamemodeTimes == null || gamemodeTimes.isEmpty()) { + if (Verify.isEmpty(gamemodeTimes)) { return; } Benchmark.start("Database: Save GMTimes"); @@ -244,12 +245,11 @@ public class GMTimesTable extends Table { } private void addNewGMTimesRows(Map> gamemodeTimes) throws SQLException { - if (gamemodeTimes == null || gamemodeTimes.isEmpty()) { + if (Verify.isEmpty(gamemodeTimes)) { return; } PreparedStatement statement = null; String[] gms = getGMKeyArray(); - try { statement = prepareStatement( "INSERT INTO " + tableName + " (" @@ -287,9 +287,11 @@ public class GMTimesTable extends Table { } private void addNewGMTimesRow(int userId, Map gamemodeTimes) throws SQLException { + if (Verify.isEmpty(gamemodeTimes)) { + return; + } PreparedStatement statement = null; String[] gms = getGMKeyArray(); - try { statement = prepareStatement("INSERT INTO " + tableName + " (" + columnUserID + ", " diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/NicknamesTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/NicknamesTable.java index b0936b6fc..ec85698b8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/NicknamesTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/NicknamesTable.java @@ -54,15 +54,7 @@ public class NicknamesTable extends Table { } private void alterTablesV3() { - String query; - if (usingMySQL) { - query = "ALTER TABLE " + tableName + " ADD " + columnCurrent + " boolean NOT NULL DEFAULT 0"; - - } else { - query = "ALTER TABLE " + tableName + " ADD COLUMN " + columnCurrent + " boolean NOT NULL DEFAULT 0"; - } - - executeUnsafe(query); + addColumns(columnCurrent + " boolean NOT NULL DEFAULT 0"); } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/TPSTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/TPSTable.java index 7f178683b..55921e575 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/TPSTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/TPSTable.java @@ -73,32 +73,15 @@ public class TPSTable extends Table { } private void alterTablesV6() { - try { - if (usingMySQL) { - execute("ALTER TABLE " + tableName + " ADD " + columnCPUUsage + " double NOT NULL DEFAULT 0"); - } else { - execute("ALTER TABLE " + tableName + " ADD COLUMN " + columnCPUUsage + " double NOT NULL DEFAULT 0"); - } - } catch (SQLException ignored) { - } + addColumns(columnCPUUsage + " double NOT NULL DEFAULT 0"); } private void alterTablesV7() { - String[] sql; - if (usingMySQL) { - sql = new String[]{ - "ALTER TABLE " + tableName + " ADD " + columnRAMUsage + " bigint NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD " + columnEntities + " integer NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD " + columnChunksLoaded + " integer NOT NULL DEFAULT 0" - }; - } else { - sql = new String[]{ - "ALTER TABLE " + tableName + " ADD COLUMN " + columnRAMUsage + " bigint NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD COLUMN " + columnEntities + " integer NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD COLUMN " + columnChunksLoaded + " integer NOT NULL DEFAULT 0" - }; - } - executeUnsafe(sql); + addColumns( + columnRAMUsage + " bigint NOT NULL DEFAULT 0", + columnEntities + " integer NOT NULL DEFAULT 0", + columnChunksLoaded + " integer NOT NULL DEFAULT 0" + ); } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java index 8172f63a1..9b36d93a2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java @@ -107,6 +107,7 @@ public abstract class Table { * @throws SQLException */ protected PreparedStatement prepareStatement(String sql) throws SQLException { + Log.debug(sql); return getConnection().prepareStatement(sql); } @@ -145,4 +146,30 @@ public abstract class Table { protected List>> splitIntoBatches(Map> objects) { return DBUtils.splitIntoBatchesId(objects); } + + protected void addColumns(String... columnInfo) { + for (int i = 0; i < columnInfo.length; i++) { + columnInfo[i] = "ALTER TABLE " + tableName + " ADD " + (usingMySQL ? "" : "COLUMN ") + columnInfo[i]; + } + executeUnsafe(columnInfo); + } + + protected void removeColumns(String... columnNames) { + if (usingMySQL) { + StringBuilder sqlBuild = new StringBuilder(); + sqlBuild.append("ALTER TABLE ").append(tableName); + for (int i = 0; i < columnNames.length; i++) { + sqlBuild.append(" DROP COLUMN ").append(columnNames[i]); + if (i < columnNames.length - 1) { + sqlBuild.append(","); + } + } + executeUnsafe(sqlBuild.toString()); + } + } + + @Override + public String toString() { + return tableName; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java index b76da386c..622c6068b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java @@ -3,11 +3,12 @@ package main.java.com.djrapitops.plan.database.tables; import com.djrapitops.plugin.utilities.player.Fetch; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.data.UserData; +import main.java.com.djrapitops.plan.data.time.GMTimes; +import main.java.com.djrapitops.plan.data.time.WorldTimes; import main.java.com.djrapitops.plan.database.DBUtils; import main.java.com.djrapitops.plan.database.databases.SQLDB; import main.java.com.djrapitops.plan.utilities.Benchmark; import main.java.com.djrapitops.plan.utilities.uuid.UUIDUtility; -import org.bukkit.GameMode; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -23,30 +24,42 @@ public class UsersTable extends Table { private final String columnID; private final String columnUUID; - /** - * @deprecated removed in 3.5.2 - */ - @Deprecated - private final String columnDemAge; - /** - * @deprecated removed in 3.5.2 - */ - @Deprecated - private final String columnDemGender; private final String columnGeolocation; private final String columnLastGM; private final String columnLastGMSwapTime; private final String columnPlayTime; private final String columnLoginTimes; private final String columnLastPlayed; - private final String columnPlayerKills; private final String columnDeaths; private final String columnMobKills; + /** + * @since 3.3.0 + */ private final String columnRegistered; + /** + * @since 3.3.0 + */ private final String columnOP; + /** + * @since 3.3.0 + */ private final String columnName; + /** + * @since 3.3.0 + */ private final String columnBanned; + /** + * @since 3.3.0 + */ private final String columnContainsBukkitData; + /** + * @since 3.6.0 + */ + private final String columnLastWorldSwapTime; + /** + * @since 3.6.0 + */ + private final String columnLastWorld; /** * @param db @@ -56,8 +69,6 @@ public class UsersTable extends Table { super("plan_users", db, usingMySQL); columnID = "id"; columnUUID = "uuid"; - columnDemAge = "age"; - columnDemGender = "gender"; columnGeolocation = "geolocation"; columnLastGM = "last_gamemode"; columnLastGMSwapTime = "last_gamemode_swap"; @@ -65,14 +76,16 @@ public class UsersTable extends Table { columnLoginTimes = "login_times"; columnLastPlayed = "last_played"; columnMobKills = "mob_kills"; - columnPlayerKills = "player_kills"; // Removed in 2.7.0 + columnDeaths = "deaths"; - // Added in 3.3.0 columnRegistered = "registered"; columnOP = "opped"; columnName = "name"; columnBanned = "banned"; columnContainsBukkitData = "contains_bukkit_data"; + + columnLastWorldSwapTime = "last_world_swap"; + columnLastWorld = "last_world"; } /** @@ -96,7 +109,9 @@ public class UsersTable extends Table { + columnOP + " boolean NOT NULL DEFAULT 0, " + columnName + " varchar(16) NOT NULL, " + columnBanned + " boolean NOT NULL DEFAULT 0, " - + columnContainsBukkitData + " boolean NOT NULL DEFAULT 0" + + columnContainsBukkitData + " boolean NOT NULL DEFAULT 0, " + + columnLastWorld + " varchar(255) NOT NULL, " + + columnLastWorldSwapTime + " bigint NOT NULL" + (usingMySQL ? ", PRIMARY KEY (" + columnID + ")" : "") + ")" ); @@ -110,6 +125,9 @@ public class UsersTable extends Table { if (version < 5) { alterTablesV5(); } + if (version < 8) { + alterTablesV8(); + } return true; } catch (SQLException ex) { Log.toLog(this.getClass().getName(), ex); @@ -117,54 +135,33 @@ public class UsersTable extends Table { } } + private void alterTablesV8() { + addColumns( + columnLastWorldSwapTime + " bigint NOT NULL DEFAULT 0", + columnLastWorld + " varchar(255) NOT NULL DEFAULT 'Unknown'" + ); + } + private void alterTablesV5() { - if (usingMySQL) { - try { - execute("ALTER TABLE " + tableName - + " DROP COLUMN " + columnDemAge + "," - + " DROP COLUMN " + columnDemGender); - } catch (Exception ignored) { - } - } + removeColumns("age", "gender"); } private void alterTablesV4() { - String[] statements; - if (usingMySQL) { - statements = new String[]{ - "ALTER TABLE " + tableName + " ADD " + columnContainsBukkitData + " boolean NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD " + columnOP + " boolean NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD " + columnBanned + " boolean NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD " + columnName + " varchar(16) NOT NULL DEFAULT \'Unknown\'", - "ALTER TABLE " + tableName + " ADD " + columnRegistered + " bigint NOT NULL DEFAULT 0" - }; - } else { - statements = new String[]{ - "ALTER TABLE " + tableName + " ADD COLUMN " + columnContainsBukkitData + " boolean NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD COLUMN " + columnOP + " boolean NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD COLUMN " + columnBanned + " boolean NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD COLUMN " + columnName + " varchar(16) NOT NULL DEFAULT \'Unknown\'", - "ALTER TABLE " + tableName + " ADD COLUMN " + columnRegistered + " bigint NOT NULL DEFAULT 0" - }; - } - executeUnsafe(statements); + addColumns( + columnContainsBukkitData + " boolean NOT NULL DEFAULT 0", + columnOP + " boolean NOT NULL DEFAULT 0", + columnBanned + " boolean NOT NULL DEFAULT 0", + columnName + " varchar(16) NOT NULL DEFAULT 'Unknown'", + columnRegistered + " bigint NOT NULL DEFAULT 0" + ); } private void alterTablesV3() { - String[] statements; - if (usingMySQL) { - statements = new String[]{ - "ALTER TABLE " + tableName + " ADD " + columnDeaths + " integer NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD " + columnMobKills + " integer NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " DROP INDEX " + columnPlayerKills - }; - } else { - statements = new String[]{ - "ALTER TABLE " + tableName + " ADD COLUMN " + columnDeaths + " integer NOT NULL DEFAULT 0", - "ALTER TABLE " + tableName + " ADD COLUMN " + columnMobKills + " integer NOT NULL DEFAULT 0" - }; - } - executeUnsafe(statements); + addColumns( + columnDeaths + " integer NOT NULL DEFAULT 0", + columnMobKills + " integer NOT NULL DEFAULT 0" + ); + removeColumns("player_kills"); } /** @@ -383,14 +380,19 @@ public class UsersTable extends Table { long registered = set.getLong(columnRegistered); UserData data = new UserData(uuid, registered, op, gm, name, false); data.setBanned(banned); - data.setLastGamemode(gm); data.setGeolocation(set.getString(columnGeolocation)); - data.setLastGmSwapTime(set.getLong(columnLastGMSwapTime)); + data.getGmTimes().setLastStateChange(set.getLong(columnLastGMSwapTime)); data.setPlayTime(set.getLong(columnPlayTime)); data.setLoginTimes(set.getInt(columnLoginTimes)); data.setLastPlayed(set.getLong(columnLastPlayed)); data.setDeaths(set.getInt(columnDeaths)); data.setMobKills(set.getInt(columnMobKills)); + WorldTimes worldTimes = data.getWorldTimes(); + worldTimes.setLastStateChange(set.getLong(columnLastWorldSwapTime)); + String lastWorld = set.getString(columnLastWorld); + if (!"Unknown".equals(lastWorld)) { + worldTimes.setState(lastWorld); + } return data; } } finally { @@ -422,14 +424,19 @@ public class UsersTable extends Table { long registered = set.getLong(columnRegistered); UserData data = new UserData(uuid, registered, op, gm, name, false); data.setBanned(banned); - data.setLastGamemode(gm); data.setGeolocation(set.getString(columnGeolocation)); - data.setLastGmSwapTime(set.getLong(columnLastGMSwapTime)); + data.getGmTimes().setLastStateChange(set.getLong(columnLastGMSwapTime)); data.setPlayTime(set.getLong(columnPlayTime)); data.setLoginTimes(set.getInt(columnLoginTimes)); data.setLastPlayed(set.getLong(columnLastPlayed)); data.setDeaths(set.getInt(columnDeaths)); data.setMobKills(set.getInt(columnMobKills)); + WorldTimes worldTimes = data.getWorldTimes(); + worldTimes.setLastStateChange(set.getLong(columnLastWorldSwapTime)); + String lastWorld = set.getString(columnLastWorld); + if (!"Unknown".equals(lastWorld)) { + worldTimes.setState(lastWorld); + } datas.add(data); } } finally { @@ -454,13 +461,20 @@ public class UsersTable extends Table { set = statement.executeQuery(); while (set.next()) { data.setGeolocation(set.getString(columnGeolocation)); - data.setLastGamemode(set.getString(columnLastGM)); - data.setLastGmSwapTime(set.getLong(columnLastGMSwapTime)); + GMTimes gmTimes = data.getGmTimes(); + gmTimes.setState(set.getString(columnLastGM)); + gmTimes.setLastStateChange(set.getLong(columnLastGMSwapTime)); data.setPlayTime(set.getLong(columnPlayTime)); data.setLoginTimes(set.getInt(columnLoginTimes)); data.setLastPlayed(set.getLong(columnLastPlayed)); data.setDeaths(set.getInt(columnDeaths)); data.setMobKills(set.getInt(columnMobKills)); + WorldTimes worldTimes = data.getWorldTimes(); + worldTimes.setLastStateChange(set.getLong(columnLastWorldSwapTime)); + String lastWorld = set.getString(columnLastWorld); + if (!"Unknown".equals(lastWorld)) { + worldTimes.setState(lastWorld); + } } } finally { close(set); @@ -489,13 +503,20 @@ public class UsersTable extends Table { } UserData uData = userDatas.get(uuid); uData.setGeolocation(set.getString(columnGeolocation)); - uData.setLastGamemode(set.getString(columnLastGM)); - uData.setLastGmSwapTime(set.getLong(columnLastGMSwapTime)); uData.setPlayTime(set.getLong(columnPlayTime)); uData.setLoginTimes(set.getInt(columnLoginTimes)); uData.setLastPlayed(set.getLong(columnLastPlayed)); uData.setDeaths(set.getInt(columnDeaths)); uData.setMobKills(set.getInt(columnMobKills)); + GMTimes gmTimes = uData.getGmTimes(); + gmTimes.setState(set.getString(columnLastGM)); + gmTimes.setLastStateChange(set.getLong(columnLastGMSwapTime)); + WorldTimes worldTimes = uData.getWorldTimes(); + worldTimes.setLastStateChange(set.getLong(columnLastWorldSwapTime)); + String lastWorld = set.getString(columnLastWorld); + if (!"Unknown".equals(lastWorld)) { + worldTimes.setState(lastWorld); + } } } finally { close(set); @@ -537,7 +558,10 @@ public class UsersTable extends Table { statement.setBoolean(11, data.isBanned()); statement.setString(12, data.getName()); statement.setLong(13, data.getRegistered()); - statement.setString(14, uuid.toString()); + WorldTimes worldTimes = data.getWorldTimes(); + statement.setString(14, worldTimes.getState()); + statement.setLong(15, worldTimes.getLastStateChange()); + statement.setString(16, uuid.toString()); update = statement.executeUpdate(); } if (update == 0) { @@ -546,13 +570,9 @@ public class UsersTable extends Table { statement.setString(1, uuid.toString()); statement.setString(2, data.getGeolocation()); - String gm = data.getLastGamemode(); - if (gm != null) { - statement.setString(3, gm); - } else { - statement.setString(3, "SURVIVAL"); - } - statement.setLong(4, data.getLastGmSwapTime()); + GMTimes gmTimes = data.getGmTimes(); + statement.setString(3, gmTimes.getState()); + statement.setLong(4, gmTimes.getLastStateChange()); statement.setLong(5, data.getPlayTime()); statement.setInt(6, data.getLoginTimes()); statement.setLong(7, data.getLastPlayed()); @@ -563,6 +583,9 @@ public class UsersTable extends Table { statement.setBoolean(12, data.isBanned()); statement.setString(13, data.getName()); statement.setLong(14, data.getRegistered()); + WorldTimes worldTimes = data.getWorldTimes(); + statement.setString(15, worldTimes.getState()); + statement.setLong(16, worldTimes.getLastStateChange()); statement.execute(); } } finally { @@ -579,7 +602,7 @@ public class UsersTable extends Table { ResultSet set = null; try { try { - statement = prepareStatement("SELECT " + columnDemAge + " FROM " + tableName + " LIMIT 1"); + statement = prepareStatement("SELECT age FROM " + tableName + " LIMIT 1"); set = statement.executeQuery(); Log.debug("UsersTable has V4 columns."); return true; @@ -594,7 +617,7 @@ public class UsersTable extends Table { private String getInsertStatement() { final boolean hasV4Columns = tableHasV4Columns(); - String v4rows = hasV4Columns ? columnDemAge + ", " + columnDemGender + ", " : ""; + String v4rows = hasV4Columns ? "age, gender, " : ""; String v4values = hasV4Columns ? "-1, Deprecated, " : ""; return "INSERT INTO " + tableName + " (" + v4rows @@ -611,13 +634,15 @@ public class UsersTable extends Table { + columnOP + ", " + columnBanned + ", " + columnName + ", " - + columnRegistered - + ") VALUES (" + v4values + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + columnRegistered + ", " + + columnLastWorld + ", " + + columnLastWorldSwapTime + + ") VALUES (" + v4values + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; } private String getUpdateStatement() { final boolean hasV4Columns = tableHasV4Columns(); - String v4rows = hasV4Columns ? columnDemAge + "=-1, " + columnDemGender + "='Deprecated', " : ""; + String v4rows = hasV4Columns ? "age=-1, gender='Deprecated', " : ""; return "UPDATE " + tableName + " SET " + v4rows + columnGeolocation + "=?, " @@ -632,7 +657,9 @@ public class UsersTable extends Table { + columnOP + "=?, " + columnBanned + "=?, " + columnName + "=?, " - + columnRegistered + "=? " + + columnRegistered + "=?, " + + columnLastWorld + "=?, " + + columnLastWorldSwapTime + "=? " + "WHERE " + columnUUID + "=?"; } @@ -665,13 +692,9 @@ public class UsersTable extends Table { UUID uuid = uData.getUuid(); statement.setString(1, uuid.toString()); statement.setString(2, uData.getGeolocation()); - String gm = uData.getLastGamemode(); - if (gm != null) { - statement.setString(3, gm); - } else { - statement.setString(3, "SURVIVAL"); - } - statement.setLong(4, uData.getLastGmSwapTime()); + GMTimes gmTimes = uData.getGmTimes(); + statement.setString(3, gmTimes.getState()); + statement.setLong(4, gmTimes.getLastStateChange()); statement.setLong(5, uData.getPlayTime()); statement.setInt(6, uData.getLoginTimes()); statement.setLong(7, uData.getLastPlayed()); @@ -682,6 +705,9 @@ public class UsersTable extends Table { statement.setBoolean(12, uData.isBanned()); statement.setString(13, uData.getName()); statement.setLong(14, uData.getRegistered()); + WorldTimes worldTimes = uData.getWorldTimes(); + statement.setString(15, worldTimes.getState()); + statement.setLong(16, worldTimes.getLastStateChange()); statement.addBatch(); commitRequired = true; i++; @@ -728,13 +754,9 @@ public class UsersTable extends Table { } uData.access(); statement.setString(1, uData.getGeolocation()); - String gm = uData.getLastGamemode(); - if (gm != null) { - statement.setString(2, gm); - } else { - statement.setString(2, GameMode.SURVIVAL.name()); - } - statement.setLong(3, uData.getLastGmSwapTime()); + GMTimes gmTimes = uData.getGmTimes(); + statement.setString(2, gmTimes.getState()); + statement.setLong(3, uData.getGmTimes().getLastStateChange()); statement.setLong(4, uData.getPlayTime()); statement.setInt(5, uData.getLoginTimes()); statement.setLong(6, uData.getLastPlayed()); @@ -745,7 +767,10 @@ public class UsersTable extends Table { statement.setBoolean(11, uData.isBanned()); statement.setString(12, uData.getName()); statement.setLong(13, uData.getRegistered()); - statement.setString(14, uuid.toString()); + WorldTimes worldTimes = uData.getWorldTimes(); + statement.setString(14, worldTimes.getState()); + statement.setLong(15, worldTimes.getLastStateChange()); + statement.setString(16, uuid.toString()); statement.addBatch(); uData.stopAccessing(); commitRequired = true; diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTable.java index a0e658815..2a0dc0154 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTable.java @@ -8,6 +8,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -82,7 +83,7 @@ public class WorldTable extends Table { * @param worlds List of world names. * @throws SQLException Database error occurs. */ - public void saveWorlds(List worlds) throws SQLException { + public void saveWorlds(Collection worlds) throws SQLException { Verify.nullCheck(worlds); List saved = getWorlds(); @@ -113,4 +114,10 @@ public class WorldTable extends Table { public String getColumnID() { return columnWorldId; } + + public String getColumnWorldName() { + return columnWorldName; + } + + } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTimesTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTimesTable.java index 9f35a2263..c246b2de3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTimesTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTimesTable.java @@ -1,9 +1,15 @@ package main.java.com.djrapitops.plan.database.tables; +import com.djrapitops.plugin.utilities.Verify; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.database.databases.SQLDB; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; /** * Table class representing database table plan_world_times. @@ -14,11 +20,15 @@ import java.sql.SQLException; public class WorldTimesTable extends Table { private final WorldTable worldTable; + private final String worldIDColumn; + private final String worldNameColumn; private final String columnWorldId; - private final String columnUserId; + private final String columnUserID; private final String columnPlaytime; + private final String selectWorldIDsql; + /** * Constructor. * @@ -28,9 +38,13 @@ public class WorldTimesTable extends Table { public WorldTimesTable(SQLDB db, boolean usingMySQL) { super("plan_world_times", db, usingMySQL); worldTable = db.getWorldTable(); + worldIDColumn = worldTable + "." + worldTable.getColumnID(); + worldNameColumn = worldTable.getColumnWorldName(); columnWorldId = "world_id"; - columnUserId = "user_id"; + columnUserID = "user_id"; columnPlaytime = "playtime"; + + selectWorldIDsql = "(SELECT " + worldIDColumn + " FROM " + worldTable + " WHERE (" + worldNameColumn + "=?))"; } @Override @@ -38,10 +52,10 @@ public class WorldTimesTable extends Table { UsersTable usersTable = db.getUsersTable(); try { execute("CREATE TABLE IF NOT EXISTS " + tableName + " (" - + columnUserId + " integer NOT NULL, " + + columnUserID + " integer NOT NULL, " + columnWorldId + " integer NOT NULL, " + columnPlaytime + " bigint NOT NULL, " - + "FOREIGN KEY(" + columnUserId + ") REFERENCES " + usersTable.getTableName() + "(" + usersTable.getColumnID() + "), " + + "FOREIGN KEY(" + columnUserID + ") REFERENCES " + usersTable.getTableName() + "(" + usersTable.getColumnID() + "), " + "FOREIGN KEY(" + columnWorldId + ") REFERENCES " + worldTable.getTableName() + "(" + worldTable.getColumnID() + ")" + ")" ); @@ -51,4 +65,261 @@ public class WorldTimesTable extends Table { return false; } } + + public boolean removeUserWorldTimes(int userId) { + PreparedStatement statement = null; + try { + statement = prepareStatement("DELETE FROM " + tableName + " WHERE (" + columnUserID + "=?)"); + statement.setInt(1, userId); + statement.execute(); + return true; + } catch (SQLException ex) { + Log.toLog(this.getClass().getName(), ex); + return false; + } finally { + close(statement); + } + } + + /** + * @param userId + * @return + * @throws SQLException + */ + public Map getWorldTimes(int userId) throws SQLException { + PreparedStatement statement = null; + ResultSet set = null; + try { + statement = prepareStatement("SELECT " + + columnPlaytime + ", " + + worldNameColumn + + " FROM " + tableName + ", " + worldTable + + " WHERE (" + columnUserID + "=?)" + + " AND (" + worldIDColumn + "=" + tableName + "." + columnWorldId + ")"); + statement.setInt(1, userId); + set = statement.executeQuery(); + HashMap times = new HashMap<>(); + while (set.next()) { + times.put(set.getString(worldNameColumn), set.getLong(columnPlaytime)); + } + return times; + } finally { + close(set); + close(statement); + } + } + + public Map> getWorldTimes(Collection userIds) throws SQLException { + PreparedStatement statement = null; + ResultSet set = null; + Map> times = new HashMap<>(); + for (Integer id : userIds) { + times.put(id, new HashMap<>()); + } + try { + statement = prepareStatement("SELECT " + + columnUserID + ", " + + columnPlaytime + ", " + + worldNameColumn + + " FROM " + tableName + ", " + worldTable + + " WHERE (" + worldIDColumn + "=" + tableName + "." + columnWorldId + ")"); + set = statement.executeQuery(); + while (set.next()) { + int id = set.getInt(columnUserID); + if (!userIds.contains(id)) { + continue; + } + Map worldTimes = times.get(id); + worldTimes.put(set.getString(worldNameColumn), set.getLong(columnPlaytime)); + } + return times; + } finally { + close(set); + close(statement); + } + } + + public void saveWorldTimes(int userId, Map worldTimes) throws SQLException { + if (Verify.isEmpty(worldTimes)) { + return; + } + Map saved = getWorldTimes(userId); + + Map newData = new HashMap<>(); + Map updateData = new HashMap<>(); + + for (Map.Entry entry : worldTimes.entrySet()) { + String world = entry.getKey(); + long time = entry.getValue(); + Long savedTime = saved.get(world); + + if (savedTime == null) { + newData.put(world, time); + } else { + if (savedTime < time) { + updateData.put(world, time); + } + } + } + insertWorlds(userId, newData); + updateWorlds(userId, updateData); + } + + private void updateWorlds(int userId, Map updateData) throws SQLException { + if (Verify.isEmpty(updateData)) { + return; + } + PreparedStatement statement = null; + try { + statement = prepareStatement( + "UPDATE " + tableName + " SET " + columnPlaytime + "=?" + + " WHERE (" + selectWorldIDsql + "=" + columnWorldId + ")" + + " AND (" + columnUserID + "=?)" + ); + boolean commitRequired = false; + for (Map.Entry entry : updateData.entrySet()) { + String worldName = entry.getKey(); + long time = entry.getValue(); + statement.setLong(1, time); + statement.setString(2, worldName); + statement.setInt(3, userId); + statement.addBatch(); + commitRequired = true; + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } + + private void insertWorlds(int userId, Map newData) throws SQLException { + if (Verify.isEmpty(newData)) { + return; + } + PreparedStatement statement = null; + try { + statement = prepareStatement( + "INSERT INTO " + tableName + " (" + + columnUserID + ", " + + columnWorldId + ", " + + columnPlaytime + + ") VALUES (?, " + selectWorldIDsql + ", ?)" + ); + boolean commitRequired = false; + for (Map.Entry entry : newData.entrySet()) { + String worldName = entry.getKey(); + long time = entry.getValue(); + statement.setInt(1, userId); + statement.setString(2, worldName); + statement.setLong(3, time); + statement.addBatch(); + commitRequired = true; + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } + + public void saveWorldTimes(Map> worldTimesMultiple) throws SQLException { + if (Verify.isEmpty(worldTimesMultiple)) { + return; + } + Map> saved = getWorldTimes(worldTimesMultiple.keySet()); + + Map> newData = new HashMap<>(); + Map> updateData = new HashMap<>(); + + for (Map.Entry> entry : worldTimesMultiple.entrySet()) { + int userId = entry.getKey(); + Map savedTimes = saved.get(userId); + Map worldTimes = entry.getValue(); + Map newTimes = new HashMap<>(worldTimes); + newTimes.keySet().removeAll(savedTimes.keySet()); + + newData.put(userId, newTimes); + + for (Map.Entry times : savedTimes.entrySet()) { + String world = times.getKey(); + long savedTime = times.getValue(); + Long toSave = worldTimes.get(world); + if (toSave != null && toSave <= savedTime) { + worldTimes.remove(world); + } + } + updateData.put(userId, worldTimes); + } + insertWorlds(newData); + updateWorlds(updateData); + } + + private void updateWorlds(Map> updateData) throws SQLException { + if (Verify.isEmpty(updateData)) { + return; + } + PreparedStatement statement = null; + try { + statement = prepareStatement( + "UPDATE " + tableName + " SET " + columnPlaytime + "=?" + + " WHERE (" + selectWorldIDsql + "=" + columnWorldId + ")" + + " AND (" + columnUserID + "=?)" + ); + boolean commitRequired = false; + for (Map.Entry> entry : updateData.entrySet()) { + int userId = entry.getKey(); + for (Map.Entry times : entry.getValue().entrySet()) { + String worldName = times.getKey(); + long time = times.getValue(); + statement.setLong(1, time); + statement.setString(2, worldName); + statement.setInt(3, userId); + statement.addBatch(); + commitRequired = true; + } + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } + + private void insertWorlds(Map> newData) throws SQLException { + if (Verify.isEmpty(newData)) { + return; + } + PreparedStatement statement = null; + try { + statement = prepareStatement( + "INSERT INTO " + tableName + " (" + + columnUserID + ", " + + columnWorldId + ", " + + columnPlaytime + + ") VALUES (?, " + selectWorldIDsql + ", ?)" + ); + boolean commitRequired = false; + for (Map.Entry> entry : newData.entrySet()) { + int userId = entry.getKey(); + for (Map.Entry times : entry.getValue().entrySet()) { + String worldName = times.getKey(); + long time = times.getValue(); + statement.setInt(1, userId); + statement.setString(2, worldName); + statement.setLong(3, time); + statement.addBatch(); + commitRequired = true; + } + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/NewPlayerCreator.java b/Plan/src/main/java/com/djrapitops/plan/utilities/NewPlayerCreator.java index de8738637..2ca0b656c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/NewPlayerCreator.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/NewPlayerCreator.java @@ -46,13 +46,11 @@ public class NewPlayerCreator { */ public static UserData createNewPlayer(IOfflinePlayer player, Gamemode gm) { long registered = player.getFirstPlayed(); - UserData data = new UserData(player.getUniqueId(), registered, player.isOp(), "SURVIVAL", player.getName(), player.isOnline()); - data.setLastGamemode(gm.name()); + UserData data = new UserData(player.getUniqueId(), registered, player.isOp(), gm.name(), player.getName(), player.isOnline()); data.setLastPlayed(MiscUtils.getTime()); data.setPlayTime(0L); data.setTimesKicked(0); data.setLoginTimes(0); - data.setLastGmSwapTime(0L); data.setDeaths(0); data.setMobKills(0); data.setBanned(false); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/PlaceholderUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/PlaceholderUtils.java index ef3268468..5ee6e5871 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/PlaceholderUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/PlaceholderUtils.java @@ -6,6 +6,7 @@ import main.java.com.djrapitops.plan.data.AnalysisData; import main.java.com.djrapitops.plan.data.SessionData; import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.data.analysis.GamemodePart; +import main.java.com.djrapitops.plan.database.tables.GMTimesTable; import main.java.com.djrapitops.plan.ui.html.Html; import main.java.com.djrapitops.plan.ui.html.graphs.PlayerActivityGraphCreator; import main.java.com.djrapitops.plan.ui.html.graphs.PunchCardGraphCreator; @@ -77,8 +78,8 @@ public class PlaceholderUtils { boolean isActive = AnalysisUtils.isActive(now, data.getLastPlayed(), data.getPlayTime(), data.getLoginTimes()); replaceMap.put("%active%", isActive ? Html.ACTIVE.parse() : Html.INACTIVE.parse()); GamemodePart gmPart = new GamemodePart(); - Map gmTimes = data.getGmTimes(); - String[] gms = new String[]{"SURVIVAL", "CREATIVE", "ADVENTURE", "SPECTATOR"}; + Map gmTimes = data.getGmTimes().getTimes(); + String[] gms = GMTimesTable.getGMKeyArray(); for (String gm : gms) { Long time = gmTimes.get(gm); if (time != null) { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java index 7f474fa76..6f0f27385 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java @@ -262,7 +262,7 @@ public class Analysis { Benchmark.start("Analysis: Fill Dataset"); rawData.forEach(uData -> { uData.access(); - Map gmTimes = uData.getGmTimes(); + Map gmTimes = uData.getGmTimes().getTimes(); String[] gms = new String[]{"SURVIVAL", "CREATIVE", "ADVENTURE", "SPECTATOR"}; if (gmTimes != null) { for (String gm : gms) { diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/UserDataTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/UserDataTest.java index 1b192d1c8..3fa5a8ba2 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/data/UserDataTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/UserDataTest.java @@ -16,7 +16,9 @@ import test.java.utils.TestInit; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -142,45 +144,6 @@ public class UserDataTest { assertTrue("Added something", test.getNicknames().isEmpty()); } - /** - * - */ - @Test - public void testSetGMTime() { - test.setGMTime("SURVIVAL", 1L); - final Long result = test.getGmTimes().get("SURVIVAL"); - assertTrue("" + result, result == 1L); - } - - /** - * - */ - @Test - public void testSetGMTimeWhenGMTimesNull() { - test.setGmTimes(null); - String gm = "SURVIVAL"; - test.setGMTime(gm, 1L); - final Long result = test.getGmTimes().get(gm); - assertTrue("" + result, result == 1L); - } - - /** - * - */ - @Test - public void testSetAllGMTimes() { - HashMap gmTimes = new HashMap<>(); - gmTimes.put(null, 0L); - test.setGmTimes(gmTimes); - test.setAllGMTimes(1L, 2L, 3L, 4L); - Map times = test.getGmTimes(); - assertTrue("Cleared gmTimes", !times.containsKey(null)); - assertTrue("Not equal 0", times.get("SURVIVAL") == 1L); - assertTrue("Not equal 1", times.get("CREATIVE") == 2L); - assertTrue("Not equal 2", times.get("ADVENTURE") == 3L); - assertTrue("Not equal 3", times.get("SPECTATOR") == 4L); - } - /** * */ @@ -238,16 +201,6 @@ public class UserDataTest { assertTrue("Added something", test.getSessions().isEmpty()); } - /** - * - */ - @Test - public void testSetCurrentSession() { - SessionData s = new SessionData(0); - test.setCurrentSession(s); - assertEquals(test.getCurrentSession(), s); - } - /** * */ diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/GamemodeHandlingTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/GamemodeHandlingTest.java index 1a3dd2b67..d33b17b27 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/GamemodeHandlingTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/GamemodeHandlingTest.java @@ -8,6 +8,7 @@ package test.java.main.java.com.djrapitops.plan.data.handling; import com.djrapitops.plugin.utilities.player.Gamemode; import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.data.handling.GamemodeHandling; +import main.java.com.djrapitops.plan.data.time.GMTimes; import org.junit.Before; import org.junit.Test; import test.java.utils.MockUtils; @@ -39,12 +40,11 @@ public class GamemodeHandlingTest { public void testProcessGamemodeInfo() { UserData data = MockUtils.mockUser(); data.setPlayTime(100L); - data.setLastGamemode("CREATIVE"); - data.setLastGmSwapTime(50L); + data.setGmTimes(new GMTimes("CREATIVE", 50L)); data.setLastPlayed(1000L); long time = 2000L; GamemodeHandling.processGamemodeInfo(data, time, Gamemode.SURVIVAL); - Long result = data.getGmTimes().get(Gamemode.CREATIVE.name()); + Long result = data.getGmTimes().getTime("CREATIVE"); assertTrue("Gamemode time was " + result, result == 1050L); result = data.getPlayTime(); assertTrue("Playtime was" + result, result == 1100L); @@ -63,12 +63,11 @@ public class GamemodeHandlingTest { public void testProcessGamemodeInfoSameGM() { UserData data = MockUtils.mockUser(); data.setPlayTime(100L); - data.setLastGamemode("SURVIVAL"); - data.setLastGmSwapTime(50L); + data.setGmTimes(new GMTimes("SURVIVAL", 50L)); data.setLastPlayed(1000L); long time = 2000L; GamemodeHandling.processGamemodeInfo(data, time, Gamemode.SURVIVAL); - Long result = data.getGmTimes().get(Gamemode.SURVIVAL.name()); + Long result = data.getGmTimes().getTime("SURVIVAL"); assertTrue("Gamemode time was " + result, result == 1050L); result = data.getPlayTime(); assertTrue("Playtime was" + result, result == 1100L); @@ -87,12 +86,11 @@ public class GamemodeHandlingTest { public void testProcessGamemodeInfoNullNewGM() { UserData data = MockUtils.mockUser(); data.setPlayTime(100L); - data.setLastGamemode("SURVIVAL"); - data.setLastGmSwapTime(50L); + data.setGmTimes(new GMTimes("SURVIVAL", 50L)); data.setLastPlayed(1000L); long time = 2000L; GamemodeHandling.processGamemodeInfo(data, time, null); - Long result = data.getGmTimes().get(Gamemode.SURVIVAL.name()); + Long result = data.getGmTimes().getTime("SURVIVAL"); assertTrue("Gamemode time was " + result, result == 0L); result = data.getPlayTime(); assertTrue("Playtime was" + result, result == 100L); @@ -111,12 +109,11 @@ public class GamemodeHandlingTest { public void testProcessGamemodeInfoNullOldGM() { UserData data = MockUtils.mockUser(); data.setPlayTime(100L); - data.setLastGamemode(null); - data.setLastGmSwapTime(50L); + data.setGmTimes(new GMTimes(null, 50L)); data.setLastPlayed(1000L); long time = 2000L; GamemodeHandling.processGamemodeInfo(data, time, Gamemode.SURVIVAL); - Long result = data.getGmTimes().get(Gamemode.SURVIVAL.name()); + Long result = data.getGmTimes().getTime(Gamemode.SURVIVAL.name()); assertTrue("Gamemode time was " + result, result == 1050L); result = data.getPlayTime(); assertTrue("Playtime was" + result, result == 1100L); @@ -127,30 +124,4 @@ public class GamemodeHandlingTest { result = data.getLastGmSwapTime(); assertTrue("Last swaptime was " + result, result == 1100L); } - - /** - * - */ - @Test - public void testProcessGamemodeInfoNullGMTimes() { - UserData data = MockUtils.mockUser(); - data.setGmTimes(null); - data.setPlayTime(100L); - data.setLastGamemode(null); - data.setLastGmSwapTime(50L); - data.setLastPlayed(1000L); - long time = 2000L; - GamemodeHandling.processGamemodeInfo(data, time, Gamemode.SURVIVAL); - Long result = data.getGmTimes().get(Gamemode.SURVIVAL.name()); - assertTrue("Gamemode time was " + result, result == 1050L); - result = data.getPlayTime(); - assertTrue("Playtime was" + result, result == 1100L); - result = data.getLastPlayed(); - assertTrue("Last Played was" + result, result == 2000L); - String lastGM = data.getLastGamemode(); - assertTrue("Last gm not Survival", "SURVIVAL".equals(lastGM)); - result = data.getLastGmSwapTime(); - assertTrue("Last swaptime was " + result, result == 1100L); - } - } diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/GamemodeInfoTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/GamemodeInfoTest.java index ff1d1642c..ef240b6e5 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/GamemodeInfoTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/GamemodeInfoTest.java @@ -8,6 +8,7 @@ package test.java.main.java.com.djrapitops.plan.data.handling.info; import com.djrapitops.plugin.utilities.player.Gamemode; import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.data.handling.info.GamemodeInfo; +import main.java.com.djrapitops.plan.data.time.GMTimes; import org.junit.Before; import org.junit.Test; import test.java.utils.MockUtils; @@ -39,13 +40,12 @@ public class GamemodeInfoTest { public void testProcess() { UserData data = MockUtils.mockUser(); data.setPlayTime(100L); - data.setLastGamemode("CREATIVE"); - data.setLastGmSwapTime(50L); + data.setGmTimes(new GMTimes("CREATIVE", 50L)); data.setLastPlayed(1000L); long time = 2000L; GamemodeInfo i = new GamemodeInfo(data.getUuid(), time, Gamemode.SURVIVAL); assertTrue(i.process(data)); - Long result = data.getGmTimes().get(Gamemode.CREATIVE.name()); + Long result = data.getGmTimes().getTime(Gamemode.CREATIVE.name()); assertTrue("Gamemode time was " + result, result == 1050L); result = data.getPlayTime(); assertTrue("Playtime was" + result, result == 1100L); @@ -64,13 +64,12 @@ public class GamemodeInfoTest { public void testProcessWrongUUID() { UserData data = MockUtils.mockUser(); data.setPlayTime(100L); - data.setLastGamemode("CREATIVE"); - data.setLastGmSwapTime(50L); + data.setGmTimes(new GMTimes("CREATIVE", 50L)); data.setLastPlayed(1000L); long time = 2000L; GamemodeInfo i = new GamemodeInfo(null, time, Gamemode.SURVIVAL); assertTrue(!i.process(data)); - Long result = data.getGmTimes().get(Gamemode.CREATIVE.name()); + Long result = data.getGmTimes().getTime(Gamemode.CREATIVE.name()); assertTrue("Gamemode time was " + result, result == 0L); result = data.getPlayTime(); assertTrue("Playtime was" + result, result == 100L); @@ -89,13 +88,12 @@ public class GamemodeInfoTest { public void testProcessNullGM() { UserData data = MockUtils.mockUser(); data.setPlayTime(100L); - data.setLastGamemode("CREATIVE"); - data.setLastGmSwapTime(50L); + data.setGmTimes(new GMTimes("CREATIVE", 50L)); data.setLastPlayed(1000L); long time = 2000L; GamemodeInfo i = new GamemodeInfo(data.getUuid(), time, null); assertTrue(!i.process(data)); - Long result = data.getGmTimes().get(Gamemode.CREATIVE.name()); + Long result = data.getGmTimes().getTime(Gamemode.CREATIVE.name()); assertTrue("Gamemode time was " + result, result == 0L); result = data.getPlayTime(); assertTrue("Playtime was" + result, result == 100L); diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/LogoutInfoTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/LogoutInfoTest.java index 7215eb344..3334e545c 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/LogoutInfoTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/LogoutInfoTest.java @@ -43,7 +43,7 @@ public class LogoutInfoTest { data.setLastPlayed(10L); data.updateBanned(false); long time = 20L; - data.setLastGamemode("SURVIVAL"); + data.getGmTimes().setState("SURVIVAL"); LogoutInfo i = new LogoutInfo(data.getUuid(), time, true, Gamemode.CREATIVE, new SessionData(0, 1)); assertTrue(i.process(data)); assertTrue("Last Played wrong", data.getLastPlayed() == 20L); diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/ReloadInfoTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/ReloadInfoTest.java index dd405622f..29e56be06 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/ReloadInfoTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/handling/info/ReloadInfoTest.java @@ -8,6 +8,7 @@ package test.java.main.java.com.djrapitops.plan.data.handling.info; import com.djrapitops.plugin.utilities.player.Gamemode; import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.data.handling.info.ReloadInfo; +import main.java.com.djrapitops.plan.utilities.MiscUtils; import org.bukkit.plugin.java.JavaPlugin; import org.junit.Before; import org.junit.Test; @@ -20,6 +21,7 @@ import test.java.utils.TestInit; import java.net.InetAddress; import java.net.UnknownHostException; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** @@ -50,7 +52,7 @@ public class ReloadInfoTest { public void testProcess() throws UnknownHostException { UserData data = MockUtils.mockUser(); InetAddress ip = InetAddress.getByName("137.19.188.146"); - long time = 10L; + long time = MiscUtils.getTime(); int loginTimes = data.getLoginTimes(); String nick = "TestProcessLoginInfo"; ReloadInfo i = new ReloadInfo(data.getUuid(), time, ip, true, nick, Gamemode.CREATIVE); @@ -62,7 +64,7 @@ public class ReloadInfoTest { assertTrue("Nick not last nick", data.getLastNick().equals(nick)); String geo = data.getGeolocation(); assertTrue("Wrong location " + geo, geo.equals("United States")); - assertTrue("Didn't process gamemode", data.getLastGamemode().equals("CREATIVE")); + assertEquals("CREATIVE", data.getGmTimes().getState()); } /** diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/data/time/GMTimesTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/data/time/GMTimesTest.java new file mode 100644 index 000000000..f934db212 --- /dev/null +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/data/time/GMTimesTest.java @@ -0,0 +1,103 @@ +package test.java.main.java.com.djrapitops.plan.data.time; + +import main.java.com.djrapitops.plan.data.time.GMTimes; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertTrue; + +public class GMTimesTest { + @Test + public void setAllGMTimes() throws Exception { + GMTimes test = new GMTimes(); + test.setAllGMTimes(1L, 2L, 3L, 4L); + Map times = test.getTimes(); + assertTrue(times.get("SURVIVAL") == 1L); + assertTrue(times.get("CREATIVE") == 2L); + assertTrue(times.get("ADVENTURE") == 3L); + assertTrue(times.get("SPECTATOR") == 4L); + } + + @Test + public void setAllGMTimesTooFew() throws Exception { + GMTimes test = new GMTimes(); + test.setAllGMTimes(1L, 2L); + Map times = test.getTimes(); + assertTrue(times.get("SURVIVAL") == 1L); + assertTrue(times.get("CREATIVE") == 2L); + assertTrue(times.get("ADVENTURE") == 0L); + assertTrue(times.get("SPECTATOR") == 0L); + } + + @Test + public void setAllGMTimesTooMany() throws Exception { + GMTimes test = new GMTimes(); + test.setAllGMTimes(1L, 2L, 3L, 4L, 5L, 6L); + Map times = test.getTimes(); + assertTrue(times.get("SURVIVAL") == 1L); + assertTrue(times.get("CREATIVE") == 2L); + assertTrue(times.get("ADVENTURE") == 3L); + assertTrue(times.get("SPECTATOR") == 4L); + } + + @Test + public void resetTimes() throws Exception { + GMTimes test = new GMTimes(); + test.setAllGMTimes(4, 3, 2, 1); + test.resetTimes(10); + assertTrue(10L == test.getTime("SURVIVAL")); + assertTrue(0L == test.getTime("ADVENTURE")); + } + + @Test + public void setTime() throws Exception { + GMTimes test = new GMTimes(); + test.setTime("SURVIVAL", 5L); + assertTrue(5L == test.getTime("SURVIVAL")); + } + + @Test + public void renameState() throws Exception { + GMTimes test = new GMTimes(); + test.setAllGMTimes(5L); + test.renameState("SURVIVAL", "Survival"); + assertTrue(0L == test.getTime("SURVIVAL")); + assertTrue(5L == test.getTime("Survival")); + } + + @Test + public void changeStateNormal() throws Exception { + GMTimes test = new GMTimes(new HashMap<>(), "SURVIVAL", 0); + test.changeState("CREATIVE", 5L); + assertTrue(5L == test.getTime("SURVIVAL")); + assertTrue(0L == test.getTime("CREATIVE")); + test.changeState("ADVENTURE", 20L); + assertTrue(5L == test.getTime("SURVIVAL")); + assertTrue(15L == test.getTime("CREATIVE")); + assertTrue(0L == test.getTime("ADVENTURE")); + } + + @Test + public void changeStateMissingStartTime() throws Exception { + GMTimes test = new GMTimes("SURVIVAL"); + test.changeState("CREATIVE", 5L); + assertTrue(5L == test.getTime("SURVIVAL")); + assertTrue(0L == test.getTime("CREATIVE")); + test.changeState("ADVENTURE", 20L); + assertTrue(5L == test.getTime("SURVIVAL")); + assertTrue(15L == test.getTime("CREATIVE")); + assertTrue(0L == test.getTime("ADVENTURE")); + } + + @Test + public void changeStateMissingStartState() throws Exception { + GMTimes test = new GMTimes(); + test.changeState("CREATIVE", 5L); + assertTrue(5L == test.getTime("CREATIVE")); + test.changeState("ADVENTURE", 20L); + assertTrue(20L == test.getTime("CREATIVE")); + assertTrue(0L == test.getTime("ADVENTURE")); + } +} \ No newline at end of file diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/database/DatabaseTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/database/DatabaseTest.java index 7bf29969a..7289e4289 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/database/DatabaseTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/database/DatabaseTest.java @@ -11,6 +11,8 @@ import main.java.com.djrapitops.plan.data.SessionData; import main.java.com.djrapitops.plan.data.TPS; import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor; +import main.java.com.djrapitops.plan.data.time.GMTimes; +import main.java.com.djrapitops.plan.data.time.WorldTimes; import main.java.com.djrapitops.plan.database.Database; import main.java.com.djrapitops.plan.database.databases.MySQLDB; import main.java.com.djrapitops.plan.database.databases.SQLiteDB; @@ -225,12 +227,22 @@ public class DatabaseTest { public void testSaveUserData() throws SQLException { db.init(); UserData data = MockUtils.mockUser(); + GMTimes gmTimes = data.getGmTimes(); + gmTimes.setAllGMTimes(5L, 10L, 15L, 20L); + gmTimes.setState("SURVIVAL"); + gmTimes.setLastStateChange(10L); + WorldTimes worldTimes = data.getWorldTimes(); + worldTimes.setTime("World", 20L); + worldTimes.setState("World"); + worldTimes.setLastStateChange(10L); db.saveUserData(data); data.addNickname("TestUpdateForSave"); db.saveUserData(data); DBCallableProcessor process = new DBCallableProcessor() { @Override public void process(UserData d) { + System.out.println("\nOriginal: " + data); + System.out.println("Database: "+d); assertTrue("Not Equals", data.equals(d)); } }; @@ -259,6 +271,8 @@ public class DatabaseTest { public void testSaveMultipleUserData() throws SQLException, UnknownHostException { db.init(); UserData data = MockUtils.mockUser(); + data.getGmTimes().setAllGMTimes(5L, 10L, 15L, 20L); + data.getWorldTimes().setTime("World", 20L); data.addIpAddress(InetAddress.getByName("185.64.113.61")); data.addSession(new SessionData(1286349L, 2342978L)); data.addNickname("TestNick"); @@ -269,6 +283,7 @@ public class DatabaseTest { System.out.println(data.toString()); data.addNickname("TestUpdateForSave"); UserData data2 = MockUtils.mockUser2(); + data2.getGmTimes().setAllGMTimes(5L, 10L, 15L, 20L); data2.addNickname("Alright"); data.addNickname("TestNick2"); data2.addIpAddress(InetAddress.getByName("185.64.113.60")); @@ -315,6 +330,7 @@ public class DatabaseTest { * @throws SQLException */ @Test + @Ignore("Backup has to be rewritten") public void testBackup() throws SQLException { db.init(); UserData data = MockUtils.mockUser(); @@ -346,6 +362,7 @@ public class DatabaseTest { */ // Big test because @Test + @Ignore("Backup has to be rewritten") public void testRestore() throws SQLException { db.init(); UserData data = MockUtils.mockUser(); diff --git a/Plan/src/test/java/main/java/com/djrapitops/plan/utilities/NewPlayerCreatorTest.java b/Plan/src/test/java/main/java/com/djrapitops/plan/utilities/NewPlayerCreatorTest.java index 557c2d293..84159b03f 100644 --- a/Plan/src/test/java/main/java/com/djrapitops/plan/utilities/NewPlayerCreatorTest.java +++ b/Plan/src/test/java/main/java/com/djrapitops/plan/utilities/NewPlayerCreatorTest.java @@ -59,13 +59,11 @@ public class NewPlayerCreatorTest { IOfflinePlayer p = BukkitOfflinePlayer.wrap(MockUtils.mockPlayer2()); UserData result = NewPlayerCreator.createNewOfflinePlayer(p); UserData exp = new UserData(p); - exp.setLastGamemode("SURVIVAL"); + exp.getGmTimes().setState("SURVIVAL"); exp.setLastPlayed(MiscUtils.getTime()); - long zero = Long.parseLong("0"); - exp.setPlayTime(zero); + exp.setPlayTime(0); exp.setTimesKicked(0); exp.setLoginTimes(0); - exp.setLastGmSwapTime(zero); exp.setDeaths(0); exp.setMobKills(0); assertTrue(exp.equals(result)); @@ -79,13 +77,11 @@ public class NewPlayerCreatorTest { IPlayer p = BukkitPlayer.wrap(MockUtils.mockPlayer2()); UserData result = NewPlayerCreator.createNewPlayer(p); UserData exp = new UserData(p); - exp.setLastGamemode("SPECTATOR"); + exp.getGmTimes().setState("SPECTATOR"); exp.setLastPlayed(MiscUtils.getTime()); - long zero = Long.parseLong("0"); - exp.setPlayTime(zero); + exp.setPlayTime(0); exp.setTimesKicked(0); exp.setLoginTimes(0); - exp.setLastGmSwapTime(zero); exp.setDeaths(0); exp.setMobKills(0); assertTrue(exp.equals(result)); @@ -99,13 +95,11 @@ public class NewPlayerCreatorTest { IOfflinePlayer p = BukkitOfflinePlayer.wrap(MockUtils.mockPlayer()); UserData result = NewPlayerCreator.createNewPlayer(p, Gamemode.CREATIVE); UserData exp = new UserData(p); - exp.setLastGamemode("CREATIVE"); + exp.getGmTimes().setState("CREATIVE"); exp.setLastPlayed(MiscUtils.getTime()); - long zero = Long.parseLong("0"); - exp.setPlayTime(zero); + exp.setPlayTime(0); exp.setTimesKicked(0); exp.setLoginTimes(0); - exp.setLastGmSwapTime(zero); exp.setDeaths(0); exp.setMobKills(0); assertTrue(exp.equals(result)); diff --git a/Plan/src/test/java/utils/MockUtils.java b/Plan/src/test/java/utils/MockUtils.java index b2f792f4e..4e7389c11 100644 --- a/Plan/src/test/java/utils/MockUtils.java +++ b/Plan/src/test/java/utils/MockUtils.java @@ -5,6 +5,7 @@ import com.djrapitops.plugin.utilities.player.IPlayer; import main.java.com.djrapitops.plan.data.KillData; import main.java.com.djrapitops.plan.data.SessionData; import main.java.com.djrapitops.plan.data.UserData; +import main.java.com.djrapitops.plan.data.time.GMTimes; import main.java.com.djrapitops.plan.utilities.NewPlayerCreator; import org.bukkit.GameMode; import org.bukkit.Location; @@ -43,12 +44,13 @@ public class MockUtils { mock.addNickname("MoreNicks"); mock.addPlayerKill(new KillData(getPlayer2UUID(), 1, "WEP", 126873643232L)); mock.addSession(new SessionData(12345L, 23456L)); - mock.setAllGMTimes(1234, 2345, 4356, 4767); + GMTimes gmTimes = mock.getGmTimes(); + gmTimes.setAllGMTimes(1234, 2345, 4356, 4767); + gmTimes.setState("ADVENTURE"); mock.setDeaths(5); mock.setTimesKicked(5); mock.setPlayTime(34438926); mock.setGeolocation("Finland"); - mock.setLastGamemode("ADVENTURE"); mock.setLoginTimes(5); mock.setMobKills(5); return mock;