From 912b638d97e30ef58c47a87ebf99becff7731ebe Mon Sep 17 00:00:00 2001
From: Martin <ms618@hdm-stuttgart.de>
Date: Sat, 13 Jan 2024 23:29:50 +0100
Subject: [PATCH] Update: Parser.java (added method to verify PlayerStatistics
 data) Update: ParserTest.java (change text of an exception) Update:
 AzureDB.java (rephrased some exceptions; fixed SQL statement of
 "uploadCommunityMap" method) Update: OracleDB.java (rephrased some
 exceptions; fixed SQL statement of "uploadCommunityMap" method) Update:
 GsonHandler.java (rephrased some exceptions) Update: DDL_Script_Oracle.sql
 (added second community map) Update: DDL_Script_AzureDB.sql (added second
 community map) Update: Persistence.java (added method to verify core maps and
 community maps; moved methods from RuntimeInfo.java for creating
 RemoteMapsList and setting map for next game round) Update: RuntimeInfo.java
 (moved methods from RuntimeInfo.java for creating RemoteMapsList and setting
 map for next game round; added method to calculate game time) Update:
 log4j2.xml (enabled logging to file)

---
 .../Model/DataStorage/Classes/AzureDB.java    |  64 ++++----
 .../DataStorage/Classes/GsonHandler.java      |  60 +++++---
 .../Model/DataStorage/Classes/OracleDB.java   |  64 ++++----
 .../DataStorage/Classes/Persistence.java      | 139 ++++++++++++++++--
 .../DataStorage/Classes/PlayerStatistics.java |   2 +-
 .../DataStorage/Classes/RuntimeInfo.java      |  45 +-----
 .../DataStorage/Classes/Utilities/Parser.java |  28 ++++
 .../Scripts/DDL_Script_AzureDB.sql            |   8 +
 .../DataStorage/Scripts/DDL_Script_Oracle.sql |   8 +
 src/main/resources/log4j2.xml                 |   1 +
 src/main/resources/maps/communityMaps.json    |   7 +
 11 files changed, 282 insertions(+), 144 deletions(-)

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 38e6fcb0..ee75891c 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
@@ -36,7 +36,7 @@ public class AzureDB implements ISQLDataBase {
             //log.info("Database connection test" + connection.getCatalog());
             connection.setAutoCommit(true);
 
-            log.info("Connecting to the database!");
+            log.info("Connecting to SQL database ...");
 
             return connection;
         }
@@ -53,7 +53,7 @@ public class AzureDB implements ISQLDataBase {
             String sql = "SELECT * FROM CoreMaps";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             while(rs.next()){
@@ -61,12 +61,12 @@ public class AzureDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Coremaps retrieved successfully");
+            log.info("Core-Maps retrieved successfully from SQL server!");
             return newMaps;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving coremaps! " + e.getMessage());
+            throw new SQLException("Error retrieving Core-Maps from SQL server! " + e.getMessage());
         }
     }
 
@@ -77,7 +77,7 @@ public class AzureDB implements ISQLDataBase {
             String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM communitymaps";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             while(rs.next()){
@@ -85,12 +85,12 @@ public class AzureDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Community map names retrieved successfully");
+            log.info("Community-Map names retrieved successfully from SQL server!");
             return tempList;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving community map names! " + e.getMessage());
+            throw new SQLException("Error retrieving Community-Map names from SQL server! " + e.getMessage());
         }
     }
 
@@ -101,38 +101,38 @@ public class AzureDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, mapID);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
             MapData mapChosen = new MapData("", "",0,0, "");
             if(rs.next() == false){             //if no data matches
-                throw new SQLException("No match on Database");
+                throw new SQLException("No match on SQL database!");
             }
             while(rs.next()) {
                 mapChosen = new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data"));
             }
             rs.close();
             stmt.close();
-            log.info("Community map retrieved successfully");
+            log.info("Community-Map retrieved successfully from SQL server!");
 
             String sql2 = "UPDATE communitymaps SET map_downloads = map_downloads + 1 WHERE map_id = ?";
             PreparedStatement stmt2 = connection.prepareStatement(sql2);
             stmt2.setString(1, mapID);
             stmt2.executeQuery();
