From 81d2f6feb28d1739a0e18fa811f2a694c6776999 Mon Sep 17 00:00:00 2001 From: Francois G Date: Thu, 9 Mar 2023 22:11:16 +0100 Subject: [PATCH] Add playerDetails route --- src/be/jeffcheasey88/peeratcode/Main.java | 2 + .../peeratcode/model/Player.java | 17 +++++ .../repository/DatabaseRepository.java | 69 +++++++++++++++++-- .../peeratcode/routes/PlayerDetails.java | 55 +++++++++++++++ 4 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java diff --git a/src/be/jeffcheasey88/peeratcode/Main.java b/src/be/jeffcheasey88/peeratcode/Main.java index 15fbc0b..0b32cf4 100644 --- a/src/be/jeffcheasey88/peeratcode/Main.java +++ b/src/be/jeffcheasey88/peeratcode/Main.java @@ -30,6 +30,7 @@ import be.jeffcheasey88.peeratcode.routes.ChapterElement; import be.jeffcheasey88.peeratcode.routes.ChapterList; import be.jeffcheasey88.peeratcode.routes.Leaderboard; import be.jeffcheasey88.peeratcode.routes.Login; +import be.jeffcheasey88.peeratcode.routes.PlayerDetails; import be.jeffcheasey88.peeratcode.routes.PuzzleElement; import be.jeffcheasey88.peeratcode.routes.PuzzleResponse; import be.jeffcheasey88.peeratcode.routes.Register; @@ -100,6 +101,7 @@ public class Main { router.register(new Result(router.getDataBase())); router.register(new PuzzleResponse(router.getDataBase())); router.register(new Leaderboard(router.getDataBase())); + router.register(new PlayerDetails(router.getDataBase())); } private static void startWebServer(Configuration config, Router router) throws IOException { diff --git a/src/be/jeffcheasey88/peeratcode/model/Player.java b/src/be/jeffcheasey88/peeratcode/model/Player.java index 070f271..555afc5 100644 --- a/src/be/jeffcheasey88/peeratcode/model/Player.java +++ b/src/be/jeffcheasey88/peeratcode/model/Player.java @@ -1,6 +1,8 @@ package be.jeffcheasey88.peeratcode.model; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; public class Player implements Comparable { public static final String PATH_TO_CODE = "/home/%s/peer-at-source/"; @@ -16,6 +18,8 @@ public class Player implements Comparable { private int totalScore; private int totalCompletion; private int totalTries; + + private String badges; // To change to a set of model public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup) { this(pseudo, email, firstname, lastname, description, sgroup, null); @@ -23,6 +27,10 @@ public class Player implements Comparable { public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup, byte[] avatar) { + this(pseudo, email, firstname, lastname, description, sgroup, null, null); + } + public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup, + byte[] avatar, String badges) { this.pseudo = pseudo; this.email = email; this.firstname = firstname; @@ -34,6 +42,8 @@ public class Player implements Comparable { totalScore = 0; totalCompletion = 0; totalTries = 0; + + this.badges = null; } public String getPseudo() { @@ -91,6 +101,13 @@ public class Player implements Comparable { public void setTotalTries(int totalTries) { this.totalTries = totalTries; } + + public String getBadges() { + return badges; + } + public void setBadges(String initBadges) { + badges = initBadges; + } @Override public int compareTo(Player other) { diff --git a/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java b/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java index 390d2c1..8731b05 100644 --- a/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java +++ b/src/be/jeffcheasey88/peeratcode/repository/DatabaseRepository.java @@ -4,6 +4,7 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; @@ -15,6 +16,7 @@ import com.password4j.Hash; import com.password4j.Password; 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.Player; @@ -31,7 +33,18 @@ public class DatabaseRepository { private static final String CHECK_PASSWORD = "SELECT id_player, passwd FROM players WHERE pseudo=?"; 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 = "SELECT * FROM players WHERE id_player = ?"; + private static final String GET_PLAYER = "SELECT * FROM players WHERE "; + private static final String GET_PLAYER_BY_ID = GET_PLAYER + "id_player = ?"; + private static final String GET_PLAYER_BY_PSEUDO = GET_PLAYER + "pseudo = ?"; + private static final String GET_PLAYER_DETAILS = "SELECT p.pseudo, p.email, p.firstname, p.lastname, p.description, p.avatar, p.sgroup,\n" + + " SUM(c.score) AS playerScore, COUNT(c.id_completion) AS playerCompletions, SUM(c.tries) AS playerTries,\n" + + " GROUP_CONCAT(DISTINCT b.id_badge ORDER BY b.id_badge ASC SEPARATOR ', ') AS badges\n" + + "FROM players p\n" + + "LEFT JOIN completions c ON p.id_player = c.fk_player\n" + + "LEFT JOIN containsBadges cb ON p.id_player = cb.fk_player\n" + + "LEFT JOIN badges b ON cb.fk_badge = b.id_badge\n"; + private static final String GET_PLAYER_DETAILS_BY_ID = GET_PLAYER_DETAILS + "WHERE p.id_player = ? GROUP BY p.id_player;"; + private static final String GET_PLAYER_DETAILS_BY_PSEUDO = GET_PLAYER_DETAILS + "WHERE p.pseudo = ? GROUP BY p.pseudo;"; private static final String ALL_PLAYERS_FOR_LEADERBOARD = "SELECT p.*, sum(c.score) AS playerScore, count(c.id_completion) AS playerCompletions, sum(c.tries) AS playerTries FROM players p LEFT JOIN completions c ON c.fk_player = p.id_player GROUP BY p.id_player ORDER BY playerScore DESC"; private static final String INSERT_COMPLETION = "INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"; private static final String UPDATE_COMPLETION = "UPDATE completions SET tries = ?, filename = ?, score = ? WHERE fk_puzzle = ? AND fk_player = ?"; @@ -67,10 +80,30 @@ public class DatabaseRepository { } private Player makePlayer(ResultSet playerResult) throws SQLException { - return new Player(playerResult.getString("pseudo"), playerResult.getString("email"), + Player p = new Player(playerResult.getString("pseudo"), playerResult.getString("email"), playerResult.getString("firstName"), playerResult.getString("LastName"), playerResult.getString("description"), playerResult.getString("sgroup"), playerResult.getBytes("avatar")); + if (hasColumn(playerResult, "playerScore")) { + p.setTotalScore(playerResult.getInt("playerScore")); + p.setTotalCompletion(playerResult.getInt("playerCompletions")); + p.setTotalTries(playerResult.getInt("playerTries")); + } + if (hasColumn(playerResult, "badges")) { + p.setBadges(playerResult.getString("badges")); + } + return p; + } + private boolean hasColumn(ResultSet rs, String columnName) throws SQLException { + // Found on StackOverflow + ResultSetMetaData rsmd = rs.getMetaData(); + int columns = rsmd.getColumnCount(); + for (int x = 1; x <= columns; x++) { + if (columnName.equals(rsmd.getColumnName(x))) { + return true; + } + } + return false; } private List getPuzzlesInChapter(int id) throws SQLException { @@ -150,6 +183,35 @@ public class DatabaseRepository { } return null; } + + public Player getPlayerDetails(int idPlayer) { + try { + ensureConnection(); + PreparedStatement completionsStmt = con.prepareStatement(GET_PLAYER_DETAILS_BY_ID); + completionsStmt.setInt(1, idPlayer); + ResultSet result = completionsStmt.executeQuery(); + if (result.next()) { + return makePlayer(result); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + public Player getPlayerDetails(String pseudoPlayer) { + try { + ensureConnection(); + PreparedStatement completionsStmt = con.prepareStatement(GET_PLAYER_DETAILS_BY_PSEUDO); + completionsStmt.setString(1, pseudoPlayer); + ResultSet result = completionsStmt.executeQuery(); + if (result.next()) { + return makePlayer(result); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } public SortedSet getAllPlayerForLeaderboard() { try { @@ -160,9 +222,6 @@ public class DatabaseRepository { Player tmpPlayer; while (result.next()){ tmpPlayer = makePlayer(result); - tmpPlayer.setTotalScore(result.getInt("playerScore")); - tmpPlayer.setTotalCompletion(result.getInt("playerCompletions")); - tmpPlayer.setTotalTries(result.getInt("playerTries")); players.add(tmpPlayer); } return players; diff --git a/src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java b/src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java new file mode 100644 index 0000000..b3c8714 --- /dev/null +++ b/src/be/jeffcheasey88/peeratcode/routes/PlayerDetails.java @@ -0,0 +1,55 @@ +package be.jeffcheasey88.peeratcode.routes; + +import be.jeffcheasey88.peeratcode.model.Player; +import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; +import be.jeffcheasey88.peeratcode.webserver.HttpReader; +import be.jeffcheasey88.peeratcode.webserver.HttpUtil; +import be.jeffcheasey88.peeratcode.webserver.HttpWriter; +import be.jeffcheasey88.peeratcode.webserver.Response; +import be.jeffcheasey88.peeratcode.webserver.User; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import java.util.SortedSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PlayerDetails implements Response { + + private final DatabaseRepository databaseRepo; + + public PlayerDetails(DatabaseRepository databaseRepo) { + this.databaseRepo = databaseRepo; + } + + @Override + public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { + HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); + int id = user.getId(); + if (matcher.groupCount() > 0) { + id = Integer.parseInt(matcher.group(1)); + } + Player player = databaseRepo.getPlayerDetails(id); + JSONObject playerJSON = new JSONObject(); + if (player != null) { + playerJSON.put("pseudo", player.getPseudo()); + playerJSON.put("email", player.getEmail()); + playerJSON.put("firstname", player.getFirstname()); + playerJSON.put("lastname", player.getLastname()); + playerJSON.put("description", player.getDescription()); + playerJSON.put("group", player.getGroup()); + playerJSON.put("score", player.getTotalScore()); + playerJSON.put("completions", player.getTotalCompletion()); + playerJSON.put("tries", player.getTotalTries()); + playerJSON.put("badges", player.getBadges()); + playerJSON.put("avatar", player.getAvatar()); + } + writer.write(playerJSON.toJSONString()); + } + + @Override + public Pattern getPattern() { + return Pattern.compile("^\\/player\\/(.+)?$"); + } +}