package linea; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.sql.*; import java.util.ArrayList; import java.util.List; public class DatabaseConnection { private static final Path DB_PATH = resolveDbPath(); private static final String DB_URL = "jdbc:sqlite:" + DB_PATH; private Connection conn; private static Path resolveDbPath() { Path cwd = Paths.get("").toAbsolutePath().normalize(); Path inProjetDev = cwd.resolve("Projet-Dev").resolve("Jeu.db"); if (Files.exists(cwd.resolve("Projet-Dev"))) { return inProjetDev; } return cwd.resolve("Jeu.db"); } public void connect() { try { Path parent = DB_PATH.getParent(); if (parent != null) { Files.createDirectories(parent); } conn = DriverManager.getConnection(DB_URL); System.out.println("Connexion à la DB OK: " + DB_PATH); } catch (SQLException e) { System.err.println("Erreur de connexion DB: " + e.getMessage()); } catch (Exception e) { System.err.println("Erreur accès fichier DB: " + e.getMessage()); } } public void disconnect() { if (conn == null) { return; } try { if (!conn.isClosed()) { conn.close(); System.out.println("Déconnexion DB OK"); } } catch (SQLException e) { System.err.println("Erreur à la fermeture DB: " + e.getMessage()); } } public void createTables() { if (conn == null) { System.err.println("DB non connectée, impossible de créer les tables."); return; } String createCompte = """ CREATE TABLE IF NOT EXISTS Compte ( id_compte INTEGER PRIMARY KEY AUTOINCREMENT, pseudo TEXT NOT NULL ); """; String createScore = """ CREATE TABLE IF NOT EXISTS Score ( id_score INTEGER PRIMARY KEY AUTOINCREMENT, valeur_score INTEGER, nb_mort INTEGER, temps_jeu INTEGER, id_compte INTEGER, FOREIGN KEY(id_compte) REFERENCES Compte(id_compte) ); """; String createProgressionCampagne = """ CREATE TABLE IF NOT EXISTS ProgressionCampagne ( id_compte INTEGER PRIMARY KEY, niveau_debloque_max INTEGER NOT NULL DEFAULT 1, FOREIGN KEY(id_compte) REFERENCES Compte(id_compte) ); """; try (Statement stmt = conn.createStatement()) { stmt.executeUpdate(createCompte); stmt.executeUpdate(createScore); stmt.executeUpdate("DROP TABLE IF EXISTS Niveau"); stmt.executeUpdate(createProgressionCampagne); System.out.println("Tables créées / existantes OK"); } catch (SQLException e) { System.err.println("Erreur création tables : " + e.getMessage()); } } public void sauvegarderScore(int valeur, int idCompte, int nbMort, int tempsJeuSec) { if (conn == null || idCompte <= 0) return; String sql = "INSERT INTO Score (valeur_score, nb_mort, temps_jeu, id_compte) VALUES (?, ?, ?, ?)"; try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, valeur); ps.setInt(2, nbMort); ps.setInt(3, tempsJeuSec); ps.setInt(4, idCompte); ps.executeUpdate(); } catch (SQLException e) { System.err.println("Erreur sauvegarde score : " + e.getMessage()); } } public int getMeilleurScoreParCompte(int idCompte) { if (conn == null || idCompte <= 0) return 0; String sql = "SELECT MAX(valeur_score) FROM Score WHERE id_compte = ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, idCompte); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) return rs.getInt(1); } } catch (SQLException e) { System.err.println("Erreur lecture meilleur score : " + e.getMessage()); } return 0; } public int creerCompte(String pseudo) { if (conn == null || pseudo == null || pseudo.isBlank()) return -1; String sql = "INSERT INTO Compte (pseudo) VALUES (?)"; try (PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { ps.setString(1, pseudo.trim()); ps.executeUpdate(); try (ResultSet rs = ps.getGeneratedKeys()) { if (rs.next()) { int idCompte = rs.getInt(1); initialiserProgressionCampagne(idCompte); return idCompte; } } } catch (SQLException e) { System.err.println("Erreur création compte : " + e.getMessage()); } return -1; } public int getIdParPseudo(String pseudo) { if (conn == null || pseudo == null || pseudo.isBlank()) return -1; String sql = "SELECT id_compte FROM Compte WHERE pseudo = ? LIMIT 1"; try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, pseudo.trim()); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) return rs.getInt(1); } } catch (SQLException e) { System.err.println("Erreur lecture compte : " + e.getMessage()); } return -1; } public void supprimerCompte(int idCompte) { if (conn == null || idCompte <= 0) return; try (PreparedStatement ps0 = conn.prepareStatement("DELETE FROM ProgressionCampagne WHERE id_compte = ?"); PreparedStatement ps1 = conn.prepareStatement("DELETE FROM Score WHERE id_compte = ?"); PreparedStatement ps2 = conn.prepareStatement("DELETE FROM Compte WHERE id_compte = ?")) { ps0.setInt(1, idCompte); ps0.executeUpdate(); ps1.setInt(1, idCompte); ps1.executeUpdate(); ps2.setInt(1, idCompte); ps2.executeUpdate(); } catch (SQLException e) { System.err.println("Erreur suppression compte : " + e.getMessage()); } } public List getPseudos() { List pseudos = new ArrayList<>(); if (conn == null) return pseudos; String sql = "SELECT pseudo FROM Compte ORDER BY pseudo"; try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { while (rs.next()) { pseudos.add(rs.getString("pseudo")); } } catch (SQLException e) { System.err.println("Erreur lecture comptes : " + e.getMessage()); } return pseudos; } private void initialiserProgressionCampagne(int idCompte) { if (conn == null || idCompte <= 0) return; String sql = "INSERT OR IGNORE INTO ProgressionCampagne (id_compte, niveau_debloque_max) VALUES (?, 1)"; try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, idCompte); ps.executeUpdate(); } catch (SQLException e) { System.err.println("Erreur init progression campagne : " + e.getMessage()); } } public int getNiveauDebloqueCampagne(int idCompte) { if (conn == null || idCompte <= 0) return 1; initialiserProgressionCampagne(idCompte); String sql = "SELECT niveau_debloque_max FROM ProgressionCampagne WHERE id_compte = ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, idCompte); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { int niveau = rs.getInt("niveau_debloque_max"); if (niveau < 1) return 1; return Math.min(100, niveau); } } } catch (SQLException e) { System.err.println("Erreur lecture progression campagne : " + e.getMessage()); } return 1; } public void debloquerNiveauCampagne(int idCompte, int niveauTermine) { if (conn == null || idCompte <= 0) return; int niveauCible = Math.min(100, Math.max(1, niveauTermine + 1)); initialiserProgressionCampagne(idCompte); String sql = "UPDATE ProgressionCampagne SET niveau_debloque_max = MAX(niveau_debloque_max, ?) WHERE id_compte = ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, niveauCible); ps.setInt(2, idCompte); ps.executeUpdate(); } catch (SQLException e) { System.err.println("Erreur mise à jour progression campagne : " + e.getMessage()); } } public String getStatsParCompte(int idCompte) { if (conn == null || idCompte <= 0) { return "Aucune statistique disponible."; } String sql = "SELECT COALESCE(SUM(nb_mort),0) AS morts, " + "COALESCE(SUM(temps_jeu),0) AS temps, " + "COALESCE(MAX(valeur_score),0) AS meilleur " + "FROM Score WHERE id_compte = ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { ps.setInt(1, idCompte); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { int morts = rs.getInt("morts"); int temps = rs.getInt("temps"); int meilleur = rs.getInt("meilleur"); return "Nombre de morts : " + morts + "\nTemps de jeu total : " + temps + " s" + "\nMeilleur score : " + meilleur; } } } catch (SQLException e) { return "Erreur lecture stats : " + e.getMessage(); } return "Aucune statistique disponible."; } public String getStatsCampagneParCompte(int idCompte) { if (conn == null || idCompte <= 0) { return "Campagne : non disponible."; } int niveauMax = getNiveauDebloqueCampagne(idCompte); int niveauxTermines = Math.max(0, niveauMax - 1); return "Campagne\n" + "Niveau max atteint : " + niveauMax + "\nNiveaux terminés : " + niveauxTermines; } }