-            log.info("Sending SQL statement to update Download-Counter");
+            log.info("Sending SQL statement to update Download-Counter for downloaded map.");
             stmt2.close();
 
             return mapChosen;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving community map! " + e.getMessage());
+            throw new SQLException("Error retrieving Community-Map from SQL server! " + e.getMessage());
         }
     }
 
     @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) VALUES (?, ?, ?, ?, ?)";
+            String sql = "INSERT INTO communitymaps (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());
@@ -140,15 +140,15 @@ public class AzureDB implements ISQLDataBase {
             stmt.setInt(4, map.getMapHeight());
             stmt.setString(5, map.getMapData());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Community Map uploaded successfully");
+            log.info("Community-Map uploaded successfully to SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error uploading created community map! " + e.getMessage());
+            throw new SQLException("Error uploading created Community-Map to SQL server! " + e.getMessage());
         }
     }
 
@@ -160,15 +160,15 @@ public class AzureDB implements ISQLDataBase {
             stmt.setString(1, playerName);
             stmt.setString(2, playerPW);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Online account created successfully");
+            log.info("Online account created successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error creating online account! " + e.getMessage());
+            throw new SQLException("Error creating online account on SQL server! " + e.getMessage());
         }
     }
 
@@ -179,7 +179,7 @@ public class AzureDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             String password = "";
@@ -188,12 +188,12 @@ public class AzureDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Player credentials retrieved successfully");
+            log.info("Player credentials retrieved successfully from SQL server!");
             return password;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving retrieving player credentials! " + e.getMessage());
+            throw new SQLException("Error retrieving retrieving player credentials from SQL server! " + e.getMessage());
         }
     }
 
@@ -204,10 +204,10 @@ public class AzureDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
             if(rs.next() == false){             //if no data matches
-                throw new SQLException("No match on database");
+                throw new SQLException("No match on SQL database!");
             }
             PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
             while(rs.next()) {
@@ -215,12 +215,12 @@ public class AzureDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Player statistics retrieved successfully");
+            log.info("Player statistics retrieved successfully from SQL server!");
             return stats;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving player statistics! " + e.getMessage());
+            throw new SQLException("Error retrieving player statistics from SQL server! " + e.getMessage());
         }
     }
 
@@ -237,15 +237,15 @@ public class AzureDB implements ISQLDataBase {
             stmt.setInt(6, stats.getGameTime());
             stmt.setString(7, account.getPlayerName());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Player statistics updated successfully");
+            log.info("Player statistics updated successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error updating player statistics! " + e.getMessage());
+            throw new SQLException("Error updating player statistics on SQL server! " + e.getMessage());
         }
     }
 
@@ -256,15 +256,15 @@ public class AzureDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, account.getPlayerName());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Player statistics reset successfully");
+            log.info("Player statistics reset successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error resetting player statistics! " + e.getMessage());
+            throw new SQLException("Error resetting player statistics on SQL server! " + e.getMessage());
         }
     }
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java
index b330be1f..0ad125eb 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java
@@ -37,12 +37,18 @@ public class GsonHandler {
         }
         try (FileReader reader = new FileReader(filePath)) {
             ArrayList<MapData> maps = gson.fromJson(reader, mapDataType);
-            log.info("GSON - Maps successfully loaded from JSON");
+            log.info("GSON - Maps successfully loaded from JSON!");
             return maps;
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Loading maps from JSON failed");
-            throw new GSONException("Error loading maps!");
+            if(type == MapType.COREMAP){
+                log.info("GSON - Loading Community-Maps from JSON failed!");
+                throw new GSONException("Loading Community-Maps from JSON failed!");
+            }
+            else{
+                log.info("GSON - Loading Community-Maps from JSON failed!");
+                throw new GSONException("Loading Community-Maps from JSON failed!");
+            }
         }
     }
 
