From 9a3d3b7c3ec5795d7904ceef7daf4b5f47f8a624 Mon Sep 17 00:00:00 2001
From: Martin <ms618@hdm-stuttgart.de>
Date: Tue, 27 Feb 2024 17:11:32 +0100
Subject: [PATCH] Added PowerUps Tracking! Update: AzureDB.java (made changes
 according to PlayerStatistics.java now tracking collected powerups) Update:
 CreateAccountController.java (added call of stats verification method)
 Update: DDL_Script_Oracle.sql (improved DDL script and added column for
 powerups tracking) Update: LoadingScreenController.java (added call of stats
 verification method) Update: LoginController.java (added call of stats
 verification method) Update: OracleDB.java (made changes according to
 PlayerStatistics.java now tracking collected powerups) Update:
 ParserTest.java (made changes according to changes in Parser.java) Update
 Parser.java (made changes to PlayerStatistics.java now tracking collected
 powerups) Update Persistence.java (made changes to PlayerStatistics.java now
 tracking collected powerups; moved stats verification to separate method)
 Update PlayerStatistics.java (now tracking collected powerups) Update:
 playerStatsLocal.json (made changes to PlayerStatistics.java now tracking
 collected powerups) Update: RuntimeInfo.java (made changes to
 PlayerStatistics.java now tracking collected powerups) Update:
 ThreadStartup3.java (made changes to PlayerStatistics.java now tracking
 collected powerups) Update: ThreadUpdateStats.java (made changes to
 PlayerStatistics.java now tracking collected powerups)

---
 .../Controller/CreateAccountController.java   |   1 +
 .../Controller/LoadingScreenController.java   |   1 +
 .../Controller/LoginController.java           |   1 +
 .../Model/DataStorage/Classes/AzureDB.java    |  31 +--
 .../Model/DataStorage/Classes/OracleDB.java   |  31 +--
 .../DataStorage/Classes/Persistence.java      |  27 ++-
 .../DataStorage/Classes/PlayerStatistics.java |  14 +-
 .../DataStorage/Classes/RuntimeInfo.java      |  18 +-
 .../DataStorage/Classes/ThreadStartup3.java   |   4 +-
 .../Classes/ThreadUpdateStats.java            |   4 +-
 .../DataStorage/Classes/Utilities/Parser.java |   4 +
 .../DataStorage/Scripts/DDL_Script_Oracle.sql | 180 +++++++++++++-----
 .../resources/player/playerStatsLocal.json    |   1 +
 .../Classes/Utilities/ParserTest.java         |  21 +-
 14 files changed, 233 insertions(+), 105 deletions(-)

diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/CreateAccountController.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/CreateAccountController.java
index 88f6abb7..2d3f9ec1 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/CreateAccountController.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/CreateAccountController.java
@@ -75,6 +75,7 @@ public class CreateAccountController implements Initializable {
             persistence.createAccount(playerName.getText(), password.getText(), accountType);
             persistence.resetPlayerStatistics();
             persistence.loadPlayerStatistics();
+            persistence.verifyPlayerStatistics();
             log.info(accountType + " Account created");
             switchScene("MainMenu");
         } catch (DatabaseException e) {
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/LoadingScreenController.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/LoadingScreenController.java
index 732adab8..1caf9992 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/LoadingScreenController.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/LoadingScreenController.java
@@ -183,6 +183,7 @@ public class LoadingScreenController implements Initializable {
         if (persistence.getAccount().getAccountType() != AccountType.NONE) {
             try {
                 persistence.loadPlayerStatistics();
+                persistence.verifyPlayerStatistics();
                 statsLoaded = true;
             } catch (DatabaseException e) {
                 log.error(e);
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/LoginController.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/LoginController.java
index 0acc6fd5..fef25215 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/LoginController.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/LoginController.java
@@ -41,6 +41,7 @@ public class LoginController {
             log.info("Login Player: " + playerName);
             persistence.login(playerName.getText(), password.getText());
             persistence.loadPlayerStatistics();
+            persistence.verifyPlayerStatistics();
             Platform.runLater(() -> switchScene("MainMenu"));
         } catch (NoSuchAlgorithmException e) {
             log.error(e);
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java
index 1d6efb78..af68c33e 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java
@@ -48,7 +48,7 @@ public class AzureDB implements ISQLDataBase {
     public ArrayList<MapData> getCoreMaps() throws SQLException {
         try (Connection connection = connect()) {
             ArrayList<MapData> newMaps = new ArrayList<MapData>();
-            String sql = "SELECT * FROM CoreMaps";
+            String sql = "SELECT * FROM coremap";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
             log.info("Sending SQL statement.");
@@ -71,7 +71,7 @@ public class AzureDB implements ISQLDataBase {
     public ArrayList<MapInfo> getCommunityMapsList() throws SQLException {
         try (Connection connection = connect()) {
             ArrayList<MapInfo> tempList = new ArrayList<MapInfo>();
-            String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM communitymaps";
+            String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM communitymap";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
             log.info("Sending SQL statement.");
@@ -93,7 +93,7 @@ public class AzureDB implements ISQLDataBase {
     @Override
     public PlayerStatistics getStatistics(String playerName) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time FROM players WHERE player_name = ?";
+            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, powerups_collected, ingame_time FROM player WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
 
@@ -102,9 +102,9 @@ public class AzureDB implements ISQLDataBase {
             if (!rs.isBeforeFirst()) {             //if no data matches
                 throw new SQLException("No match on SQL database!");
             }
-            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0, 0);
             while (rs.next()) {
-                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("ingame_time"));
+                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("powerups_collected"), rs.getInt("ingame_time"));
             }
             rs.close();
             stmt.close();
@@ -119,7 +119,7 @@ public class AzureDB implements ISQLDataBase {
     @Override
     public MapData getCommunityMapByID(String mapID) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "SELECT * FROM communitymaps WHERE map_ID = ?";
+            String sql = "SELECT * FROM communitymap WHERE map_ID = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, mapID);
 
@@ -136,7 +136,7 @@ public class AzureDB implements ISQLDataBase {
             stmt.close();
             log.info("Community-Map retrieved successfully from SQL server!");
 
-            String sql2 = "UPDATE communitymaps SET map_downloads = map_downloads + 1 WHERE map_id = ?";
+            String sql2 = "UPDATE communitymap SET map_downloads = map_downloads + 1 WHERE map_id = ?";
             PreparedStatement stmt2 = connection.prepareStatement(sql2);
             stmt2.setString(1, mapID);
             stmt2.executeQuery();
@@ -153,7 +153,7 @@ public class AzureDB implements ISQLDataBase {
     @Override
     public String checkCredentials(String playerName) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "SELECT player_pw FROM players WHERE player_name = ?";
+            String sql = "SELECT player_pw FROM player WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
 
@@ -177,7 +177,7 @@ public class AzureDB implements ISQLDataBase {
     @Override
     public void uploadCommunityMap(MapData map) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "INSERT INTO communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads) VALUES (?, ?, ?, ?, ?, 0)";
+            String sql = "INSERT INTO communitymap (map_id, map_name, map_width, map_height, map_data, map_downloads) VALUES (?, ?, ?, ?, ?, 0)";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, map.getMapID());
             stmt.setString(2, map.getMapName());
@@ -199,7 +199,7 @@ public class AzureDB implements ISQLDataBase {
     @Override
     public void createPlayer(String playerName, String playerPW) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0)";
+            String sql = "INSERT INTO player (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, powerups_collected, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0, 0)";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
             stmt.setString(2, playerPW);
@@ -218,15 +218,16 @@ public class AzureDB implements ISQLDataBase {
     @Override
     public void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "UPDATE players SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?";
+            String sql = "UPDATE player SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, powerups_collected = ?, ingame_time = ? WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setInt(1, stats.getGamesWon());
             stmt.setInt(2, stats.getGamesLost());
             stmt.setInt(3, stats.getKills());
             stmt.setInt(4, stats.getDeaths());
             stmt.setInt(5, stats.getBlocksDestroyed());
-            stmt.setInt(6, stats.getGameTime());
-            stmt.setString(7, account.getPlayerName());
+            stmt.setInt(6, stats.getPowerUpsCollected());
+            stmt.setInt(7, stats.getGameTime());
+            stmt.setString(8, account.getPlayerName());
 
             log.info("Sending SQL statement.");
             stmt.executeQuery();
@@ -242,7 +243,7 @@ public class AzureDB implements ISQLDataBase {
     @Override
     public void resetPlayerStats(PlayerAccount account) throws SQLException {        //verification of player credentials necessary beforehand (use methode "verifyAccountData" in "Persistence.java)
         try (Connection connection = connect()) {
-            String sql = "UPDATE players SET games_won = 0, games_lost = 0, kills = 0, deaths = 0, blocks_destroyed = 0, ingame_time = 0 WHERE player_name = ?";
+            String sql = "UPDATE player SET games_won = 0, games_lost = 0, kills = 0, deaths = 0, blocks_destroyed = 0, powerups_collected = 0, ingame_time = 0 WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, account.getPlayerName());
 
@@ -257,4 +258,4 @@ public class AzureDB implements ISQLDataBase {
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java
index e0c0418a..13371c39 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java
@@ -49,7 +49,7 @@ public class OracleDB implements ISQLDataBase {
     public ArrayList<MapData> getCoreMaps() throws SQLException {
         try (Connection connection = connect()) {
             ArrayList<MapData> newMaps = new ArrayList<MapData>();
-            String sql = "SELECT * FROM battlearenadata.coremaps";
+            String sql = "SELECT * FROM battlearenadata.coremap";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
             log.info("Sending SQL statement.");
@@ -72,7 +72,7 @@ public class OracleDB implements ISQLDataBase {
     public ArrayList<MapInfo> getCommunityMapsList() throws SQLException {
         try (Connection connection = connect()) {
             ArrayList<MapInfo> tempList = new ArrayList<MapInfo>();
-            String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM battlearenadata.communitymaps";
+            String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM battlearenadata.communitymap";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
             log.info("Sending SQL statement.");
@@ -94,7 +94,7 @@ public class OracleDB implements ISQLDataBase {
     @Override
     public PlayerStatistics getStatistics(String playerName) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time FROM battlearenadata.players WHERE player_name = ?";
+            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, powerups_collected, ingame_time FROM battlearenadata.player WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
 
@@ -103,9 +103,9 @@ public class OracleDB implements ISQLDataBase {
             if (!rs.isBeforeFirst()) {             //if no data matches
                 throw new SQLException("No match on SQL database!");
             }
-            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0, 0);
             while (rs.next()) {
-                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("ingame_time"));
+                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("powerups_collected"), rs.getInt("ingame_time"));
             }
             rs.close();
             stmt.close();
@@ -120,7 +120,7 @@ public class OracleDB implements ISQLDataBase {
     @Override
     public MapData getCommunityMapByID(String mapID) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "SELECT * FROM battlearenadata.communitymaps WHERE map_ID = ?";
+            String sql = "SELECT * FROM battlearenadata.communitymap WHERE map_ID = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, mapID);
 
@@ -137,7 +137,7 @@ public class OracleDB implements ISQLDataBase {
             stmt.close();
             log.info("Community-Map retrieved successfully from SQL server!");
 
-            String sql2 = "UPDATE battlearenadata.communitymaps SET map_downloads = map_downloads + 1 WHERE map_id = ?";
+            String sql2 = "UPDATE battlearenadata.communitymap SET map_downloads = map_downloads + 1 WHERE map_id = ?";
             PreparedStatement stmt2 = connection.prepareStatement(sql2);
             stmt2.setString(1, mapID);
             stmt2.executeQuery();
@@ -154,7 +154,7 @@ public class OracleDB implements ISQLDataBase {
     @Override
     public String checkCredentials(String playerName) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "SELECT player_pw FROM battlearenadata.players WHERE player_name = ?";
+            String sql = "SELECT player_pw FROM battlearenadata.player WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
 
@@ -178,7 +178,7 @@ public class OracleDB implements ISQLDataBase {
     @Override
     public void uploadCommunityMap(MapData map) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads) VALUES (?, ?, ?, ?, ?, 0)";
+            String sql = "INSERT INTO battlearenadata.communitymap (map_id, map_name, map_width, map_height, map_data, map_downloads) VALUES (?, ?, ?, ?, ?, 0)";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, map.getMapID());
             stmt.setString(2, map.getMapName());
@@ -200,7 +200,7 @@ public class OracleDB implements ISQLDataBase {
     @Override
     public void createPlayer(String playerName, String playerPW) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0)";
+            String sql = "INSERT INTO battlearenadata.player (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, powerups_collected, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0, 0)";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
             stmt.setString(2, playerPW);
@@ -219,15 +219,16 @@ public class OracleDB implements ISQLDataBase {
     @Override
     public void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException {
         try (Connection connection = connect()) {
-            String sql = "UPDATE battlearenadata.players SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?";
+            String sql = "UPDATE battlearenadata.player SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, powerups_collected = ?, ingame_time = ? WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setInt(1, stats.getGamesWon());
             stmt.setInt(2, stats.getGamesLost());
             stmt.setInt(3, stats.getKills());
             stmt.setInt(4, stats.getDeaths());
             stmt.setInt(5, stats.getBlocksDestroyed());
-            stmt.setInt(6, stats.getGameTime());
-            stmt.setString(7, account.getPlayerName());
+            stmt.setInt(6, stats.getPowerUpsCollected());
+            stmt.setInt(7, stats.getGameTime());
+            stmt.setString(8, account.getPlayerName());
 
             log.info("Sending SQL statement.");
             stmt.executeQuery();
@@ -243,7 +244,7 @@ public class OracleDB implements ISQLDataBase {
     @Override
     public void resetPlayerStats(PlayerAccount account) throws SQLException {        //verification of player credentials necessary beforehand (use methode "verifyAccountData" in "Persistence.java)
         try (Connection connection = connect()) {
-            String sql = "UPDATE battlearenadata.players SET games_won = 0, games_lost = 0, kills = 0, deaths = 0, blocks_destroyed = 0, ingame_time = 0 WHERE player_name = ?";
+            String sql = "UPDATE battlearenadata.player SET games_won = 0, games_lost = 0, kills = 0, deaths = 0, blocks_destroyed = 0, powerups_collected = 0, ingame_time = 0 WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, account.getPlayerName());
 
@@ -258,4 +259,4 @@ public class OracleDB implements ISQLDataBase {
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java
index d79787ae..852381ac 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java
@@ -19,7 +19,7 @@ public class Persistence {
     private static final Logger log = LogManager.getLogger(Persistence.class);
     private static final Persistence persistenceSingleton = new Persistence();
     private final GsonHandler gsonHandler = new GsonHandler();
-    protected OracleDB db = new OracleDB(); //optionally make methods of GsonHandler and OracleDB static ; "protected" for testing purposes to showcase Mockito tests
+    private OracleDB db = new OracleDB(); //optionally make methods of GsonHandler and OracleDB static ; "protected" for testing purposes to showcase Mockito tests
     private ArrayList<MapData> coreMaps;
     private ArrayList<MapData> communityMaps;
     private PlayerStatistics statistics;
@@ -73,10 +73,8 @@ public class Persistence {
         try {
             if (account.getAccountType() == AccountType.LOCAL) {
                 statistics = gsonHandler.loadStats();
-                Parser.playerStatsValid(statistics);
             } else {
                 statistics = db.getStatistics(account.getPlayerName());
-                Parser.playerStatsValid(statistics);
             }
             log.info("Player statistics successfully loaded!");
         } catch (SQLException e) {
@@ -89,8 +87,6 @@ public class Persistence {
         } catch (GSONException e) {
             log.error(e);
             throw new DatabaseException(e.getMessage());
-        } catch (ParserException e) {
-            throw new RuntimeException("Player statistics data corrupted!");
         }
     }
 
@@ -221,13 +217,14 @@ public class Persistence {
         }
     }
 
-    public synchronized void updatePlayerStatistics(int kills, int deaths, int gameTime, int blocksDestroyed, boolean gameWon) throws DatabaseException {  //after game round; only update stats in RAM, not in persistence (run savePlayerStatistics() method at end of program to save stats to persistence)
+    public synchronized void updatePlayerStatistics(int kills, int deaths, int gameTime, int blocksDestroyed, int powerUpsCollected, boolean gameWon) throws DatabaseException {  //after game round; only update stats in RAM, not in persistence (run savePlayerStatistics() method at end of program to save stats to persistence)
         try {
-            Parser.playerStatsValid(new PlayerStatistics(0, 0, kills, deaths, blocksDestroyed, gameTime)); //temp instance of PLayerStatistics to validate new values
+            Parser.playerStatsValid(new PlayerStatistics(0, 0, kills, deaths, blocksDestroyed, powerUpsCollected, gameTime)); //temp instance of PLayerStatistics to validate new values
             statistics.addKills(kills);
             statistics.addDeaths(deaths);
             statistics.addGameTime(gameTime);
             statistics.addBlocksDestroyed(blocksDestroyed);
+            statistics.addPowerUpsCollected(powerUpsCollected);
             if (gameWon) {
                 statistics.addGamesWon();
             } else {
@@ -362,6 +359,16 @@ public class Persistence {
         }
     }
 
+    public synchronized void verifyPlayerStatistics() throws DatabaseException {
+        try {
+            Parser.playerStatsValid(statistics);
+            log.info("Player statistics valid!");
+        } catch (Exception e) {
+            log.error(e);
+            throw new DatabaseException(e.getMessage());
+        }
+    }
+
     public synchronized void resetPlayerAccount() throws DatabaseException {
         try {
             account = new PlayerAccount("", "", AccountType.NONE);
@@ -375,12 +382,12 @@ public class Persistence {
     public synchronized void resetPlayerStatistics() throws DatabaseException {
         try {
             if (account.getAccountType() == AccountType.LOCAL) {
-                statistics = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+                statistics = new PlayerStatistics(0, 0, 0, 0, 0, 0, 0);
                 gsonHandler.saveStats(statistics);
             } else if (account.getAccountType() == AccountType.ONLINE) {
                 verifyPlayerAccount();
                 db.resetPlayerStats(account);
-                statistics = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+                statistics = new PlayerStatistics(0, 0, 0, 0, 0, 0, 0);
             }
             log.info("Player statistics successfully reset on local storage!");
         } catch (Exception e) {
@@ -443,4 +450,4 @@ public class Persistence {
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java
index fa2a0549..a39d5933 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java
@@ -10,14 +10,16 @@ public class PlayerStatistics {
     private int kills = 0;
     private int deaths = 0;
     private int blocksDestroyed = 0;
+    private int powerUpsCollected = 0;
     private int gameTime = 0;   //in seconds
 
-    public PlayerStatistics(int gamesWon, int gamesLost, int kills, int deaths, int blocksDestroyed, int gameTime) {
+    public PlayerStatistics(int gamesWon, int gamesLost, int kills, int deaths, int blocksDestroyed, int powerUpsCollected, int gameTime) {
         this.gamesWon = gamesWon;
         this.gamesLost = gamesLost;
         this.kills = kills;
         this.deaths = deaths;
         this.blocksDestroyed = blocksDestroyed;
+        this.powerUpsCollected = powerUpsCollected;
         this.gameTime = gameTime;
     }
 
@@ -61,6 +63,14 @@ public class PlayerStatistics {
         this.blocksDestroyed = this.blocksDestroyed + blocksDestroyed;
     }
 
+    public int getPowerUpsCollected() {
+        return powerUpsCollected;
+    }
+
+    protected void addPowerUpsCollected(int powerUpsCollected) {
+        this.powerUpsCollected = this.powerUpsCollected + powerUpsCollected;
+    }
+
     public int getGameTime() {
         return gameTime;
     }
@@ -73,4 +83,4 @@ public class PlayerStatistics {
         this.gameTime = this.gameTime + gameTime;
     }
 
-}
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
index b908c3e9..e6fd178d 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
@@ -43,6 +43,7 @@ public class RuntimeInfo {
     private int kills = 0;
     private int deaths = 0;
     private int blocksDestroyed = 0;
+    private int powerUpsCollected = 0;
     private int gameTime = 0;
 
     //multiplayer
@@ -83,11 +84,12 @@ public class RuntimeInfo {
     }
 
     public void resetGameStats() {
+        gameWon = false;
         kills = 0;
         deaths = 0;
         blocksDestroyed = 0;
+        powerUpsCollected = 0;
         gameTime = 0;
-        gameWon = false;
     }
 
     public GameState getGameState() {
@@ -178,6 +180,18 @@ public class RuntimeInfo {
         blocksDestroyed = blocksDestroyed + 1;
     }
 
+    public int getPowerUpsCollected() {
+        return powerUpsCollected;
+    }
+
+    public void setPowerUpsCollected(int powerUpsCollected) {
+        this.powerUpsCollected = powerUpsCollected;
+    }
+
+    public void addPowerUpsCollected() {
+        powerUpsCollected = powerUpsCollected + 1;
+    }
+
     public int getGameTime() {
         return gameTime;
     }
@@ -241,4 +255,4 @@ public class RuntimeInfo {
     public void setPlayerID(int playerID) {
         this.playerID = playerID;
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ThreadStartup3.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ThreadStartup3.java
index 4ee8d151..bf5ff7d7 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ThreadStartup3.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ThreadStartup3.java
@@ -18,9 +18,7 @@ public class ThreadStartup3 extends Thread{
             threadsInstance.setThreadStartup3Msg("");
             threadsInstance.setThreadStartup3(ThreadStatus.RUNNING);
             persistenceInst.loadPlayerStatistics();
-            if(persistenceInst.getAccount().getAccountType() != AccountType.NONE){
-                persistenceInst.verifyPlayerAccount();
-            }
+            persistenceInst.verifyPlayerStatistics();
             log.info("Startup routine part3 complete!");
             threadsInstance.setThreadStartup3(ThreadStatus.FINISHED);
         } catch (Exception e) {
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ThreadUpdateStats.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ThreadUpdateStats.java
index b5f93bd9..c5b27d96 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ThreadUpdateStats.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ThreadUpdateStats.java
@@ -17,7 +17,7 @@ public class ThreadUpdateStats extends Thread{
         try {
             threadsInstance.setThreadUpdateStatsMsg("");
             threadsInstance.setThreadUpdateStats(ThreadStatus.RUNNING);
-            persistenceInst.updatePlayerStatistics(runtimeInfoInst.getKills(), runtimeInfoInst.getDeaths(), runtimeInfoInst.getGameTime(), runtimeInfoInst.getBlocksDestroyed(), runtimeInfoInst.isGameWon());
+            persistenceInst.updatePlayerStatistics(runtimeInfoInst.getKills(), runtimeInfoInst.getDeaths(), runtimeInfoInst.getGameTime(), runtimeInfoInst.getBlocksDestroyed(), runtimeInfoInst.getPowerUpsCollected(), runtimeInfoInst.isGameWon());
             runtimeInfoInst.resetGameStats();
             log.info("Update statistics thread finished successfully!");
             threadsInstance.setThreadUpdateStats(ThreadStatus.FINISHED);
@@ -28,4 +28,4 @@ public class ThreadUpdateStats extends Thread{
             threadsInstance.setThreadUpdateStats(ThreadStatus.FAILED);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
index 280cfe87..9fcf03ea 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
@@ -342,6 +342,10 @@ public class Parser {
             throw new ParserException("Player statistics data corrupted - Minimum value for destroyed blocks is 0!");
         }
 
+        if (stats.getPowerUpsCollected() < 0) {
+            throw new ParserException("Player statistics data corrupted - Minimum value for collected Powerups is 0!");
+        }
+
         if (stats.getGameTime() < 0) {
             throw new ParserException("Player statistics data corrupted - Minimum value for ingame time is 0 seconds!");
         }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql
index 63b515d5..bd22080f 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql
@@ -1,8 +1,14 @@
 --Note: DDL to be run as admin on OracleDB; Passwords for user accounts are not included and must be inserted before execution
 
-DROP TABLE battlearenadata.coremaps;
-DROP TABLE battlearenadata.communitymaps;
-DROP TABLE battlearenadata.players;
+ALTER TABLE battlearenadata.player DROP CONSTRAINT player_name_uni;
+ALTER TABLE battlearenadata.communitymap DROP CONSTRAINT map_data_uni2;
+ALTER TABLE battlearenadata.communitymap DROP CONSTRAINT map_id_uni2;
+ALTER TABLE battlearenadata.coremap DROP CONSTRAINT map_data_uni;
+ALTER TABLE battlearenadata.coremap DROP CONSTRAINT map_id_uni;
+
+DROP TABLE battlearenadata.coremap;
+DROP TABLE battlearenadata.communitymap;
+DROP TABLE battlearenadata.player;
 
 DROP USER battlearenaplayer;
 DROP USER battlearenadata;
@@ -12,50 +18,128 @@ CREATE USER battlearenadata IDENTIFIED BY "insertPasswordHere";
 
 GRANT CONNECT TO battlearenaplayer;
 
-CREATE TABLE battlearenadata.coremaps(
-                                         map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
-                                         map_name VARCHAR(30) NOT NULL,
-                                         map_width INTEGER NOT NULL,
-                                         map_height INTEGER NOT NULL,
-                                         map_data VARCHAR(1082) NOT NULL UNIQUE); --allows for map size up to 19x19 (when using double digit numbers for tiles)
-
-CREATE TABLE battlearenadata.communitymaps(
-                                              map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
-                                              map_name VARCHAR(30) NOT NULL,
-                                              map_width INTEGER NOT NULL,
-                                              map_height INTEGER NOT NULL,
-                                              map_data VARCHAR(1082) NOT NULL UNIQUE,  --allows for map size up to 19x19 (when using double digit numbers for tiles)
-                                              map_downloads INTEGER NOT NULL);
-
-CREATE TABLE battlearenadata.players(
-                        player_name VARCHAR(40) NOT NULL UNIQUE, --Player name is PlayerID
-                        player_pw VARCHAR(40) NOT NULL,
-                        games_won INTEGER NOT NULL,
-                        games_lost INTEGER NOT NULL,
-                        kills INTEGER NOT NULL,
-                        deaths INTEGER NOT NULL,
-                        blocks_destroyed INTEGER NOT NULL,
-                        ingame_time INTEGER NOT NULL);
-
-ALTER USER battlearenadata QUOTA 500M ON coremaps;
-ALTER USER battlearenadata QUOTA 500M ON communitymaps;
-ALTER USER battlearenadata QUOTA 500M ON players;
-
-INSERT INTO battlearenadata.coremaps (map_id, map_name, map_width, map_height, map_data)
+CREATE TABLE battlearenadata.coremap(
+                                        map_id CHAR(40)
+    , map_name VARCHAR(30)
+    , map_width INTEGER
+    , map_height INTEGER
+    , map_data VARCHAR(1082));
+
+ALTER TABLE battlearenadata.coremap ADD CONSTRAINT map_id_uni UNIQUE (map_id);
+ALTER TABLE battlearenadata.coremap MODIFY map_id NOT NULL;
+ALTER TABLE battlearenadata.coremap MODIFY map_name NOT NULL;
+ALTER TABLE battlearenadata.coremap MODIFY map_width NOT NULL;
+ALTER TABLE battlearenadata.coremap MODIFY map_height NOT NULL;
+ALTER TABLE battlearenadata.coremap ADD CONSTRAINT map_data_uni UNIQUE (map_data);
+ALTER TABLE battlearenadata.coremap MODIFY map_data NOT NULL;
+
+CREATE TABLE battlearenadata.communitymap(
+                                             map_id CHAR(40)
+    , map_name VARCHAR(30)
+    , map_width INTEGER
+    , map_height INTEGER
+    , map_data VARCHAR(1082)
+    , map_downloads INTEGER);
+
+ALTER TABLE battlearenadata.communitymap ADD CONSTRAINT map_id_uni2 UNIQUE (map_id);
+ALTER TABLE battlearenadata.communitymap MODIFY map_id NOT NULL;
+ALTER TABLE battlearenadata.communitymap MODIFY map_name NOT NULL;
+ALTER TABLE battlearenadata.communitymap MODIFY map_width NOT NULL;
+ALTER TABLE battlearenadata.communitymap MODIFY map_height NOT NULL;
+ALTER TABLE battlearenadata.communitymap ADD CONSTRAINT map_data_uni2 UNIQUE (map_data);
+ALTER TABLE battlearenadata.communitymap MODIFY map_data NOT NULL;
+ALTER TABLE battlearenadata.communitymap MODIFY map_downloads NOT NULL;
+
+CREATE TABLE battlearenadata.player(
+                                       player_name VARCHAR(40)
+    , player_pw VARCHAR(40)
+    , games_won INTEGER
+    , games_lost INTEGER
+    , kills INTEGER
+    , deaths INTEGER
+    , blocks_destroyed INTEGER
+    , powerups_collected INTEGER
+    , ingame_time INTEGER);
+
+ALTER TABLE battlearenadata.player ADD CONSTRAINT player_name_uni UNIQUE (player_name);
+ALTER TABLE battlearenadata.player MODIFY player_name NOT NULL;
+ALTER TABLE battlearenadata.player MODIFY player_pw NOT NULL;
+ALTER TABLE battlearenadata.player MODIFY games_won NOT NULL;
+ALTER TABLE battlearenadata.player MODIFY games_lost NOT NULL;
+ALTER TABLE battlearenadata.player MODIFY kills NOT NULL;
+ALTER TABLE battlearenadata.player MODIFY deaths NOT NULL;
+ALTER TABLE battlearenadata.player MODIFY blocks_destroyed NOT NULL;
+ALTER TABLE battlearenadata.player MODIFY powerups_collected NOT NULL;
+ALTER TABLE battlearenadata.player MODIFY ingame_time NOT NULL;
+
+ALTER USER battlearenadata QUOTA 500M ON coremap;
+ALTER USER battlearenadata QUOTA 500M ON communitymap;
+ALTER USER battlearenadata QUOTA 500M ON player;
+
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
+VALUES ('b3d1910a7c4f0c5f4987e9af701a8fdd841b9cb2',
+        'SE3',
+        18,
+        18,
+        '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 0 0 0 16 0 0 0 16 0 16 16 16 0 0 0 0 10 10 0 0 0 16 0 0 0 16 0 16 0 0 0 0 0 0 10 10 0 0 0 16 0 0 0 16 0 16 16 16 0 0 0 0 10 10 0 0 0 16 0 16 0 16 0 16 0 0 0 0 0 0 10 10 0 0 0 0 16 0 16 0 0 16 16 16 0 0 0 0 10 10 0 1 1 0 1 1 0 0 0 0 1 1 0 1 1 0 10 10 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 10 10 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 10 10 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 10 10 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 10 10 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 10 10 0 0 11 10 10 0 11 10 10 0 0 11 10 10 0 0 10 10 0 0 11 0 0 0 11 0 0 0 0 0 0 11 0 0 10 10 0 0 11 10 10 0 11 10 10 0 0 11 10 10 0 0 10 10 0 0 0 0 11 0 11 0 0 0 0 0 0 11 0 0 10 10 0 0 11 10 10 0 11 10 10 0 0 11 10 10 0 0 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10');
+
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
 VALUES ('b8f5da1a3619a3585978a6d9c8c683c3210193e6',
-        'Arena1',
+        'Ruins',
         18,
         18,
         '11 10 13 10 13 10 10 12 14 14 11 10 10 13 10 13 10 12 11 0 0 0 0 0 16 0 2 2 0 3 0 0 0 3 0 12 11 0 16 0 0 0 0 0 1 2 0 0 0 0 16 0 1 12 11 16 0 0 3 0 16 0 2 2 0 0 3 0 0 0 0 12 11 0 3 0 0 16 0 1 1 2 0 0 0 0 16 0 0 12 11 0 0 16 16 0 0 0 1 2 0 0 0 0 3 16 0 12 11 16 0 0 12 10 10 15 12 2 11 15 16 15 15 11 0 12 11 0 0 0 12 0 1 1 0 2 0 0 0 0 0 11 0 12 11 0 0 16 12 5 5 5 5 4 5 5 5 5 0 11 1 12 11 0 0 0 12 11 10 10 10 2 12 0 0 1 0 11 0 12 11 0 0 0 12 1 0 0 11 2 12 16 0 1 0 11 0 12 11 0 0 0 12 0 1 0 11 2 12 0 16 0 0 11 0 12 11 0 1 0 12 0 0 12 11 2 12 11 13 10 13 11 0 12 11 0 0 0 12 0 0 0 0 2 0 0 0 0 0 0 0 12 11 0 0 0 12 15 13 10 12 14 11 10 13 10 13 12 0 12 11 1 0 0 1 0 0 0 0 2 0 0 1 1 0 0 0 12 11 0 0 1 0 0 1 0 0 2 0 0 1 0 0 1 0 12 11 10 15 15 10 10 15 10 12 14 11 10 10 15 10 15 10 12');
 
-INSERT INTO battlearenadata.coremaps (map_id, map_name, map_width, map_height, map_data)
-VALUES ('6b9ff964a4afc821672645d5c2bb8fb2b0dcb2e8',
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
+VALUES ('f482b89b32ab4315a85108d83fb57ec09cdb7e09',
         'Outpost',
         18,
         18,
-        '16 16 16 16 16 16 16 16 16 16 10 12 13 11 12 14 11 12 16 0 16 0 0 1 0 0 0 0 1 0 0 1 0 2 0 12 16 0 0 0 0 0 16 16 0 0 15 3 0 0 0 2 1 12 16 0 0 2 16 0 0 1 16 0 15 15 3 3 0 2 0 12 11 10 12 2 11 10 12 0 16 0 0 15 15 3 1 2 0 12 11 0 0 2 0 0 12 0 0 16 0 0 15 3 0 2 0 12 11 0 10 2 10 0 12 0 0 16 0 0 15 15 12 2 11 12 11 0 10 2 10 0 12 0 0 0 0 0 0 0 0 2 0 16 11 0 1 2 10 0 12 16 0 0 11 10 0 10 12 2 0 16 11 0 10 2 10 0 1 0 0 16 11 3 0 0 12 0 1 16 11 0 10 2 10 0 12 0 16 0 11 0 0 1 12 2 0 16 11 0 10 2 10 0 12 0 0 0 11 0 0 0 12 2 0 16 11 0 0 1 0 0 12 16 0 0 11 0 0 0 12 0 0 16 11 10 12 2 11 10 12 0 16 0 11 0 10 10 12 2 0 16 16 0 0 2 16 0 0 0 0 0 11 0 0 3 12 0 11 12 16 0 16 16 16 0 0 16 0 0 1 0 0 0 0 2 0 12 16 0 0 0 0 0 0 0 0 0 11 0 0 1 0 2 0 12 16 16 16 16 16 16 16 16 16 16 11 12 13 11 12 14 11 12');
+        '16 16 16 16 16 16 16 16 16 16 10 12 13 11 12 14 11 12 16 0 16 0 0 1 0 0 0 0 21 0 0 1 0 2 0 12 16 0 0 0 0 0 16 16 0 0 15 3 0 0 0 2 1 12 16 0 0 2 16 0 0 1 16 0 15 15 3 3 0 2 0 12 11 10 12 2 11 10 12 0 16 0 0 15 15 3 1 2 0 12 11 0 0 2 0 0 12 0 0 16 0 0 15 3 0 2 0 12 11 0 10 2 10 0 12 0 0 16 0 0 15 15 12 2 11 12 11 0 10 2 10 0 12 0 0 0 0 0 0 0 0 2 0 16 11 0 1 2 10 0 12 16 0 0 11 10 21 10 12 2 0 16 11 0 10 2 10 0 21 0 0 16 11 3 0 0 12 0 1 16 11 0 10 2 10 0 12 0 16 0 11 0 0 1 12 2 0 16 11 0 10 2 10 0 12 0 0 0 11 0 0 0 12 2 0 16 11 0 0 1 0 0 12 16 0 0 11 0 0 0 12 0 0 16 11 10 12 2 11 10 12 0 16 0 11 0 10 10 12 2 0 16 16 0 0 2 16 0 0 0 0 0 11 0 0 3 12 0 11 12 16 0 16 16 16 0 0 16 0 0 21 0 0 0 0 2 0 12 16 0 0 0 0 0 0 0 0 0 11 0 0 1 0 2 0 12 16 16 16 16 16 16 16 16 16 16 11 12 13 11 12 14 11 12');
+
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
+VALUES ('82e6709231e6add4279097f5efe074f862eea1d8',
+        'Kings-Crossing',
+        18,
+        18,
+        '10 10 10 10 10 10 10 12 14 14 11 10 10 10 10 10 10 10 10 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 10 10 0 11 10 10 12 0 21 2 2 21 0 11 10 10 12 0 10 10 0 11 4 4 4 0 21 2 2 21 0 4 4 4 12 0 10 10 0 11 4 4 0 0 21 2 2 21 0 0 4 4 12 0 10 10 0 11 4 0 0 0 21 2 2 21 0 0 0 4 12 0 10 10 0 0 0 0 0 21 1 2 2 1 21 0 0 0 0 0 10 10 0 21 21 21 21 1 1 2 2 1 1 21 21 21 21 0 10 14 5 5 5 5 5 5 5 6 6 5 5 5 5 5 5 5 14 14 5 5 5 5 5 5 5 6 6 5 5 5 5 5 5 5 14 10 0 21 21 21 21 1 1 2 2 1 1 21 21 21 21 0 10 10 0 0 0 0 0 21 1 2 2 1 21 0 0 0 0 0 10 10 0 11 4 0 0 0 21 2 2 21 0 0 0 4 12 0 10 10 0 11 4 4 0 0 21 2 2 21 0 0 4 4 12 0 10 10 0 11 4 4 4 0 21 2 2 21 0 4 4 4 12 0 10 10 0 11 10 10 12 0 21 2 2 21 0 11 10 10 12 0 10 10 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 10 10 10 10 10 10 10 10 12 14 14 11 10 10 10 10 10 10 10');
+
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
+VALUES ('db8fb88e7a0c7bb133f792b5dd6b3ebbd9d6a15f',
+        'Maze',
+        18,
+        18,
+        '16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 0 0 0 0 0 0 0 0 0 0 16 0 0 0 0 0 16 16 0 16 16 16 16 0 16 16 16 16 16 0 16 16 16 0 16 16 0 16 0 0 0 0 0 0 20 0 0 0 0 0 16 0 16 16 0 16 16 16 16 16 16 16 0 16 16 16 16 0 16 0 16 16 0 0 20 0 0 0 0 0 0 0 0 0 16 0 16 0 16 16 0 16 0 16 16 16 16 16 16 16 16 0 16 0 16 20 16 16 0 16 0 0 0 0 20 0 0 0 16 0 16 0 16 0 16 16 0 16 16 16 16 16 0 16 16 0 16 0 16 0 16 0 16 16 20 0 0 16 0 0 0 16 16 0 16 0 16 0 16 0 16 16 0 16 0 16 0 16 0 16 16 20 0 0 0 0 16 0 16 16 0 16 0 16 0 16 16 16 16 16 16 16 16 0 16 0 16 16 0 16 20 16 0 0 0 0 0 16 0 0 0 20 0 0 16 16 0 16 0 16 16 16 16 16 0 16 0 16 16 16 16 0 16 16 0 16 0 0 0 0 0 0 0 16 0 0 0 0 16 0 16 16 0 16 16 0 16 16 16 16 16 16 16 16 16 0 16 0 16 16 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16');
+
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
+VALUES ('ac7c6f0fcaaf730804925aae280cce26f0da481e',
+        'AsymmetricBomberman',
+        18,
+        18,
+        '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 1 20 1 20 1 20 1 20 1 20 1 20 1 1 10 10 1 1 20 10 20 10 20 10 20 10 20 10 20 10 20 1 10 10 1 20 1 20 1 20 1 20 1 20 1 20 1 20 1 20 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 1 20 1 20 1 20 1 20 1 20 1 20 1 20 1 20 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 1 20 1 20 1 20 1 20 1 20 1 20 1 20 1 20 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 1 20 1 20 1 20 1 20 1 20 1 20 1 20 1 20 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 1 20 1 20 1 20 1 20 1 20 1 20 1 20 1 20 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 1 20 1 20 1 20 1 20 1 20 1 20 1 20 1 20 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 1 20 1 20 1 20 1 20 1 20 1 20 1 20 1 1 10 10 1 1 20 10 20 10 20 10 20 10 20 10 20 10 1 1 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10');
+
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
+VALUES ('ff52df212fcd29f16db9d7aa11d305cad9063c35',
+        'SymmetricBomberman',
+        18,
+        18,
+        '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 20 20 1 20 1 20 20 1 20 1 20 1 20 1 10 10 1 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 20 20 1 20 1 20 1 20 20 1 20 1 20 1 20 1 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 1 20 1 20 1 20 1 20 20 1 20 1 20 1 20 1 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 1 20 1 20 1 20 1 20 20 1 20 1 20 1 20 1 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 1 20 1 20 1 20 1 20 20 1 20 1 20 1 20 1 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 1 20 1 20 1 20 1 20 20 1 20 1 20 1 20 1 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 1 20 1 20 1 20 1 20 20 1 20 1 20 1 20 20 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 1 10 10 1 20 1 20 1 20 1 20 1 20 20 1 20 20 1 1 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10');
+
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
+VALUES ('8bf04771fc5eea669f8dda582fe8d8b159f15009',
+        'SymmetricBombermanFullBoxed',
+        18,
+        18,
+        '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1 1 20 20 20 20 20 20 20 20 20 20 20 20 1 1 10 10 1 10 20 10 20 10 20 10 10 20 10 20 10 20 10 1 10 10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10 10 10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 10 20 10 20 10 20 10 20 10 10 20 10 20 10 20 10 20 10 10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 10 1 10 20 10 20 10 20 10 10 20 10 20 10 20 10 1 10 10 1 1 20 20 20 20 20 20 20 20 20 20 20 20 1 1 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10');
+
+INSERT INTO battlearenadata.coremap (map_id, map_name, map_width, map_height, map_data)
+VALUES ('09f4fbab8fd30c11a585ade60258aadebb424c23',
+        'HelloWorld',
+        18,
+        18,
+        '10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 10 11 0 11 0 11 10 0 11 0 0 11 0 0 11 10 10 10 10 11 0 11 0 11 0 0 11 0 0 11 0 0 11 0 11 10 10 11 10 10 0 11 10 0 11 0 0 11 0 0 11 0 11 10 10 11 0 11 0 11 0 0 11 0 0 11 0 0 11 0 11 10 10 11 0 11 0 11 10 0 11 10 0 11 10 0 11 10 10 10 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 10 0 0 0 0 0 0 16 16 16 16 0 0 0 0 0 0 10 10 0 0 0 0 0 16 16 16 16 16 16 0 0 0 0 0 10 10 0 0 0 0 16 16 16 16 16 16 16 16 0 0 0 0 10 10 0 0 0 0 16 16 16 16 16 16 16 16 0 0 0 0 10 10 0 0 0 0 16 16 16 16 16 16 16 16 0 0 0 0 10 10 0 0 0 0 16 16 16 16 16 16 16 16 0 0 0 0 10 10 0 0 0 0 0 16 16 16 16 16 16 0 0 0 0 0 10 10 0 0 0 0 0 0 16 16 16 16 0 0 0 0 0 0 10 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10');
 
-INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
+INSERT INTO battlearenadata.communitymap (map_id, map_name, map_width, map_height, map_data, map_downloads)
 VALUES ('fbf44184867512faecc195ae75ca55d5ab7bad2d',
         'Arena3',
         18,
@@ -63,7 +147,7 @@ VALUES ('fbf44184867512faecc195ae75ca55d5ab7bad2d',
         '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12',
         0);
 
-INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
+INSERT INTO battlearenadata.communitymap (map_id, map_name, map_width, map_height, map_data, map_downloads)
 VALUES ('1c23b362fd666c5fb7ed60ca611b17246424e49f',
         'Arena4',
         18,
@@ -71,30 +155,32 @@ VALUES ('1c23b362fd666c5fb7ed60ca611b17246424e49f',
         '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 4 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12',
         0);
 
-INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
+INSERT INTO battlearenadata.player (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, powerups_collected, ingame_time)
 VALUES ('Player1',
-        '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', --Hash of password "password"
+        '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
         18,
         0,
         80,
         0,
         140,
+        45,
         5000);
 
-INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
+INSERT INTO battlearenadata.player (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, powerups_collected, ingame_time)
 VALUES ('Player2',
-        '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', --Hash of password "password"
+        '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8',
         15,
         3,
         50,
         5,
         110,
+        36,
         6000);
 
-GRANT SELECT ON battlearenadata.coremaps TO battlearenaplayer;
+GRANT SELECT ON battlearenadata.coremap TO battlearenaplayer;
 
-GRANT SELECT, INSERT ON battlearenadata.communitymaps TO battlearenaplayer;
+GRANT SELECT, INSERT ON battlearenadata.communitymap TO battlearenaplayer;
 
-GRANT SELECT, INSERT, UPDATE ON battlearenadata.players TO battlearenaplayer;
+GRANT SELECT, INSERT, UPDATE ON battlearenadata.player TO battlearenaplayer;
 
-GRANT UPDATE (map_downloads) ON battlearenadata.communitymaps  TO battlearenaplayer;
\ No newline at end of file
+GRANT UPDATE (map_downloads) ON battlearenadata.communitymap TO battlearenaplayer;
\ No newline at end of file
diff --git a/src/main/resources/player/playerStatsLocal.json b/src/main/resources/player/playerStatsLocal.json
index 5e8195f7..67229e9a 100644
--- a/src/main/resources/player/playerStatsLocal.json
+++ b/src/main/resources/player/playerStatsLocal.json
@@ -4,5 +4,6 @@
   "kills": 0,
   "deaths": 0,
   "blocksDestroyed": 0,
+  "powerUpsCollected": 0,
   "gameTime": 0
 }
\ No newline at end of file
diff --git a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java
index 980f0054..fc2b3ca0 100644
--- a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java
+++ b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java
@@ -226,28 +226,31 @@ class ParserTest {
 
     @Test
     void statsValid(){
-        PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+        PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0, 0);
         assertDoesNotThrow(() -> Parser.playerStatsValid(stats));
     }
 
     @Test
     void statsInvalid(){
-        ParserException testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, -1, 0, 0, 0, 0)));
-        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for lost games is 0!"));
-
-        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(-1, 0, 0, 0, 0, 0)));
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(-1, 0, 0, 0, 0, 0, 0)));
         assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for won games is 0!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, -1, 0, 0, 0)));
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, -1, 0, 0, 0, 0, 0)));
+        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for lost games is 0!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, -1, 0, 0, 0, 0)));
         assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for kills is 0!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, -1, 0, 0)));
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, -1, 0, 0, 0)));
         assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for deaths is 0!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, 0, -1, 0)));
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, 0, -1, 0, 0)));
         assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for destroyed blocks is 0!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, 0, 0, -1)));
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, 0, 0, -1, 0)));
+        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for collected Powerups is 0!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, 0, 0, 0, -1)));
         assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for ingame time is 0 seconds!"));
     }
 
-- 
GitLab