diff --git a/src/be/jeffcheasey88/peeratcode/model/Player.java b/src/be/jeffcheasey88/peeratcode/model/Player.java index e3da650..ae3e5e0 100644 --- a/src/be/jeffcheasey88/peeratcode/model/Player.java +++ b/src/be/jeffcheasey88/peeratcode/model/Player.java @@ -1,9 +1,11 @@ package be.jeffcheasey88.peeratcode.model; +import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import java.util.Objects; import java.util.Set; import java.util.SortedSet; @@ -21,46 +23,26 @@ public class Player implements Comparable { private String firstname; private String lastname; private String description; - private LinkedHashSet groups; + private Set groups; private byte[] avatar; private int rank; private int totalScore; private int totalCompletion; private int totalTries; - + private Set badges; public Player(String pseudo, String email, String firstname, String lastname, String description) { - this(pseudo, email, firstname, lastname, description, null, null); - } - - public Player(String pseudo, String email, String firstname, String lastname, String description, String groups) { - this(pseudo, email, firstname, lastname, description, groups, null); - } - - public Player(String pseudo, String email, String firstname, String lastname, String description, String groups, - byte[] avatar) { - this(pseudo, email, firstname, lastname, description, groups, avatar, null); - } - public Player(String pseudo, String email, String firstname, String lastname, String description, String groups, - byte[] avatar, Set badges) { this.pseudo = pseudo; this.email = email; this.firstname = firstname; this.lastname = lastname; this.description = description; - setGroups(groups); - this.avatar = avatar; totalScore = 0; totalCompletion = 0; totalTries = 0; - - if (badges != null) - this.badges = new HashSet(badges); - else - this.badges = new HashSet(); } public String getPseudo() { @@ -83,41 +65,42 @@ public class Player implements Comparable { return this.description; } - public Set getGroups() { + public Set getGroups() { return groups; } - + /** * SEE SET_TAGS IN PUZZLE + * * @return DEATH */ public JSONArray getJsonGroups() { - if (groups == null) - return null; - JSONArray groupsJSON = new JSONArray(); - for (String group: groups) { - JSONObject groupJSON = new JSONObject(); - groupJSON.put("name", group); - groupsJSON.add(groupJSON); + if (groups != null) { + JSONArray groupsJSON = new JSONArray(); + for (Group group : groups) { + groupsJSON.add(group.getJson()); + } + return groupsJSON; } - return groupsJSON; + return null; } - - public void setGroups(String groups) { - if (groups == null || groups.isEmpty()) - this.groups = null; - else - this.groups = new LinkedHashSet(Arrays.asList(groups.split(","))); + + public void addGroup(Group newGroup) { + if (newGroup != null) { + if (this.groups == null) + this.groups = new HashSet(); + this.groups.add(newGroup); + } } public byte[] getAvatar() { return this.avatar; } - + public void setAvatar(byte[] newAvatar) { avatar = newAvatar; } - + public String getPathToSourceCode() { return String.format(PATH_TO_CODE, pseudo); } @@ -129,7 +112,7 @@ public class Player implements Comparable { public void setRank(int newRank) { rank = newRank; } - + public int getTotalScore() { return totalScore; } @@ -153,20 +136,21 @@ public class Player implements Comparable { public void setTotalTries(int totalTries) { this.totalTries = totalTries; } - + public Set getBadges() { return badges; } - + /** * SEE SET_TAGS IN PUZZLE + * * @return DEATH */ public JSONArray getJsonBadges() { if (badges == null) return null; JSONArray badgesJSON = new JSONArray(); - for (Badge badge: badges) { + for (Badge badge : badges) { JSONObject badgeJSON = new JSONObject(); badgeJSON.put("name", badge.getName()); byte[] logo = badge.getLogo(); @@ -178,6 +162,14 @@ public class Player implements Comparable { return badgesJSON; } + public void addBadge(Badge newBadge) { + if (newBadge != null) { + if (badges == null) + badges = new HashSet(); + badges.add(newBadge); + } + } + @Override public int compareTo(Player other) { if (this == other) @@ -186,17 +178,32 @@ public class Player implements Comparable { return -1; int compare = Integer.compare(other.getTotalScore(), totalScore); if (compare == 0) { - compare = Integer.compare(other.getTotalCompletion(), totalCompletion); + compare = Integer.compare(other.getTotalCompletion(), totalCompletion); if (compare == 0) { - compare = Integer.compare(totalTries, other.getTotalTries()); - if(compare == 0) compare = other.getPseudo().compareTo(pseudo); + compare = Integer.compare(totalTries, other.getTotalTries()); + if (compare == 0) + compare = other.getPseudo().compareTo(pseudo); } } return compare; } - public void addBadge(Badge newBadge) { - badges.add(newBadge); + @Override + public int hashCode() { + return Objects.hash(email, pseudo); } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Player other = (Player) obj; + return Objects.equals(email, other.email) && Objects.equals(pseudo, other.pseudo); + } + } diff --git a/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java b/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java index bad66b0..51360b6 100644 --- a/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java +++ b/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java @@ -19,6 +19,7 @@ import be.jeffcheasey88.peeratcode.Configuration; import be.jeffcheasey88.peeratcode.model.Badge; import be.jeffcheasey88.peeratcode.model.Chapter; import be.jeffcheasey88.peeratcode.model.Completion; +import be.jeffcheasey88.peeratcode.model.Group; import be.jeffcheasey88.peeratcode.model.Player; import be.jeffcheasey88.peeratcode.model.Puzzle; @@ -34,12 +35,12 @@ public class DatabaseRepository { private static final String SCORE = "SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?"; private static final String GET_COMPLETION = "SELECT id_completion, tries, fileName, score FROM completions WHERE fk_puzzle = ? AND fk_player = ?"; private static final String GET_PLAYER_SIMPLE = "SELECT pseudo, email, firstname, lastname, description FROM players WHERE id_player = ?"; - private static final String GET_PLAYER_DETAILS = "SELECT p.*, scores.score, scores.completions, scores.tries, scores.rank, GROUP_CONCAT(DISTINCT g.name ORDER BY g.fk_chapter, g.fk_puzzle) AS sgroup FROM players p, (SELECT fk_player, SUM(c.score) AS score, COUNT(c.id_completion) AS completions, SUM(c.tries) AS tries, rank() over(ORDER BY score DESC) AS rank FROM completions c GROUP BY c.fk_player) AS scores LEFT JOIN containsGroups cg ON scores.fk_player = cg.fk_player LEFT JOIN groups g ON cg.fk_group = g.id_group WHERE p.id_player = scores.fk_player AND "; + private static final String GET_PLAYER_DETAILS = "SELECT p.*, scores.score, scores.completions, scores.tries, scores.rank, g.* FROM players p, (SELECT fk_player, SUM(c.score) AS score, COUNT(c.id_completion) AS completions, SUM(c.tries) AS tries, rank() over(ORDER BY score DESC) AS rank FROM completions c GROUP BY c.fk_player) AS scores LEFT JOIN containsGroups cg ON scores.fk_player = cg.fk_player LEFT JOIN groups g ON cg.fk_group = g.id_group WHERE p.id_player = scores.fk_player AND "; private static final String GET_PLAYER_DETAILS_BY_ID = GET_PLAYER_DETAILS - + " p.id_player = ? GROUP BY p.id_player;"; + + " p.id_player = ? ORDER BY g.fk_chapter, g.fk_puzzle;"; private static final String GET_PLAYER_DETAILS_BY_PSEUDO = GET_PLAYER_DETAILS - + "p.pseudo = ? GROUP BY p.pseudo;"; - private static final String ALL_PLAYERS_FOR_LEADERBOARD = "select DISTINCT p.*, scores.* from players p ,(SELECT fk_player, SUM(c.score) AS score, COUNT(c.id_completion) AS completions, SUM(c.tries) AS tries, rank() over(ORDER BY score DESC) AS rank FROM completions c GROUP BY c.fk_player) AS scores LEFT JOIN containsGroups cg ON scores.fk_player = cg.fk_player WHERE p.id_player = scores.fk_player"; + + "p.pseudo = ? ORDER BY g.fk_chapter, g.fk_puzzle;"; + private static final String ALL_PLAYERS_FOR_LEADERBOARD = "select p.*, scores.*, g.* from players p ,(SELECT fk_player, SUM(c.score) AS score, COUNT(c.id_completion) AS completions, SUM(c.tries) AS tries, rank() over(ORDER BY score DESC) AS rank FROM completions c GROUP BY c.fk_player) AS scores LEFT JOIN containsGroups cg ON scores.fk_player = cg.fk_player LEFT JOIN groups g ON cg.fk_group = g.id_group WHERE p.id_player = scores.fk_player ORDER BY g.fk_chapter, g.fk_puzzle"; private static final String GET_BADGE = "SELECT * FROM badges WHERE id_badge = ?"; private static final String GET_BADGES_OF_PLAYER = "SELECT * FROM badges b LEFT JOIN containsBadges cb ON cb.fk_badge = b.id_badge WHERE cb.fk_player = ?"; private static final String INSERT_COMPLETION = "INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"; @@ -67,7 +68,8 @@ public class DatabaseRepository { } private Chapter makeChapter(ResultSet chapterResult) throws SQLException { - return new Chapter(chapterResult.getInt("id_chapter"), chapterResult.getString("name"), chapterResult.getTimestamp("start_date"), chapterResult.getTimestamp("end_date")); + return new Chapter(chapterResult.getInt("id_chapter"), chapterResult.getString("name"), + chapterResult.getTimestamp("start_date"), chapterResult.getTimestamp("end_date")); } private Completion makeCompletion(int playerId, int puzzleId, ResultSet completionResult) throws SQLException { @@ -83,18 +85,27 @@ public class DatabaseRepository { if (hasColumn(playerResult, "avatar")) { p.setAvatar(playerResult.getBytes("avatar")); } - if (hasColumn(playerResult, "sgroup")) { - p.setGroups(playerResult.getString("sgroup")); - } if (hasColumn(playerResult, "score")) { p.setRank(playerResult.getInt("rank")); p.setTotalScore(playerResult.getInt("score")); p.setTotalCompletion(playerResult.getInt("completions")); p.setTotalTries(playerResult.getInt("tries")); } + // Manage groups + String groupName = playerResult.getString("name"); + if (groupName != null) { + p.addGroup(makeGroup(playerResult)); + } + return p; } + private Group makeGroup(ResultSet result) throws SQLException { + Group gr = new Group(result.getString("name"), result.getInt("fk_chapter"), result.getInt("fk_puzzle")); + + return gr; + } + private Badge makeBadge(ResultSet rs) throws SQLException { return new Badge(rs.getString("name"), rs.getBytes("logo"), rs.getInt("level")); } @@ -196,7 +207,7 @@ public class DatabaseRepository { public Player getPlayerDetails(String pseudoPlayer) { return getPlayerDetails(-1, pseudoPlayer); } - + private Player getPlayerDetails(int id, String pseudo) { try { ensureConnection(); @@ -209,16 +220,21 @@ public class DatabaseRepository { completionsStmt.setInt(1, id); } ResultSet result = completionsStmt.executeQuery(); - if (result.next()) { - Player player = makePlayer(result); - completionsStmt = con.prepareStatement(GET_BADGES_OF_PLAYER); - completionsStmt.setInt(1, result.getInt("id_player")); - ResultSet resultBadges = completionsStmt.executeQuery(); - while (resultBadges.next()) { - player.addBadge(makeBadge(resultBadges)); + Player player = null; + while (result.next()) { + if (player == null) { + player = makePlayer(result); + completionsStmt = con.prepareStatement(GET_BADGES_OF_PLAYER); + completionsStmt.setInt(1, result.getInt("id_player")); + ResultSet resultBadges = completionsStmt.executeQuery(); + while (resultBadges.next()) { + player.addBadge(makeBadge(resultBadges)); + } + } else { + player.addGroup(makeGroup(result)); } - return player; } + return player; } catch (SQLException e) { e.printStackTrace(); } @@ -230,13 +246,17 @@ public class DatabaseRepository { ensureConnection(); PreparedStatement playersStmt = con.prepareStatement(ALL_PLAYERS_FOR_LEADERBOARD); ResultSet result = playersStmt.executeQuery(); - SortedSet players = new TreeSet(); + ArrayList players = new ArrayList(); Player tmpPlayer; while (result.next()) { tmpPlayer = makePlayer(result); - players.add(tmpPlayer); + if (!players.contains(tmpPlayer)) { + players.add(tmpPlayer); + } else { + players.get(players.indexOf(tmpPlayer)).addGroup(makeGroup(result)); + } } - return players; + return new TreeSet(players); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java b/src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java index 5f3b3cc..7307ad2 100644 --- a/src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java +++ b/src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java @@ -44,7 +44,7 @@ public class PlayerDetails implements Response { playerJSON.put("score", player.getTotalScore()); playerJSON.put("completions", player.getTotalCompletion()); playerJSON.put("tries", player.getTotalTries()); - if (player.getBadges().size() > 0) playerJSON.put("badges", player.getJsonBadges()); + if (player.getBadges() != null) playerJSON.put("badges", player.getJsonBadges()); if(player.getAvatar() != null) playerJSON.put("avatar", Base64.getEncoder().encodeToString(player.getAvatar())); writer.write(playerJSON.toJSONString().replace("\\", "")); } else {