@@ -56,80 +62,86 @@ public class GsonHandler {
         }
         try (FileWriter writer = new FileWriter(filePath)) {
             gson.toJson(maps, writer);
-            log.info("GSON - Maps successfully saved to JSON");
+            log.info("GSON - Maps successfully saved to JSON!");
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Saving maps to JSON failed");
-            throw new GSONException("Error saving maps!");
+            if(type == MapType.COREMAP){
+                log.info("GSON - Saving Core-Maps to JSON failed!");
+                throw new GSONException("Saving Core-Maps to JSON failed!");
+            }
+            else{
+                log.info("GSON - Saving Community-Maps to JSON failed!");
+                throw new GSONException("Saving Community-Maps to JSON failed!");
+            }
         }
     }
 
     public PlayerStatistics loadStats() throws GSONException {
         try (FileReader reader = new FileReader(filePathPlayerStats)) {
             PlayerStatistics stats = gson.fromJson(reader, playerStatsType);
-            log.info("GSON - Player statistics successfully loaded from JSON");
+            log.info("GSON - Player statistics successfully loaded from JSON!");
             return stats;
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Loading player statistics from JSON failed");
-            throw new GSONException("Error loading player statistics!");
+            log.info("GSON - Loading player statistics from JSON failed!");
+            throw new GSONException("Loading player statistics from JSON failed!");
         }
     }
 
     public void saveStats(PlayerStatistics stats) throws GSONException {
         try (FileWriter writer = new FileWriter(filePathPlayerStats)) {
             gson.toJson(stats, writer);
-            log.info("GSON - Player statistics successfully saved to JSON");
+            log.info("GSON - Player statistics successfully saved to JSON!");
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Saving player statistics to JSON failed");
-            throw new GSONException("Error saving player statistics!");
+            log.info("GSON - Saving player statistics to JSON failed!");
+            throw new GSONException("Saving player statistics to JSON failed!");
         }
     }
 
     public AppSettings loadSettings() throws GSONException {
         try (FileReader reader = new FileReader(filePathSettings)) {
             AppSettings settings = gson.fromJson(reader, settingsType);
-            log.info("GSON - Settings successfully loaded from JSON");
+            log.info("GSON - Settings successfully loaded from JSON!");
             return settings;
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Loading settings from JSON failed");
-            throw new GSONException("Error Loading settings!");
+            log.info("GSON - Loading settings from JSON failed!");
+            throw new GSONException("Loading settings from JSON failed!");
         }
     }
 
     public void saveSettings(AppSettings settings) throws GSONException {
         try (FileWriter writer = new FileWriter(filePathSettings)) {
             gson.toJson(settings, writer);
-            log.info("GSON - Settings successfully saved to JSON");
+            log.info("GSON - Settings successfully saved to JSON!");
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Saving settings to JSON failed");
-            throw new GSONException("Error saving settings!");
+            log.info("GSON - Saving settings to JSON failed!");
+            throw new GSONException("Saving settings to JSON failed!");
         }
     }
 
     public PlayerAccount loadAccount() throws GSONException {
         try (FileReader reader = new FileReader(filePathPlayerAccount)) {
             PlayerAccount account = gson.fromJson(reader, accountType);
-            log.info("GSON - Player account information successfully loaded from JSON");
+            log.info("GSON - Player account information successfully loaded from JSON!");
             return account;
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Loading player account information from JSON failed");
-            throw new GSONException("Error loading player account information!");
+            log.info("GSON - Loading player account information from JSON failed!");
+            throw new GSONException("Loading player account information from JSON failed!");
         }
     }
 
     public void saveAccount(PlayerAccount account) throws GSONException {
         try (FileWriter writer = new FileWriter(filePathPlayerAccount)) {
             gson.toJson(account, writer);
-            log.info("GSON - Player account information successfully saved to JSON");
+            log.info("GSON - Player account information successfully saved to JSON!");
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Saving player account information to JSON failed");
-            throw new GSONException("Error loading player account information!");
+            log.info("GSON - Saving player account information to JSON failed!");
+            throw new GSONException("Saving player account information to JSON failed!");
         }
     }
 
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 582b425c..2acc83f4 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
@@ -37,7 +37,7 @@ public class OracleDB implements ISQLDataBase {
             ods.setPassword(password);
             Connection conn = ods.getConnection();
 
-            log.info("Connecting to the database!");
+            log.info("Connecting to SQL database ...");
 
             return conn;
         }
@@ -54,7 +54,7 @@ public class OracleDB implements ISQLDataBase {
             String sql = "SELECT * FROM battlearenadata.coremaps";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             while(rs.next()){
@@ -62,12 +62,12 @@ public class OracleDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Coremaps retrieved successfully");
+            log.info("Core-Maps retrieved successfully from SQL server!");
             return newMaps;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving coremaps! " + e.getMessage());
+            throw new SQLException("Error retrieving Core-Maps from SQL server! " + e.getMessage());
         }
     }
 
@@ -78,7 +78,7 @@ public class OracleDB implements ISQLDataBase {
             String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM battlearenadata.communitymaps";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             while(rs.next()){
@@ -86,12 +86,12 @@ public class OracleDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Community map names retrieved successfully");
+            log.info("Community-Map names retrieved successfully from SQL server!");
             return tempList;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving community map names! " + e.getMessage());
+            throw new SQLException("Error retrieving Community-Map names from SQL server! " + e.getMessage());
         }
     }
 
@@ -102,38 +102,38 @@ public class OracleDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, mapID);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
             MapData mapChosen = new MapData("", "",0,0, "");
             if(rs.next() == false){             //if no data matches
-                throw new SQLException("No match on Database");
+                throw new SQLException("No match on SQL database!");
             }
             while(rs.next()) {
                 mapChosen = new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data"));
             }
             rs.close();
             stmt.close();
-            log.info("Community map retrieved successfully");
+            log.info("Community-Map retrieved successfully from SQL server!");
 
             String sql2 = "UPDATE battlearenadata.communitymaps SET map_downloads = map_downloads + 1 WHERE map_id = ?";
             PreparedStatement stmt2 = connection.prepareStatement(sql2);
             stmt2.setString(1, mapID);
             stmt2.executeQuery();
-            log.info("Sending SQL statement to update Download-Counter");
+            log.info("Sending SQL statement to update Download-Counter for downloaded map!");
             stmt2.close();
 
             return mapChosen;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving community map! " + e.getMessage());
+            throw new SQLException("Error retrieving Community-Map from SQL server! " + e.getMessage());
         }
     }
 
     @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) VALUES (?, ?, ?, ?, ?)";
+            String sql = "INSERT INTO battlearenadata.communitymaps (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());
@@ -141,15 +141,15 @@ public class OracleDB implements ISQLDataBase {
             stmt.setInt(4, map.getMapHeight());
             stmt.setString(5, map.getMapData());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Community Map uploaded successfully");
+            log.info("Community-Map uploaded successfully to SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error uploading created community map! " + e.getMessage());
+            throw new SQLException("Error uploading created Community-Map to SQL server! " + e.getMessage());
         }
     }
 
@@ -161,15 +161,15 @@ public class OracleDB implements ISQLDataBase {
             stmt.setString(1, playerName);
             stmt.setString(2, playerPW);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Online account created successfully");
+            log.info("Online account created successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error creating online account! " + e.getMessage());
+            throw new SQLException("Error creating online account on SQL server! " + e.getMessage());
         }
     }
 
@@ -180,7 +180,7 @@ public class OracleDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             String password = "";
@@ -189,12 +189,12 @@ public class OracleDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Player credentials retrieved successfully");
+            log.info("Player credentials retrieved successfully from SQL server!");
             return password;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving retrieving player credentials! " + e.getMessage());
+            throw new SQLException("Error retrieving retrieving player credentials from SQL server! " + e.getMessage());
         }
     }
 
@@ -205,10 +205,10 @@ public class OracleDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
             if(rs.next() == false){             //if no data matches
-                throw new SQLException("No match on database");
+                throw new SQLException("No match on SQL database!");
             }
             PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
             while(rs.next()) {
@@ -216,12 +216,12 @@ public class OracleDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Player statistics retrieved successfully");
+            log.info("Player statistics retrieved successfully from SQL server!");
             return stats;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving player statistics! " + e.getMessage());
+            throw new SQLException("Error retrieving player statistics from SQL server! " + e.getMessage());
         }
     }
 
@@ -238,15 +238,15 @@ public class OracleDB implements ISQLDataBase {
             stmt.setInt(6, stats.getGameTime());
             stmt.setString(7, account.getPlayerName());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Player statistics updated successfully");
+            log.info("Player statistics updated successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error updating player statistics! " + e.getMessage());
+            throw new SQLException("Error updating player statistics on SQL server! " + e.getMessage());
         }
     }
 
@@ -257,15 +257,15 @@ public class OracleDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, account.getPlayerName());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Player statistics reset successfully");
+            log.info("Player statistics reset successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error resetting player statistics! " + e.getMessage());
+            throw new SQLException("Error resetting player statistics on SQL server! " + e.getMessage());
         }
     }
 
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 63697bae..1614d296 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
@@ -16,12 +16,15 @@ 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(); //evtl. Methoden von OracleDB static machen und von GSON Handler
-    protected ArrayList<MapData> coreMaps;
-    protected ArrayList<MapData> communityMaps;
-    protected PlayerStatistics statistics;
-    protected PlayerAccount account;
+    private OracleDB db = new OracleDB(); //evtl. Methoden von OracleDB static machen und von GSON Handler
+    private ArrayList<MapData> coreMaps;
+    private ArrayList<MapData> communityMaps;
+    private PlayerStatistics statistics;
+    private PlayerAccount account;
     private AppSettings settings;
+    //protected ArrayList<String> coreMapsListLocal;      //for drop-down list -- kommt eigentlich eher in RuntimeInfo
+    //protected ArrayList<String> communityMapsListLocal;  //for drop-down list -- kommt eigentlich eher in RuntimeInfo
+    protected ArrayList<MapInfo> communityMapsListRemote;  //for community map browser
 
 
 
@@ -31,10 +34,15 @@ public class Persistence {
         return persistenceSingleton;
     }
 
+    public PlayerStatistics getStatistics() {
+        return statistics;
+    }
+
     public void loadCoreMaps() throws DatabaseException {
         try {
             coreMaps = gsonHandler.loadMaps(MapType.COREMAP);
-            log.info("Core-Maps successfully loaded from file");
+            log.info("Core-Maps successfully loaded from file!");
+            //createCoreMapsList();
         }
         catch(Exception e){
             log.error(e);
@@ -45,7 +53,8 @@ public class Persistence {
     public void loadCommunityMaps() throws DatabaseException {
         try {
             communityMaps = gsonHandler.loadMaps(MapType.COMMUNITYMAP);
-            log.info("Community-Maps successfully loaded from file");
+            log.info("Community-Maps successfully loaded from file!");
+            //createLocalCommunityMapsList();
         }
         catch(Exception e){
             log.error(e);
@@ -57,7 +66,8 @@ public class Persistence {
         try {
             coreMaps = db.getCoreMaps();
             gsonHandler.saveMaps(coreMaps, MapType.COREMAP);
-            log.info("Maps successfully updated from SQL-Server");
+            //createCoreMapsList();
+            log.info("Core-Maps successfully updated from SQL-Server!");
         }
         catch(Exception e){
             log.error(e);
@@ -79,6 +89,7 @@ public class Persistence {
         try {
             communityMaps.add(db.getCommunityMapByID(mapID));
             gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
+            //createLocalCommunityMapsList();
             log.info("Community Map successfully retrieved from SQL-Server!");
         }
         catch(Exception e){
@@ -86,7 +97,7 @@ public class Persistence {
             if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
                 throw new DatabaseException("No connection to SQL server!");
             }
-            else if(e.getMessage().equals("No match on Database")){
+            else if(e.getMessage().equals("No match on Database!")){
                 throw new DatabaseException("No map existing for mapID: " + mapID);
             }
             else{
@@ -104,7 +115,8 @@ public class Persistence {
             }
             communityMaps.add(map);
             gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
-            log.info("Newly created map stored successfully in JSON");
+            //createLocalCommunityMapsList();
+            log.info("Newly created map stored successfully in JSON!");
         }
         catch(Exception e){
             log.error(e);
@@ -139,7 +151,7 @@ public class Persistence {
     public void loadSettings() throws DatabaseException {
         try {
             settings = gsonHandler.loadSettings();
-            log.info("Application settings successfully loaded from file");
+            log.info("Application settings successfully loaded from file!");
         }
         catch(Exception e){
             log.error(e);
@@ -163,6 +175,7 @@ public class Persistence {
                 throw new DatabaseException("Corrupted Account-Type. Please restart game.");
             }
             gsonHandler.saveAccount(account);
+            log.info("Player account successfully created!");
         }
         catch(ParserException e){
             log.error(e);
@@ -189,6 +202,7 @@ public class Persistence {
     public void loadPlayerAccount() throws DatabaseException {
         try {
             gsonHandler.loadAccount();
+            log.info("Player account successfully loaded!");
         }
         catch(Exception e){
             log.error(e);
@@ -199,7 +213,7 @@ public class Persistence {
     public void verifyPlayerAccount() throws DatabaseException {
         try {
             if (account.getAccountType() == AccountType.NONE) {
-                throw new DatabaseException("Must create playerAccount first");
+                throw new DatabaseException("Must create playerAccount first!");
             } else if (account.getAccountType() == AccountType.LOCAL) {
                 Parser.usernameValid(account.getPlayerName());
             } else if (account.getAccountType() == AccountType.ONLINE) {
@@ -212,6 +226,7 @@ public class Persistence {
             else{
                 throw new DatabaseException("AccountType invalid - accountData corrupted! Please create new Account or login with existing!");
             }
+            log.info("Player account successfully verified!");
         }
         catch(ParserException e){
             log.error(e);
@@ -222,7 +237,7 @@ public class Persistence {
             if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
                 throw new DatabaseException("No connection to SQL server! Do you want to continue without tracking statistics?");
             }
-            else if(e.getMessage().contains("No match on Database")){
+            else if(e.getMessage().contains("No match on SQL database!")){
                 throw new DatabaseException("No entry for player name " + account.getPlayerName() + " on SQL server. Please create account or login with different username!");
             }
             else{
@@ -242,6 +257,7 @@ public class Persistence {
             } else {
                 statistics = db.getStatistics(account.getPlayerName());
             }
+            log.info("Player statistics successfully loaded!");
         }
         catch(SQLException e){
             log.error(e);
@@ -285,7 +301,7 @@ public class Persistence {
         }
     }
 
-    public void resetPlayerStatistics() throws DatabaseException{     //on shutdown of game
+    public void resetPlayerStatistics() throws DatabaseException{
         try {
             verifyPlayerAccount();
             if (account.getAccountType() == AccountType.LOCAL) {
@@ -295,7 +311,7 @@ public class Persistence {
                 db.resetPlayerStats(account);
                 statistics = new PlayerStatistics(0, 0, 0, 0, 0, 0);
             }
-            log.info("Statistics successfully reset!");
+            log.info("Player statistics successfully reset on local storage!");
         }
         catch(Exception e){
             log.error(e);
@@ -306,20 +322,111 @@ public class Persistence {
         //implement me (user can click button to reset settings to default values)
     }
 
-    public void resetMaps(){
+    public void resetCoreMaps(){
         try {
             coreMaps = new ArrayList<MapData>();
             coreMaps.add(new MapData("09a02b54d05b5b7ebc29a4383ca12d3dda846b72", "Arena1", 18, 18, "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 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 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"));
             coreMaps.add(new MapData("0ab15557ab6dc4be60dfe6a9b0288bac3036bd97", "Arena2", 18, 18, "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 5 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"));
             gsonHandler.saveMaps(coreMaps, MapType.COREMAP);
+            log.info("Core maps successfully reset on local storage!");
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
 
+    public void resetCommunityMaps(){
+        try {
             communityMaps = new ArrayList<MapData>();
             communityMaps.add(new MapData("fbf44184867512faecc195ae75ca55d5ab7bad2d", "Arena3", 18, 18, "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"));
+            communityMaps.add(new MapData("1c23b362fd666c5fb7ed60ca611b17246424e49f", "Arena4", 18, 18, "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"));
             gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
+            log.info("Community maps successfully reset on local storage!");
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+    public void verifyCoreMaps() throws DatabaseException{
+        try {
+            for (int i = 0; coreMaps.size() > i; i++) {
+                Parser.mapDataValid(coreMaps.get(i).getMapData());
+                Parser.mapNameValid(coreMaps.get(i).getMapName());
+                Parser.sha1HexHashValid(coreMaps.get(i).getMapID());
+                if(!HashGenerator.hashAndHex(coreMaps.get(i).getMapData()).equals(coreMaps.get(i).getMapID())){
+                    throw new DatabaseException("mapData Hash does not match mapID!");
+                }
+            }
+            log.info("Core-Maps data is valid!");
         }
         catch(Exception e){
             log.error(e);
+            throw new DatabaseException(e.getMessage());
+        }
+    }
+
+    public void verifyCommunityMaps() throws DatabaseException{
+        try {
+            for (int i = 0; communityMaps.size() > i; i++) {
+                Parser.mapDataValid(communityMaps.get(i).getMapData());
+                Parser.mapNameValid(communityMaps.get(i).getMapName());
+                Parser.sha1HexHashValid(communityMaps.get(i).getMapID());
+                if(!HashGenerator.hashAndHex(communityMaps.get(i).getMapData()).equals(communityMaps.get(i).getMapID())){
+                    throw new DatabaseException("mapData Hash does not match mapID!");
+                }
+            }
+            log.info("Community-Maps data is valid!");
         }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException(e.getMessage());
+        }
+    }
+
+    //kommen beide eigentlich eher in die RuntimeInfo
+/*    public void createCoreMapsList(){               //for dropdown list in "create" scene
+        coreMapsListLocal = new ArrayList<String>();
+        for(int i = 0; i < coreMaps.size(); i++){
+            coreMapsListLocal.add(coreMaps.get(i).getMapName() + " (" + coreMaps.get(i).getMapID() + ")");
+        }
+    }
+
+    public void createLocalCommunityMapsList(){     //for dropdown list in "create" scene
+        communityMapsListLocal = new ArrayList<String>();
+        for (int i = 0; i < communityMaps.size(); i++) {
+            communityMapsListLocal.add(communityMaps.get(i).getMapName() + " (" + communityMaps.get(i).getMapID() + ")");
+        }
+    }*/
+
+    public void createRemoteCommunityMapsList(){        //for Map-Browser
+        try {
+            communityMapsListRemote = db.getCommunityMapsList();
+            log.info("MapList successfully retrieved from server!");
+            //log.info(communityMapsListRemote.get(0).getMapName());                 //for testing purposes
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+    public String getGameMap(String mapSelected, boolean choseCoremaps) throws DatabaseException{
+
+            String mapID = mapSelected.substring(mapSelected.indexOf("(") + 1, mapSelected.length() - 1);
+            if (choseCoremaps) {
+                for (int index = 0; index < coreMaps.size(); index++) {
+                    if (coreMaps.get(index).getMapID().equals(mapID)) {
+                        return coreMaps.get(index).getMapID();
+                    }
+                }
+            } else {
+                for (int index = 0; index < communityMaps.size(); index++) {
+                    if (communityMaps.get(index).getMapID().equals(mapID)) {
+                        return coreMaps.get(index).getMapID();
+                    }
+                }
+            }
+            throw new DatabaseException("Database error - Map not found!");
     }
 
 }
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 53232423..dbfdd698 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
@@ -11,7 +11,7 @@ public class PlayerStatistics {
     private int kills = 0;
     private int deaths = 0;
     private int blocksDestroyed = 0;
-    private int gameTime = 0;
+    private int gameTime = 0;   //in seconds
 
     public PlayerStatistics(int gamesLost, int gamesWon, int kills, int deaths, int blocksDestroyed, int gameTime) {
         this.gamesLost = gamesLost;
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 641449a5..12c229b2 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
@@ -13,9 +13,6 @@ public class RuntimeInfo {
     private static final Logger log = LogManager.getLogger(RuntimeInfo.class);
     private static final RuntimeInfo runtimeInfoSingleton = new RuntimeInfo();
     private final Persistence persistenceInst = Persistence.getInstance();
-    protected ArrayList<String> coreMapsListLocal;      //for drop-down list
-    protected ArrayList<String> communityMapsListLocal;  //for drop-down list
-    protected ArrayList<MapInfo> communityMapsListRemote;  //for community map browser
     protected String mapDataGame;
     protected boolean offlineMode;  //if Account-Type is online but no SQL connection: start game without stats tracking
 
@@ -43,47 +40,17 @@ public class RuntimeInfo {
     }
 
     public void setGameMap(String mapSelected, boolean choseCoremaps){
-        String mapID = mapSelected.substring(mapSelected.indexOf("(") + 1, mapSelected.length() - 1);
-
-        if(choseCoremaps) {
-            for (int index = 0; index < persistenceInst.coreMaps.size(); index++) {
-                if (persistenceInst.coreMaps.get(index).getMapID().equals(mapID)) {
-                    mapDataGame = persistenceInst.coreMaps.get(index).getMapID();
-                }
-            }
-        }
-        else  {
-            for (int index = 0; index < persistenceInst.communityMaps.size(); index++) {
-                if (persistenceInst.communityMaps.get(index).getMapID().equals(mapID)) {
-                    mapDataGame = persistenceInst.coreMaps.get(index).getMapID();
-                }
-            }
-        }
-    }
-
-    public void createCoreMapsList(){               //for dropdown list in "create" scene
-        coreMapsListLocal = new ArrayList<String>();
-        for(int i = 0; i < persistenceInst.coreMaps.size(); i++){
-            coreMapsListLocal.add(persistenceInst.coreMaps.get(i).getMapName() + " (" + persistenceInst.coreMaps.get(i).getMapID() + ")");
-        }
-    }
-
-    public void createLocalCommunityMapsList(){     //for dropdown list in "create" scene
-        communityMapsListLocal = new ArrayList<String>();
-        for (int i = 0; i < persistenceInst.communityMaps.size(); i++) {
-            communityMapsListLocal.add(persistenceInst.communityMaps.get(i).getMapName() + " (" + persistenceInst.communityMaps.get(i).getMapID() + ")");
-        }
-    }
-
-    public void createRemoteCommunityMapsList(){        //for Map-Browser
         try {
-            communityMapsListRemote = persistenceInst.db.getCommunityMapsList();
-            log.info("MapList successfully retrieved from server!");
-            //log.info(communityMapsListRemote.get(0).getMapName());                 //for testing purposes
+            mapDataGame = persistenceInst.getGameMap(mapSelected, choseCoremaps);
         }
         catch(Exception e){
             log.error(e);
         }
     }
 
+
+    public int gameTimeInHours(){
+        return persistenceInst.getStatistics().getGameTime() / 3600;
+    }
+
 }
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 385d1a4f..1c3337c5 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
@@ -1,6 +1,7 @@
 package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities;
 
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.PlayerStatistics;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -322,4 +323,31 @@ public class Parser {
         }
     }
 
+    public void playerStatsValid(PlayerStatistics stats) throws ParserException{
+
+        if(stats.getGamesLost() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for lost games is 0!");
+        }
+
+        if(stats.getGamesWon() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for won games is 0!");
+        }
+
+        if(stats.getKills() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for kills is 0!");
+        }
+
+        if(stats.getDeaths() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for deaths is 0!");
+        }
+
+        if(stats.getBlocksDestroyed() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for destroyed blocks 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_AzureDB.sql b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql
index c4029043..3ee29cb2 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql
@@ -54,6 +54,14 @@ 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 communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
+VALUES ('1c23b362fd666c5fb7ed60ca611b17246424e49f',
+        'Arena4',
+        18,
+        18,
+        '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 players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
 VALUES ('Player1',
         'password',
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 97ff0eea..2e1959bf 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
@@ -63,6 +63,14 @@ 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)
+VALUES ('1c23b362fd666c5fb7ed60ca611b17246424e49f',
+        'Arena4',
+        18,
+        18,
+        '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)
 VALUES ('Player1',
         'password',
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 6fb85716..9a77de28 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -16,6 +16,7 @@
         </Logger>
         <Root level="info">
             <AppenderRef ref="STDOUT"/>
+            <AppenderRef ref="A1"/>
         </Root>
     </Loggers>
 </Configuration>
\ No newline at end of file
diff --git a/src/main/resources/maps/communityMaps.json b/src/main/resources/maps/communityMaps.json
index a5c9f6ba..9c99ec44 100644
--- a/src/main/resources/maps/communityMaps.json
+++ b/src/main/resources/maps/communityMaps.json
@@ -5,5 +5,12 @@
     "mapWidth": 18,
     "mapHeight": 18,
     "mapData": "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"
+  },
+  {
+    "mapID": "1c23b362fd666c5fb7ed60ca611b17246424e49f",
+    "mapName": "Arena4",
+    "mapWidth": 18,
+    "mapHeight": 18,
+    "mapData": "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"
   }
 ]
\ No newline at end of file
-- 
GitLab